2015-05-05 16 views
10

Ich versuche, zwei separate Listen von Variablennamen in eine data.table (v1.9.4) zu übergeben. Es gibt die richtigen Spalten zurück, aber es entfernt die Variablennamen. Dies funktioniert wie erwartet:Kombinieren mehrerer Listen von Variablennamen in data.table?

dt <- data.table(a=1:3, b=4:6, c=7:9, d=10:12) 
dt 
    a b c d 
1: 1 4 7 10 
2: 2 5 8 11 
3: 3 6 9 12 

Es funktioniert auch eine einzelne Liste von Namen zu übergeben:

dt[,list(a,b)] 
    a b 
1: 1 4 
2: 2 5 
3: 3 6 

Aber wenn ich mehrere Listen übergeben müssen, gibt es die richtigen Spalten, sondern streift die Variablennamen :

dt[,c(list(a,b), list(c,d))] 
    V1 V2 V3 V4 
1: 1 4 7 10 
2: 2 5 8 11 
3: 3 6 9 12 

Warum zwei Listen? Ich verwende mehrere quote() 'd Listen von Variablen. Ich habe FAQ-Frage 1.6 gelesen, und ich weiß, dass eine Problemumgehung ist, einen Zeichenvektor zu verwenden, der mit = FALSE verwendet. Aber meine realen Anwendungsfall beinhaltet eine Mischung aus Namen vorbei und Ausdrücke auf eine Funktion, zB

varnames <- quote(list(a,b)) 
expr <- quote(list(a*b, c+d)) 
function(dt, varnames, expr) { 
    dt[,c(varnames, expr)] 
} 

Und ich möchte die „VarNames“ Spalten ihren richtigen Namen haben (und sie tun, wenn Sie nur passieren einzige Liste wie

dt[,list(a,b,a*b,c+d)] 
    a b V3 V4 
1: 1 4 4 17 
2: 2 5 10 19 
3: 3 6 18 21 

Wie kann ich mehrere Listen in einer data.table so kombinieren, dass sie immer noch die richtigen Spaltennamen zurück? (ich bin nicht ganz sicher, ob dies ein data.table Problem ist, oder wenn ich Ich mache gerade etwas albernes in der Art, wie ich Listen in R zu kombinieren versuche, aber c() scheint zu tun, was ich will.)

+1

Es funktioniert mit benannten Listen, nicht sicher, ob das für Ihre Zwecke akzeptabel wäre. 'dt [, c (Liste (a = a, b = b), Liste (c = c, d = d))]' –

+0

Interessant - danke! Das ist sicherlich eine Problemumgehung, und es ist besser als die Problemumgehung von 1.6, da das auch mit Ausdrücken funktioniert (nicht nur Variablennamen). Aber ich würde immer noch gerne wissen, ob es eine Möglichkeit gibt, unbenannte Listen zu kombinieren, so dass es mit der regulären (sauberen!) Data.table-Syntax funktioniert. (Oder wenn ich mit der Art und Weise, wie ich zitierte Listen kombiniere, etwas Dummes mache.) – cauchy

+1

@cauchy Du machst nichts falsches, 'data.table' macht Dir nur einen Gefallen im einfachen Listenfall, indem Du den unbenannte Liste in eine benannte, aber es kann nicht in komplizierteren Fällen tun, da die Absicht nicht klar ist – eddi

Antwort

4

Eine weitere Möglichkeit, vor der Zeit zu konstruieren ist:

varnames[4:5] <- expr[2:3] # this results in `list(a, b, a * b, c + d)` 
dt[, eval(varnames)] 

produziert:

a b V3 V4 
1: 1 4 4 17 
2: 2 5 10 19 
3: 3 6 18 21 

Mehr allgemein an, dass Sie eine Liste haben von in der Liste aufgeführten Ausdrücken:

exprlist <- list(quote(list(a, b)), quote(list(c, c %% a)), quote(list(a + b))) 
expr <- as.call(Reduce(function(x, y) c(as.list(x), as.list(y)[-1]), exprlist)) # @eddi 
dt[, eval(expr)] 
+0

Cool! Ich wusste nicht, dass das gemacht werden könnte. Habe auch nie einen Fall gesehen, in dem diese Art von Zuweisung funktioniert, aber 'c (varnames, expr [-1])' nicht. 'Ausdrücke sind komisch. – Frank

+1

ziemlich cool - ich schlage vor zu vereinfachen: 'as.call (Reduzieren (Funktion (x, y) c (as.list (x), als.list (y) [- 1]), exprlist)) ' – eddi

+0

@eddi, großartig, ich habe versucht, etwas in der Art zu tun, aber ich konnte es nicht richtig zum Laufen bringen. – BrodieG

1

Hier ist eine mögliche Abhilfe, den vollständigen Ausschreibungs mit .SD

varnames <- quote(list(a,b)) 
expr <- quote(list(a*b, c+d)) 

myFunc <- function(dt, varnames, expr) { 
    dt[, c(.SD[, eval(varnames)], eval(expr))] 
} 

myFunc(dt, varnames, expr) 

# a b V1 V2 
# 1: 1 4 4 17 
# 2: 2 5 10 19 
# 3: 3 6 18 21 
+0

Wow, ich bin überrascht zu sehen, dass es in diesem Fall funktioniert. Ich denke, .SD() gibt Spalten mit Namen zurück, die an sie angehängt sind, also funktioniert es aus dem gleichen Grund wie die von docendo discimus vorgeschlagene benannte Liste. Der Hauptnachteil davon für mich ist, dass ich Zehntausende von Spalten habe und nur eine kleine Anzahl von Variablen benötige, und .SD() ist wirklich ineffizient, wenn du die meisten Spalten nicht verwendest. – cauchy

Verwandte Themen