条件累加减法

时间:2017-03-15 17:04:36

标签: r data.table dplyr cumsum

这就是我的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,则有一个条件,然后将Shares除以2之后减去7-(2/2)=6值。所以第四个值是6-3=3,第五个值是dt[, Balance:= ifelse( Year == 2014, cumsum(Total[1]-Shares/2), cumsum(Total[1] - Shares))] 。我想结束最后一行的计算。

我的尝试是:

{{1}}

2 个答案:

答案 0 :(得分:1)

这是一种方法。

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

shift用于创建滞后变量,第一个元素使用fill=0填充0。其他元素计算为Shares * (1 - (0.5 *(Year == 2015)))除了Years == 2015时返回共享,在这种情况下返回Shares * 0.5

返回

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

答案 1 :(得分:1)

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)

也返回

> 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