【问题标题】:Calculate column values from previous rows in different columns从不同列中的先前行计算列值
【发布时间】:2019-07-05 02:54:07
【问题描述】:

我正在尝试根据存储在前一行中但来自不同列的值来更新给定列的值。

我可以使用适用于小型数据集的 for 循环来完成此操作,但在处理大型 DT(例如超过 1MM 行)时,此过程当然需要很长时间。下面是一个小例子:

library(data.table)

DT <- data.table(Year = 2019:2038, Area = 500, Cos = c(0,0,0,150,0,0,
  0,0,350,0,0,0,0,0,0,0,120,200,80,100), Rep = c(0,0,0,0,150,0,0,0,0,
  350,0,0,0,0,0,0,0,0,0,0), Calc = c(500,500,500,500,500,500,500,500,
  500,500,500,500,500,500,500,500,500,380,180,100))

基本上,我想复制计算如下的“Calc”列:

1) 如果行 == 1

Calc[1] == Area[1]

2) 对于行 > 1

Calc[i] == Rep[i] + Calc[i-1] - Cos[i-1]

如果有任何反馈,我将不胜感激

非常感谢

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    在这种特殊情况下,您可以使用:

    DT[, newCalc := Calc[1L] + cumsum(Rep - shift(Cos, fill=0L))]
    

    输出:

        Year Area Cos Rep Calc    d newCalc
     1: 2019  500   0   0  500    0     500
     2: 2020  500   0   0  500    0     500
     3: 2021  500   0   0  500    0     500
     4: 2022  500 150   0  500    0     500
     5: 2023  500   0 150  500    0     500
     6: 2024  500   0   0  500    0     500
     7: 2025  500   0   0  500    0     500
     8: 2026  500   0   0  500    0     500
     9: 2027  500 350   0  500    0     500
    10: 2028  500   0 350  500    0     500
    11: 2029  500   0   0  500    0     500
    12: 2030  500   0   0  500    0     500
    13: 2031  500   0   0  500    0     500
    14: 2032  500   0   0  500    0     500
    15: 2033  500   0   0  500    0     500
    16: 2034  500   0   0  500    0     500
    17: 2035  500 120   0  500    0     500
    18: 2036  500 200   0  380 -120     380
    19: 2037  500  80   0  180 -200     180
    20: 2038  500 100   0  100  -80     100
    

    【讨论】:

      【解决方案2】:

      我们可以使用Reduceaccumulate = TRUE

      DT[, newCalc := Reduce(`+`, Rep - shift(Cos, fill = 0), 
               init = Area[1], accumulate = TRUE)[-1]]
      DT
      #    Year Area Cos Rep Calc newCalc
      # 1: 2019  500   0   0  500     500
      # 2: 2020  500   0   0  500     500
      # 3: 2021  500   0   0  500     500
      # 4: 2022  500 150   0  500     500
      # 5: 2023  500   0 150  500     500
      # 6: 2024  500   0   0  500     500
      # 7: 2025  500   0   0  500     500
      # 8: 2026  500   0   0  500     500
      # 9: 2027  500 350   0  500     500
      #10: 2028  500   0 350  500     500
      #11: 2029  500   0   0  500     500
      #12: 2030  500   0   0  500     500
      #13: 2031  500   0   0  500     500
      #14: 2032  500   0   0  500     500
      #15: 2033  500   0   0  500     500
      #16: 2034  500   0   0  500     500
      #17: 2035  500 120   0  500     500
      #18: 2036  500 200   0  380     380
      #19: 2037  500  80   0  180     180
      #20: 2038  500 100   0  100     100
      

      或与accumulate 相同,来自tidyverse

      library(tidyverse)
      DT %>% 
         mutate(newCalc = accumulate(Rep - lag(Cos, default = 0),
                .init = first(Area), `+`)[-1])
      

      【讨论】:

        猜你喜欢
        • 2016-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-24
        • 1970-01-01
        • 2019-10-12
        • 1970-01-01
        • 2021-11-07
        相关资源
        最近更新 更多