Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

R - Il pacchetto dplyr

R

Il pacchetto dplyr

Introduzione

  • Il pacchetto dplyr fa parte dell’insieme di pacchetti tidyverse che comprende tra gli altri ggplot2, tidyr, readr, purrr ed altri.
  • Questo pacchetto permette la manipolazione dei dati con una sintassi intuitiva che richiama l’SQL.
  • Alcune note importanti per lavorare con dplyr.
    • Nota 1: Il pacchetto lavora (quasi) esclusivamente con DataFrame e il risultato delle funzioni sono sempre DataFrame. In alternativa è possibile lavorare con un oggetto particolare di dplyr che si chiama tbl_df (detto anche tibble). Esso ha diversi vantaggi rispetto al DataFrame. Per ottenere un tbl_df, basta crearlo con l'istruzione as_tibble() che ha come unico parametro il DataFrame. Anche se una funzione è applicata a un tibble, il risultato dà sempre un DataFrame. Le funzioni group_by() e ungroup() sono eccezioni che non lavorano con DataFrame.
    • Nota 2: Tutte le funzioni di dplyr non alterano il DataFrame al quale vengono applicate (cioè non hanno un 'side-effect'). Quindi è necessario assegnare il risultato ad un nuovo DataFrame. È per questo che in tutti gli esempi il risultato sarà sempre una assegnazione del tipo df <- Funzione().
  • Le funzioni fornite da dplyr sono:
    • mutate() e transmute(): per aggiungere nuove variabili che sono calcolate in base a variabili esistenti.
    • select() e rename(): per selezionare le variabili.
    • filter() e slice(): per filtrare le righe (cioè le osservazioni).
    • summarise(): per creare righe riassuntive.
    • arrange(): per ordinare le righe.
    • distinct(): per selezionare valori unici delle variabili.
    • sample_n() e sample_frac(): per estrarre un certo numero di righe random.
    • group_by() e ungroup(): per creare e rimuovere dei raggruppamenti di righe.

Mutate e Transmute
  • Le funzioni mutate() e transmute() si applicano ad un DataFrame per ottenere un nuovo DataFrame al quale si sono aggiunte nuove variabili a partire da variabili esistenti. Nella mutate() le nuove colonne sono aggiunte al DataFrame preservando le colonne esistenti, nella transmute() le colonne sono aggiunte senza preservare le colonne esistenti che vengono eliminate.
  • La sintassi è la seguente:

df_new <- mutate(df, nuova_variabile = funzione, ...)
df_new <- transmute(df, nuova_variabile = funzione, ...)

  • df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, nuova_variabile è la variabile che si sta creando e la funzione è una espressione.
  • Le coppie 'nuova_variabile' / 'funzione', possono essere più di una come indicato dai puntini (...), consentendo così l'aggiunta di più colonne.

  • Esempi.
  • Per questo esempio si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Si vuole aggiungere al DataFrame la colonna ‘k’ calcolata come il rapporto tra ‘Income’ e ‘Age’.

# Esempio di mutate().
df1 <- mutate(Credit, k = Income / Age)
str(df1)
'data.frame': 400 obs. of  13 variables:
$ ID       : int  1 2 3 4 5 6 7 8 9 10 ...
$ Income   : num  14.9 106 104.6 148.9 55.9 ...
$ Limit    : int  3606 6645 7075 9504 4897 8047 3388 7114 3300 6819 ...
$ Rating   : int  283 483 514 681 357 569 259 512 266 491 ...
$ Cards    : int  2 3 4 3 2 4 2 2 5 3 ...
$ Age      : int  34 82 71 36 68 77 37 87 66 41 ...
$ Education: int  11 15 11 11 16 10 12 9 13 19 ...
$ Gender   : Factor w/ 2 levels " Male","Female": 1 2 1 2 1 1 2 1 2 2 ...
$ Student  : Factor w/ 2 levels "No","Yes": 1 2 1 1 1 1 1 1 1 2 ...
$ Married  : Factor w/ 2 levels "No","Yes": 2 2 1 1 2 1 1 1 1 2 ...
$ Ethnicity: Factor w/ 3 levels "African American",..: 3 2 2 2 3 3 1 2 3 1 ...
$ Balance  : int  333 903 580 964 331 1151 203 872 279 1350 ...
$ k        : num  0.438 1.293 1.473 4.137 0.822 ...

# Esempio di transmute().
df2 <- transmute(Credit, k = Income / Age)
str(df2)
'data.frame': 400 obs. of  1 variable:
$ k: num  0.438 1.293 1.473 4.137 0.822 ...

  • Come si vede il DataFrame df1 presenta 13 variabili (12 originali, più l’ultima aggiunta dalla mutate()). Il DataFrame df2 presenta invece la solo variabile ‘k’.

Select e Rename
  • Le funzioni select() e rename() si applicano ad un DataFrame per ottenere un nuovo DataFrame contenente le sole variabili selezionate o con tutte le variabili dove alcune di esse sono rinominate.
  • La sintassi è la seguente:

df_new <- select(df, variabile, …)
df_new <- rename(df, nuova_variabile = variabile, …)

  • Nella select(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, variabile è la prima delle variabili che si stanno selezionando, le altre variabili sono indicate dai puntini (...).
  • Nella rename(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, le coppie ‘nuova_variabile’ / ‘variabile’ sono i nomi delle nuove variabili che rinominano le vecchie variabili e possono essere più di una come indicato dai puntini (...), consentendo così la rinomina di più colonne.

  • Esempi.
  • Per questi esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Esempi di select().

# Seleziona tutte le variabili.
df1 <- select(Credit, everything())
# Seleziona le variabili indicate per nome.
df1 <- select(Credit, ID, Income)
# Seleziona le variabili indicate per indice.
df1 <- select(Credit, 3:5)
# Seleziona le variabili il cui nome inizia con una stringa.
df1 <- select(Credit, starts_with('I'))
# Seleziona le variabili il cui nome termina con una stringa.
df1 <- select(Credit, ends_with('e'))
# Seleziona le variabili il cui nome contiene con una stringa.
df1 <- select(Credit, contains('en'))
# Seleziona le variabili il cui nome contiene la Regular Expression.
df1 <- select(Credit, contains('exp'))

# Seleziona tutte le variabili eccetto quelle indicate per nome.
df1 <- select(Credit, -c(ID, Income))
# Seleziona tutte le variabili eccetto quelle indicate per indice.
df1 <- select(Credit, -c(3:5))
# Analogamente per le selezioni di variabili che non iniziano con una stringa,
# o non terminano con una stringa, o non contengono una stringa,
# o non contengono una Regular Expression.

  • Esempio di rename().

# Rinomina alcune variabili.
df1 <- rename(Credit, ID1 = ID, Income1 = Income)

Filter e Slice
  • Le funzioni filter() e slice() si applicano ad un DataFrame per ottenere un nuovo DataFrame con meno righe, cioè filtrato. Le righe ottenute rispettano dei criteri che sono logici (con la funzione filter()) oppure in base all'indice della riga (con la funzione slice()).
  • La sintassi è la seguente:

df_new <- filter(df, condizione, …)
df_new <- slice(df, valore, …)

  • Nella filter(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, condizione è la prima delle condizioni logiche che si stanno applicando, le altre sono indicate dai puntini (...). Le condizioni logiche permesse sono le classiche AND (operatore '&'), OR (operatore '|') e NOT (operatore '|').
  • Nella slice(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, valore è il primo dei valori numerici degli indici di riga che si stanno filtrando, gli altri sono indicati dai puntini (...). Per esempio se il valore è 3, sarà filtrata solo la terza riga.

  • Esempi.
  • Per questi esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Esempi di filter().

# Variabile uguale a un valore.
df1 <-  filter(Credit, Age == 34)
# Variabile diversa da un valore.
df1 <-  filter(Credit, Age != 34)
# Variabile uguale a più valori.
df1 <-  filter(Credit, Age %in% c(34, 82))
# Condizione NOT.
df1 <-  filter(Credit, !Age %in% c(34, 82))
# Più condizioni in AND (con l'operatore '|').
df1 <-  filter(Credit, Age == 34 & Married == 'Yes')
# Più condizioni in AND (con più argomenti).
df1 <-  filter(Credit, Age == 34, Married == 'Yes')
# Più condizioni in OR.
df1 <-  filter(Credit, Age == 34 | Student == 'Yes')
# Condizione in una Regular Expression (variabile Ethnicity con la sottostringa 'Asia').
df1 <-  filter(Credit, grepl('Asia', Ethnicity))

  • Esempi di slice().

# Solo le prime 3 righe.
df1 <- slice(Credit, 1:3)
# Solo l'ultima riga.
df1 <- slice(Credit, n())
# Solo le ultime 3 righe.
df1 <- slice(Credit, -1:-(n()-3))

Summarise
  • Le funzioni summarise() si applicano ad un DataFrame per ottenere un nuovo DataFrame con una sola riga che riassume gli indicatori principali delle variabili. I valori possono essere statistici (media, mediana e moda), range (minimo e massimo), di posizione (primo e ultimo), di quantità (numero di casi, numero di casi distinti) ed altri.
  • Ci sono le seguenti funzioni:
    • summarise(): raggruppa le coppie variabile / funzione.
    • summarise_at(): raggruppa tutte le variabili indicate per tutte le funzioni indicate.
    • summarise_if(): raggruppa tutte le variabili che rispettano una condizione per tutte le funzioni indicate.
    • summarise_all(): raggruppa tutte le variabili per tutte le funzioni indicate.
  • Tutte le funzioni hanno una doppia sintassi, sia summarise (con la 's') che summarize (con la 'z').
  • Le sintassi delle varie funzioni sono le seguenti:

df_new <- summarise(df, nome = funzione, …)
df_new <- summarise_at(df, vars(), lst(…))
df_new <- summarise_if(df, condizione, lst(…))
df_new <- summarise_if(df, lst(…))

  • Nella summarise(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, le coppie ‘nome’ / ‘funzione’ sono i nomi delle nuove variabili che sono calcolate con le funzioni indicate; queste coppie possono essere più di una come indicato dai puntini (...), consentendo così il calcolo di più colonne.
  • Nella summarise_at(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, vars() contiene l'elenco delle variabili da trattare, lst() contiene la lista delle funzioni da applicare alle variabili.
  • Nella summarise_if(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, condizione è la condizione per le variabili da trattare, lst() contiene la lista delle funzioni da applicare alle variabili.
  • Nella summarise_all(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, lst() contiene la lista delle funzioni da applicare a tutte le variabili. È da notare che le funzioni devono essere coerenti con tutte le variabili per non incorrere in errore (non si può per esempio calcolare la media di un fattore).

  • Per tutti gli esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Esempio di summarise().
  • Nell'esempio seguente, si definiscono le nuove variabili ('Income_mean' e 'Limit_mean') che sono calcolate come la media delle variabili 'Income' e 'Limit'.

# Calcola la media di due variabili.
df1 <-  summarise(Credit, Income_mean = mean(Income), Limit_mean = mean(Limit))
print(df1)
 Income_mean Limit_mean
1    45.21889     4735.6

  • Esempio di summarise_at().
  • Nell'esempio seguente, si lavora con le variabili 'Income' e 'Limit'; per esse si calcola il minino, il massimo e la media. Le variabili ottenute hanno come nome la stringa ottenuta dal nome della variabile più il '_' più il nome della funzione.

# Calcola il minimo, il massimo e la media di due variabili.
df1 <-  summarise_at(Credit, vars(Income, Limit), lst(min, max, mean))
print(df1)
 Income_min Limit_min Income_max Limit_max Income_mean Limit_mean
1     10.354       855    186.634     13913    45.21889     4735.6

  • Esempio di summarise_if().
  • Nell'esempio seguente, si lavora con tutte le variabili numeriche (condizione 'is.numeric'); per esse si calcola il minino, il massimo e la media. Le variabili ottenute hanno come nome la stringa ottenuta dal nome della variabile più il '_' più il nome della funzione.

# Calcola il minimo, il massimo e la media di tutte le variabili numeriche.
df1 <-  summarise_if(Credit, is.numeric, lst(min, max, mean))
print(df1)
 ID_min Income_min Limit_min Rating_min Cards_min Age_min Education_min Balance_min
1      1     10.354       855         93         1      23             5           0
 ID_max Income_max Limit_max Rating_max Cards_max Age_max Education_max Balance_max
1    400    186.634     13913        982         9      98            20        1999
 ID_mean Income_mean Limit_mean Rating_mean Cards_mean Age_mean Education_mean Balance_mean
1   200.5    45.21889     4735.6      354.94     2.9575  55.6675          13.45 520.015

  • Esempio di summarise_all().
  • Nell'esempio seguente, si lavora con tutte tre variabili numeriche ('Income', 'Limit', 'Rating') ; per esse si calcola il minino, il massimo e la media. Le variabili sono ottenute dal DataFrame Credit che viene filtrato con select(). Questo primo passaggio è necessario, perché il DataFrame contiene anche variabili sulle quali non è possibile eseguire le funzioni numeriche. La summarise_all() è quindi applicata al DataFrame filtrato. Le variabili estratte hanno come nome la stringa ottenuta dal nome della variabile più il '_' più il nome della funzione.

# Calcola il minimo, il massimo e la media di tre variabili.
df1 <- select(Credit, Income, Limit, Rating)
df1 <- summarise_all(df1, lst(min, max, mean))
print(df1)
 Income_min Limit_min Rating_min Income_max Limit_max Rating_max Income_mean Limit_mean Rating_mean
1     10.354       855         93    186.634     13913        982    45.21889     4735.6 354.94

Arrange
  • La funzione arrange() si applica ad un DataFrame per ottenere un nuovo DataFrame ordinato secondo i criteri indicati nei parametri.
  • La sintassi è la seguente:

df_new <- arrange(df, variabile, …)

  • df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, variabile è la prima delle variabili da ordinare, le altre sono indicate dai puntini (...). L'ordinamento può essere ascendente (default) o discendente.

  • Per tutti gli esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Esempio di arrange().
  • Nell'esempio seguente, si ordina il DataFrame Credit. Nel primo caso in base a due variabili, nel secondo e nel terzo caso la seconda variabile è ordinata in modo discendente.

# Ordina per le due variabili ascendenti.
df1 <- arrange(Credit, Age, Income)
# Ordina per le due variabili, la prima ascendente, la seconda discendente.
df1 <- arrange(Credit, Age, desc(Income))
# Ordina per le due variabili, la prima ascendente, la seconda discendente.
df1 <- arrange(Credit, Age, -Income)

Distinct
  • La funzione distinct() si applica ad un DataFrame per ottenere un nuovo DataFrame le cui righe sono i valori distinti delle variabili. Tramite una opzione è possibile mostrare anche tutte le altre variabili (per queste verrà mostrata solo la prima riga).
  • La sintassi è la seguente:

df_new <- distinct(df, variabile, …)

  • df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, variabile è la prima delle variabili da estrarre, le altre sono indicate dai puntini (...).

  • Per tutti gli esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Esempio di distinct().
  • Nel primo esempio si estraggono solo i distinti valori della variabile 'Age'. Nel secondo esempio si estraggono tutte le coppie distinte delle due variabili 'Age' e 'Cards'. Nel terzo esempio ci sono tante righe quante sono nel secondo esempio; per ogni riga sono anche estratte tutte le altre variabili ma per queste viene mostrata solo la prima riga.

# Estrae solo i distinti valori della variabile.
df1 <- distinct(Credit, Age)
# Estrae solo i distinti valori delle due variabili.
df1 <- distinct(Credit, Age, Cards)
# Estrae i distinti valori delle due variabili aggiungendo tutte le altre.
df1 <- distinct(Credit, Age, Cards, .keep_all = TRUE)

Sample_n e Sample_frac
  • Le funzioni sample_n() e sample_frac() si applicano ad un DataFrame per ottenere un nuovo DataFrame con meno righe estratte in modo casuale. Con sample_n() si ottengono il numero esatto di righe richieste, con sample_frac() si ottiene un numero di righe pari alla frazione decimale richiesta. Tramite l'opzione 'replace = TRUE', si imposta la modalità che fa sì che una riga possa essere estratta più volte.
  • Le sintassi sono le seguenti:

df_new <- sample_n(df, numero)
df_new <- sample_frac(df, numero)

  • Nella sample_n(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, numero è il numero di righe da estrarre.
  • Nella sample_frac(): df_new è il nuovo DataFrame, df è il DataFrame che si sta elaborando, numero è la frazione di righe da estrarre (esempio: 1 indica il 100%, 0.5 il 50%, ecc.).

  • Per tutti gli esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Esempio di distinct().
  • Nel primo esempio si estraggono 10 righe casuali e distinte. Nel secondo esempio si estrae la frazione 0.1 di tutte le righe; nel DataFrame ci sono 400 righe, perciò sono estratte 40 righe. Nel terzo esempio ci sono ancora 10 righe, ma sono possibili righe duplicate.

# Estrae 10 righe.
df1 <- sample_n(Credit, size = 10)
# Estrae il 10% delle righe.
df1 <- sample_frac(Credit, size = 0.1)
# Estrae 10 righe.
df1 <- sample_n(Credit, size = 10, replace = TRUE)

Group_by e Ungroup
  • Le funzioni group_by() e ungroup() contrariamente alle altre funzioni di dplyr non si applicano ad un DataFrame. La funzione group_by() trasforma un DataFrame in un oggetto 'grouped_df' che è un oggetto di dplyr che racchiude in sé le righe raggruppate. La funzione ungroup() fa l'operazione opposta, cioè rimuove i gruppi; riceve un oggetto 'grouped_df' e restituisce un oggeto 'tbl_df' (tibble).
  • La creazione di gruppi è utile quando si elaborano dati in sequenza, in particolare utilizzando il 'pipe' cioè l'operatore %>% che viene descritto nel relativo paragrafo.
  • La sintassi è la seguente:

df_new <- group_by(df, variabile, )
df_new <- ungroup(df)

  • Nella group_by(): df_new è il nuovo oggetto di tipo grouped_df, df è il DataFrame che si sta elaborando, variabile è la prima delle variabili con le quali creare il raggruppamento; le altre variabili sono indicate con i puntini (...).
  • Nella ungroup(): df_new è il nuovo oggetto di tipo tbl_df, df è l'oggetto di tipo grouped_df che si sta elaborando.

  • Esempi.
  • Per questi esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • Il primo esempio crea un raggruppamento per le variabili 'Cards' e 'Age'. Il secondo esempio rimuove il raggruppamento creato nel primo esempio.

# Raggruppa per due variabili.
df1 <- group_by(Credit, Cards, Age)
# Rimuove il raggruppamento.
df1 <-  ungroup(df1)

Pipe
  • Il pacchetto dplyr ha introdotto un comodo operatore chiamato 'pipe' che permette di accodare le varie istruzioni. L'operatore è questo: %>%.
  • In pratica con il pipe si invia l'output di una funzione direttamente all'input di un'altra funzione.
  • Quando si utilizza il pipe, nelle funzioni utilizzate non è necessario indicare come primo argomento il DataFrame con il quale si sta lavorando.

  • Esempio.
  • Per questi esempi si utilizza il DataFrame ‘Credit’ presente nel package ‘ISLR’ che va quindi installato e caricato in memoria.
  • In questo esempio si parte dal DataFrame Credit. La prima operazione è un filtraggio (Cards == 1 e Income >= 40). La seconda operazione è la rimozione di tutte le variabili eccetto ID, Rating e Income. La terza operazione è l'ordinamento per Age. L'ultima operazione è l'estrazione delle prime 3 righe.

# Utilizzo del pipe.
df1 <- Credit %>%
 filter(Cards == 1, Income >= 40) %>%
   select(ID, Rating, Age) %>%
     arrange(Age) %>%
       sample_n(3)
print(df1)
  ID Rating Age
1 364    433  80
2 272    347  30
3  19    448  28



© 2022 Carlo Vecchio
Torna ai contenuti