2016-03-31 13 views
3

ich eine Datentabelle ähnlich wie diese haben (außer es 150 Spalten und etwa 5 Millionen Zeilen hat):Mit R, data.table, bedingt Summe Spalten

set.seed(1) 
dt <- data.table(ID=1:10, Status=c(rep("OUT",2),rep("IN",2),"ON",rep("OUT",2),rep("IN",2),"ON"), 
      t1=round(rnorm(10),1), t2=round(rnorm(10),1), t3=round(rnorm(10),1), 
      t4=round(rnorm(10),1), t5=round(rnorm(10),1), t6=round(rnorm(10),1), 
      t7=round(rnorm(10),1),t8=round(rnorm(10),1)) 

die Ausgänge:

ID Status t1 t2 t3 t4 t5 t6 t7 t8 
1: 1 OUT -0.6 1.5 0.9 1.4 -0.2 0.4 2.4 0.5 
2: 2 OUT 0.2 0.4 0.8 -0.1 -0.3 -0.6 0.0 -0.7 
3: 3  IN -0.8 -0.6 0.1 0.4 0.7 0.3 0.7 0.6 
4: 4  IN 1.6 -2.2 -2.0 -0.1 0.6 -1.1 0.0 -0.9 
5: 5  ON 0.3 1.1 0.6 -1.4 -0.7 1.4 -0.7 -1.3 
6: 6 OUT -0.8 0.0 -0.1 -0.4 -0.7 2.0 0.2 0.3 
7: 7 OUT 0.5 0.0 -0.2 -0.4 0.4 -0.4 -1.8 -0.4 
8: 8  IN 0.7 0.9 -1.5 -0.1 0.8 -1.0 1.5 0.0 
9: 9  IN 0.6 0.8 -0.5 1.1 -0.1 0.6 0.2 0.1 
10: 10  ON -0.3 0.6 0.4 0.8 0.9 -0.1 2.2 -0.6 

mit data.table, würde Ich mag eine neue Spalte (mit: =) hinzufügen Gesamt genannt, den folgenden Komponenten enthalten würde:

Für jede Zeile

wenn Status = OUT, Summe Spalten t1: t4 und t8

wenn Status = IN, Summe Spalten T5, T6, T8

wenn Status = ON, Summe Spalten t1: t3 und t6: t8

Die endgültige Ausgabe sollte wie folgt aussehen: mit effizienter data.table Syntax

ID Status t1 t2 t3 t4 t5 t6 t7 t8 Total 
1: 1 OUT -0.6 1.5 0.9 1.4 -0.2 0.4 2.4 0.5 3.7 
2: 2 OUT 0.2 0.4 0.8 -0.1 -0.3 -0.6 0.0 -0.7 0.6 
3: 3  IN -0.8 -0.6 0.1 0.4 0.7 0.3 0.7 0.6 1.6 
4: 4  IN 1.6 -2.2 -2.0 -0.1 0.6 -1.1 0.0 -0.9 -1.4 
5: 5  ON 0.3 1.1 0.6 -1.4 -0.7 1.4 -0.7 -1.3 1.4 
6: 6 OUT -0.8 0.0 -0.1 -0.4 -0.7 2.0 0.2 0.3 -1.0 
7: 7 OUT 0.5 0.0 -0.2 -0.4 0.4 -0.4 -1.8 -0.4 -0.5 
8: 8  IN 0.7 0.9 -1.5 -0.1 0.8 -1.0 1.5 0.0 -0.2 
9: 9  IN 0.6 0.8 -0.5 1.1 -0.1 0.6 0.2 0.1 0.6 
10: 10  ON -0.3 0.6 0.4 0.8 0.9 -0.1 2.2 -0.6 2.2 

ich data.table ziemlich neu bin (derzeit mit Version 1.9.6) und möchte für eine Lösung versuchen.

+3

Ich denke, wenn man nur drei Bedingungen haben können Sie nur eine Zeile schreiben für jede Bedingung, zum Beispiel für "OUT", könnten Sie 'dt [Status ==" OUT ", Gesamt: = rowSums (.SD), .SDcols = c (1: 4, 8) + 2] 'ODER' '' dt [Status == "OUT", Gesamt: = Reduzieren ('+', .SD), .SDcols = c (1: 4, 8) + 2] '' 'und ähnlich für die anderen beiden Bedingungen –

+0

@DavidArenburg Vielen Dank für Ihre schnelle Antwort. Ich möchte Spaltennamen verwenden, da mein realer Datensatz groß ist. Ich habe versucht mit .SCcols = c (t1: t4, t8) + 2, aber habe einen Fehler "Fehler in eval (expr, envir, enclos): Objekt 't1' nicht gefunden". Wie kann ich das mit Spaltennamen machen? Auch verwendet. SDcols = c (3: 6, 10) + 2 (# as 3,6,10 sind die Spaltennummern) und Fehler "Fehler in' [.data.table' (dt, Status == "OUT ",': = '(Summe, rowSums (.SD)),: .SDcols ist numerisch aber außerhalb der Grenzen (oder NA)". Also habe ich es mit .SDcols = c (3: 6, 10) (ohne die +2 diesmal) und es funktionierte Was ist die +2 für? – FG7

+0

Sie könnten einen wirklich langen Datentabellenausdruck schreiben, um dies alles auf einmal zu machen, aber es könnte sauberer und lesbarer sein, um 3 Tabellen Ihres zu erstellen Aggregation und dann verwenden rbind, um sie zusammen zu setzen – giraffehere

Antwort

5

Ich denke, es zu tun eins nach dem anderen, wie in den Kommentaren angedeutet, ist völlig in Ordnung, aber man kann auch eine Lookup-Tabelle erstellen:

cond = data.table(Status = c("OUT", "IN", "ON"), 
        cols = Map(paste0, 't', list(c(1:4, 8), c(5,6,8), c(1:3, 6:8)))) 
# Status    cols 
#1: OUT t1,t2,t3,t4,t8 
#2:  IN   t5,t6,t8 
#3:  ON t1,t2,t3,t6,t7,t8 

dt[cond, Total := Reduce(`+`, .SD[, cols[[1]], with = F]), on = 'Status', by = .EACHI] 
# ID Status t1 t2 t3 t4 t5 t6 t7 t8 Total 
# 1: 1 OUT -0.6 1.5 0.9 1.4 -0.2 0.4 2.4 0.5 3.7 
# 2: 2 OUT 0.2 0.4 0.8 -0.1 -0.3 -0.6 0.0 -0.7 0.6 
# 3: 3  IN -0.8 -0.6 0.1 0.4 0.7 0.3 0.7 0.6 1.6 
# 4: 4  IN 1.6 -2.2 -2.0 -0.1 0.6 -1.1 0.0 -0.9 -1.4 
# 5: 5  ON 0.3 1.1 0.6 -1.4 -0.7 1.4 -0.7 -1.3 1.4 
# 6: 6 OUT -0.8 0.0 -0.1 -0.4 -0.7 2.0 0.2 0.3 -1.0 
# 7: 7 OUT 0.5 0.0 -0.2 -0.4 0.4 -0.4 -1.8 -0.4 -0.5 
# 8: 8  IN 0.7 0.9 -1.5 -0.1 0.8 -1.0 1.5 0.0 -0.2 
# 9: 9  IN 0.6 0.8 -0.5 1.1 -0.1 0.6 0.2 0.1 0.6 
#10: 10  ON -0.3 0.6 0.4 0.8 0.9 -0.1 2.2 -0.6 2.2 
Verwandte Themen