首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >R取决于前一行的data.table值

R取决于前一行的data.table值
EN

Stack Overflow用户
提问于 2019-05-28 21:01:58
回答 2查看 386关注 0票数 2

我正在尝试解决here提出的问题。基本上,我需要的是,对于data.table的每一行,获取前一行中每个变量的值,并使用它们来定义下一行中的变量值。

我尝试过使用data.table,但结果相当笨重,而且我认为效率极低(特别是对于大量的行)。我还尝试使用shift()函数,但无法在我的临时解决方案中使用它。

下面是一个玩具示例:

代码语言:javascript
复制
library(data.table)
DT = data.table(a = numeric(10L), b = numeric(10L), c = numeric(10L), iter = 1:10)

for(i in DT[,.I]){

  DT[i, c('a','b','c') := {
    if(iter == 1) {
      a = 1
      b = 2
      c = 3
    } else { # if it is not the first iteration
      a = DT[i-1, a + b] # read the values from the previous row to compute the new values
      b = DT[i-1, b] - a
      c = a / b + DT[i-1, c]
    }

    .(a, b, c)
  }]

}

下面是输出:

代码语言:javascript
复制
     a  b          c iter
 1:  1  2  3.0000000    1
 2:  3 -1  0.0000000    2
 3:  2 -3 -0.6666667    3
 4: -1 -2 -0.1666667    4
 5: -3  1 -3.1666667    5
 6: -2  3 -3.8333333    6
 7:  1  2 -3.3333333    7
 8:  3 -1 -6.3333333    8
 9:  2 -3 -7.0000000    9
10: -1 -2 -6.5000000   10

有人能帮我改进一下代码吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-05-29 07:50:25

另一种选择:

代码语言:javascript
复制
cols <- c('a','b','c')
A <- 1; B <- 2; C <- 3
DT[iter==1, (cols) := .(A, B, C)]
DT[iter>1, 
    (cols) := {
        A = A + B
        B = B - A
        C = A / B + C
        .(A, B, C)
    },
    by=iter]
票数 2
EN

Stack Overflow用户

发布于 2019-05-28 22:15:08

您可以在acumulate = T中使用Reduce

代码语言:javascript
复制
fun <- function(x, junk){
 x[1] <- sum(x[1:2])
 x[2] <- diff(x[1:2])
 x[3] <- x[1]/x[2] + x[3]
 x
}

dt <- 
  as.data.table(do.call(rbind, Reduce(fun, numeric(9L), accumulate = T, init = 1:3)))

setnames(dt, c('a', 'b', 'c'))

dt
#      a  b          c
#  1:  1  2  3.0000000
#  2:  3 -1  0.0000000
#  3:  2 -3 -0.6666667
#  4: -1 -2 -0.1666667
#  5: -3  1 -3.1666667
#  6: -2  3 -3.8333333
#  7:  1  2 -3.3333333
#  8:  3 -1 -6.3333333
#  9:  2 -3 -7.0000000
# 10: -1 -2 -6.5000000

您可以使用transpose而不是do.call(rbind,,如下所示,但如果加载了tidyversepurrr,请确保transposedata.table::transpose

代码语言:javascript
复制
dt <- 
  as.data.table(transpose(Reduce(fun, numeric(9L), accumulate = T, init = 1:3)))

关于junk的说明

每次迭代,Reduce都会将前一个输出(或init)以及其x参数的第i个元素传递给f。因此,即使您不打算在函数f中使用Reducex参数,您仍然需要为它提供一个参数。如果你不添加这个额外的“垃圾”参数,你会在运行时得到一个“未使用的参数”错误,因为它试图向f添加额外的参数,但是f只有一个参数。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56342915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档