损失与dplyr结转并变异

时间:2018-08-19 20:00:25

标签: r dplyr purrr mutate

我正在研究R中的税收模型,我需要进行亏损结转,而我在如何在代码中没有另一个(!)循环的情况下苦苦挣扎。也许您有个建议?

下面的可复制示例:

taxable_income<-c(-10,-10,-10,-10,-10,20,20,20,20,20) #define taxable income amounts
data_test<-data.frame(taxable_income) #put into data frame
data_test$carry_fwd<-0 #initialize carry forward and tax payable columns
data_test$tax_payable<-0
tax_rate<-0.27 #tax rate of 27%
#what I would like to be able to do is conditionally carry-forward a loss so that I end up with the following:
data_test$carry_fwd[1]<-ifelse(data_test$taxable_income[1]<0,data_test$taxable_income[1],0)  #first year, carry-forward balance only depends on in-year taxable income
data_test$tax_payable[1]<-max(data_test$taxable_income[1],0)*tax_rate  #first year, taxable only depends on in-year taxable income
for(i in seq(2,NROW(data_test))) {
  #carry forward any further losses and/or any carried forward losses not yet offset by income
  data_test$carry_fwd[i]<-ifelse(data_test$taxable_income[i]+data_test$carry_fwd[i-1]<0,data_test$taxable_income[i]+data_test$carry_fwd[i-1],0)
  #pay taxes if the income net carried forward losses is positive
  data_test$tax_payable[i]<-max(data_test$taxable_income[i]+data_test$carry_fwd[i-1],0)*tax_rate
  }

循环工作正常,但是由于这是一段代码,将被重复很多次,因此我想找到一种通过更快的(dplyr?)脚本来工作的方法。其余的模型代码是使用tidyverse完成的-这也许是应用purr的地方吗?

1 个答案:

答案 0 :(得分:2)

这是一个dplyr解决方案:)

library(tidyverse)

tax_rate <- 0.27
data_test <- tibble(taxable_income = c(-10,-10,-10,-10,-10,20,20,20,20,20))

data_test %>% 
  mutate(cum_sum     = cumsum(taxable_income),
         carry_fwd   = if_else(cum_sum <= 0, cum_sum, 0),
         tax_payable = case_when(cum_sum  > taxable_income & cum_sum > 0     ~ taxable_income * tax_rate,
                                 cum_sum <= taxable_income & cum_sum > 0     ~ cum_sum * tax_rate,
                                 T ~ 0)) %>% 
  select(-cum_sum)

结果

# A tibble: 10 x 3
   taxable_income carry_fwd tax_payable
            <dbl>     <dbl>       <dbl>
 1            -10       -10         0  
 2            -10       -20         0  
 3            -10       -30         0  
 4            -10       -40         0  
 5            -10       -50         0  
 6             20       -30         0  
 7             20       -10         0  
 8             20         0         2.7
 9             20         0         5.4
10             20         0         5.4