2014-09-12 26 views
12

Chcę pogrupować ramkę danych według kolumny (właściciela) i wypisać nową ramkę danych, która ma zliczenia każdego rodzaju czynnika przy każdej obserwacji. Prawdziwa rama danych jest dość duża i istnieje 10 różnych czynników.Podsumowanie obliczeń współczynnika z dplyr

Oto przykład wejście:

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 

Szukałem wyjścia, które wygląda następująco:

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 

topnienia dostaje mi partway tam:

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 

Ale co to jest ostatni krok? Jeśli "wartość" byłaby wartością numeryczną, po prostu odszedłbym:

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

Dziękuję bardzo!

+0

To stara sprawa, ale za to, co warte jest mało znana cecha 'dcast', który pozwala na zastosuj funkcję agregującą/podsumowującą w tych przypadkach. Domyślam się, że domyślnie się liczy. – shadowtalker

Odpowiedz

22

Można użyć tidyr z 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) 

który daje wyświetlamy

# 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 (obserwacja, Val, obs1: obs2)%>% group_by (właściciel, zmienna, wartość)%>% summary (n = n())%>% spread (wartość, n, wypełnienie = 0) ' –

+0

@Rory Kirchner Nazwy kolumn powinny być spójne. Tutaj, w 'gather (...)' utworzyłeś zmienną 'Val', ale w' group_by (...) 'i później ta zmienna została odrzucona, a na jej miejscu użyto' value'. – akrun

+0

Hm-- Val -> wartość dla mnie: df%>% gather (obserwacja, Val, obs1: obs2) -> wartość zmiennej właściciela jako nazwy kolumn –

3

Jeśli chcesz zrezygnować z dplyr, można podzielić na listach.

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

Jeśli chciał count, wystarczy utworzyć sapply lub lapply wezwanie do uruchomienia poprzez listy i uzyskać zliczania każdego z nich. Lub dosłownie każda inna funkcja, którą chcesz.

19

W 2017 odpowiedź jest

library(dplyr) 
library(tidyr) 

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

Który daje argumenty wyjściowe

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

To jest lepsza odpowiedź w dzisiejszych czasach. – Monduiz

Powiązane problemy