class: center, middle, inverse, title-slide # Estrazione (subsetting) ### Stefano Bussolon ### 3 gennaio 2019 --- # Filtri ed estrazione A partire da una struttura di dati (un vettore, una matrice, un data frame) è spesso necessario estrarre un sottoinsieme di dati. Subsetting è l'operazione di estrazione di un sottoinsieme di valori da un vettore, una lista o un data frame. --- ## Estrazione da vettori Il modo più semplice per ottenere un sottoinsieme di dati da un vettore è attraverso l'operatore di estrazione `[]`. Per capirne il funzionamento, è utile ricordare che in R le strutture di dati principali (vettori, matrici, liste, data frame) sono delle collezioni **ordinate** di elementi. Questo significa che ogni elemento ha una posizione nella collezione. La sintassi `vettore1[5]` permettere di accedere al quinto elemento del vettore `vettore1`. Nell'esempio precedente `5` è l'indice che viene usato per selezionare un elemento del vettore. In R non esistono scalari, e dunque `5` equivale a `c(5)`. --- ```r vettore1 <- c(2,4,6,8,10,12,14,16,18,20) # seleziona il quinto elemento vettore1[5] ``` ``` ## [1] 10 ``` ```r vettore1[c(5)] # == vettore1[5] ``` ``` ## [1] 10 ``` ```r # seleziona tutti gli elementi tranne il 5 vettore1[c(-5)] ``` ``` ## [1] 2 4 6 8 12 14 16 18 20 ``` ```r # seleziona gli elementi con indice TRUE vettore1[c(FALSE,FALSE,FALSE,FALSE,TRUE, FALSE,FALSE,FALSE,FALSE,FALSE)] ``` ``` ## [1] 10 ``` --- In questi esempi abbiamo visto alcune potenzialità dell'operatore di estrazione. Se l'indice è un vettore numerico, verranno estratti gli elementi corrispondenti agli indici del vettore. Se l'indice è di numeri negativi, verranno esclusi dall'estrazione gli elementi corrispondenti. Se l'indice è un vettore booleano della stessa lunghezza del vettore da cui si fa l'estrazione, verranno estratti gli elementi che corrispondono al valore `TRUE` dell'indice. Se agli elementi vettore di partenza è stato associato un nome, l'indice può essere un vettore stringa contenente i nomi degli elementi da estrarre. --- ```r names(vettore1) <- c("due","quattro","sei","otto","dieci", "dodici","quattordici","sedici","diciotto","venti") vettore1 ``` ``` ## due quattro sei otto dieci dodici ## 2 4 6 8 10 12 ## quattordici sedici diciotto venti ## 14 16 18 20 ``` ```r vettore1["dieci"] ``` ``` ## dieci ## 10 ``` ```r vettore1[5] ``` ``` ## dieci ## 10 ``` --- ### Riciclare i vettori Cosa succede se il filtro booleano ha una lunghezza minore del vettore da filtrare? ```r vettore1[c(TRUE,TRUE,FALSE)] ``` ``` ## due quattro otto dieci quattordici sedici ## 2 4 8 10 14 16 ## venti ## 20 ``` Il vettore più corto viene *riciclato* - ovvero ripetuto tante volte da pareggiare la lunghezza del vettore più lungo. --- ### Estrazione da matrici ```r matrice1 <- matrix(c(11,12,13,14,21,22,23,24,31,32,33,34), nrow=4,ncol=3) colnames(matrice1) <- c("C_A", "C_B", "C_C") rownames(matrice1) <- c("R1","R2","R3","R4") matrice1 ``` ``` ## C_A C_B C_C ## R1 11 21 31 ## R2 12 22 32 ## R3 13 23 33 ## R4 14 24 34 ``` --- ```r # estrae l'elemento della seconda riga, seconda colonna matrice1[2,2] ``` ``` ## [1] 22 ``` ```r # estrae la prima e la terza colonna della prima riga matrice1[1,c(1,3)] ``` ``` ## C_A C_C ## 11 31 ``` ```r # estrae tutta la terza riga matrice1[3,] ``` ``` ## C_A C_B C_C ## 13 23 33 ``` --- ```r # estrae la riga "R2" matrice1["R2",] ``` ``` ## C_A C_B C_C ## 12 22 32 ``` ```r # estrae righe e colonne per nome matrice1["R3","C_A"] ``` ``` ## [1] 13 ``` --- L'estrazione di elementi di una matrice è una estensione a due dimensioni dell'estrazione di un vettore. La sintassi è `matrice[indice righe, indice colonne]`. Per estensione, l'estrazione di un array tridimensionale sarà `array [indice dimensione 1, indice dimensione 2, indice dimensione 3]`. L'indice vuoto estrae l'intero vettore di quella dimensione. ```r # estrae tutti gli elementi del vettore vettore1[] ``` ``` ## due quattro sei otto dieci dodici ## 2 4 6 8 10 12 ## quattordici sedici diciotto venti ## 14 16 18 20 ``` --- ```r # estrae tutte le righe della colonna 2 matrice1[,2] ``` ``` ## R1 R2 R3 R4 ## 21 22 23 24 ``` ```r # estrae tutte le colonne della riga 2 matrice1[2,] ``` ``` ## C_A C_B C_C ## 12 22 32 ``` ```r # estrae l'intera matrice matrice1[,] ``` ``` ## C_A C_B C_C ## R1 11 21 31 ## R2 12 22 32 ## R3 13 23 33 ## R4 14 24 34 ``` --- ```r (indici2d <- matrix(c(1,1,2,2,1,3,4,3),ncol = 2, byrow = TRUE)) ``` ``` ## [,1] [,2] ## [1,] 1 1 ## [2,] 2 2 ## [3,] 1 3 ## [4,] 4 3 ``` ```r matrice1[indici2d] ``` ``` ## [1] 11 22 31 34 ``` indici2d è una matrice `r*2`. Ogni riga è una coppia di valori che corrisponde alla riga e alla colonna dell'elemento da estrarre. Dunque questa sintassi ha estratto gli elementi `matrice1[1,1]`, `matrice1[2,2]`, `matrice1[1,3]`, `matrice1[4,3]`. --- ## Estrazione da liste ```r lista1 <- list( nomi=c("Marco","Alessia"), amici=c("Luigi","Francesco","Raffaella"), provincia=c("Brescia")) lista1 ``` ``` ## $nomi ## [1] "Marco" "Alessia" ## ## $amici ## [1] "Luigi" "Francesco" "Raffaella" ## ## $provincia ## [1] "Brescia" ``` --- ```r lista1$nomi ``` ``` ## [1] "Marco" "Alessia" ``` ```r # la sintassi [[]] estrae i valori dell'oggetto selezionato lista1[[2]] ``` ``` ## [1] "Luigi" "Francesco" "Raffaella" ``` ```r # la sintassi [] estrae l'oggetto lista1[2] ``` ``` ## $amici ## [1] "Luigi" "Francesco" "Raffaella" ``` --- ### Estrazione di data frame ```r nome <- c("luigi","mario","antonella","luca") anno <- c(1956,1945,1972, 1976) condizione <- c("exp","controllo","exp","controllo") soggetti <- data.frame (nome,anno,condizione) soggetti ``` ``` ## nome anno condizione ## 1 luigi 1956 exp ## 2 mario 1945 controllo ## 3 antonella 1972 exp ## 4 luca 1976 controllo ``` --- ```r # stessa sintassi delle matrici # tutte le righe, colonna 3 soggetti[,3] ``` ``` ## [1] exp controllo exp controllo ## Levels: controllo exp ``` ```r # riga 3, tutte le colonne soggetti[3,] ``` ``` ## nome anno condizione ## 3 antonella 1972 exp ``` ```r # cella 3,3 soggetti[3,3] ``` ``` ## [1] exp ## Levels: controllo exp ``` --- ```r # il data frame è una lista, e dunque vale anche la sintassi $ soggetti$anno ``` ``` ## [1] 1956 1945 1972 1976 ``` ```r # il data frame è una lista, e dunque posso selezionare per colonna soggetti[2] ``` ``` ## anno ## 1 1956 ## 2 1945 ## 3 1972 ## 4 1976 ``` ```r soggetti[soggetti$condizione=="exp",] ``` ``` ## nome anno condizione ## 1 luigi 1956 exp ## 3 antonella 1972 exp ``` --- ## Subset La funzione subset permette di filtrare vettori, matrici e data frame (per riga) ```r subset(soggetti,condizione=="controllo") ``` ``` ## nome anno condizione ## 2 mario 1945 controllo ## 4 luca 1976 controllo ``` ```r subset(soggetti,anno<1970, select=nome) ``` ``` ## nome ## 1 luigi ## 2 mario ``` --- ## Filtri logici Come abbiamo visto parlando di estrazione da vettori, gli indici possono essere dei vettori logici. I vettori logici possono essere creati attraverso l'applicazione di operatori logici ai vettori. ```r vettore_logico1 <- vettore1 > 10 vettore1[vettore_logico1] ``` ``` ## dodici quattordici sedici diciotto venti ## 12 14 16 18 20 ``` --- ## Usare la sintassi sql ```r library(sqldf) ``` ``` ## Loading required package: gsubfn ``` ``` ## Loading required package: proto ``` ``` ## Loading required package: RSQLite ``` ```r # seleziona tutte le variabili (*) di soggetti dove la condizione è 'exp' risultato <- sqldf("select * from soggetti where condizione == 'exp'") risultato ``` ``` ## nome anno condizione ## 1 luigi 1956 exp ## 2 antonella 1972 exp ``` ```r rm(risultato) ``` --- ```r # seleziona la variabile 'nome' da soggetti dove anno è maggiore di 1970 sqldf("select nome from soggetti where anno>1970") ``` ``` ## nome ## 1 antonella ## 2 luca ``` --- ## Which Dato un filtro booleano, la funzione `which()` ritorna l'indice di quei valori che corrispondono a TRUE ```r # quali valori sono uguali a 4 which(vettore1==4) ``` ``` ## quattro ## 2 ``` ```r # l'indice dei valori superiori a 7 which(vettore1>7) ``` ``` ## otto dieci dodici quattordici sedici diciotto ## 4 5 6 7 8 9 ## venti ## 10 ``` ```r # quale cella ha il valore massimo? which(vettore1==max(vettore1)) ``` ``` ## venti ## 10 ``` --- ## Riferimenti * [Subsetting - Advanced R.](http://adv-r.had.co.nz/Subsetting.html#lookup-tables) * [Extracting elements - psyr.org](https://psyr.org/vectors.html#64_extracting_multiple_elements) * [Subsetting - R Programming for Data Science](https://bookdown.org/rdpeng/rprogdatascience/subsetting-r-objects.html) * [Indexing - R Language Definition](https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Indexing) * [Subset Data in R with R Subset Examples - RProgramming.net](http://rprogramming.net/subset-data-in-r/) * [indexing - Is there an R function for finding the index of an element in a vector? - Stack Overflow](https://stackoverflow.com/questions/5577727/is-there-an-r-function-for-finding-the-index-of-an-element-in-a-vector)