2014-04-11 15 views
17

Angenommen, ich eine Datenrahmen haben, so dass:Wie erhält man die kumulative Summe nach Gruppe in 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 

Was ist der beste Weg, um die kumulative Summe von group und rep, so dass zu bekommen:

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

'cumsum' ist eine Funktion. Geben Sie "Cumsum" ein. Es gibt auch eine 'by'-Funktion, die eine Dokumentation mit ähnlichen Funktionen verknüpft (tippe'? By' und schaue unter "Siehe auch") ... so, 'by (df $ value, df $ group, cumsum)' ist one way – Frank

+0

Können Sie eine Antwort mit der Demo geben? +1 –

+0

Um alles in einen Datenrahmen zu bekommen: 'do.call (rbind, durch (df $ value, df $ group, cumsum))' – josliber

Antwort

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

ich mit der Arbeit würde empfehlen, tidy Form der Daten. Hier ist ein Ansatz mit dplyr, aber es wäre trivial zu data.table oder Base R. zu übersetzen

Zuerst habe ich den Datensatz erstellen werden, die zufällige Samen Einstellung des Exempel statuieren reproduzierbar:

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 

nächste mit dplyr, ich werde zuerst von Gruppe auf einzelne Zeilen kollabieren, und dann die kumulative Summe berechnen:

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 

In den meisten Fällen sind Sie am besten von leav ing die Daten in dieser Form (es wird leichter zu arbeiten), aber Sie können neu gestalten, wenn Sie benötigen:

library(reshape2) 

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

%> group d1 d2 
%> 1  0 0 2 
%> 2  1 2 4