---
title: "Estrazione (subsetting)"
author: "Stefano Bussolon"
date: "3 gennaio 2019"
description: "Filtri - subsetting"
output: html_document

noknit: (function(inputFile, encoding) { 
      out_dir <- '../../dest/dispensa/html';
      rmarkdown::render(inputFile,
                        encoding=encoding, 
                        output_file=file.path(dirname(inputFile), out_dir,
                        'strutture_di_dati.html')) })


---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

# 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

### 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 filtri_vettore}

vettore1 <- c(2,4,6,8,10,12,14,16,18,20)
vettore1[5]           # seleziona il quinto elemento
vettore1[c(5)]        # == vettore1[5]
vettore1[c(-5)] # seleziona tutti gli elementi tranne il 5
vettore1[c(FALSE,FALSE,FALSE,FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE)]
```

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 filtri_names}
names(vettore1) <- c("due","quattro","sei","otto","dieci","dodici","quattordici","sedici","diciotto","venti")
vettore1
vettore1["dieci"]
vettore1[5]

```

### Riciclare i vettori

Cosa succede se il filtro booleano ha una lunghezza minore del vettore da filtrare?

```{r filtri_riuso}
vettore1[c(TRUE,TRUE,FALSE)]
```

Il vettore più corto viene *riciclato* - ovvero ripetuto tante volte da pareggiare la lunghezza del vettore più lungo.

* [20 Vectors | R for Data Science](https://r4ds.had.co.nz/vectors.html#using-atomic-vectors)


### Estrazione da matrici

```{r filtri_matrici}
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
# estrae l'elemento della seconda riga, seconda colonna
matrice1[2,2]
# estrae la prima e la terza colonna della prima riga
matrice1[1,c(1,3)]
# estrae tutta la terza riga
matrice1[3,]
# estrae la riga "R2"
matrice1["R2",]
# estrae righe e colonne per nome
matrice1["R3","C_A"] 
```

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 filtri_vuoto}
# estrae tutti gli elementi del vettore
vettore1[]
# estrae tutte le righe della colonna 2
matrice1[,2]
# estrae tutte le colonne della riga 2
matrice1[2,]
# estrae l'intera matrice
matrice1[,]

```

```{r filtri_2d}
(indici2d <- matrix(c(1,1,2,2,1,3,4,3),ncol = 2, byrow = TRUE))
matrice1[indici2d]

```

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 filtri_liste}
lista1 <- list(nomi=c("Marco","Alessia"), amici=c("Luigi","Francesco","Raffaella"), provincia=c("Brescia"))
lista1$nomi
# la sintassi [[]] estrae i valori dell'oggetto selezionato
lista1[[2]]
# la sintassi [] estrae l'oggetto
lista1[2]
```



### Estrazione di data frame

```{r filtri_df}

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
# stessa sintassi delle matrici
# tutte le righe, colonna 3
soggetti[,3]
# riga 3, tutte le colonne
soggetti[3,]
# cella 3,3
soggetti[3,3]
# il data frame è una lista, e dunque vale anche la sintassi $
soggetti$anno
# il data frame è una lista, e dunque posso selezionare per colonna
soggetti[2]

# sposta in filtri
soggetti[soggetti$condizione=="exp",]

subset(soggetti,condizione=="controllo")

```




### Filtrare i dati

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 filtri_logico}

vettore_logico1 <- vettore1 > 10
vettore1[vettore_logico1]

```

+++todo+++ approfondire

# Usare la sintassi sql

[sqldf package | R Documentation](https://www.rdocumentation.org/packages/sqldf/versions/0.4-11)

```{r filtri_sqldf}
library(sqldf)
# seleziona tutte le variabili (*) di soggetti dove la condizione è 'exp'
risultato <- sqldf("select * from soggetti where condizione == 'exp'")
risultato
rm(risultato)
# seleziona la variabile 'nome' da soggetti dove anno è maggiore di 1970
sqldf("select nome from soggetti where anno>1970")
```

## Which


Dato un filtro booleano, la funzione `which()` ritorna l'indice di quei valori che corrispondono a TRUE

```{r filtri_which}
vettore1
# quali valori sono uguali a 4
which(vettore1==4)
# l'indice dei valori superiori a 7
which(vettore1>7)
# quale cella ha il valore massimo?
which(vettore1==max(vettore1))

```



## 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)


