条件累加减法

Conditional cumulative subtraction

这是我的 data.table 的样子:

library(data.table)
dt <- fread('
   Year      Total      Shares  Balance
   2017        10        1       10
   2016        12        2        9 
   2015        10        2        7
   2014        10        3        6
   2013        10        NA       3
')

**Balance** 是我想要的专栏。我试图通过取 Total 的第一个值 10(它也应该是 Balance 字段的第一个值)然后累积减去 Shares 中的值来找到累积减法。所以第二个值是 10-1 =9 第三个值是 9-2 = 7 等等。有一个条件,如果Year是2014年,那么用2除后减去Shares的值。所以第四个值是 7-(2/2)=6,第五个值是 6-3=3。我想从最后一行结束计算。

我的尝试是:

dt[, Balance:= ifelse( Year == 2014, cumsum(Total[1]-Shares/2), cumsum(Total[1] - Shares))]

这是一种方法。

dt[, Balance2 := Total[1] - cumsum(shift(Shares * (1 - (0.5 *(Year == 2015))), fill=0))]

shift用于创建滞后变量,第一个元素补0,使用fill=0。其他元素计算为 Shares * (1 - (0.5 *(Year == 2015))) 其中 return 份额,除非 Years == 2015,在这种情况下 Shares * 0.5 是 return。

哪个return

dt
   Year Total Shares Balance Balance2
1: 2017    10      1      10       10
2: 2016    12      2       9        9
3: 2015    10      2       7        7
4: 2014    10      3       6        6
5: 2013    10     NA       3        3

FWIW,我想提供一个功能替代方案,允许在累积差异、索引等方面进行更灵活的计算。我还使用 read.table 读取了数据。

dt <- read.table(header=TRUE, text='
   Year      Total      Shares  Balance
            2017        10        1       10
            2016        12        2        9 
            2015        10        2        7
            2014        10        3        6
            2013        10        NA       3
            ')

makeNewBalance <- function(dt) {
    output <- NULL
    for (i in 1:nrow(dt)) {
        if (i==1) {
            output[i] <- dt$Total[i]
        } else {
            output[i] <- output[i-1] - as.integer(ifelse(dt$Year[i]==2014, 
                                                         dt$Shares[i-1]/2, 
                                                         dt$Shares[i-1]))
        }
    }
    return(output)
}

dt$NewBalance <- makeNewBalance(dt)

这也是 returns

> dt
  Year Total Shares Balance NewBalance
1 2017    10      1      10         10
2 2016    12      2       9          9
3 2015    10      2       7          7
4 2014    10      3       6          6
5 2013    10     NA       3          3