a <- 1
# ma anche
b = 2
# tuttavia si preferisce la notazione a freccia,
# perché funziona anche così:
3 -> c
# per visualizzare il valore di una variabile:
c
[1] 3
[1] "stringa"
Analisi Dati e Statistica, 2024–25
Università di Trento, Dipartimento di Ingegneria Industriale
Ultimo aggiornamento: 05/12/2024
L’analisi statistica richiede l’uso di software specifico
Oggi i due software/linguaggi più utilizzati in questo campo sono Python e R, seguiti da Matlab
Noi utilizzeremo R perché specifico per la statistica, orientato alla grafica e open source
.Rproj
)Ogni linguaggio usa delle variabili per memorizzare valori ed oggetti mediante un’operazione di assegnazione:
a <- 1
# ma anche
b = 2
# tuttavia si preferisce la notazione a freccia,
# perché funziona anche così:
3 -> c
# per visualizzare il valore di una variabile:
c
[1] 3
[1] "stringa"
L’esecuzione di un comando fornisce direttamente un risultato:
Si noti il testo [1]
all’inizio della riga di output: sarà chiaro più avanti
"a"
, "string"
, 'my text'
1
, 3.1416
1L
TRUE
, FALSE
(oppure T
e F
)1+4i
NA
: valore mancanteNULL
: nienteInf
: InfinitoNaN
: Not a Number (esempio 0/0
)# Si costruiscono con l'operatore/funzione c():
v1 <- c(10, 2, 7.5, 3)
# oppure con una sequenza:
v2 <- 1:10
# anche con passo specificato:
v3 <- seq(1, 10, 0.5)
# Le funzioni si chiamano con le parentesi tonde,
# separando argomenti con ,
Si noti in questo caso l’output per v3
:
[1] 1.0 1.5 2.0 2.5 3.0 3.5 4.0 4.5 5.0 5.5 6.0
[12] 6.5 7.0 7.5 8.0 8.5 9.0 9.5 10.0
Il primo elemento della prima riga è l’elemento [1]
del vettore, mentre il primo elemento della seconda riga è l’elemento [12]
. In tutto, il vettore v3
ha 19 elementi
Le variabili sono nativamente dei vettori. Gli scalari sono solo vettori di dimensione 1:
Le funzioni e gli operatori agiscono quindi sempre su vettori (sono vettorializzati):
mode()
: storage modeclass()
: classe (alto livello, uguale a mode()
per tipi base)typeof()
: tipo (basso livello)length()
: lunghezza vettoreattributes()
: metadatistr()
: struttura di un oggettosummary()
: riassunto statisticomatrix()
array()
costruisce matrici n-dimensionalidim
:factor
Una stringa può essere pensata come un vettore di caratteri di lunghezza maggiore di 1.
Le funzioni di manipolazione di stringhe più comuni sono cat()
, paste()
e paste0()
. La prima serve a stampare la stringa tale e quale:
Le due funzioni paste()
e paste0()
servono a unire due o più stringhe, la prima inserendo uno spazio in mezzo, la seconda senza spazio:
[r,c]
, la base è 1[1] 2 3 10
[1] 2 4 6 8 10
Il secondo caso funziona grazie all’operatore modulo:
[1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE FALSE
[10] TRUE
NOTA: TRUE
e FALSE
possono essere abbreviati in T
e F
[1] 1 4 9 16 25
[1] 36
[1] 100
{}
return()
dim(v) <- c(2,3)
: come si dichiarano?value
e rappresenta il lato destro dell’assegnazione!R supporta le tipiche istruzioni di controllo di flusso
if(cond) expr
if(cond) true.expr else false.expr
ifelse(cond, true.expr, false.expr)
for(var in seq) expr
while(cond) expr
repeat expr
break
next
Scrivere una funzione sum_all
che sommi tutti gli elementi con indice dispari di un vettore numerico. La funzione deve avere un argomento x
e restituire la somma di tutti gli elementi di x
, usando un ciclo for
.
<-
e =
=
come assegnazione è valido solo al top-level<-
è valido ovunque, anche come argomento di funzione:dataframe
$
Anche in assegnazione:
Dal data frame mtcars
, estrarre le righe corrispondenti ai veicoli con cilindrata (disp
) maggiore di 200 e peso minore di 3.5 tonnellate (wt
)
Una lista è una sequenza di coppie chiave-valore, cioè una sequenza di valori identificati da un nome, o chiave.
A differenza dei vettori (che sono sempre omogenei) possono contenere valori eterogenei.
Una lista può essere indicizzata in tre modi:
$
: si estrae un unico elemento per nome[]
: si estraggono elementi per posizione e si ottiene una lista[[]]
: si estrae un unico elemento per posizionesort
, rev
, order
sample
, expand.grid
by
, aggregate
table
Per ordinare un vettore si usa la funzione sort
:
Per riordinare un data frame si estraggono gli indici ordinati:
A B
1 1 0.2016819
5 5 0.6291140
4 4 0.6607978
2 2 0.8983897
3 3 0.9446753
La funzione order
ritorna appunto gli indici di un vettore ordinati secondo i valori:
dove il primo è l’indice del valore più piccolo di df$B
e l’ultimo l’indice del più grande
Campionare un insiame di dati (un vettore) significa estrarre un sottoinsieme (detto campione) di valori in maniera casuale. Si esegue con la funzione sample
:
[1] 2 3 1 5 7 10 6 4 9 8
[1] 9 5 5 9 9 5 5 2 10 9
La dimensione del campione può essere uguale (caso sopra) o più piccola dell’insieme iniziale:
Una griglia è una matrice che contiene tutte le combinazioni (ordinate) tra \(n\) vettori di dimensioni possibilmente diverse. In R viene rappresentata come un data frame e costruita con la funzione expand.grid
:
Riordinare il dataframe df
in maniera casuale:
Per aggregazione si intende raggruppare righe aventi elementi comuni in un data frame e applicare ad ogni gruppo una data funzione. È utile ad esempio per il calcolo di sub-totali.
In R può essere eseguita mediante la funzione by
o la funzione aggregate
(cambia il tipo di output):
Una tabella di contingenza conta le occorrenze tra una coppia di colonne in un data frame:
Ozone Solar.R Wind Temp Month Day
1 41 190 7.4 67 5 1
2 36 118 8.0 72 5 2
3 12 149 12.6 74 5 3
Month
OzHi 5 6 7 8 9
FALSE 25 9 20 19 27
TRUE 1 0 6 7 2
<NA> 5 21 5 5 1
NOTA: with()
serve per risparmiarsi di scrivere airquality$Ozone
e airquality$Month
tapply()
, che opera su una tabella analogamente alle funzioni di aggregazione:Con aggregate()
si farebbe:
Dato che la statistica si occupa generalmente di grandi quantità di dati è fondamentale poter importare ed esportare dati in formati generici.
Generalmente i dati sono presentati in forma tabulare (per righe e colonne)
I formati più semplici e comuni sono:
Un Flat File con campi separati da spazi può avere questo aspetto:
# Dati raccolti il 10/8/2023
x y z
1.2 3.7 2.7
2.1 2.5 3.9
3.8 2.2 6.8
Un simile file può essere importato come data frame in questo modo:
La funzione read.table()
dispone di numerose opzioni che consentono di gestire tutti i possibili casi in cui file contenga campi separati da caratteri specifici (spazi od altro)
Un Flat File con campi a larghezza fissa può avere questo aspetto:
# Dati raccolti il 10/8/2023
x y z
1.2 3.7 2.7
2.1 2.5 3.9
3.8 2.2 6.8
Un simile file può essere importato come data frame in questo modo:
Il parametro skip=1
richiede di saltare la prima linea (commento)
I file CSV sono FF speciali in cui il separatore di campo è la virgola. In questi casi si usa la funzione read.csv()
che opera analogamente a read.table()
ma non richiede di specificare il separatore.
Un CSV ha questo aspetto:
# Dati raccolti il 10/8/2023
x,y,z
1.2,3.7,2.7
2.1,2.5,3.9
3.8,2.2,6.8
Software che usano lingue latine (Italiano, Spagnolo, Portoghese e Francese) adottano la virgola come separatore decimale. Di conseguenza quando questi software (ad. es. MS Excel) generano dei CSV usano il punto e virgola come separatore di campo.
In questo caso da R è necessario utilizzare la funzione read.csv2()
, che assume la virgola come separatore decimale e il punto e virgola come separatore di campo.
L’operazione opposta all’importazione di un file in un data frame è l’esportazione di un data frame su un file.
Questa operazione viene eseguita con le funzioni opposte alle precedenti:
write.table()
write.fwf()
write.csv()
e write.csv2()
Tutte queste funzioni hanno due argomenti obbligatori: il data frame da salvare e il file di destinazione:
Altri argomenti opzionali servono per personalizzare il risultato.
Assieme a RStudio è emersa una new wave di librerie R che modificano radicalmente l’approccio. Vanno sotto il nome collettivo di tidyverse
ggplot2
: graficipurrr
: programmazione funzionaledplyr
: manipolazione datistringr
: manipolazione stringhetibble
: data frame miglioratireadr
: importazione datitidyr
: preparazione datilubridate
: manipolazione dateL’approccio tidyverse
ha alcune caratteristiche comuni:
+
(ggplot(...) + geom_line()
), ogni funzione è un layer%>%
(a %>% str()
invece di str(a)
)È utile consultare i cheat sheet: https://posit.co/resources/cheatsheets/
# creo l'istogramma di un campione di 10 elementi da 100 numeri casuali
# infissa:
hist(sample(rnorm(100), 10))
Poco leggibile, il primo passo dell’algoritmo è quello più interno
# creo l'istogramma di un campione di 10 elementi da 100 numeri casuali
# infissa:
hist(sample(rnorm(100), 10))
# infissa sequenziata:
s <- rnorm(100)
c <- sample(s, 10)
hist(c)
Più leggibile, l’algoritmo è più evidente, ma richiede la creazione di variabili intermedie
# creo l'istogramma di un campione di 10 elementi da 100 numeri casuali
# infissa:
hist(sample(rnorm(100), 10))
# infissa sequenziata:
s <- rnorm(100)
c <- sample(s, 10)
hist(c)
# prefissa con pipe:
rnorm(100) %>% sample(10) %>% hist()
Molto più leggibile, l’algoritmo sequenziale è evidente, non sono necessarie variabili intermedie
# creo l'istogramma di un campione di 10 elementi da 100 numeri casuali
# infissa:
hist(sample(rnorm(100), 10))
# infissa sequenziata:
s <- rnorm(100)
c <- sample(s, 10)
hist(c)
# prefissa con pipe:
rnorm(100) %>% sample(10) %>% hist()
# anche su più righe:
rnorm(100) %>%
1 sample(10) %>%
2 hist
paolo.bosetti@unitn.it — https://paolobosetti.quarto.pub/ADAS