Ricerca Sociale con R

Una wiki per l'analisi dei dati con R

Strumenti Utente

Strumenti Sito


r:tidyverse:dplyr_summarise

summarise (dplyr)

summarise() (o summarize()) produce tabelle riassuntive, a partire da un dataframe.

library(tidyverse)

La sintassi è

summarise(.data, ..., .groups = NULL)

dove i puntini vanno sostituiti dalla funzione (o dalle funzioni) che si vogliono applicare ai dati per sintetizzarli, ad esempio:

summarise(mtcars, 
          # nome della colonna e funzione
          disp = mean(disp))
      disp
1 230.7219

oppure

# due funzioni
mtcars %>%
  summarise(disp = mean(disp), 
            n = n())
      disp  n
1 230.7219 32

Non è obbligatorio indicare il nome delle colonne, ma il risultato potrebbe risultare poco chiaro o poco adeguato dal punto di vista estetico:

# senza nome della colonna
mtcars %>%
  summarise(mean(disp), 
            sd(disp),
            n())
  mean(disp) sd(disp) n()
1   230.7219 123.9387  32

Con variabile di raggruppamento

Normalmente, questa funzione viene utilizzata con una variabile di raggruppamento, per avere una tabella di sintesi di una o più misure riferite ai gruppi.

Ad esempio, nel dataset dei personaggi di Starwars, possiamo confrontare i dati di altezza e massa per sesso:

starwars %>% 
  group_by(sex) %>% 
  summarise(height = mean(height, na.rm=T),
            mass = mean(mass, na.rm=T))
# A tibble: 5 x 3
  sex            height   mass
  <chr>           <dbl>  <dbl>
1 female           169.   54.7
2 hermaphroditic   175  1358  
3 male             179.   81.0
4 none             131.   69.8
5 <NA>             181.   48  

In questo caso, otteniamo una colonna con i nomi dei gruppi (modalità della variabile di raggruppamento), e una colonna per ciascuna delle misure indicate quali argomento della funzione.

Con i selettori

vedi Indicare e scegliere le variabili

Con across(), possiamo applicare la stessa funzione a più variabili. Ad esempio, qui, con everything(), calcoliamo la media di tutte le variabili:

mtcars %>%
  summarise(across(everything(), mean))
       mpg    cyl     disp       hp     drat      wt     qsec     vs      am
1 20.09062 6.1875 230.7219 146.6875 3.596563 3.21725 17.84875 0.4375 0.40625
    gear   carb
1 3.6875 2.8125

E con pivot_longer() organizziamo la tabella in verticale:

mtcars %>%
  summarise(across(everything(), mean)) %>% 
  pivot_longer(everything())
# A tibble: 11 x 2
   name    value
   <chr>   <dbl>
 1 mpg    20.1  
 2 cyl     6.19 
 3 disp  231.   
 4 hp    147.   
 5 drat    3.60 
 6 wt      3.22 
 7 qsec   17.8  
 8 vs      0.438
 9 am      0.406
10 gear    3.69 
11 carb    2.81 

Esempi

Più di una variabile e più di una funzione

  • indichiamo le funzioni con lst(),

  • i nomi delle variabili vengono costruiti come var_fun

starwars %>% 
  group_by(sex) %>% 
  summarise(across(where(is.numeric), lst(mean, sd), na.rm = T))
# A tibble: 5 x 7
  sex      height_mean height_sd mass_mean mass_sd birth_year_mean birth_year_sd
  <chr>          <dbl>     <dbl>     <dbl>   <dbl>           <dbl>         <dbl>
1 female          169.     15.3       54.7    8.59            47.2          15.0
2 hermaph~        175      NA       1358     NA              600            NA  
3 male            179.     36.0       81.0   28.2             85.5         157. 
4 none            131.     49.1       69.8   51.0             53.3          51.6
5 <NA>            181.      2.89      48     NA               62            NA  

Possiamo anche dare un nome alle funzioni (lst equivale a list):

starwars %>% 
  group_by(sex) %>% 
  summarise(across(where(is.numeric), 
            lst("media" = mean, "ds" = sd), na.rm = T))
# A tibble: 5 x 7
  sex   height_media height_ds mass_media mass_ds birth_year_media birth_year_ds
  <chr>        <dbl>     <dbl>      <dbl>   <dbl>            <dbl>         <dbl>
1 fema~         169.     15.3        54.7    8.59             47.2          15.0
2 herm~         175      NA        1358     NA               600            NA  
3 male          179.     36.0        81.0   28.2              85.5         157. 
4 none          131.     49.1        69.8   51.0              53.3          51.6
5 <NA>          181.      2.89       48     NA                62            NA  

I valori di sintesi dell’intero dataset mtcars:

mtcars %>%
  summarise(across(everything(), lst(min, mean, median, sd, max))) 
  mpg_min mpg_mean mpg_median   mpg_sd mpg_max cyl_min cyl_mean cyl_median ...
1    10.4 20.09062       19.2 6.026948    33.9       4   6.1875          6 ...

Per farne una tabella verticale:

mtcars %>%
  summarise(across(everything(), lst(min, mean, median, sd, max))) %>% 
  # formato lungo
  pivot_longer(everything())
# A tibble: 6 x 2
  name       value
  <chr>      <dbl>
1 mpg_min    10.4 
2 mpg_mean   20.1 
3 mpg_median 19.2 
4 mpg_sd      6.03
5 mpg_max    33.9 
6 cyl_min     4 
...  

dividiamo la colonna name in due con separate():

mtcars %>%
  summarise(across(everything(), lst(min, mean, median, sd, max))) %>% 
  pivot_longer(everything()) %>% 
  # dividiamo le colonne
  separate(name, into=c("name", "fun"))
# A tibble: 6 x 3
  name  fun    value
  <chr> <chr>  <dbl>
1 mpg   min    10.4 
2 mpg   mean   20.1 
3 mpg   median 19.2 
4 mpg   sd      6.03
5 mpg   max    33.9 
6 cyl   min     4   
...

E infine, con pivot_wider(), costruiamo la tabella:

mtcars %>%
  summarise(across(everything(), lst(min, mean, median, sd, max))) %>% 
  # formato lungo
  pivot_longer(everything()) %>% 
  # dividiamo le colonne
  separate(name, into=c("name", "fun")) %>% 
  pivot_wider(names_from = fun, values_from = value)
# A tibble: 11 x 6
   name    min    mean median      sd    max
   <chr> <dbl>   <dbl>  <dbl>   <dbl>  <dbl>
 1 mpg   10.4   20.1    19.2    6.03   33.9 
 2 cyl    4      6.19    6      1.79    8   
 3 disp  71.1  231.    196.   124.    472   
 4 hp    52    147.    123     68.6   335   
 5 drat   2.76   3.60    3.70   0.535   4.93
 6 wt     1.51   3.22    3.32   0.978   5.42
 7 qsec  14.5   17.8    17.7    1.79   22.9 
 8 vs     0      0.438   0      0.504   1   
 9 am     0      0.406   0      0.499   1   
10 gear   3      3.69    4      0.738   5   
11 carb   1      2.81    2      1.62    8   

Sintesi di una batteria di domande

Abbiamo una batteria di domande relative all’uso di Internet, con modalità di risposta “Sì”/“No”. Il nome delle colonne relative alla batteria inizia con “NT.Intrn.”.

  • usiamo summarise() con across(), per applicare la stessa funzione a tutte le variabili che selezioniamo in questo caso con starts_with() (ma possiamo indicare anche un vettore di nomi, o gli indici)

  • usiamo una formula (~ sum(., ...)) per indicare la funzione da applicare, con i relativi argomenti. Il punto rappresenta le variabili selezionate

data %>% 
  summarise(across(starts_with("NT.Intrn."), 
                   ~ sum(.=="Sì", na.rm=TRUE)))
  NT.Intrn.casa NT.Intrn.lavoro NT.Intrn.cell NT.Intrn.altrove NT.Intrn.no
1           249             115           300               42           2

Infine, sempre con pivot_longer(everything()), costruiamo una tabella verticale:

data %>% 
  summarise(across(starts_with("NT.Intrn."), 
                   ~ sum(.=="Sì", na.rm=TRUE))) %>% 
  pivot_longer(everything()) 
# A tibble: 5 x 2
  name             value
  <chr>            <int>
1 NT.Intrn.casa      249
2 NT.Intrn.lavoro    115
3 NT.Intrn.cell      300
4 NT.Intrn.altrove    45
5 NT.Intrn.no          2

(dati estratti casualmente da un dataset personale)

Domande? Scrivimi

Messenger Telegram Email
r/tidyverse/dplyr_summarise.txt · Ultima modifica: 02/12/2022 17:07 da Agnese Vardanega