2015-01-10 26 views
18

Sto usando summarise_each di dplyr per applicare una funzione a più colonne di dati. Una cosa bella è che puoi applicare più funzioni contemporaneamente. Il fatto è che è fastidioso che l'output sia un dataframe con una singola riga. Sembra che dovrebbe restituire tante righe quante sono le funzioni, con tante colonne quante sono le colonne che sono state riepilogate.usa dplyr's summarise_each per restituire una riga per funzione?

library(dplyr) 
default <- 
    iris %>% 
    summarise_each(funs(min, max), matches("Petal")) 

restituisce

> default 
    Petal.Length_min Petal.Width_min Petal.Length_max Petal.Width_max 
1    1    0.1    6.9    2.5 

Preferirei qualcosa di simile

library(reshape2) 
desired <- 
    iris %>% 
    select(matches("Petal")) %>% 
    melt() %>% 
    group_by(variable) %>% 
    summarize(min=min(value),max=max(value)) %>% 
    t() 

che restituisce qualcosa di simile (non un dataframe, ma tutti voi ottiene l'idea)

> desired 
     [,1]   [,2]   
variable "Petal.Length" "Petal.Width" 
min  "1.0"   "0.1"   
max  "6.9"   "2.5" 

c'è un'opzione in summari se_each per fare questo? Se no, Hadley, ti dispiacerebbe aggiungerla?

risposta

22

È possibile ottenere un output simile combinando i pacchetti dplyr e tidyr. Qualcosa in questo senso può aiutare

library(dplyr) 
library(tidyr) 

iris %>% 
    select(matches("Petal")) %>% 
    summarise_each(funs(min, max)) %>% 
    gather(variable, value) %>% 
    separate(variable, c("var", "stat"), sep = "\\_") %>% 
    spread(var, value) 
## stat Petal.Length Petal.Width 
## 1 max   6.9   2.5 
## 2 min   1.0   0.1 
+2

cool, e un po 'più breve (con valori predefiniti) 'gather%>% separate (chiave, c (" chiave "," stat "), sep =" _ ")%>% spread (chiave, valore)' – ckluss

+0

@ckluss Bello, grazie. Sentiti libero di modificare la risposta per aggiornarlo. – dickoa

+0

Molto bello. Mi dà una ragione per tuffarmi finalmente in tidyr. Grazie molto. –

6

Per quanto ne so, non esiste un argomento del genere. Ad ogni modo, ecco una soluzione alternativa che manda in ordine i dati, penso che sarebbe anche meglio che avere tante righe quante sono le funzioni e tante colonne quante sono le colonne riepilogate. (Si noti che add_rownames richiede dplyr 0.4.0)

library("dplyr") 
library("tidyr") 

iris %>% 
    summarise_each(funs(min, max, mean, median), matches("Petal")) %>% 
    t %>% 
    as.data.frame %>% 
    add_rownames %>% 
    separate(rowname, into = c("feature", "fun"), sep = "_") 

rendimenti:

 feature fun  V1 
1 Petal.Length min 1.000000 
2 Petal.Width min 0.100000 
3 Petal.Length max 6.900000 
4 Petal.Width max 2.500000 
5 Petal.Length mean 3.758000 
6 Petal.Width mean 1.199333 
7 Petal.Length median 4.350000 
8 Petal.Width median 1.300000 
+0

Potrei vedere questo formato essere utile in molte situazioni. Grazie! –

+0

Piccola nota pedantica: 'add_rownames()' è ora deprecato e il suggerimento è di usare 'tibble :: rownames_to_column()'. –

2

Una possibilità è quella di utilizzare purrr::map_df (davvero map_dfc per semplificare nuovo ad un data.frame con bind_cols se map_df va bene per ora) con una funzione che rende un vettore di risultati di ogni funzione, ovvero

library(tidyverse) 

iris %>% select(contains('Petal')) %>% 
    map_dfc(~c(min(.x), max(.x))) %>% 
    mutate(stat = c('min', 'max')) # to add column of function names 

#> # A tibble: 2 × 3 
#> Petal.Length Petal.Width stat 
#>   <dbl>  <dbl> <chr> 
#> 1   1.0   0.1 min 
#> 2   6.9   2.5 max 
+0

cambia 'dmap' ->' map_df' per la versione più recente di 'purrr', per [notizie tidyverse] (http://purrr.tidyverse.org/news/#purrr-and-dplyr) – Paul

Problemi correlati