2016-05-04 5 views
0

In R würde ich gerne die Summe einer Wertspalte (gruppiert durch einen Buchstaben in Spalte 't1') von der Summe derselben Wertspalte (gruppiert durch den gleichen Buchstaben) subtrahieren in Spalte "t2"). Wiederholen Sie den Vorgang für jeden Brief und für jede Jahresgruppe.Finde Datenrahmen Spaltenunterschiede pro Mehrfachgruppierungen

Betrachten;

set.seed(3)  
df <- data.frame(age = rep(1:3,each=25), 
         t1 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,1],3), 
         t2 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,2],3), 
        value = sample(1:10,75,replace=T)) 

Dieser Datenrahmen zeigt 3 Werte in der 'Alter' Spalte 2 Spalten mit Kategorien (T1 und T2) und einem zugeordneten Wert (value).

Als Beispiel ist hier, wie es könnte für ‚A‘ arbeiten:

library(plyr); 

# extract rows with A 
df2 <- df[df$t1=="A" | df$t2=="A",] 
# remove where t1 and t2 are the same (not needed) 
df2 <- df2[df2$t1 != df2$t2,] 
# use ddply to subtract sum of 'value' for A in t1 from t2 
df2 <- ddply(df2, .(age), transform, change = sum(value[t2=="A"])-sum(value[t1=="A"])) 
# create a name 
df2$cat <- "A" 
# remove all the duplicate rows, just need one summary value 
df2 <- df2[ !duplicated(df2$change), ] 
# keep summary data 
df2 <- df2[,c(1,6,5)] 

jetzt brauche ich diese Werte für alle zu tun, die in T1 und T2 auftreten (in diesem Fall A, B, C & D), Erstellen einer Zusammenfassung von 12 Zeilen.

Ich versuchte eine Schleife mit;

for (c in as.character(unique(df$t1))) 

bekam aber nowehere

Dank viel

+0

Ich denke, ich vermisse etwas ... Wie können Sie den Wert von t1 oder t2 subtrahieren? Diese Spalten sind Buchstaben. –

+0

Ihre Beschreibung ist mir nicht klar. (Zum einen ist "A" in keiner Weise eine Variable in Ihren Daten.) Geben Sie vielleicht einfach ein df_out an, das die erwarteten Ergebnisse enthält. – Frank

+1

Entschuldigung, es könnte meine schlechte Erklärung sein; Wo t2 = A, summiere dann 'Wert', und wo t1 = A, summiere 'Wert'. Ziehen Sie letztere von den ersteren ab. Wiederholen Sie dies für jeden eindeutigen Buchstaben für jede Jahrgangsgruppe. – Sam

Antwort

2

Hier ist eine Basis-R-Lösung, die Aggregation und Zusammenführung beinhaltet:

# aggregate by age and t1 or t2 
t1Agg <- aggregate(value ~ t1 + age, data=df, FUN=sum) 
t2Agg <- aggregate(value ~ t2 + age, data=df, FUN=sum) 

# merge aggregated data 
aggData <- merge(t1Agg, t2Agg, by.x=c("age","t1"), by.y=c("age","t2")) 
names(aggData) <- c("age", "t", "value.t1", "value.t2") 

aggData$diff <- aggData$value.t1 - aggData$value.t2 
+0

danke, nett und einfach, ich habe mich in ddply verzettelt, wenn es in Wirklichkeit nur ein paar einfache Schritte mit Aggregat ist. – Sam

1

ich empfehlen würde zuerst Ihre Daten aufräumt und dann können Sie spread post- summarise und fügen Sie eine neue Spalte:

# Make reproducible 
set.seed(4) 
df <- data.frame(age = rep(1:3,each=25), 
       t1 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,1],3), 
       t2 = rep(expand.grid(LETTERS[1:5],LETTERS[1:5])[,2],3), 
       value = sample(1:10,75,replace=T)) 

library(tidyr) 
library(dplyr) 

df_tidy <- gather(df, t_var, t_val, -age, -value) 
sample_n(df_tidy, 3) 
#  age value t_var t_val 
# 104 2  6 t2  A 
# 48 2  9 t1  C 
# 66 3  7 t1  A 

df_tidy %>% 
    group_by(age, t_var, t_val) %>% 
    summarise(val_sum = sum(value)) %>% 
    spread(t_var, val_sum) %>% 
    mutate(diff = t1 - t2) 

#  age t_val t1 t2 diff 
# (int) (chr) (int) (int) (int) 
# 1  1  A 30 22  8 
# 2  1  B 32 32  0 
# 3  1  C 27 28 -1 
# 4  1  D 38 39 -1 
# 5  1  E 30 36 -6 
# 6  2  A 36 35  1 
# 7  2  B 26 30 -4 
# 8  2  C 40 27 13 
# 9  2  D 27 31 -4 
# 10  2  E 28 34 -6 
# 11  3  A 26 39 -13 
# 12  3  B 19 26 -7 
# 13  3  C 31 29  2 
# 14  3  D 41 33  8 
# 15  3  E 39 29 10 
Verwandte Themen