2016-05-31 9 views
-3

Wie kann ich nach "id" gruppieren, einige arithmetische Funktionen auf die letzten vier Spalten (nach Gruppe) anwenden und neue Zeilen zu dem df hinzufügen, der das enthält Ergebnisse. Hier ist ein anschauliches Beispiel mit 5 Proben (id) und 8 Spalten:Rbind Zeilen nach df mit Ergebnissen berechnet nach Gruppe für mehrere Spalten nach Name

d1 d2 id type   treat v1_gm v2_pct v3_pct 
1 info info 1 leaf   NA  0.2 70  90 
2 info info 1 flower  A  0.5 80  80 
3 info info 2 leaf   NA  0.4 65  80 
4 info info 2 flower  A  0.1 90  90 
5 info info 3 leaf   NA  0.6 55  80 
6 info info 3 stem   A  0.3 80  30 
7 info info 4 leaf   NA  0.6 30  40 
8 info info 4 flower  A  0.7 75  75 
9 info info 5 leaf/stem NA  0.8 80  75 

Reproduzierbare Beispiel:

df <- data.frame(matrix(NA, nrow = 9, ncol = 8), row.names=NULL) 
colnames(df) <- c("d1","d2","id","type","treat","v1_gm","v2_pct","v3_pct") 
df$d1 <- "info" 
df$d2 <- "info" 
id <- c(1,1,2,2,3,3,4,4,5) 
df$id <- c(1,1,2,2,3,3,4,4,5) 
df$type <- c("leaf","flower","leaf","flower","leaf","stem","leaf","flower","leaf/stem") 
df$treat <- c(NA,"A",NA,"A",NA,"A",NA,"A",NA) 
df$v1_gm <- c(0.2,0.5,0.4,0.1,0.6,0.3,0.6,0.7,0.8) 
df$v2_pct <- c(70,80,65,90,55,80,30,75,80) 
df$v3_pct <- c(90,80,80,90,80,30,40,75,75) 

Die Ergebnistabelle etwas wie folgt aussehen soll. Die Zeilen 3, 6, 9 und 13 sind die neuen Zeilen mit den Ergebnissen. Die neuen Zeilen können am Ende der Tabelle angehängt werden oder in ein tmp df eingefügt werden, um später mit rbind hinzugefügt zu werden (ich kann nicht herausfinden, wie es geht, so oder so). Die Gruppierung var ist die Spalte "id". Die Funktion sum wird für "v1_gm" verwendet. Die Funktion "Mittelwert" wird für mehrere aufeinanderfolgende Spalten verwendet, hier "v1_pct" und "v3_pct", die namentlich aufgerufen werden sollten (z. B. v1_pct: v3_pct). Der Wert für "type" in den neuen Zeilen wird von "type" in den Gruppenzeilen verkettet, "d1" und "d2" werden einfach aus der Gruppenzeile kopiert, wo treat == "A", und "treat" in der neuen Zeile Zeile ist der Wert "cmb" zugewiesen.

d1 d2 id type   treat v1_gm v2_pct v3_pct 
1 info info 1 leaf   NA 0.2 70  90 
2 info info 1 flower  A  0.5 80  80 
3 info info 1 leaf/flower cmb 0.7 75  85 
4 info info 2 leaf   NA 0.4 65  80 
5 info info 2 flower  A  0.1 90  90 
6 info info 2 leaf/flower cmb 0.5 77.5 85 
7 info info 3 leaf   NA 0.6 55  80 
8 info info 3 stem   A  0.3 80  30 
9 info info 3 leaf/stem cmb 0.9 67.5 55 
10 info info 4 leaf   NA 0.6 30  40 
11 info info 4 flower  A  0.7 75  75 
13 info info 4 leaf/flower cmb 1.3 52.5 57.5 
14 info info 5 leaf/stem NA 0.8 80  75 

Antwort

0

Mit einigen Änderungen von @Arun ‚s Antwort, löst das folgende Skript das Problem vollständig.

library("dplyr") 
res1 <- df %>% 
    group_by(id) %>% 
    mutate( 
    v1_gm = sum(v1_gm), 
    v2_pct = mean(v2_pct), 
    v3_pct = mean(v3_pct), 
    type = paste(type,collapse="/")) %>% 
    filter(treat == "A") %>% 
    mutate(treat = as.character("calculated")) 
final_res1 <- bind_rows(df,res1) 
final_res1$id <- as.character(final_res1$id) 
final_res1 <- final_res1 [order(final_res1$id, final_res1$treat, na.last=FALSE), ] 
1

Ich bin nicht sicher, ob Sie die Gruppenübersichten als Zeile zum Datenrahmen hinzufügen können. Sie sollten es als Spalte tun können.

library("dplyr") 
res1 <- df %>% group_by(id) %>% mutate(sumV1 = sum(v1_gm),meanV2 = mean(v2_pct),meanV3 = mean(v3_pct),gr_type = paste(type,collapse="/")) %>% filter(treat == "A") %>% select(d1,d2,id,type,v1_gm=sumV1, v2_pct = meanV2, v3_pct = meanV3,type = gr_type) 

diese Ihnen die Antworten geben und dann verwenden bind_rows Sie das gewünschte Ergebnis erhalten werden

final_res <- bind_rows(df,res1) 
+0

Concatenate in str_c (Typ, sep = „/“) scheint nicht zu funktionieren, aber wenn es so wäre, ich könnte das Ergebnis in eine Zeitdatei, löschen Sie alle Zeilen schicken, wo behandeln! = "A ", benennen Sie die berechneten Spalten in die ursprünglichen Spaltennamen und rbind tmp in die ursprüngliche Datei um. –

+0

Entschuldigung, Sie können stattdessen den Befehl paste verwenden. Ich habe die Änderungen an der Antwort vorgenommen. Sie können dann mit dem Pipe-Befehl filtern. – theArun

+0

In Wirklichkeit hat die tatsächliche Datentabelle, die ich habe, zusätzliche 25 Spalten ähnlich wie nach v3_pct, die alle genauso behandelt werden müssen wie v2_pct und v3_pct (dh gemittelt nach Gruppe). Wenn die letzte Spalte v25 ist, gibt es eine Möglichkeit, Ihren Code zu verallgemeinern, um v1_pct: v25 auszuwählen, um zu vermeiden, dass jeder für die Berechnung separat eingegeben wird? –

Verwandte Themen