2014-04-11 25 views
17

Załóżmy, że mam dataframe takie, że:Jak uzyskać łączną sumę według grupy w R?

df<-data.frame(id=1:8,group=c(1,0,0,1,1,0,1,0),rep=c(rep("d1",4),rep("d2",4)),value=rbinom(8,1,0.6)) 
df 
    id group rep value 
1 1  1 d1  0 
2 2  0 d1  0 
3 3  0 d1  0 
4 4  1 d1  1 
5 5  1 d2  1 
6 6  0 d2  0 
7 7  1 d2  1 
8 8  0 d2  1 

Jaki jest najlepszy sposób, aby uzyskać skumulowaną sumę przez group i rep takie, że:

cumsum 
group d1 d1+d2 d1+d2+d3 
0  0  1  ... 
1  1  3  ... 
+2

'cumsum' jest funkcją. Wpisz '? Cumsum'. Istnieje również funkcja 'by', która ma dokumentację łączącą się z podobnymi funkcjami (wpisz'? By' i spójrz na "Zobacz także") ... więc, 'by (df $ value, df $ group, cumsum)' to w jedną stronę – Frank

+0

Czy możesz dać odpowiedź za pomocą demo? +1 –

+0

Aby uzyskać wszystko w ramce danych: 'do.call (rbind, by (wartość df $, df $ group, cumsum))' – josliber

Odpowiedz

10
library(data.table) 

# convert to data.table in place 
setDT(df) 

# dcast and do individual sums 
dt.cast = dcast.data.table(df, group ~ rep, value.var = 'value', 
          fun.aggregate = sum) 
dt.cast 
# group d1 d2 
#1:  0 0 1 
#2:  1 1 2 

# cumsum 
dt.cast[, as.list(cumsum(unlist(.SD))), by = group] 
# group d1 d2 
#1:  0 0 1 
#2:  1 1 3 
13

polecam pracy z tidy forma danych. Oto podejście z dplyr, ale byłoby trywialne przełożyć do data.table lub podstawy R.

Pierwszej będę tworzyć zestaw danych, ustawienie losowych, aby za przykładem powtarzalną:

set.seed(1014) 
df <- data.frame(
    id = 1:8, 
    group = c(1, 0, 0, 1, 1, 0, 1, 0), 
    rep = c(rep("d1", 4), rep("d2", 4)), 
    value = rbinom(8, 1, 0.6) 
) 
df 

%> id group rep value 
%> 1 1  1 d1  1 
%> 2 2  0 d1  0 
%> 3 3  0 d1  0 
%> 4 4  1 d1  1 
%> 5 5  1 d2  1 
%> 6 6  0 d2  1 
%> 7 7  1 d2  1 
%> 8 8  0 d2  1 

następnie, używając dplyr, będę pierwszy zwinąć do poszczególnych wierszy przez grupy i następnie obliczyć skumulowaną sumę:

library(dplyr) 

df <- df %>% 
    group_by(group, rep) %>% 
    summarise(value = sum(value)) %>% 
    mutate(csum = cumsum(value)) 
df 

%> Source: local data frame [4 x 4] 
%> Groups: group 
%> 
%> group rep value csum 
%> 1  0 d1  0 0 
%> 2  0 d2  2 2 
%> 3  1 d1  2 2 
%> 4  1 d2  2 4 

w większości przypadków, jesteś najlepszym z leav ing dane w niniejszym formularzu (będzie łatwiej pracować), ale można przekształcić, jeśli chcesz:

library(reshape2) 

dcast(df, group ~ rep, value.var = "csum") 

%> group d1 d2 
%> 1  0 0 2 
%> 2  1 2 4 
Powiązane problemy