2016-04-01 17 views
3

Wrangling Daten mit data.table ‚s Bewertung, finde ich mich Zeilen wie diese dritte Linie viel zu schreiben:Shortcut für Streicher in data.table Zuweisungen

DT = data.table(a = 1:10) 
name = 'a' 
DT[,eval(parse(text=sprintf('%s_plus_one := %s + 1',name,name)))] 

was ich gehofft hatte zu

DT[,s('%s_plus_one := %s + 1',name,name)] 
zu reduzieren

eine Funktion wie mit:

# s is *very* short for substitute and evalute 
s <- function(...) 
    eval(parse(text=sprintf(...))) 

aber dann bekomme ich diesen Fehler:

Ich weiß, ich kann dies tun:

# sp is short for substitute and parse 
sp <- function(...) 
    parse(text=sprintf(...)) 

DT[,eval(sp('%s_plus_one := %s + 1',name,name))] 
DT 
#>  a a_plus_one 
#> 1: 1   2 
#> 2: 2   3 
#> 3: 3   4 
#> 4: 4   5 

aber Gebäude Strings in einer data.table Zuordnung zu bewerten ist so verbreitet, dass ich gehofft hatte minimiert so viel wie möglich eingeben.

+1

Warum Anruf von Sprachobjekten nicht erstellen, statt Zeichenfolge zu analysieren? Es gibt eine Art Validierung, bevor es ausgewertet wird. – jangorecki

Antwort

7

Die meiste Zeit sollte es nicht einmal nötig sein, in die Welt von eval(parse()) zu gehen. Das heißt, in diesem Beispiel, setzen Sie den Namen in Klammern auf der linken Seite und verwenden get auf der rechten Seite:

DT[, (paste0(name,"_plus_one")) := get(name) + 1] 

DT 
#  a a_plus_one 
# 1: 1   2 
# 2: 2   3 
# 3: 3   4 
# 4: 4   5 
# 5: 5   6 
# 6: 6   7 
# 7: 7   8 
# 8: 8   9 
# 9: 9   10 
#10: 10   11 
+2

Ich habe es nicht versucht, aber ich bin mir ziemlich sicher, dass die Klammern nicht auf lhs benötigt werden – eddi

+2

@eddi - in diesem Fall, yep, aber ich tendiere es aus Reflex als 'DT [, (name): = get (name) + 1] 'und' DT [, name: = get (name) + 1] 'geben unterschiedliche Ergebnisse. – thelatemail

2

Wir .SDcols

DT[,(paste0(name,"_plus_one")) := .SD+1, .SDcols=name] 
DT 
#  a a_plus_one 
# 1: 1   2 
# 2: 2   3 
# 3: 3   4 
# 4: 4   5 
# 5: 5   6 
# 6: 6   7 
# 7: 7   8 
# 8: 8   9 
# 9: 9   10 
#10: 10   11 

verwenden könnte als @thelatemail dies erwähnt würde auch mit mehreren Spalten arbeiten

DT = data.table(a = 1:10, b=2:11) 
name <- c("a","b") 
DT[,(paste0(name,"_plus_one")) := .SD + 1, .SDcols=name] 
+0

Bonusfrage: Gibt es eine Möglichkeit, diese Lösung beim Zusammenführen zweier data.tables zu verwenden, die gleichnamige Variablen enthalten, wie in [diese Frage] (http://stackoverflow.com/questions/36367293)? – Jthorpe

+0

@Jthorpe Vielleicht können Sie '.EACHI' überprüfen. Ohne ein Beispiel ist nicht klar, wie Sie es machen wollen. – akrun