【问题标题】:data.table row value depend on previous value in Rdata.table 行值取决于 R 中的先前值
【发布时间】:2022-01-21 09:24:00
【问题描述】:

我有一个 data.table x,它有 2 列 ab
我想计算一个c 列。

library(data.table)

x = data.table(a = c(1:5), b = c(1,0,2,3,6), c = NA)
x$a[1] = NA
x$b[1] = NA

x
#>        a     b      c
#>    <int> <num> <lgcl>
#> 1:    NA    NA     NA
#> 2:     2     0     NA
#> 3:     3     2     NA
#> 4:     4     3     NA
#> 5:     5     6     NA

算法是:

 c[i] = ifelse(a[i] < b[i] & c[i-1] < b[i], a[i], b[i])

我不想使用 for 循环,因为它太慢了。 我想使用 data.table 函数,或者像这样的快速方法:

x$c = fifelse(x$a < x$b & lag(x$c) < x$b, x$a, x$b)

但它不起作用,因为 x$c 计算现在正在进行中。 有什么解决办法吗?

感谢您的帮助 亚诺斯

【问题讨论】:

  • 预期输出是什么? c[i-1] &lt; b[i] 将永远是 NA 除非你有一个起始值...

标签: data.table


【解决方案1】:

您可以将Reduceaccumulate=T 选项一起使用:

library(data.table)

x = data.table(a = c(1:5), b = c(1,0,2,3,6), c = NA)
x$a[1] = NA
x$b[1] = NA

x[,c:=Reduce(f = function(prev,val) ifelse((val$a < val$b & prev<val$b),val$a,val$b), 
             x = split(.SD[-1],seq_len(.N-1)), init = NA
             ,accumulate = T)][]

#>        a     b     c
#>    <int> <num> <num>
#> 1:    NA    NA    NA
#> 2:     2     0     0
#> 3:     3     2     2
#> 4:     4     3     3
#> 5:     5     6     5

Reduce 将上一行计算的结果传递给计算下一行。 accumulate=T 返回中间结果而不是只返回最后一行。

【讨论】:

  • 谢谢!!!!!!这对我来说太复杂了! :D 如果我有两列,并且“c”的值取决于“a”和“b”以及之前的“c”?
  • 在您给出的fifelse 示例中,我没有看到b:您能告诉我应该如何使用b 吗?
  • 这是一个确切的例子:x = data.table(a = c(1:5), b = c(1,0,2,3,6), c ='') x$ a[1] = NA x$b[1] = NA x$c[1] = NA 计算应该从第 2 行开始(首先不是 NA 行)! “c”值应该根据这个算法得到: c[i] = ifelse(a[i]
  • 查看我的编辑,这有点棘手,但似乎有效
  • 很好,瓦尔迪!我特别喜欢 x=split(.SD, .N), init=NA (...) 的使用,因为它非常易读、优雅且健壮。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 2020-11-05
  • 2018-09-30
  • 2019-04-11
  • 2022-01-14
相关资源
最近更新 更多