【问题标题】:Conditional cumulative subtraction条件累加减法
【发布时间】:2017-03-15 17:04:35
【问题描述】:

这就是我的 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))]

【问题讨论】:

    标签: r data.table dplyr cumsum


    【解决方案1】:

    这是一种方法。

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

    shift用于创建滞后变量,第一个元素用0填充,使用fill=0。其他元素计算为 Shares * (1 - (0.5 *(Year == 2015))),它返回 Shares,除非 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
    

    【讨论】:

      【解决方案2】:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-19
        • 1970-01-01
        • 1970-01-01
        • 2019-03-02
        • 1970-01-01
        • 2012-05-11
        • 2015-06-04
        • 2017-10-27
        相关资源
        最近更新 更多