5

グループ内の前の行の値を使用してテーブルの値を更新したいと思います (そして、特定の条件で更新を停止する可能性があります)。

以下に例を示します。

set.seed(12345)

field <- data.table(time=1:3, player = letters[1:2], prospects = round(rnorm(6),2))
setkey(field, player, time)
field[time == 1, energy := round(rnorm(2),2)] #initial level - this is what I want to propagate down the table
#let 'prospects < 0.27' be the condition that stops the process, and sets 'energy = 0'
#player defines the groups within which the updates are made

これが私が持っているテーブルです。

> field
time player prospects energy
1:    1      a      0.81  -0.32
2:    2      a      0.25     NA
3:    3      a      2.05     NA
4:    1      b      1.63  -1.66
5:    2      b      2.20     NA
6:    3      b      0.49     NA

これが私が欲しいテーブルです。

> field
time player prospects energy
1:    1      a      0.81  -0.32
2:    2      a      0.25  0
3:    3      a      2.05  0
4:    1      b      1.63  -1.66
5:    2      b      2.20  -1.66
6:    3      b      0.49  -1.66

前もって感謝します

4

2 に答える 2

2

もっと良い方法があるのか​​もしれませんが、これが私の頭に浮かんだ方法です。これはroll=TRUE引数を使用します。アイデアは、最初にenergy=0.0whereを設定することprospects < 0.27です:

field[prospects < 0.27, energy := 0.0]

次に、 NA 値を から削除すると、次のようにすべての組み合わせを結合してfield使用できます。roll=TRUE

field[!is.na(energy)][CJ(c("a", "b"), 1:3), roll=TRUE][, prospects := field$prospects][]
#    player time prospects energy
# 1:      a    1      0.81   0.63
# 2:      a    2      0.25   0.00
# 3:      a    3      2.05   0.00
# 4:      b    1      1.63  -0.28
# 5:      b    2      2.20  -0.28
# 6:      b    3      0.49  -0.28

prospectsも変更されるため、リセットrollする必要があります。もっとうまくできるかもしれませんが、アイデアはわかります。


energyロールが列でのみ実行されるように、バリエーション:

field[!is.na(energy)][CJ(c("a", "b"), 1:3), list(energy), 
           roll=TRUE][, prospects := field$prospects][]

na.locfまたは、 packageから使用する方が簡単かもしれませんzoo:

field[time == 1, energy := round(rnorm(2),2)]
field[prospects < 0.27, energy := 0.0]
require(zoo)
field[, energy := na.locf(energy, na.rm=FALSE)]

これは、各グループの最初の行が非 NA であることが保証されている場合に機能します。これは構造上ここにあります。そうでない場合は、グループごとに na.locf を実行することもできます:

field[, energy := na.locf(energy, na.rm=FALSE), by=player]
于 2013-09-20T11:31:13.077 に答える