簡體   English   中英

計算不同列中前一行的列值

[英]Calculate column values from previous rows in different columns

我正在嘗試根據存儲在上一行中但來自不同列的值來更新給定列的值。

我可以使用適用於小型數據集的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)如果row == 1

Calc[1] == Area[1]

2)對於行> 1

Calc[i] == Rep[i] + Calc[i-1] - Cos[i-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

我們可以使用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

或與從tidyverse accumulate

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM