2016-12-12 14 views
4

私はかなり大きなデータセットを持っています。別の列の値に基づいて値を時間的に前進させることに興味があります。たとえば、Value = 3Time = 0DesiredShift = 2の場合、3を2行下に移動してTime = 2にします。ここに再現可能な例があります。他の列のラグ値による行値の移動

再現性のある偽のデータ

library(data.table) 
set.seed(1) 
rowsPerID <- 8 
dat <- CJ(1:2, 1:rowsPerID) 
setnames(dat, c("ID","Time")) 
dat[, Value := rpois(.N, 4)] 
dat[, Shift := sample(0:2, size=.N, replace=TRUE)] 

フェイクデータ

#  ID Time Value Shift 
# 1: 1 1  3  2 
# 2: 1 2  3  2 
# 3: 1 3  4  1 
# 4: 1 4  7  2 
# 5: 1 5  2  2 
# 6: 1 6  7  0 
# 7: 1 7  7  1 
# 8: 1 8  5  0 
# 9: 2 1  5  0 
# 10: 2 2  1  1 
# 11: 2 3  2  0 
# 12: 2 4  2  1 
# 13: 2 5  5  2 
# 14: 2 6  3  1 
# 15: 2 7  5  1 
# 16: 2 8  4  1 

を構築し、私は、各ValueShift列に従って前方にシフトします。したがって、Time=1の値が Value = 3Shift = 2の値であるため、行3の DesiredOutputの列は3に等しくなります。

行4に示す3 + 4 = 7以降速度であるので、私はdata.tableの利点 をIDグループによってこれを行うと、うまくいけば取ることができるようにしたいダウン3つのシフトダウン1

2及び4シフトこの問題に対する関心。

私はdata.table::shift機能を使用してこの作業を取得するために期待していたが、私は複数のラグパラメータを使用して、この作品を作るために方法がわからないよ

#  ID Time Value Shift DesiredOutput 
# 1: 1 1  3  2  NA 
# 2: 1 2  3  2  NA 
# 3: 1 3  4  1  3 
# 4: 1 4  7  2  3+4 = 7 
# 5: 1 5  2  2  NA 
# 6: 1 6  7  0  7+7 = 14 
# 7: 1 7  7  1  2 
# 8: 1 8  5  0  7+5 = 12 
# 9: 2 1  5  0  5 
# 10: 2 2  1  1  NA 
# 11: 2 3  2  0  1+2 = 3 
# 12: 2 4  2  1  NA 
# 13: 2 5  5  2  2 
# 14: 2 6  3  1  NA 
# 15: 2 7  5  1  3+5=8 
# 16: 2 8  4  1  5 

望ましい結果。

答えて

6

これを試してください:あなたの最後のステップは、不要なコピーを行っているものの

dat[, TargetIndex:= .I + Shift] 

toMerge = dat[, list(Out = sum(Value)), by='TargetIndex'] 

dat[, TargetIndex:= .I] 

# dat = merge(dat, toMerge, by='TargetIndex', all=TRUE) 
dat[toMerge, on='TargetIndex', DesiredOutput:= i.Out] 

> dat 
#  ID Time Value Shift TargetIndex DesiredOutput 
# 1: 1 1  3  2   1   NA 
# 2: 1 2  3  2   2   NA 
# 3: 1 3  4  1   3    3 
# 4: 1 4  7  2   4    7 
# 5: 1 5  2  2   5   NA 
# 6: 1 6  7  0   6   14 
# 7: 1 7  7  1   7    2 
# 8: 1 8  5  0   8   12 
# 9: 2 1  5  0   9    5 
# 10: 2 2  1  1   10   NA 
# 11: 2 3  2  0   11    3 
# 12: 2 4  2  1   12   NA 
# 13: 2 5  5  2   13    2 
# 14: 2 6  3  1   14   NA 
# 15: 2 7  5  1   15    8 
# 16: 2 8  4  1   16    5 
+2

ええ、私は、ほとんど同じものを投稿しました。おそらく 'dat [toMerge、on =" TargetIndex "、DesiredOutput:= i.Out]'を代わりに実行することができます。 –

+2

私は、行の索引付けがマージより安いと思います: 'm = dat [、rid(Shift + .I、v = Value)] [rid <= .N、sum(v)、by = rid]; dat [m $ rid、x:= m $ V1] '私はこれが期待される結果をもたらすかどうかはわかりません。また、fyiでは 'by =。(TargetIndex + Shift)'のように 'by'カラムを動的に定義することができます。 – Frank

+0

これは素晴らしいです。ありがとうございました! –

関連する問題