【问题标题】:Use previous calculated row value in r Continued在 r 中使用先前计算的行值(续)
【发布时间】:2015-10-28 14:40:37
【问题描述】:

我有一个如下所示的 data.table:

DT <- data.table(A=1:20, B=1:20*10, C=1:20*100)
DT
    A  B   C
1:  1  10  100
2:  2  20  200
3:  3  30  300
4:  4  40  400
5:  5  50  500
...
20: 20 200 2000

我希望能够计算一个新列“G”,它的第一个值作为 B 列中前 20 行的平均值作为第一个值,然后我想使用 G 列的第一行来帮助计算G的下一行值。

假设B列前20行的平均值为105,G中下一行的计算公式为:DT$G[2] = DT$G[1]*2,下一行又是DT$G[3]=DT$G[2]*2。这意味着不应在下一行中再次使用第一个值,依此类推。

    A    B   C       G
1:  1   10   100     105
2:  2   20   200     210
3:  3   30   300     420
4:  4   40   400     840
5:  5   50   500     1680
...
20: 20  200  2000    55050240

对此有什么想法吗?

【问题讨论】:

  • 你有什么想法?
  • DT[, G := mean(B[1:20]) * 2^(0:19)]

标签: r data.table lag


【解决方案1】:

你可以用一点算术来做到这一点:

DT$G <- mean(DT$B[1:20])
DT$G <- DT$G * cumprod(rep(2,nrow(DT)))/2

或使用data.table 语法,由@DavidArenburg 提供:

DT[ , G := mean(B[1:20]) * cumprod(rep(2, .N)) / 2]

或来自@Frank

DT$G <- cumprod(c( mean(head(DT$B,20)), rep(2,nrow(DT)-1) ))

【讨论】:

  • 对于(未来的)读者,请使用:= 语法,因为&lt;- 会导致丢失列指针的过度分配(这会导致警告下次你使用:= 时必须浅拷贝)。
  • 我看到它实现了我的解决方案,但它的方式不是我想要的方式。您创建一个“2”的向量,取 2 的累积乘积,除以 2,然后乘以平均值。但我想有办法直接使用前一行,而不是这样。但顺便感谢您的努力
  • @KhalidN 每行计算一个值,然后回头再重新计算将非常低效且缓慢。这个解决方案是完全矢量化的,我猜这是最好的。
  • @DavidArenburg 是的,我可以理解它的设置速度有点慢,但是对于像我这样的更复杂的问题,我需要这样的解决方案。我真正的问题是一个比上面提到的更复杂的公式。我的第一行的真实公式是这样的:DT$R[1]
【解决方案2】:
mycalc <- function(x, n) {
  y <- numeric(n)
  y[1] <- mean(x)
  for (i in 2:n) y[i] <- 2*y[i-1]
  y
}
DT[ , G := mycalc(B[1:20], .N)]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 2018-11-17
    相关资源
    最近更新 更多