R:使用上一行的值更新(受条件限制) [英] R: Update with value of previous row (subject to condition)
问题描述
我想将表格中的值更新为上一行(在组内)的值,(可能会停止指定条件下的更新)
是一个示例:
set.seed(12345)
字段< - data.table时间= 1:3,玩家=字母[1:2],前景=轮(rnorm(6),2))
setkey能量:= round(rnorm(2),2)] #initial level - 这是我想传播下来的表
#let'prospects< 0.27'是停止进程的条件,并设置'energy = 0'
#player定义进行更新的组
这是我的表。
>场
时间玩家潜在能量
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
这是我想要的表格。
>场
时间玩家潜在能量
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
提前感谢
可能有更好的方法,但这是我的想法。这使用 roll = TRUE
参数。想法是首先设置 energy = 0.0
其中前景< 0.27
:
字段[prospects< 0.27,energy:= 0.0]
然后,如果我们从字段
,我们可以使用 roll = TRUE
通过与所有组合进行联接,如下所示:
字段[!is.na(energy)] [CJ(c(a,b),1:3) = field $ prospects] []
#玩家时间前景能量
#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
我们必须重置潜在客户
,因为 roll
更改它也。
这是一个变体,所以只能在 energy
列:
字段[!is.na(energy) CJ(c(a,b),1:3),list(energy),
roll = TRUE] [,prospects:= field $ prospects] []
或者使用 na.locf
从包
动物园
:
= 1,energy:= round(rnorm(2),2)]
/ pre>
field [prospects& 0.27,energy:= 0.0]
require(zoo)
field [,energy:= na.locf(energy,na.rm = FALSE)]
如果每个组的第一行保证为非NA,这是按照构造工作的。但是如果没有,你也可以按组运行na.locf:
field [,energy:= na.locf ,na.rm = FALSE),by = player]
I would like to update the value in a table with values of the previous row, within groups, (and probably stop the updates on a given condition)
Here is an example:
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
Here is the table I have.
> 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
Here is the table I want.
> 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
Thanks in advance
解决方案Probably there are better ways, but this is what came to my mind. This makes use of
roll=TRUE
argument. The idea is to first setenergy=0.0
whereprospects < 0.27
:field[prospects < 0.27, energy := 0.0]
Then, if we remove the NA values from
field
, we can useroll=TRUE
by doing a join with all combinations as follows: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
We've to reset
prospects
because theroll
changes it too. You could do it better, but you get the idea.
A variation, so that the roll is performed only on
energy
column:field[!is.na(energy)][CJ(c("a", "b"), 1:3), list(energy), roll=TRUE][, prospects := field$prospects][]
Or it may be simpler to use
na.locf
from packagezoo
: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)]
which works if the first row of each group is guaranteed to be non-NA, which it is here by construction. But if not, you can run na.locf by group, too :
field[, energy := na.locf(energy, na.rm=FALSE), by=player]
这篇关于R:使用上一行的值更新(受条件限制)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!