Cartella di lavoro
setwd('D:/Documents/BDA_esercitazioni/lab1') getwd()
Carica una libreria di dataset pre-installata
library(datasets)
Sommario dati
help(datasets) #Spiega
library(help = "datasets")
head(iris) # Mostra le prime sei righe del dataset
summary(iris) # Riassume le principali statistiche descrittive
plot(iris) # Scatterplot, analisi descrittivo-visiva
Clear packages
detach("package:datasets", unload = TRUE)
Clear plots
dev.off()
Inizia con la pulizia del workspace
rm(list = ls())
Oggetti, variabili e funzioni base
# Creare degli oggetti, che verranno visualizzati nel workspace in alto a destra
x = 2
# R deduce le caratteristiche dell'oggetto dall'inizializzazione.
class(x)
typeof(x)
# Cambiare il tipo della variabile (non sempre è possibile)
int_x = as.integer(x)
# Funzioni base con x = 2
y = exp(x)
(z = sin(x)) # Visualizzo il risultato
t = atan(x)
q = log(x)
w = y + z + t
e = exp(1)
pi_greco = pi
Valori speciali
x = NA # Not available (e.g. dati mancanti) genera altri NA
(y = log(x)) # Si propagano
x = NAN # Not a number (e.g. operazioni matematiche non ben definite)
(y = log(-1))
x = Inf # Valori ottenuti tramite operazioni matematiche definite al limite
log(0) o 1/0
Operatori logici
== uguale
> strettamente maggiore
< strettamente minore
>= maggiore o uguale
<= minore o uguale
!= diverso
Operatori booleani
& and
| or
! not
%in% # Inclusione insiemistica
Es:
X=100
(b=x>99) restituisce b con valore true
Caratteri e stringhe in un unico tipo: character
c1 = "a"
stringa1 = "Ciao"
stringa2 = "Come stai?"
# Le stringhe si possono concatenare ma non sommare (stringa1 + stringa2)
paste(stringa1, stringa2, sep = " ") # Concatena con spazio
paste(stringa1, stringa2, sep = "") # Senza spazio
sequenze ordinate di oggetti dello stesso tipo, non colonna o riga hanno
Vettori
# Vettori:
un solo indice.
# Per crearli diversi modi
(v1 = c(0.5,1,2,4,3.7,1)) #Concatena
(v2 = seq(from = 0, to = 1, by = 0.1)) # Punti equispaziati con passo 0.1, da 0 a 1
(v3 = seq(from = 0, to = 1, length.out = 5)) # 5 punti equispaziati tra 0 e 1
(v4 = rep(x = 1, times = 5)) # un vettore lungo 5 in cui ripeto l'elemento 1: 11111
(v5 = rep(x = c(1,2), times = 5)) # vettore con elementi di un vettore ripetuti 5 volte 1212121212
# Quanto è lungo un vettore (numero oggetti)?
length(v1)
# Somma e prodotto (sottrazione e divisione) N.B. non sto cambiando il vettore di partenza
v4+4, 4*v4, v4/4, v3+v4, v3*v4, v3/v4
# Se i vettori hanno dimensioni diverse elementi di + corto ripartono dall'inizio, viene segnalato
Es: V1= 0 1 2 3 1 V2= 4 5 2
v1+v2 4 6 4 7 6
v1*v2 0 5 4 12 5
Prodotto scalare
# Prodotto scalare (somma prodotti elementi corrispondenti, risultato scalare)
v3%*%v4 # Se le dimensioni sono diverse, fallisce
Estrarre e modificare gli elementi del vettore
# Estrarre/modificare gli elementi del vettore
v1[1] # Primo elemento
v1[1:3] # Da 1 a 3 (primo, sec, terzo)
v1[c(1,3,5)] # primo, terzo e quinto el
v1[-1] # Tutti gli elementi tranne il primo
v1[-c(1,3,5)] # Tutti gli elementi tranne primo, terzo e quinto
v1[v1>2] # Estraggo gli elementi maggiori di 2 v1>2 restituisce vett di booleani, true se verifica condiz
Funzioni utili
# Funzioni utili
(s = sum(v1)) # Somma tutti gli elementi del vettore
(p = prod(v1)) # Prodotto di tutti gli elementi
(d = diff(v1)) # Vettore generato con la regola d[i] = v[i+1] - v[i]
(cs = cumsum(v1)) # Somme cumulate, cs[i] = sum(v1[1:i])
# Tutte le funzioni sono applicabili a ciascun elemento
(sin(v1)) (exp(v1))
# Qualunque tipo si può mettere in un vettore, per es si può creare un vettore di stringhe, ma operazioni non valgono
v_str = rep("ciao",20)
Matrici
# Matrici sono collezioni 2-dimensionali di variabili, come una successione di vettori tutti della stessa lunghezza e con dati dello stesso tipo.
m1 <- matrix(c(T, T, F, F, T, F), nrow = 2) T T F F T F
m2 <- matrix(c("a", "b”, "c", "d"), nrow = 2, byrow = T) “a” “b” “c” “d”
m1 = cbind(c(1,2,3),c(4,5,6),c(7,8,9)) # Costruita per colonne
m2 = rbind(c(1,2,3,4),c(5,6,7,8),c(9,10,11,12)) # Per righe
m3 = matrix(data = 2, nrow = 4, ncol = 3) # ricicla i valori lungo righe (tutti 2) fa warning
m4_col = matrix(data = c(1,2,3), nrow = 3,ncol = 10) # lungo le colonne
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 1 1 1 1 1 1 1 1 1
[2,] 2 2 2 2 2 2 2 2 2 2
[3,] 3 3 3 3 3 3 3 3 3 3
m4 = matrix(data = c(1,2,3), nrow = 4,ncol = 10, byrow = T) # riciclare lungo le colonne e anche le righe
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 2 3 1 2 3 1 2 3 1
[2,] 2 3 1 2 3 1 2 3 1 2
[3,] 3 1 2 3 1 2 3 1 2 3
[4,] 1 2 3 1 2 3 1 2 3 1
(d2 = dim(m2)) # Un vettore di due interi, non funziona sui vettori
d2[1] # Numero di righe
d2[2] # Numero di colonne
Operazioni con matrici
# Operazioni con matrici
m1 + 1
m1*2
m1 + c(1,2,3) # Somma vettore ai vett (default col) della matr, se le dim non sono compatibili ricicla
m1 + m1 # Stessa dimensione: componente per componente
m1 + m2 # Dimensione diversa: ERRORE
m1*m1 # matrice con prodotti componente per componente
m1*m2 # dim diversa: ERRORE
m1[2,3] # seleziono elemento in seconda riga, terza colonna
m1[,3] # Terza colonna (tutte le righe)
m1%*%m1 # per ogni elemento sommo prodotto elementi corrispondenti di riga e col con quegli indici
deve essere mxn %*% nxp = mxp, altrimenti errore
t(m2) # Matrice trasposta (scambia righe e col)
(inv_m = solve(m)) # Inversa di matrice quadrata non singolare, moltiplicate restituiscono mat identità
det(m) # Determinante di una matrice quadrata
D = eigen(m) # restituisce autovalori e autovettori
Liste
# Liste generiche successioni di oggetti di diverso tipo. Elementi, detti campi, hanno un nome
# Creare una lista con campi
mylist = list(nome = "Marco", cognome = "Rossi", voti = c(20,22,30,NA), materie = c("analisi","chimica","fisica","probabilità"))
# Estrarre
mylist$cognome #nome lista, dollaro, nome campo
mylist[1] restituisce Marco
#Oppure creo vettori e ne faccio una lista. Campi non hanno nomi, solo numeri associati
o1 <- "Marco"
o2 <- "Rossi"
o3 <- c(20,22,30,NA)
o4 <- c("analisi","chimica","fisica","probabilità.")
list1 <- list(o1, o2, o3,o4) # Di default i campi sono dati da numeri
list1[2] # Così vedo il secondo campo, ma non vi accedo
list1[[2]] # Così accedo al secondo campo
# Posso aggiungere dopo i nomi ai campi
names(list1) = c("nome","cognome","voti","materie")
Salvataggio e caricamento
# Salvataggio di tutti i dati nel workspace
save.image("./Output/workspacelab1.rdata")
# Eliminare tutto
rm(list = ls())
# Ricaricare ciò che ho salvato
load("./Output/workspacelab1.rdata")
Data frame
# Data frames lista di vettori della stessa lunghezza, ma che possono avere tipi diversi.
vNumeric = c(1, 2, 3) vCharacter = c("a", "b", "c") vLogical = c(T, F,T)
dfa = cbind(vNumeric, vCharacter, vLogical) # crea una matrice, dati tutti convertiti ad un comune tipo meno generico possibile, in questo caso stringa con “” data frame
df = data.frame(vNumeric, vCharacter, vLogical) # Il invece mantiene i tipi dati in input.
#esempio
esame=data.frame(matricola = as.character( c( 45020, 45679, 46789, 43126, 42345,47568, 45674 )), voti_S = c( 30, 19, 29, NA, 25, 26, 27 ), voti_O = c( 3, 3, 1, NA, 3, 2,NA ), voti_TOT = c( 30, 22, 30, NA, 28, 28, 27 ))
matricola voti_S voti_O voti_TOT
1 45020 30 3 30 ogni colonna rappresenta una variabile
2 45679 19 3 22
3 46789 29 1 30
4 43126 NA NA NA
5 42345 25 3 28
6 47568 26 2 28
7 45674 27 NA 27
Manipoliamo
# Manipoliamo
esame$matricola # come per le liste (45020, 45679, 46789, 43126, 42345, 47568,45674)
esame[,2] # come per le matrici (30, 19, 29, NA, 25, 26, 27)
esame[1:3,1:3] # (prima, sec, terza riga e col)
esame[esame$voti_S < 27,] # tutte le colonne per righe che soddisfano, virgola è importante
Riassunto del data frame
# Riassunto delle caratteristiche del data frame
str(esame) summary(esame)
Importare dataframe da file esterni
# Importare dataframe da file esterni
dati = read.csv("appendiceA.txt", sep = " ", header = T) header T significa che colonne hanno nome
#oppure
dati = read.table("appendiceA.txt", header = T)
# Vediamo le prime e ultime righe
head(dati)
tail(dati)
# Visualizziamo i nomi delle righe
names(dati)
Funzioni statistiche di base
# Funzioni statistiche di base applicate a dati numerici
Indici di posizione
# Indici di posizione:
min(dati$Peso)
max(dati$Peso)
mean(dati$Peso)
median(dati$Peso)
quantile(dati$Peso, c(0.25,0.5,0.75))
Indici di dispersione
# Indici di dispersione
var(dati$Peso)
oppure a mano: 1/(length(dati$Peso) - 1) * sum((dati$Peso - mean(dati$Peso))^2)
sd(dati$Peso) #dev std campionaria
IQR(dati$Peso) # range interquartile (distanza tra il primo e il terzo quartile)
Istogramma
# Istogramma mostra distribuzione. Costruzione:
- Si divide il range dei dati in classi (intervalli);
- Calcolo per ogni classe frequenze assolute e relative e densità=(frequenza relativa)/(ampiezza classe);
- Per ogni classe si disegnano dei rettangoli di area pari alla frequenza relativa della classe considerata (ovvero di altezza pari alla densità). Se rappresentato con l'altezza uguale alle frequenze assolute, è coerente solo se le classi hanno tutte la stessa ampiezza.
#esempio Frequenze
hist( dati$Peso, prob = F )
abline(v= median(dati$Peso), col = 'red')
abline(v= mean(dati$Peso), col = 'green')
#es Densità
hist( dati$Peso, prob = T )
abline(v= median(dati$Peso), col = 'red')
abline(v= mean(dati$Peso), col = 'green')
# non esiste un numero di classi giusto, ce n’è uno std per R ma posso modificare. Valuto robustezza in base a quanto cambia grafico con numero classi
hist( dati$Peso, prob = TRUE, breaks = 15, col = 'orange', main = 'Istogramma del Peso', xlab = 'Peso', ylab = 'Densita' ) con densità rettangoli più bassi
Boxplot
# Boxplot strumento grafico utile per identificare eventuali asimmetrie della distribuzione e/o valori estremi (outlier). Per costruire:
- Valori della variabile su una retta verticale;
- Rettangolo con basi inferiore e superiore poste rispettivamente al primo e al terzo quartile (Q1 e Q3), conterrà il 50% centrale delle osservazioni;
- All'interno del rettangolo si traccia una linea all'altezza della mediana;
- Limite superiore a Q3 + 1.5*IQR e si traccia un baffo che collega la base superiore del rettangolo all'osservazione più alta all'interno del limite superiore; baffo + lungo è coda + pronunciata
- Si limite inferiore uguale a Q1 - 1.5*IQR e si traccia un baffo che collega la base inferiore del rettangolo all'osservazione più bassa contenuta all'interno del limite superiore;
- Eventuali valori maggiori del limite superiore o minori di quello inferiore vengono segnati con un cerchioe chiamati outliers (superiori o inferiori).
# baffi con lunghezza simile e mediana quasi centrale indica distribuzione più simmetrica
# es
x11()
boxplot( dati$Peso, main = 'Boxplot del Peso' , col = "forestgreen")
# Per disattivare e chiudere tutti i device grafici e reimpostare il default:
graphics.off()
Più plot nello stesso device
# Mettere più plot nello stesso device
x11()
par(mfrow = c(1,3)) # device 1x3, c'è spazio per 3 grafici
for( i in 2:4)hist(dati[,i], main = names(dati)[i], xlab = names(dati)[i], prob = T, col = i)
graphics.off() dev.off()
# Tutto sulla stessa scala, devo specificare ylim.
hist(dati[,i], main = names(dati)[i], xlab = names(dati)[i], prob = T, col = i, ylim = c(0,0.04))
Variabili categoriche
# Variabili categoriche, per es la colonna specificante il "Sesso", è variabile categorica e dicotomica. Rimane categorica indipendentemente da etichette usate per codificare (numeri) sue categorie.
# Barplot, grafico a barre con frequenze assolute e/o relative (Non ci interessa la larghezza della base dei rettangoli!)
# Calcolo le frequenze assolute e relative
f_ass = table( dati$Sesso )
f_rel = f_ass / length( dati$Sesso )
# Metodo alternativo
f_rel2 = prop.table( f_ass )
x11()
par(mfrow = c(1,2))
barplot( f_ass, col = c( 'pink', 'lightblue' ), ylab = 'F. ass' )
barplot( f_rel, col = c( 'pink', 'lightblue' ), ylab = 'F. rel' )
Grafico a torta
# Grafico a torta
x11()
pie(f_ass, col = c( 'pink', 'lightblue' ))
# es dati categorici con più di 2 classi (120 persone in una classe e ognuno la provincia di provenienza)
# Riordiniamo in maniera random i dati
prov_data = sample(prov_data)
# Diciamo a R che abbiamo una variabile categorica, ne individua i valori possibili (es: maschio, femmina).
prov_data=factor(prov_data)
# Calcoliamo le frequenze assolute e relative
(num = table(prov_data))
(table(prov_data)/length(prov_data))
# Diagramma a barre e a torta
x11()
barplot(table(prov_data)/length(prov_data), col = "gold")
x11()
pie(table(prov_data))
# Calcolo della moda
num == max(num) # Vettore di booleani
num[num == max(num)] # Restituisce il true
Pacchetti e tidyverse
# Pacchetti, righe di codice che definiscono comandi per fare cose complesse con poco sforzo.
# Load, usiamo il pacchetto "pacman" come manager degli altri. Pacchetto "tidyverse" ("tidyr") per usare e manipolare i data frames (es):
pacman::p_load(pacman, tidyverse, babynames, ggrepel)
dati <- babynames
Estrazione sottoinsieme colonne
# Estrazione sottoinsieme colonne
sel_1 <- dati %>% select(name,year) # specificandone il nome
dati %>% select(-year) # Tutte le colonne tranne "year"
dati %>% select(contains("e")) # Tutte le colonne il cui nome contiene la lettera "e"
dati %>% select(ends_with("e"))
dati %>% select(starts_with("y"))
Filtrare righe
# Filtrare righe
nome <- dati %>% filter(name == "Anna") # estrae le righe che soddisfano la condizione
solo_maschi <- dati %>% filter (sex == "M")
numerosi <- dati %>% filter ( n >= 1000)
maschi_numerosi_e_femmine_rare <- dati %>% filter((sex == "M" & n >= 1000) | (sex== "F" & n <= 10))
nomi_selezionati <- dati %>% filter( name %in% c("Anna", "Andrea"))
Riordinare
# Riordinare
dati_ordinati = dati %>% arrange(n) # Ordine crescente secondo "n"
dati_ordinati = dati %>% arrange(desc(n)) # Ordine decrescente
dati %>% arrange(n, year) # Ordina secondo "n", poi risolve i pareggi secondo "year"
Combinare tutti i comandi
# Combinare tutti i comandi (sempre meglio mettere select() alla fine)
sub_data<- dati %>% filter(year %in% 2000:2012)%>% arrange(n,year) %>%select(name, n)
Statistiche del dataset
# Estrazione dal data frame di una serie di caratteristiche/statistiche del dataset.
# esempio: serve il numero, il massimo, e la media per anno dei bambini chiamati Giovanni
dati %>% filter( name == "Giovanni") %>% summarise(total = sum(n), max = max(n), mean = mean(n))
# Ogni funzione che restituisce uno scalare può essere utilizzata
Raggruppare i valori
# Raggruppare i valori del data frame secondo i valori di alcune colonne.
.by_name <- dati %>% group_by(name)
# Nota: summarise() annulla l'ultimo raggruppamento. Se si desidera annullarli tutti, usare ungroup().
# esempio: troviamo il nome più popolare anno per anno, distinguendo tra i sessi
dati %>% group_by(year,sex) %>%filter(n == max(n)) %>% # filter() agisce separatamente sui gruppi
select(name, year,sex) %>%ungroup()
Aggiungere colonne
# Aggiungere colonne ad un dataframe esistente
# Es: aggiungere al dataset colonna in cui la proporzione dei nomi viene trasformata in una percentuale.
dati %>% mutate(perc = 100*prop)
Visualizzazione con ggplot
# Visualizzazione usando pacchetto ggplot. I grafici sono oggetti costruiti strato per strato a partire da un dataframe. Possono essere salvati come qualunque altra variabile.
# l'oggetto grafico che prende i dati dal dataframe
initial_plot = ggplot(diamonds_data)
# grafico a barre (categorica): l'argomento "mapping" stabilisce come i dati vengono manipolati. In questo caso che l'estetica - "aes" - del grafico sia data dalla variabile cut sull'asse x.
bar1 = initial_plot + geom_bar(mapping = aes(x = cut))
# dividere le barre utilizzando l'informazione nel valore "clarity"
bar2 = initial_plot + geom_bar(mapping = aes(x = cut, fill = clarity)) #fill=clarity colora i grafici in base al valore categorico della variabile clarity
# dividere i grafici:
bar3 = initial_plot + geom_bar(mapping = aes(x = cut, fill = clarity), position ="dodge")
# visualizzare le proporzioni (si perde info su numero)
bar4 = initial_plot + geom_bar(mapping = aes(x = cut, fill = clarity), position = "fill")
x11()
plot(bar)
# per istogrammi (quantitativa)
hist1 = initial_plot + geom_histogram(mapping = aes(x = price, fill = cut))
# oppure
dens1 = initial_plot + geom_density(mapping = aes(x = price, col = cut))
# per i boxplot (quantitativa)
box1 = initial_plot + geom_boxplot(mapping = aes(x = clarity, y = price, fill = clarity))
Distribuzione di probabilità
# Distribuzione di probabilità su R è identificata da una qualsiasi tra le tre funzioni seguenti:
(1) Funzione di ripartizione F(t) = P(X <= t)
(2) Funzione Quantile, inversa (generalizzata) di F
(3) Funzione Densità, ovvero f(t) = P(X = t) con X discreta, o f(t) = F'(t) se X continua
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
-
Business Data Analytics
-
Business data analytics
-
Business Intelligence
-
Big Data & Business Analytics, il nuovo motore del successo competitivo