Vettori
“Everything that exists in R is an object”. I vettori sono uno degli oggetti (o strutture di dati) più importanti. Il più semplice vettore è uno scalare, i.e., un singolo valore. Ecco qualche esempio (numerico, di testo e logico):
a <- 10
b <- 3 / 10
d <- "star"
e <- "10"
f <- T|F
g <- T|NA
Domande veloci
- Perchè non ho usato il nome
c
? - Qual è il risultato di
a*2
? E die*2
? - Qual è il risultato di
T|F
e diT|NA
? - Qual è il tipo dei vettori sopra creati? Quale comando di R si usa per conoscere il tipo di un oggetto?
Per verificare che un oggetto sia di un determinato tipo possiamo
usare, is.nometipo()
, e.g.,
is.integer(a) ; is.double(a)
## [1] FALSE
## [1] TRUE
is.character(e)
## [1] TRUE
is.logical(f)
## [1] TRUE
Per forzare il tipo di un oggetto, possiamo usare, e.g.,
as.character(a)
## [1] "10"
as.integer(e)
## [1] 10
as.numeric(f)
## [1] 1
as.numeric(d)
## Warning: NA introdotti per coercizione
## [1] NA
Nei casi in cui tale forzatura non abbia senso o faccia perdere informazioni si è avvisati!
Una finezza:
a==10L
## [1] TRUE
identical(a, 10L)
## [1] FALSE
identical(as.integer(a), 10L)
## [1] TRUE
Per creare vettori con più valori (o di lunghezza \(>1\)), il modo più comune è quello di
concatenare o combinare gli elementi che lo compongono usando
c()
(l’uso delle parentesi tonde al di fuori del comando
equivale a richiedere la stampa dell’output)
(v_num <- c(2, 3.6, 1e2))
## [1] 2.0 3.6 100.0
(v_cha <- c("hi", "goodbye", "farewell"))
## [1] "hi" "goodbye" "farewell"
Più esattamente, questi, avendo tutti gli elementi dello stesso tipo, sono detti vettori atomici.
Un’alternativa, utile soprattutto quando si vuole solo impostare un vettore, è usare:
(v_le0 <- vector())
## logical(0)
length(v_le0)
## [1] 0
(v_log <- vector(, length=2))
## [1] FALSE FALSE
Domande veloci
- Qual è il tipo di
v_num
,v_cha
ev_log
? - Se combiniamo in tutte le maniere possibili i vettori appena creati, quale è il tipo dei vettori così creati?
v_mix_1 <- c(v_log, v_num)
v_mix_2 <- c(v_num, v_cha)
v_mix_3 <- c(v_log, v_cha)
- Qual è la logica sottintesa alla definizione del tipo di vettori con elementi di tipo misto?
Sequenze di numeri con una struttura ordinata
Per creare una sequenza di interi con incremento costante \(1\)
1:10
## [1] 1 2 3 4 5 6 7 8 9 10
equivalente a
seq(1, 10, 1) ; seq(1, 10, length=10)
## [1] 1 2 3 4 5 6 7 8 9 10
## [1] 1 2 3 4 5 6 7 8 9 10
Se la variazione costante è un decremento, l’input from
deve essere non minore di quello to
.
seq(10, 1, -1)
## [1] 10 9 8 7 6 5 4 3 2 1
I parametri di seq()
da impostare sono by
o
length
, ad esempio
seq(1, 10, 2)
## [1] 1 3 5 7 9
seq(1, 10, length=5)
## [1] 1.00 3.25 5.50 7.75 10.00
seq(1, 10, 10)
## [1] 1
seq(1, 10, length=1)
## [1] 1
seq(1, 10, 2.5)
## [1] 1.0 3.5 6.0 8.5
seq(1, 10, le=2.5)
## [1] 1.0 5.5 10.0
Se il vettore contiene sequenze ripetute
rep(2, 5)
## [1] 2 2 2 2 2
rep(c(2,5), 2)
## [1] 2 5 2 5
rep(c(2, 5), c(2, 5))
## [1] 2 2 5 5 5 5 5
Estrazione (Subsetting)
Il modo più comune per estrarre elementi da un vettore è usare le
[]
all’interno delle quali si indicano le posizioni degli
elementi da estrarre.
x <- c(1, 2, 5)
x[1]
## [1] 1
x[1:2]
## [1] 1 2
x[c(1,3)]
## [1] 1 5
x[-2]
## [1] 1 5
x[-(1:2)]
## [1] 5
Domande veloci
Dato il vettore
y <- c(x, -1.2, 0, 10, 6.2, 3, -3, 9, 12, sqrt(2))
- Qual è la lunghezza ?
- Estrarre tutti gli elementi tranne il \(4^o\).
- Estrarre gli elementi in posizione \(3,5,10\).
- Estrarre tutti gli elementi tranne quelli in posizione \(3,5,10\).
- Estrarre tutti gli elementi in posizione dispari, e poi quelli in posizione pari.
L’estrazione può anche servirsi di espressioni logiche per indicare le posizioni degli elementi da estrarre.
x <- c(1:2,4,5,7,8,10,11)
x[x<5 | x>7]
## [1] 1 2 4 8 10 11
La funzione which
restituisce le posizioni degli
elementi che soddisfano la condizione
which(x<5 | x>7)
## [1] 1 2 3 4 8
Si possono effettuare anche su vettori con più di un elemento le stesse operazioni che abbiamo visto con gli scalari
x <- 1:10
x*2
## [1] 2 4 6 8 10 12 14 16 18 20
x > 5
## [1] FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE
Si noti come la stessa operazione viene ripetuta per ogni elemento del vettore se uno dei due vettori è uno scalare. Altrimenti il vettore più corto viene ripetuto tante volte quante necessarie per coprire la lunghezza del vettore più lungo.
x <- rep(10,8)
y <- c(1,2)
x*y
## [1] 10 20 10 20 10 20 10 20
x+y
## [1] 11 12 11 12 11 12 11 12
Un caso particolare di ripetizione della funzione per ogni elemento
di un vettore si ha con il comando paste()
. Esso è il
comando per eccellenza per combinare più stringhe in una sola, previa
conversione in tipo carattere gli argomenti dati in input.
paste(1:3)
## [1] "1" "2" "3"
paste(1:3, 2)
## [1] "1 2" "2 2" "3 2"
paste0(1:3, 2)
## [1] "12" "22" "32"
paste(1:3, 2, sep=".")
## [1] "1.2" "2.2" "3.2"
paste("day", 1:5)
## [1] "day 1" "day 2" "day 3" "day 4" "day 5"
Due funzioni importanti sono all()
e any
che ritornano un solo valore logico, e.g.,
x <- 0:7
# Are all the x values bigger than 0?
all(x>0)
## [1] FALSE
# Are any of the x values negative?
any(x<0)
## [1] FALSE
# then, it must be True that
any(x>0)
## [1] TRUE
Ora calcoliamo qualche statistica sui dati della temperatura degli ultimi \(\ldots\) giorni
x <- c(16.5, 16, 17, 12)
length(x)
## [1] 4
sort(x)
## [1] 12.0 16.0 16.5 17.0
order(x)
## [1] 4 2 1 3
sort(x, decreasing=T)
## [1] 17.0 16.5 16.0 12.0
sum(x)/length(x)
## [1] 15.375
mean(x)
## [1] 15.375
min(x); max(x); range(x)
## [1] 12
## [1] 17
## [1] 12 17
Names (attributo)
Possiamo attribuire agli elementi di un vettore un nome per ognuno di essi. Partiamo da un vettore numerico (senza attributi):
x <- c(1,0,5)
str(x)
## num [1:3] 1 0 5
attributes(x)
## NULL
x <- c(a=1, b=0, c=5)
# or
x <- c(1,0,5) ; names(x) <- c("a", "b", "c")
# or
setNames(c(1,0,5), c("a", "b", "c"))
## a b c
## 1 0 5
names(x)
## [1] "a" "b" "c"
attributes(x)
## $names
## [1] "a" "b" "c"
Esercizio (a casa)
- Si definisca un vettore
y
con elementi \(8, 3, 5, 7, 6, 6, 8, 9, 2\). C’è qualche elemento \(<5\)? Quanti sono? Si crei un nuovo vettorez
con gli elementi diy
che sono \(<5\). - Si crei il vettore logico
x <- c(T, T, F, T)
Come posso trasformarlo in modo che a T
corrisponda
\(1\) e a F
lo \(0\)? Le funzioni sum
e
mean
applicate su x
cosa calcolano?
sum(x) ; mean(x)
- Si definisca un vettore avente i valori 9, 2, 3, 9, 4, 10, 4, 11. Si scriva il codice per calcolare la somma dei tre valori più grandi.
- Si crei un vettore
x
di lunghezza \(4\). cosa il codice
x[c(TRUE, TRUE, NA, FALSE)]
restituisce?
Matrici e arrays
Una matrice è una struttura dati 2D con elementi omogenei (gli elementi devono essere tutti dello stesso tipo). Una matrice è un caso speciale di un array, che è multidimensionale.
(x <- matrix(c(2,3,5,7,11,13), nrow=3))
## [,1] [,2]
## [1,] 2 7
## [2,] 3 11
## [3,] 5 13
(x <- matrix(c(2,3,5,7,11,13), ncol=3))
## [,1] [,2] [,3]
## [1,] 2 5 11
## [2,] 3 7 13
È possibile creare una matrice anche importando gli elementi da un
file esterno. Ad esempio, si consideri il file ex.data
che
contiene
x y z
2 3 5
11 13 17
Il contenuto del file può essere letto tramite la funzione
scan()
e assegnato ad una matrice 2x3 utilizzando i
seguenti comandi
(x <- scan("data/ex.data", skip = 1, quiet = TRUE))
## [1] 2 3 5 11 13 17
(mx <- matrix(x, ncol=3, byrow=TRUE))
## [,1] [,2] [,3]
## [1,] 2 3 5
## [2,] 11 13 17
Impostando byrow = TRUE
si sovrascrive l’impostazione
predefinita (FALSE
) e gli elementi vengono importati per
riga invece che per colonna. length()
si generalizza a
nrow()
e ncol()
per le matrici, e a
dim()
per gli array.
nrow(mx) ; ncol(mx) ; dim(mx)
## [1] 2
## [1] 3
## [1] 2 3
Per nominare righe e colonne è possibile usare le seguenti funzioni
rownames(mx) <- paste0("r", 1:2)
colnames(mx) <- c("a", "b", "c")
mx
## a b c
## r1 2 3 5
## r2 11 13 17
Gli array sono matrici con una dimensione che può essere maggiore di \(2\).
x <- 1:20
(ax <- array(x, dim=c(5,2,2)))
## , , 1
##
## [,1] [,2]
## [1,] 1 6
## [2,] 2 7
## [3,] 3 8
## [4,] 4 9
## [5,] 5 10
##
## , , 2
##
## [,1] [,2]
## [1,] 11 16
## [2,] 12 17
## [3,] 13 18
## [4,] 14 19
## [5,] 15 20
dim(ax)
## [1] 5 2 2
Per verificare se un oggetto è una matrice o un array si può
utilizzare is.matrix()
e is.array()
, o
scoprendo le dimensioni dell’oggetto. Si noti che le matrici con una
singola riga o una singola colonna o array con una singola dimensione
continuano a mantenere memoria delle dimensioni originali. Ad
esempio,
str(2:4)
## int [1:3] 2 3 4
y <- matrix(2:4, nrow = 1) # row vector
str(y)
## int [1, 1:3] 2 3 4
y <- matrix(2:4, ncol = 1) # column vector
str(y)
## int [1:3, 1] 2 3 4
y <- array(2:4, 3) # 1d array
str(y)
## int [1:3(1d)] 2 3 4
Estrazione
Come per i vettori, gli elementi di una matrice possono essere selezionati utilizzando le parentesi quadre e indicando le posizioni delle righe e delle colonne.
mx[2,1] # select the element in the cell (2,1)
## [1] 11
mx[2, ] # select the second row
## a b c
## 11 13 17
mx["r2", ]
## a b c
## 11 13 17
mx[ ,3] # select the third column
## r1 r2
## 5 17
mx[ ,"c"]
## r1 r2
## 5 17
È possibile estrarre anche sottoinsiemi di righe e/o colonne per definire una nuova matrice con solo gli elementi selezionati:
x <- matrix(1:16, ncol=4)
(y <- x[c(1,4),c(3,4)])
## [,1] [,2]
## [1,] 9 13
## [2,] 12 16
L’uso delle []
vale anche per l’estrazione da array
ax[3,2,1]
## [1] 8
ax[ ,2, ]
## [,1] [,2]
## [1,] 6 16
## [2,] 7 17
## [3,] 8 18
## [4,] 9 19
## [5,] 10 20
ax[-1, ,1]
## [,1] [,2]
## [1,] 2 7
## [2,] 3 8
## [3,] 4 9
## [4,] 5 10
Esercizio
Si completi il codice sotto per ottenere una matrice con 2 righe e 3 colonne e con gli elementi dati dagli interi da 1 a 6.
a <- matrix(1:?, ??? ???)
- Se
is.matrix(a)
è TRUE, quale valore presumi diais.array(a)
? - Estrai dalla matrice
a
la seconda colonna e salvalo in un nuovo oggetto nominatob
. Che tipo di oggetto èb
? - Cosa pensi succeda se convertiamo
b
in una matrice? - Si crei un array, d, di dimensioni 2, 3, 2, e elementi dati dagli
integeri da 1 a 12. Cosa producono
dim()
elength()
se applicati sud
? - Cosa produce il codice
d[, , 1] <- b
Liste
Le liste differiscono dai vettori atomici in quanto i loro elementi possono essere di qualsiasi tipo, incluso liste. Si usa anche il termine “componente” di una lista anzichè “valore” per evidenziare la differenza rispetto ad un elemento di un vettore atomico.
Una lista vuota di lunghezza prespecificata può essere creata con la
funzione vector()
(x <- vector("list", length = 3))
## [[1]]
## NULL
##
## [[2]]
## NULL
##
## [[3]]
## NULL
Nel momento in cui conosciamo le componenti, possiamo o “riempire” la
lista x
appena creata o creare direttamente una lista con
queste componenti.
x1 <- 1:3
x2 <- c("A", "B", "C", "D", "E")
x3 <- matrix(1:12, nrow=3)
x[[1]] <- x1; x[[2]] <- x2; x[[3]] <- x3
x
## [[1]]
## [1] 1 2 3
##
## [[2]]
## [1] "A" "B" "C" "D" "E"
##
## [[3]]
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
mylist <- list(x1, x2, x3) # define the list 'mylist'
str(mylist)
## List of 3
## $ : int [1:3] 1 2 3
## $ : chr [1:5] "A" "B" "C" "D" ...
## $ : int [1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
Quando si crea una lista è possibile, e spesso conveniente, assegnare a ciascun componente un nome.
(mylist2 <- list(comp1 = x1, comp2 = x2, comp3 = x3))
## $comp1
## [1] 1 2 3
##
## $comp2
## [1] "A" "B" "C" "D" "E"
##
## $comp3
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
Per recuperare i nomi dei componenti possiamo usare la funzione
names()
, funzione generica che vale anche per molte altre
strutture di dati.
names(mylist)
## NULL
names(mylist2)
## [1] "comp1" "comp2" "comp3"
Quando si concatenano liste con c()
si crea una lista
costituita dalle componenti delle liste date in input.
newlist <- c(mylist, mylist2)
is.list(newlist)
## [1] TRUE
str(newlist)
## List of 6
## $ : int [1:3] 1 2 3
## $ : chr [1:5] "A" "B" "C" "D" ...
## $ : int [1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
## $ comp1: int [1:3] 1 2 3
## $ comp2: chr [1:5] "A" "B" "C" "D" ...
## $ comp3: int [1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
Se si costruisce una lista di liste, si crea una gerarchia di liste
newlist <- list(mylist, mylist2)
str(newlist)
## List of 2
## $ :List of 3
## ..$ : int [1:3] 1 2 3
## ..$ : chr [1:5] "A" "B" "C" "D" ...
## ..$ : int [1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
## $ :List of 3
## ..$ comp1: int [1:3] 1 2 3
## ..$ comp2: chr [1:5] "A" "B" "C" "D" ...
## ..$ comp3: int [1:3, 1:4] 1 2 3 4 5 6 7 8 9 10 ...
Estrazione
Per estrarre componenti o elementi interni alle componenti di una
lista si usano ancora le parentesi quadre - si noti l’output diverso a
seconda che si usi []
o le parentesi quadre
doppie[[]]
- o, in caso siano presenti, i nomi delle
componenti.
mylist[1]
## [[1]]
## [1] 1 2 3
mylist[[1]]
## [1] 1 2 3
mylist2$comp1
## [1] 1 2 3
Possiamo poi estrarre elementi interni ad una componente usando le sintassi note. E.g.,
mylist[[3]][,4]
## [1] 10 11 12
Possiamo ora completare il capitolo degli array per quanto riguarda i
nomi delle dimensioni. L’assegnazione di (o il recupero dei) nomi di un
array avviene con la funzione dimnames()
e richiede una
lista di vettori carattere con lunghezze pari alle dimensioni
dell’array.
dim(ax)
## [1] 5 2 2
dimnames(ax)
## NULL
dimnames(ax) <- list(letters[1:5], LETTERS[1:2], paste0("m", 1:2))
ax
## , , m1
##
## A B
## a 1 6
## b 2 7
## c 3 8
## d 4 9
## e 5 10
##
## , , m2
##
## A B
## a 11 16
## b 12 17
## c 13 18
## d 14 19
## e 15 20
ax['a',,'m1']
## A B
## 1 6
Esercizio
- Si creino gli oggetti seguenti
x <- list(list(1, 2), c(3, 4))
y <- c(list(1, 2), c(3, 4))
Qual è la differenza? Si estragga l’elemento con valore \(4\) da entrambi. 2. Si definisca un array di dimensioni (4, 2, 2)
b <- array(1:16, c(4, 2, 2))
Si assegni una lista di vettori carattere (di lunghezza 4, 2, 2) a
dimnames(b)
per etichettare le dimensioni di
b
.
str(x) ; str(y)
## List of 2
## $ :List of 2
## ..$ : num 1
## ..$ : num 2
## $ : num [1:2] 3 4
## List of 4
## $ : num 1
## $ : num 2
## $ : num 3
## $ : num 4
x[[2]][2]
## [1] 4
y[[4]]
## [1] 4
dimnames(b) <- list(c("R1", "R2", "R3", "R4"), c("C1", "C2"), c("A", "B"))
Fattori
I fattori sono gli oggetti tramite cui R definisce variabili categoriali.
Si consideri il vettore
country <- c("Italy","Germany","France","Germany","Germany","Germany",
"France","Italy","Italy","France")
Esso può essere definito come fattore con la funzione
factor()
countryf <- factor(country)
str(countryf)
## Factor w/ 3 levels "France","Germany",..: 3 2 1 2 2 2 1 3 3 1
class(countryf)
## [1] "factor"
typeof(countryf)
## [1] "integer"
I livelli dei fattori sono memorizzati in ordine alfabetico, o
nell’ordine in cui sono stati esplicitamente specificati in
levels
al momento della creazione con
factor()
.
countryf <- factor(country, levels=c("Italy", "France", "Germany"))
str(countryf)
## Factor w/ 3 levels "Italy","France",..: 1 3 2 3 3 3 2 1 1 2
Quando le variabili categoriali sono ordinali, i livelli hanno un
ordine naturale, La funzione ordered()
crea tali fattori
ordinati ma per il resto è identica a factor
.
La tabella di frequenza di qualunque variabile si ottiene con
table()
. In questo caso si noti la differenza:
table(country)
## country
## France Germany Italy
## 3 4 3
table(countryf)
## countryf
## Italy France Germany
## 3 3 4
Supponiamo di avere anche le informazioni su età e sesso (1=Femmina e 2=Maschio)
age <- c(47,44,44,40,38,36,42,34,34,44)
gender <- c(1,1,2,1,1,2,1,2,2,2)
Qual è l’età media degli individui per ciascun Paese?
Possiamo usare la funzione tapply()
:
tapply(age, countryf, mean)
## Italy France Germany
## 38.33333 43.33333 39.50000
Il risultato è una struttura di lunghezza pari al numero dei livelli dei fattori.
Altre funzioni della stessa famiglia sono apply()
,
lapply()
e sapply
, utili per chiamare
ripetutamente una funzione. Per visualizzare ulteriori dettagli utilizza
l’ help
.
La funzione factor()
è particolarmente utile quando i
dati contengono variabili categoriali con modalità espresse in forma
numerica. Fondamentalmente trasforma i numeri in etichette
(livelli).
Nel caso della variabile genere, può essere utile trasformarla in un fattore e definirne i livelli:
genderf <- factor(gender)
levels(genderf) <- c("F","M")
str(genderf)
## Factor w/ 2 levels "F","M": 1 1 2 1 1 2 1 2 2 2
Se vogliamo risalire nuovamente alla codifica numerica
unclass(genderf)
## [1] 1 1 2 1 1 2 1 2 2 2
## attr(,"levels")
## [1] "F" "M"
as.integer(genderf)
## [1] 1 1 2 1 1 2 1 2 2 2
Esercizio
- Definisci un vettore
x
con gli elementi 5, 12, 13, 12. Costringi questo vettore a fattore e controlla la sua struttura. Come vengono definiti i livelli? - Crea un fattore dalla sequenza di stringhe
"1", "1", "0", "1", "1", "0"
e nominalofs
. Cosa restituiscetypeof(fs)
? Per sapere quanti sono gli “1” (qual è la somma del vettore booleano) quale o quali comandi usare tra quelli sotto?
sum(as.integer(c("1", "1", "0", "1", "1", "0")))
sum(as.integer(fs))
sum(as.integer(levels(fs)[fs]))
- Converti la variabile fattore del punto precedente in un fattore con livelli “m” e “f” e calcola la tabella di frequenza.
- Si creino i fattori
v1 <- factor(letters[1:5])
levels(v1) <- rev(levels(v1))
v2 <- factor(letters[1:5], levels = rev(letters[1:5]))
Sono differenti? Per quale ragione?
Dataframes
Un dataframe è il modo più comune per archiviare i dati in R e facilitare l’analisi dei dati.
Un dataframe rappresenta un modo semplice per organizzare i dati le cui righe sono unità statistiche, mentre le colonne sono le variabili. In effetti, può essere considerata come una matrice con colonne possibilmente di tipo e classe diversi.
Potrebbe essere visualizzato in forma di matrice e le relative righe e colonne estratte utilizzando le stesse regole applicabili sulle matrici. Tuttavia, un dataframe è una struttura bidimensionale, che condivide proprietà sia della matrice che della lista. In particolare, i seguenti vincoli deve essere soddisfatti:
- le componenti devono essere vettori (numerici, di carattere o logici), fattori, matrici numeriche, liste o altri dataframe;
- matrici, liste e dataframe forniscono tante variabili al nuovo dataframe quante sono rispettivamente le colonne, elementi o variabili;
- i vettori numerici e logici e i fattori sono inclusi così come sono nel dataframe mentre i vettori carattere sono di default convertiti in fattore (con i livelli dati dai valori unici del vettore);
- i vettori che appaiono come variabili nel dataframe devono avere tutti la stessa lunghezza e le matrici devono avere anche le righe tutte della stessa lunghezza.
In parole povere, un dataframe è una lista di vettori di uguale lunghezza.
Una lista i cui componenti sono come quelli descritti sopra può
essere convertita in daframe utilizzando la funzione
as.data.frame()
.
Creazione
La funzione data.frame()
viene utilizzata per definire
un dataframe con inputs vettori nominati come nel seguente esempio
under40 <- age < 40
dat <- data.frame(country=countryf, age=age, sex=genderf, under40=under40)
Le caratteristiche dell’oggetto appena creato possono essere ottenute con:
str(dat)
## 'data.frame': 10 obs. of 4 variables:
## $ country: Factor w/ 3 levels "Italy","France",..: 1 3 2 3 3 3 2 1 1 2
## $ age : num 47 44 44 40 38 36 42 34 34 44
## $ sex : Factor w/ 2 levels "F","M": 1 1 2 1 1 2 1 2 2 2
## $ under40: logi FALSE FALSE FALSE FALSE TRUE TRUE ...
dplyr::glimpse(dat)
## Rows: 10
## Columns: 4
## $ country <fct> Italy, Germany, France, Germany, Germany, Germany, France, Ita…
## $ age <dbl> 47, 44, 44, 40, 38, 36, 42, 34, 34, 44
## $ sex <fct> F, F, M, F, F, M, F, M, M, M
## $ under40 <lgl> FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, FAL…
class(dat)
## [1] "data.frame"
is.data.frame(dat)
## [1] TRUE
La “testa” (come la “coda”) di dat
possono essere
ottenute con:
head(dat)
tail(dat)
Una visione globale può essere ottenuta con
View(dat)
o dalla scheda Environment di RStudio.
Estrazione
L’estrazione di singoli elementi, colonne, righe o una selezione di elementi, è possibile utilizzando la stessa sintassi definita per le matrici. Di seguito sono riportati alcuni esempi di base.
dat[3,2]
## [1] 44
dat[1:3, 2:4]
dat[3, ]
Si noti che se l’output è una singola colonna, restituisce un vettore invece di un dataframe
x <- dat[, 2]
str(x)
## num [1:10] 47 44 44 40 38 36 42 34 34 44
Quando si selezionano colonne da un dataframe è possibile utilizzare i nomi delle colonne invece dell’indice delle colonne (come d’altra parte valeva per le matrici). Ad esempio,
dat[ , c("age", "sex")]
Esiste un altro modo per selezionare colonne da un dataframe, ovvero utilizzando il list subsetting, che restituisce ancora un dataframe
dat["age"]
str(dat["age"])
## 'data.frame': 10 obs. of 1 variable:
## $ age: num 47 44 44 40 38 36 42 34 34 44
Se si vogliono estrarre singole variabili si può anche usare il simbolo \(\$\) (che restituisce un vettore diversamente da sopra)
dat$sex
## [1] F F M F F M F M M M
## Levels: F M
Per eliminare una componente (colonna) si può assegnare
NULL
alla colonna specifica del dataframe:
dat$under40 <- NULL
head(dat)
È possibile “aggiungere” un dataframe al percorso di ricerca,
utilizzando la funzione attach()
attach(dat)
Dopo di che si può accedere ad una variabile del dataframe “attached” direttamente (scrivendo solo il suo nome)
age
## [1] 47 44 44 40 38 36 42 34 34 44
Per distaccare il dataframe si usa il comando
detach()
detach(dat)
Esercizio
- Si crei un dataframe
newdf
con le variabili
x <- runif(8)
y <- letters[1:8]
z <- sample(c(rep(T,5),rep(F,3)))
Si descrivano le variabili (ci si aiuti con l’help).
- Si crei un dataframe con 5 righe e come colonne un vettore carattere che contiene nomi propri di persona e un vettore numerico che riporta le età.
Tibble
Una specializzazione dei dataframe è offerta dalla classe
tibble
.
library(readxl)
fav_food <- read_excel("data/favourite-food.xlsx")
fav_food
str(fav_food)
## tibble [5 × 6] (S3: tbl_df/tbl/data.frame)
## $ Student ID : num [1:5] 1 2 3 4 5
## $ Full Name : chr [1:5] "Sunil Huffmann" "Barclay Lynn" "Jayendra Lyne" "Leon Rossini" ...
## $ favourite.food: chr [1:5] "Strawberry yoghurt" "French fries" "N/A" "Anchovies" ...
## $ mealPlan : chr [1:5] "Lunch only" "Lunch only" "Breakfast and lunch" "Lunch only" ...
## $ AGE : chr [1:5] "4" "5" "7" "99999" ...
## $ SES : chr [1:5] "High" "Middle" "Low" "Middle" ...
Questa classe migliora la presentazione dei dati, soprattutto quando sono di grandi dimensioni; non forza la conversione delle variabili carattere in fattore; non aggiunge fittizi nomi di riga.