2014-09-12 4 views
12

Desidero raggruppare un frame di dati per una colonna (proprietario) e generare un nuovo frame di dati che abbia il conteggio di ciascun tipo di fattore per ogni osservazione. Il vero quadro di dati è abbastanza grande e ci sono 10 diversi fattori.riepilogo dei conteggi di un fattore con dplyr

Ecco alcuni input esempio:

library(dplyr) 
df = tbl_df(data.frame(owner=c(0,0,1,1), obs1=c("quiet", "loud", "quiet", "loud"), obs2=c("loud", "loud", "quiet", "quiet"))) 

    owner obs1 obs2 
1  0 quiet loud 
2  0 loud loud 
3  1 quiet quiet 
4  1 loud quiet 

Cercavo uscita che assomiglia a questo:

out = data.frame(owner=c("0", "0", "1", "1"), observation=c("obs1", "obs2", "obs1", "obs2"), quiet=c(1, 0, 1, 2), loud=c(1, 2, 1, 0)) 

    owner observation quiet loud 
1  0  obs1  1 1 
2  0  obs2  0 2 
3  1  obs1  1 1 
4  1  obs2  2 0 

di fusione mi viene parzialmente lì:

melted = tbl_df(melt(df, id=c("owner"))) 

    owner variable value 
1  0  obs1 quiet 
2  0  obs1 loud 
3  1  obs1 quiet 
4  1  obs1 loud 
5  0  obs2 loud 
6  0  obs2 loud 
7  1  obs2 quiet 
8  1  obs2 quiet 

Ma qual è il ultimo passo? Se "valore" era un valore numerico, andrei semplicemente:

melted %>% group_by(owner, variable) %>% summarise(counts=sum(value)) 

Grazie mille!

+0

Questa è una vecchia questione, ma per quel che vale c'è una caratteristica poco conosciuta di 'dcast' che consente di applica una funzione di aggregazione/riepilogo in questi casi. Penso che il valore predefinito sia il conteggio. – shadowtalker

risposta

22

Si potrebbe usare tidyr con dplyr

library(dplyr) 
library(tidyr) 

df %>% 
gather(observation, Val, obs1:obs2) %>% 
group_by(owner,observation, Val) %>% 
summarise(n= n()) %>% 
ungroup() %>% 
spread(Val, n, fill=0) 

che dà l'uscita

# owner observation loud quiet 
    #1  0  obs1 1  1 
    #2  0  obs2 2  0 
    #3  1  obs1 1  1 
    #4  1  obs2 0  2 
+1

'df%>% gather (osservazione, Val, obs1: obs2)%>% group_by (proprietario, variabile, valore)%>% riepilogo (n = n())%>% spread (valore, n, riempimento = 0) ' –

+0

@Rory Kirchner I nomi delle colonne devono essere coerenti. Qui, nel 'gather (...)' hai creato una variabile 'Val', ma nel' group_by (...) 'e successivamente quella variabile è stata scartata e nelle sue posizioni è stato usato' value'. – akrun

+0

Hm-- Val -> valore per me: df%>% gather (osservazione, Val, obs1: obs2) -> valore della variabile proprietario come nome della colonna –

3

Se si voleva rinunciare al dplyr, è possibile dividere in liste.

df <- split(df, list(df[[obs1]], df[[obs2]]) 

Se si voleva il count, basta creare un sapply o lapply chiamata a correre attraverso le liste e ottenere il conteggio di ciascuno. O letteralmente qualsiasi altra funzione tu voglia.

19

Nel 2017 la risposta è

library(dplyr) 
library(tidyr) 

gather(df, key, value, -owner) %>% 
    group_by(owner, key, value) %>% 
    tally %>% 
    spread(value, n, fill = 0) 

che dà uscita

Source: local data frame [4 x 4] 
Groups: owner, key [4] 

    owner key loud quiet 
* <dbl> <chr> <dbl> <dbl> 
1  0 obs1  1  1 
2  0 obs2  2  0 
3  1 obs1  1  1 
4  1 obs2  0  2 
+0

Questa è la risposta migliore in questi giorni. – Monduiz