2016-05-21 3 views
3

Angenommen, ich habe das folgende Skript, das eine DatentabelleKonstruieren Sie eine Spalte mit verzögerten Werten

library(data.table) 
dt <- data.table(a = c(1,2,3,4,5), b = c(6,7,8,9,10), c = c(22,0,0,0,0)) 

Ich möchte ersetzen die Werte von c in Reihen 2 bis 5 erzeugt als

a b c 
1: 1 6 22 
2: 2 7 31 
3: 3 8 42 
4: 4 9 55 
5: 5 10 70 

folgt die ist etwas wie

c = a + b + shift(c, n = 1, fill = 0, type="lag") 

Mit anderen Worten, halten Sie Zeile 1 gleich und wenden Sie die Formel an 2 Zeilen 5.

Ich habe versucht,

dt[2:nrow(dt), c := a + b + shift(c, n = 1, fill = 0, type="lag")] 

aber das gibt

a b c 
1: 1 6 22 
2: 2 7 9 
3: 3 8 11 
4: 4 9 13 
5: 5 10 15 

Irgendwelche Vorschläge?

+0

Ich bin nicht sicher, ob dies data.tablish ist, aber eine Variante deines Versuchs funktioniert: 'dt [-1L, c: = cumsum (a + b) + dt $ c [1L]]' – Frank

Antwort

4

A data.table Weg, es zu tun, in Anbetracht der Tatsache, dass a + b + c[i-1] hinzufügen tut tatsächlich eine kumulative Summe von a + b:

dt[, c := shift(cumsum(shift(a+b, n = 1, type = "lead")) + c[1], 
       n = 1, type = "lag", fill = c[1])] 
dt 
    a b c 
1: 1 6 22 
2: 2 7 31 
3: 3 8 42 
4: 4 9 55 
5: 5 10 70 
4

Wir auch (eine Variation von @ Vorschlag des Frank) tun könnte

dt[, c:= c[1L]][-1L, c := cumsum(a+b)+c] 
dt 
# a b c 
#1: 1 6 22 
#2: 2 7 31 
#3: 3 8 42 
#4: 4 9 55 
#5: 5 10 70 
+1

Ja, das ist eine elegante Art, das zu tun. – Frank

+0

Franks Vorschlag funktionierte für das, was ich brauchte. Die Tatsache, dass ich im Beispiel kumulativ summierte, war eine unbeabsichtigte Konsequenz davon, wie ich das Beispiel konstruiert habe. Ich weiß immer noch nicht, warum es funktioniert. Ich bekomme, dass der Code innerhalb des ersten [] ersetzt alle c Einträge mit dem ersten. Aber was macht das -1L im zweiten []? Ein Hinweis auf eine Erklärung der Verwendung von L in dieser Situation wäre großartig! – JerryN

+0

@JerryN Hier geben wir den Zeilenindex 'i' an. '-1' bedeutet, dass alle Zeilen außer der ersten ausgewählt werden. Ich habe 'L' verwendet, um eine ganzzahlige Darstellung zu geben (die in einigen Fällen schnell sein könnte). – akrun