2017-03-15 102 views
1

這是我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。我想結束最後一行的calc。

我的嘗試是:

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

回答

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))),除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 
+0

謝謝您的回答! – gibbz00

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 
+0

謝謝你的回答! – gibbz00