r - 按前一行和实际行定义值
问题描述
我有data.table
两个字段,startvalue
和endValue
,我需要根据前一行和实际行中的一些信息进行填充。虽然这在某种程度上类似于this和this,但我无法得到我想要的结果。
虚拟数据:
a <- data.table(user = c("A", "A", "A", "B", "B"),
gap = c(1, 0, 2, 2, 3),
priority = c(1, 3, 2, 2, 1))
然后我修复startValue
所有优先级== 1:
setkey(a, user, priority)
a[priority == 1, startValue := 0]
我endValue
为那些startValue
已经定义的设置:
a[!is.na(startValue), endValue := startValue + gap*3]
现在问题来了。我希望第startValue
2 行(用户 A,优先级 2)与第 1 行相同endValue
,所以我可以计算新的endValue
. 我知道我可以使用循环,但我想知道是否可以通过使用任何其他函数或函数组合来做到这一点。
我尝试了几种组合,shift
但zoo:na.locf
总是弄乱了已经存在的值。
预期结果:
b <- structure(list(user = c("A", "A", "A", "B", "B"),
gap = c(1, 2, 0, 3, 2),
priority = c(1, 2, 3, 1, 2),
startValue = c(0, 3, 9, 0, 9),
endValue = c(3, 9, 9, 9, 15)),
row.names = c(NA, -5L),
class = c("data.table", "data.frame"))
解决方案
我们可以accumulate
使用purrr
library(purrr)
library(data.table)
a[, endValue := accumulate(gap, ~ .x + .y * 3, .init = 0)[-1], user
][, startValue := shift(endValue, fill = 0), user][]
all.equal(a, b, check.attributes = FALSE)
#[1] TRUE
或者使用Reduce
frombase R
创建 'endValue' 列,然后使用lag
'endValue' 来创建按 'user' 分组的 'startValue'
a[, endValue := Reduce(function(x, y) x + y *3, gap,
accumulate = TRUE, init = 0)[-1], user]
推荐阅读
- python - 对于数组中的 x 仅在一次迭代 python 后中断
- java - 自定义 TabLayout 指示器 - Android
- javascript - jQuery - Data() 属性返回未定义
- javascript - 在控制台日志输出中转义单引号
- xml - 将 rpc 转换为 Document - 没有类型被映射到具有命名空间的名称
- linux - 如何在 linux 内核模块中使用线程本地存储?
- php - Laravel 自定义 LoginController 不会持久化会话
- python - 使用 Beautiful soup 从 LinkedIn 个人资料中抓取数据时的非类型对象问题
- python - 运行 cv.2 SelectROI 后 cv2.imshow 将不起作用
- amazon-web-services - AWS EC2 实例快速计算 1 TB 文件的 MD5SUM