2016-09-01 1 views
8

Ich versuche, diese zweistufige Prozess data.table zu vereinfachen, die auf numerische und Zeichenvariablen wirkt. Z.B. - nehmen Sie das erste Element von textvar und sum jede der numerischen Variablen. Betrachten Sie dieses kleine Beispiel:data.table Gruppierung getrennt auf numerische und Textvariablen

library(data.table) 
dt <- data.table(grpvar=letters[c(1,1,2)], textvar=c("one","two","one"), 
       numvar=1:3, othernum=2:4) 
dt 
# grpvar textvar numvar othernum 
#1:  a  one  1  2 
#2:  a  two  2  3 
#3:  b  one  3  4 

Jetzt ist mein erster Gedanke war, zu nisten .SD die eine Variable aus dem lapply Anruf fallen zu lassen, aber ich dachte, dass etwas war kompliziert:

dt[, c(textvar=textvar[1], .SD[, lapply(.SD, sum), .SDcols=-c("textvar")]), by=grpvar] 
# grpvar textvar numvar othernum 
#1:  a  one  3  5 
#2:  b  one  3  4 

Dann dachte ich, vielleicht könnte ich jede Gruppierung einzeln tun und sich ihnen anzuschließen, aber das scheint noch schlimmer:

dt[, .(textvar=textvar[1]), by=grpvar][ 
    dt[, lapply(.SD, sum), by=grpvar, .SDcols=-c("textvar")], on="grpvar" 
] 
# grpvar textvar numvar othernum 
#1:  a  one  3  5 
#2:  b  one  3  4 

gibt es eine einfachere Konstruktion, die sich um das bekommen würde Verschachtelung von .SD oder der Beitritt? Ich fühle mich als würde ich etwas Elementares übersehen.

Antwort

9

Das j -argument in data.table ist (absichtlich) ziemlich flexibel. Alles, was wir erinnern müssen ist, dass:

Solange j eine Liste zurückgibt, wird jedes Element der Liste eine Spalte in der resultierenden data.table werden.

die Tatsache verwenden, dass c(list, list) ein list ist, wir den Ausdruck konstruieren lassen sich wie folgt:

dt[, c(textvar = textvar[1L], lapply(.SD, sum)), # select/compute all cols necessary 
     .SDcols = numvar:othernum,     # provide .SD's columns 
     by = grpvar]        # group by 'grpvar' 
# grpvar textvar numvar othernum 
# 1:  a  one  3  5 
# 2:  b  one  3  4 

Hier habe ich den ersten Ausdruck mit list() seit textvar[1L] kehrt eine Länge = 1 Vektor nicht gewickelt .. dh identical(c(1, list(2, 3)), c(list(1), list(2,3))) ist TRUE. Bitte beachten Sie, dass dies nur von v1.9.7 möglich ist. Der Fehler wurde erst kürzlich in der aktuellen Entwicklungsversion behoben.

+0

Ich werde Ihr Wort für den Moment nehmen müssen, da ich auf 1.9.6 bin und nicht in der Lage bin, bis später zu aktualisieren, aber danke für die schnelle Antwort. 1.9.7 vermeidet also den Fehler "object 'textvar' not found"? – thelatemail

+0

@thelatemail, ja. Dies war ein langwieriger (und ärgerlicher) Fehler, den wir in dieser Version behoben haben. [# 495] (https://github.com/Rdatatable/data.table/issues/495). – Arun

+1

genial, gut zu hören :-) – thelatemail

Verwandte Themen