rm(list=ls())
load("introduzioneR_updated.RData")
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
1 2 3 4 5 6 7 8 9 10
Riprendiamo il lavoro fatto:
rm(list=ls())
load("introduzioneR_updated.RData")
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
1 2 3 4 5 6 7 8 9 10
I valori booleani TRUE e FALSE sono trattati nelle operazioni algebriche come 1 e 0 rispettivamente:
vettoreLunghezza10 > 5 lun mar mer gio ven lun mar mer gio ven
FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
as.numeric(vettoreLunghezza10 > 5) [1] 0 0 0 0 0 1 1 1 1 1
Questo permette di contare il numero di elementi che soddisfano una o più condizioni usando la funzione sum:
sum(vettoreLunghezza10 > 5)[1] 5
Questo in alternativa all’estrazione degli elementi e al successivo controllo della lunghezza:
length(vettoreLunghezza10[vettoreLunghezza10 > 5])[1] 5
NOTA: le parentesi quadre servono per accedere agli elementi di un oggetto (con qualche particolarità a seconda del tipo di oggetto - vedi a seguire)
MEMO: le parentesi tonde servono per: - cambiare l’ordine di priorità delle operazioni - stampare nel caso di un’assegnazione esplicita
La funzione which restituisce invece le posizioni degli elementi che soddisfano la condizione:
which(vettoreLunghezza10 > 5)lun mar mer gio ven
6 7 8 9 10
Queste posizioni possono essere utilizzate per estrarre gli elementi
vettoreLunghezza10[which(vettoreLunghezza10 > 5)]lun mar mer gio ven
6 7 8 9 10
E’ possibile però (più velocemente) passare in input all’operatore di estrazione [ direttamente il vettore di booleani
vettoreLunghezza10 > 5 lun mar mer gio ven lun mar mer gio ven
FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
vettoreLunghezza10[vettoreLunghezza10 > 5]lun mar mer gio ven
6 7 8 9 10
Proviamo ad esempio ad estrarre i numeri pari dal vettore resto della divisione per due:
vettoreLunghezza10 %% 2lun mar mer gio ven lun mar mer gio ven
1 0 1 0 1 0 1 0 1 0
I numeri pari hanno resto pari a 0:
vettoreLunghezza10 %% 2 == 0 lun mar mer gio ven lun mar mer gio ven
FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
Per cui si può sapere quali sono le posizioni degli elementi che soddisfano la condizione usando la funzione which:
which(vettoreLunghezza10 %% 2 == 0)mar gio lun mer ven
2 4 6 8 10
ed estrarre gli elementi usando la funzione [
vettoreLunghezza10[vettoreLunghezza10 %% 2 == 0]mar gio lun mer ven
2 4 6 8 10
Analogamente, ecco i numeri divisibili per 3:
vettoreLunghezza10 %% 3 == 0 lun mar mer gio ven lun mar mer gio ven
FALSE FALSE TRUE FALSE FALSE TRUE FALSE FALSE TRUE FALSE
which(vettoreLunghezza10 %% 3 == 0)mer lun gio
3 6 9
E’ possibile controllare più condizioni contemporaneamente: l’operatore & (AND logico) controlla se le due condizioni sono verificate simultaneamente; l’operatore | (OR logico) controlla se almeno una delle due condizioni è verificata
Controlliamo se il numero è divisibile sia per 2 che per 3:
vettoreLunghezza10 %% 2 == 0 & vettoreLunghezza10 %% 3 == 0 lun mar mer gio ven lun mar mer gio ven
FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
Questa è la posizione del numero in questione
which((vettoreLunghezza10 %% 2 == 0 & vettoreLunghezza10 %% 3 == 0))lun
6
e questo è il numero:
vettoreLunghezza10[(vettoreLunghezza10 %% 2 == 0 & vettoreLunghezza10 %% 3 == 0)]lun
6
Controlliamo se il numero è divisibile per 2 o per 3:
vettoreLunghezza10 %% 2 == 0 | vettoreLunghezza10 %% 3 == 0 lun mar mer gio ven lun mar mer gio ven
FALSE TRUE TRUE TRUE FALSE TRUE FALSE TRUE TRUE TRUE
Possiamo negare la condizione usando l’operatore ! (NOT logico): in questo caso ci chiediamo quale numero non è divisibile per 2 o per 3:
!(vettoreLunghezza10 %% 2 == 0 | vettoreLunghezza10 %% 3 == 0) lun mar mer gio ven lun mar mer gio ven
TRUE FALSE FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE
La funzione any controlla se la condizione è verificata su almeno uno degli elementi del vettore considerato, mentre la funzione all controlla se la condizione è verificata per tutti gli elementi.
all(vettoreLunghezza10%%2 == 0)[1] FALSE
!all(vettoreLunghezza10 > 10)[1] TRUE
any(vettoreLunghezza10%%2 == 0 | vettoreLunghezza10%%3 == 0)[1] TRUE
any(vettoreLunghezza10%%2 == 0, vettoreLunghezza10%%3 == 0)[1] TRUE
any(vettoreLunghezza10%%2 == 0 & vettoreLunghezza10%%3 == 0)[1] TRUE
any(!(vettoreLunghezza10 %% 2 == 0 | vettoreLunghezza10 %% 3 == 0))[1] TRUE
all(!(vettoreLunghezza10 %% 2 == 0 | vettoreLunghezza10 %% 3 == 0))[1] FALSE
Si può ripetere la stessa cosa su un oggetto di tipo matrice: controllo se i numeri contenuti sono divisibile per 2:
matrice1 colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
riga4 7 8
riga5 9 10
attr(,"names")
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
matrice1 %% 2 == 0 colonna1 colonna2
riga1 FALSE TRUE
riga2 FALSE TRUE
riga3 FALSE TRUE
riga4 FALSE TRUE
riga5 FALSE TRUE
In questo caso le posizioni degli elementi che soddisfano la condizione sono restituite usando un solo indice di puntamento che scorre per colonna:
which(matrice1 %% 2 == 0)[1] 6 7 8 9 10
Se vado ad estrarre gli elementi che soddisfano la condizione richiesta, devo accettare il passaggio dalla matrice al vettore:
matrice1[matrice1 %% 2 == 0] f g h i j
2 4 6 8 10
Lo stesso accade sull’oggetto di tipo array
array3d, , strato1
colonna1 colonna2 colonna3
riga1 1 5 9
riga2 2 6 10
riga3 3 7 11
riga4 4 8 12
, , strato2
colonna1 colonna2 colonna3
riga1 13 17 21
riga2 14 18 22
riga3 15 19 23
riga4 16 20 24
attr(,"names")
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x"
array3d %% 2 == 0, , strato1
colonna1 colonna2 colonna3
riga1 FALSE FALSE FALSE
riga2 TRUE TRUE TRUE
riga3 FALSE FALSE FALSE
riga4 TRUE TRUE TRUE
, , strato2
colonna1 colonna2 colonna3
riga1 FALSE FALSE FALSE
riga2 TRUE TRUE TRUE
riga3 FALSE FALSE FALSE
riga4 TRUE TRUE TRUE
which(array3d %% 2 == 0) [1] 2 4 6 8 10 12 14 16 18 20 22 24
array3d[array3d %% 2 == 0] b d f h j l n p r t v x
2 4 6 8 10 12 14 16 18 20 22 24
Per indicizzare un oggetto è possibile usare: - un vettore di interi (positivi o negativi) - un vettore di valori booleani - i nomi (“positivi” o “negativi”)
Vediamo come è possibile accedere ai vari elementi di un oggetto (chiaramente questo permette sia di estrarre gli elementi che di cambiarne il valore)
L’operatore per accedere agli elementi è la [
E’ possibile usare un vettore di interi che indica la posizione degli elementi cui si vuole accedere. Il vettore può essere composto: - di numeri positivi, che indicano le posizioni di interesse - di numeri negativi per escludere particolari posizioni
Primo elemento:
vettoreLunghezza10[1]lun
1
Primo e terzo elemento:
vettoreLunghezza10[c(1, 3)]lun mer
1 3
Escludo il primo e il terzo elemento:
vettoreLunghezza10[c(-1, -3)]mar gio ven lun mar mer gio ven
2 4 5 6 7 8 9 10
Posso utilizzare anche un vettore di valori logici (TRUE/FALSE): l’operatore [ in questo caso restituisce solo gli elementi corrispondenti alle posizioni TRUE
vettoreLunghezza3[1] 1 2 3
vettoreLunghezza3[c(T,F,T)][1] 1 3
L’uso dei vettori di valori logici permette di estrarre elementi sfruttando gli operatori relazionali: l’operatore relazione restituisce infatti un vettore di valori logici (TRUE/FALSE)
vettoreLunghezza3 %% 2 == 0[1] FALSE TRUE FALSE
che può essere passato in input all’operatore [
vettoreLunghezza3[vettoreLunghezza3 %% 2 == 0][1] 2
Nel caso il vettore di valori logici passato all’operatore [ sia di lunghezza inferiore al numero di elementi contenuti nel vettore cui si accede, viene applicata la regola del riciclaggio
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
1 2 3 4 5 6 7 8 9 10
vettoreLunghezza10[c(T)]lun mar mer gio ven lun mar mer gio ven
1 2 3 4 5 6 7 8 9 10
vettoreLunghezza10[c(F)]named integer(0)
vettoreLunghezza10[c(T,F)]lun mer ven mar gio
1 3 5 7 9
E’ possibile sfruttare anche i nomi per accedere agli elementi del vettore: attenzione, nel caso di nomi ripetuti viene restituito solo il primo elemento se si passa la stringa all’operatore [
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
1 2 3 4 5 6 7 8 9 10
vettoreLunghezza10["lun"]lun
1
Si può ovviare al problema lavorando direttamente sull’attributo names
names(vettoreLunghezza10) == "lun" [1] TRUE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE
which(names(vettoreLunghezza10) == "lun")[1] 1 6
vettoreLunghezza10[names(vettoreLunghezza10) == "lun"]lun lun
1 6
Le stesse regole valgono anche per le matrici: se si utilizza un solo indice per il puntamento si sta scorrendo la matrice per colonna
matrice1 colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
riga4 7 8
riga5 9 10
attr(,"names")
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
matrice1[7]g
4
matrice1[c(2,7)]b g
3 4
Nel caso delle matrici, lavorando con un solo indice e con gli operatori relazionali, si ottiene in output un vettore con gli elementi della matrice che soddisfano la/e condizione/i richiesta
matrice1 > 4 colonna1 colonna2
riga1 FALSE FALSE
riga2 FALSE FALSE
riga3 TRUE TRUE
riga4 TRUE TRUE
riga5 TRUE TRUE
matrice1[matrice1 > 4] c d e h i j
5 7 9 6 8 10
Questo vale anche nel caso la condizione è verificata per un blocco rettangolare che potrebbe quindi essere restituito ancora come matrice
(matrice1 > 3 & matrice1 <6) | (matrice1 > 8) colonna1 colonna2
riga1 FALSE FALSE
riga2 FALSE TRUE
riga3 TRUE FALSE
riga4 FALSE FALSE
riga5 TRUE TRUE
matrice1[(matrice1 > 3 & matrice1 <6) | (matrice1 > 8)] c e g j
5 9 4 10
Se si utilizza un doppio indice si sta scorrendo la matrice per riga (primo numero) e per colonna (secondo numero): posso usare una sintassi per accedere agli elementi di una matrice che sfrutta due indici: il primo è l’indice di riga e il secondo è l’indice di colonna
Per accedere all’elemento (prima riga, seconda colonna):
matrice1[1,2][1] 2
Per accedere all’intera prima riga:
matrice1[1,]colonna1 colonna2
1 2
Per accedere all’intera seconda colonna:
matrice1[,2]riga1 riga2 riga3 riga4 riga5
2 4 6 8 10
Per accedere a tutta la matrice, in alternativa al nome dell’oggetto, posso quindi usare:
matrice1[,] colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
riga4 7 8
riga5 9 10
NOTA: vedi sotto per una differenza con l’accesso usando il solo nome nel caso di assegnazione
Anche in questo caso posso usare su ciascuna delle due dimensioni un vettore di posizioni. Ad esempio estraggo la sottomatrice considerando la prima e la terza riga:
matrice1[c(1,3),] colonna1 colonna2
riga1 1 2
riga3 5 6
Dalla prima alla terza riga:
matrice1[1:3,] colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
Nel caso in cui l’estrazione corrisponde ad un vettore l’oggetto in output viene automaticamente semplificato (si perde la dimensione):
matrice1[1:2,2]riga1 riga2
2 4
class(matrice1[1:2,2])[1] "integer"
Da confrontare con l’analogo nel caso di estrazione di una sottomatrice:
matrice1[1:3,] colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
class(matrice1[1:3,])[1] "matrix" "array"
Una sintassi analoga permette di accedere agli elementi di un array a più dimensioni, naturalmente includendo un indice per ciascuna delle dimensioni considerate.
Elemento sulla prima riga, terza colonna, secondo strato:
array3d[1,3,2][1] 21
Estraggo il primo strato:
array3d[,,1] colonna1 colonna2 colonna3
riga1 1 5 9
riga2 2 6 10
riga3 3 7 11
riga4 4 8 12
Anche in questo caso, ove possibile, la struttura viene semplificata:
class(array3d)[1] "array"
class(array3d[,,1])[1] "matrix" "array"
Estraggo la prima riga e tutte le colonne per ciascuno strato:
array3d[1,,] strato1 strato2
colonna1 1 13
colonna2 5 17
colonna3 9 21
Attenzione alla disposizione dell’output: la prima colonna corrisponde alla prima riga del primo strato e la seconda colonna alla prima riga del secondo strato:
array3d[1,,1]colonna1 colonna2 colonna3
1 5 9
array3d[1,,2]colonna1 colonna2 colonna3
13 17 21
Discorso analogo vale se lavoro con gli indici di colonna:
array3d[,2,] strato1 strato2
riga1 5 17
riga2 6 18
riga3 7 19
riga4 8 20
array3d[,2,1]riga1 riga2 riga3 riga4
5 6 7 8
array3d[,2,2]riga1 riga2 riga3 riga4
17 18 19 20
Anche per gli array posso usare un vettore di indici per indicare le righe/colonne cui sono interessato (se gli indici sono positivi) o da escludere (se gli indici sono negativi).
Estraggo, per ciascuno strato, gli elementi sulla prima e terza riga (tutte le colonne):
array3d[c(1,3),,], , strato1
colonna1 colonna2 colonna3
riga1 1 5 9
riga3 3 7 11
, , strato2
colonna1 colonna2 colonna3
riga1 13 17 21
riga3 15 19 23
Estraggo, per ciascuno strato, gli elementi dalla prima alla terza riga (tutte le colonne):
array3d[1:3,,], , strato1
colonna1 colonna2 colonna3
riga1 1 5 9
riga2 2 6 10
riga3 3 7 11
, , strato2
colonna1 colonna2 colonna3
riga1 13 17 21
riga2 14 18 22
riga3 15 19 23
In alternativa avrei potuto escludere la quarta riga per ciascuno strato:
array3d[-4,,], , strato1
colonna1 colonna2 colonna3
riga1 1 5 9
riga2 2 6 10
riga3 3 7 11
, , strato2
colonna1 colonna2 colonna3
riga1 13 17 21
riga2 14 18 22
riga3 15 19 23
Questa volta escludo la prima e la quarta riga per ciascuno strato:
array3d[c(-1,-4),,], , strato1
colonna1 colonna2 colonna3
riga2 2 6 10
riga3 3 7 11
, , strato2
colonna1 colonna2 colonna3
riga2 14 18 22
riga3 15 19 23
Anche per gli array, laddove definiti, posso usare i nomi per puntare agli elementi:
attributes(array3d)$dim
[1] 4 3 2
$names
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s"
[20] "t" "u" "v" "w" "x"
$dimnames
$dimnames[[1]]
[1] "riga1" "riga2" "riga3" "riga4"
$dimnames[[2]]
[1] "colonna1" "colonna2" "colonna3"
$dimnames[[3]]
[1] "strato1" "strato2"
Lavorando con i nomi degli elementi devo usare la sintassi con il singolo indice
array3d["x"] x
24
array3d[c("b","x")] b x
2 24
Posso analogamente lavorare sui nomi delle dimensioni. NOTA: attenzione alla disposizione dell’output (i nomi ci aiutano a capire la “provenienza” dei vari vettori)
array3d["riga1",,] strato1 strato2
colonna1 1 13
colonna2 5 17
colonna3 9 21
array3d[,"colonna3",] strato1 strato2
riga1 9 21
riga2 10 22
riga3 11 23
riga4 12 24
array3d[,,"strato2"] colonna1 colonna2 colonna3
riga1 13 17 21
riga2 14 18 22
riga3 15 19 23
riga4 16 20 24
Anche nel caso dei nomi posso usare un vettore di nomi:
array3d[c("riga1","riga3"),,], , strato1
colonna1 colonna2 colonna3
riga1 1 5 9
riga3 3 7 11
, , strato2
colonna1 colonna2 colonna3
riga1 13 17 21
riga3 15 19 23
Con i nomi non posso però usare la negazione per escludere l’elemento:
array3d[-"x"]
array3d[-c("riga1","riga2"),,]
array3d[c(-"riga1",-"riga2"),,]La sintassi in questo caso diventa più macchinosa per escludere l’elemento di nome b
array3d[names(array3d)!="b"] a c d e f g h i j k l m n o p q r s t u v w x
1 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
Per escludere gli elementi sulla riga di nome riga1:
array3d[rownames(array3d)!="riga1"] b c d f g h j k l n o p r s t v w x
2 3 4 6 7 8 10 11 12 14 15 16 18 19 20 22 23 24
Per escludere gli elementi sulle righe di nome riga1 e riga3:
array3d[rownames(array3d)!="riga1" & rownames(array3d)!="riga3"] b d f h j l n p r t v x
2 4 6 8 10 12 14 16 18 20 22 24
Sull’array posso usare un vettore di valori logici, facendo attenzione al fatto che la struttura di output in questo caso viene sempre semplificata. I numeri > 12 si trovano tutti nel secondo strato dell’array e quindi potrebbero essere restituiti come matrice ma questo non avviene:
array3d > 12, , strato1
colonna1 colonna2 colonna3
riga1 FALSE FALSE FALSE
riga2 FALSE FALSE FALSE
riga3 FALSE FALSE FALSE
riga4 FALSE FALSE FALSE
, , strato2
colonna1 colonna2 colonna3
riga1 TRUE TRUE TRUE
riga2 TRUE TRUE TRUE
riga3 TRUE TRUE TRUE
riga4 TRUE TRUE TRUE
array3d[array3d > 12] m n o p q r s t u v w x
13 14 15 16 17 18 19 20 21 22 23 24
Sia per i vettori che per le matrici che per gli array posso accedere agli elementi con la sintassi vista sopra per riassegnare nuovi valori alle posizioni specificate:
vettoreLunghezza10[c(1, 5)]lun ven
1 5
vettoreLunghezza10[c(1, 5)] <- c(10, 50)
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
10 2 3 4 50 6 7 8 9 10
Anche nel caso dell’assegnazione vale la regola del riciclaggio:
vettoreLunghezza10[c(1, 5)] <- 0
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
0 2 3 4 0 6 7 8 9 10
Con lo stesso messaggio di warning visto in precedenza
vettoreLunghezza10[1:5] <- 1:3Warning in vettoreLunghezza10[1:5] <- 1:3: number of items to replace is not a
multiple of replacement length
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
1 2 3 1 2 6 7 8 9 10
NOTA: Per accedere a tutti gli elementi di un vettore/matrice/array3d posso usare sia solo il nome della variabile che una sintassi con l’operatore [
Ad esempio per la matrice1 posso scrivere:
matrice1 colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
riga4 7 8
riga5 9 10
attr(,"names")
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
matrice1[] colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
riga4 7 8
riga5 9 10
attr(,"names")
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
matrice1[,] colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
riga4 7 8
riga5 9 10
Rispetto all’estrazione di elementi non fa alcuna differenza ma una differenza è riscontrabile se invece si fa riferimento all’assegnazione di elementi:
varAppoggio <- matrice1
varAppoggio colonna1 colonna2
riga1 1 2
riga2 3 4
riga3 5 6
riga4 7 8
riga5 9 10
attr(,"names")
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
varAppoggio <- 10
varAppoggio[1] 10
Usando una delle sintassi con l’operatore [ l’assegnazione avviene invece preservando la struttura dell’oggetto
varAppoggio <- matrice1
varAppoggio[] <- 100
varAppoggio colonna1 colonna2
riga1 100 100
riga2 100 100
riga3 100 100
riga4 100 100
riga5 100 100
attr(,"names")
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
Una cosa abbastanza particolare è il ridimensionamento automatico del vettore in fase di assegnazione. Se provo ad accedere al 15° elemento del vettore ho uno strano ouput:
vettoreLunghezza10[15]<NA>
NA
Che forse diventa più chiaro se assegno un valore al quindicesimo elemento (che non esiste):
vettoreLunghezza10[15] <- 15
vettoreLunghezza10lun mar mer gio ven lun mar mer gio ven
1 2 3 1 2 6 7 8 9 10 NA NA NA NA 15
NOTA: il ridimensionamento automatico non funziona nel caso di matrici e array
matrice1
matrice1[6,4]
matrice1[6,4] <- 10Creazione e stampa di una lista:
lista <- list(vettore=1:10, matrice1=matrix(1:12, 4, 3), testo=letters[1:5])
lista$vettore
[1] 1 2 3 4 5 6 7 8 9 10
$matrice1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
$testo
[1] "a" "b" "c" "d" "e"
Creazione e stampa di un dataframe:
df <- data.frame(a=letters[1:10], b=1:10, c=10:1)
df a b c
1 a 1 10
2 b 2 9
3 c 3 8
4 d 4 7
5 e 5 6
6 f 6 5
7 g 7 4
8 h 8 3
9 i 9 2
10 j 10 1
Quanti elementi ci sono nella lista?
length(lista)[1] 3
E quanti nel dataframe?
length(df)[1] 3
MEMO: Il dataframe è un tipo particolare di lista:
is.list(df)[1] TRUE
is.data.frame(df)[1] TRUE
as.list(df)$a
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
$b
[1] 1 2 3 4 5 6 7 8 9 10
$c
[1] 10 9 8 7 6 5 4 3 2 1
Sia la lista che il dataframe sono contenitori per oggetti di tipo diverso:
is.atomic(lista)[1] FALSE
is.atomic(df)[1] FALSE
Per puntare agli elementi della lista ci sono diverse opzioni: - accesso attraverso l’indice dell’elemento usando l’operatore di estrazione [[
Con l’operatore [[ si accede direttamente all’elemento della lista (semplificando la struttura di output)
lista[[1]] [1] 1 2 3 4 5 6 7 8 9 10
is.atomic(lista[[1]])[1] TRUE
Si può usare anche l’operatore di estrazione [
lista[1]$vettore
[1] 1 2 3 4 5 6 7 8 9 10
ma in questo caso viene restituita una sottolista con un solo elemento
is.atomic(lista[1])[1] FALSE
is.list(lista[1])[1] TRUE
L’operatore [ permette però di accedere a più elementi della lista
lista[c(1,3)]$vettore
[1] 1 2 3 4 5 6 7 8 9 10
$testo
[1] "a" "b" "c" "d" "e"
Questo non è invece possibile usando l’operatore [[. Se si prova il comando:
lista[[c(1,3)]][1] 3
E’ come se stessi scrivendo:
lista[[1]][3][1] 3
Stesso problema si ha se si cerca di usare la [[ con un indice negativo:
lista[[-2]]Sintassi consentita con la [ per escludere uno o più elementi:
lista[-2]$vettore
[1] 1 2 3 4 5 6 7 8 9 10
$testo
[1] "a" "b" "c" "d" "e"
lista[c(-1,-3)]$matrice1
[,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
E’ possibile sfruttare i nomi degli elementi nel caso di una lista con nomi:
names(lista)[1] "vettore" "matrice1" "testo"
In questo caso è possibile usare l’operatore $ tra nome della lista e nome dell’elemento che si vuole estrarre
lista$vettore [1] 1 2 3 4 5 6 7 8 9 10
In alternativa è possibile usare la [ o le [[ con le differenze viste nel caso degli indici:
lista[["vettore"]] [1] 1 2 3 4 5 6 7 8 9 10
is.atomic(lista[["vettore"]])[1] TRUE
lista["vettore"]$vettore
[1] 1 2 3 4 5 6 7 8 9 10
is.atomic(lista["vettore"])[1] FALSE
Per estrarre due o più elementi è però necessario usare la singola [
lista[c("vettore", "testo")]$vettore
[1] 1 2 3 4 5 6 7 8 9 10
$testo
[1] "a" "b" "c" "d" "e"
Così come con gli indici non è possibile usare le [[
lista[[c("vettore", "testo")]]Il dataframe è una particolare lista: valgono quindi tutte le cose viste per la lista
df[[1]] [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
class(df[[1]])[1] "character"
df[1] a
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
10 j
class(df[[2]])[1] "integer"
df$a [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
df[c("a","c")] a c
1 a 10
2 b 9
3 c 8
4 d 7
5 e 6
6 f 5
7 g 4
8 h 3
9 i 2
10 j 1
df[-2] a c
1 a 10
2 b 9
3 c 8
4 d 7
5 e 6
6 f 5
7 g 4
8 h 3
9 i 2
10 j 1
In più per i dataframe è possibile usare la singola [ anche con la sintassi di puntamento vista per le matrici.
Ecco alcuni esempi: - per estrarre la prima colonna
df[,1] [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
df[,c(1,3)] a c
1 a 10
2 b 9
3 c 8
4 d 7
5 e 6
6 f 5
7 g 4
8 h 3
9 i 2
10 j 1
df[,-2] a c
1 a 10
2 b 9
3 c 8
4 d 7
5 e 6
6 f 5
7 g 4
8 h 3
9 i 2
10 j 1
df[2,] a b c
2 b 2 9
df[-1,] a b c
2 b 2 9
3 c 3 8
4 d 4 7
5 e 5 6
6 f 6 5
7 g 7 4
8 h 8 3
9 i 9 2
10 j 10 1
df[5, 2][1] 5
df[5:10, c(1,3)] a c
5 e 6
6 f 5
7 g 4
8 h 3
9 i 2
10 j 1
E’ possibile utilizzare in combinazione la sintassi per accedere agli elementi della lista e poi ai particolari elementi: - estrae la matrice alla seconda posizione della lista
lista[[2]] [,1] [,2] [,3]
[1,] 1 5 9
[2,] 2 6 10
[3,] 3 7 11
[4,] 4 8 12
lista[[2]][,c(2,3)] [,1] [,2]
[1,] 5 9
[2,] 6 10
[3,] 7 11
[4,] 8 12