繁体   English   中英

计算 R data.table 中一系列列的净现值

[英]Calculating net present value of a series of columns in R data.table

我有一个data.table其中 40 列代表连续 40 个时期的收入。 我正在尝试为每个观察添加一个代表收入流 NPV 的变量(即 $\\sum_{t=1}^T \\beta^{t-1} y_{i,t}$,收入)。

我的做法是:

dt[,NPV:=rowSums(.SD*.95^(0:39)),.SDcols=paste0("year_",1:40)]

但这给出了奇怪的结果。 事实上, .SD*.96^(0:39)本身正在做一些我不明白的事情——我想问题是它不知道如何将.SD与向量.95^(0:39) 一定要回收.​​..

鉴于此,我尝试了某种lapply来处理该产品,但没有奏效; 接下来,将问题指定为矩阵乘法.SD %*% .95^(0:39)也不起作用。

关于该怎么做的任何想法? 也许reshape并从那里开始......

为了具体起见,这里有一个示例,您可以在 5 个周期上进行操作。

set.seed(3654654)
dt<-data.table(id=1:10,year_1=rchisq(10,df=1),
              year_2=rchisq(10,df=1),
              year_3=rchisq(10,df=1),
              year_4=rchisq(10,df=1),
              year_5=rchisq(10,df=1))

> dt
    id     year_1     year_2       year_3      year_4      year_5
 1:  1 0.27161866 0.12764396 0.2775017833 5.210941183 0.027654609
 2:  2 2.44271387 1.21104397 0.1242118874 0.009518939 3.265443502
 3:  3 0.18095011 0.06581832 1.1619364400 0.938078133 2.238590035
 4:  4 0.02148331 3.38477084 0.1254167045 0.041640559 0.212538797
 5:  5 1.27821958 0.19046799 3.1166384038 0.586280661 0.019470595
 6:  6 0.03413820 0.68214806 0.9325970029 0.568719470 0.061664982
 7:  7 2.32055628 0.04137301 0.1810722845 0.050654213 1.377958712
 8:  8 0.95498438 0.03095528 0.7081911061 3.127335761 2.293907090
 9:  9 4.49044959 1.75553222 0.0005865227 0.207076713 0.577015216
10: 10 0.02984232 0.02522646 0.3891819870 0.178056404 0.006526457

所以净现值应该是:

           [,1]
 [1,] 5.1335813
 [2,] 6.3731923
 [3,] 3.9197555
 [4,] 3.5590199
 [5,] 4.7904516
 [6,] 2.0616800
 [7,] 3.6890640
 [8,] 6.1732355
 [9,] 6.8062594
[10,] 0.5630211

这是我迄今为止尝试过的结果:

> dt[,rowSums(.SD*.95^(0:4)),.SDcols=paste0("year_",1:5)]
 [1] 5.9153602 6.7002856 4.1382992 3.2458933 4.2281649
     2.2792677 3.7730338 6.4216247 6.0279123 0.5121889

(完全不正确——为什么?出于同样的原因,这不起作用:

> dt[,.SD*.95^(0:4),.SDcols=paste0("year_",1:5)]
        year_1     year_2       year_3      year_4     year_5
 1: 0.27161866 0.12764396 0.2775017833 5.210941183 0.02765461
 2: 2.32057818 1.15049177 0.1180012931 0.009042992 3.10217133
 3: 0.16330748 0.05940104 1.0486476371 0.846615515 2.02032751
 4: 0.01841926 2.90201790 0.1075291471 0.035701574 0.18222545
 5: 1.04111784 0.15513737 2.5385214589 0.477529263 0.01585892
 6: 0.03413820 0.68214806 0.9325970029 0.568719470 0.06166498
 7: 2.20452847 0.03930436 0.1720186702 0.048121502 1.30906078
 8: 0.86187340 0.02793714 0.6391424733 2.822420524 2.07025115
 9: 3.84999922 1.50514943 0.0005028699 0.177542396 0.49471842
10: 0.02430675 0.02054711 0.3169911608 0.145028054 0.00531584

-- 似乎是向下乘以行而不是跨列)

> dt[,.SD %*% .95^(0:4),.SDcols=paste0("year_",1:5)]
Error in .SD %*% 0.95^(0:4) : 
  requires numeric/complex matrix/vector arguments

尝试这个:

> dt[, as.matrix(.SD) %*% 0.95 ^ (0:4), .SDcols = -1]
           [,1]
 [1,] 5.1335813
 [2,] 6.3731923
 [3,] 3.9197555
 [4,] 3.5590199
 [5,] 4.7904516
 [6,] 2.0616800
 [7,] 3.6890640
 [8,] 6.1732355
 [9,] 6.8062594
[10,] 0.5630211

或者:

as.matrix(dt[, -1]) %*% 0.95 ^ (0:4)

更新:基于评论的小改进。

这是一种利用 data.table 的方式:

vs   <- paste0("year_",1:5)
exps <- 1:5 - 1

dt[,NPV:=Reduce(
  `+`,
  mapply(
    function(x,y) x*.95^y,
    .SD,
    exps,
    SIMPLIFY=FALSE)
),.SDcols=vs]

mapply将双参数函数应用于两个列表中的元素对, .SDexps Reduce+折叠结果。 当然,您也可以将其写在一行上。

#Using data.frame: df is your data frame and assuming that year 1 indicates 
#the beginning of the year and so discount factor is equal to 0 for the first 
#year and 0.95 for the second year. In the data frame, year1 starts in column2
#2 and year 5 is the last column

 df<-data.frame(dt)
NPV<-rowSums(sapply(2:ncol(df),function(i){df[,i]*0.95^(i-2)}))
> NPV
 [1] 5.1335813 6.3731923 3.9197555 3.5590199 4.7904516 2.0616800 3.6890640 6.1732355 6.8062594 0.5630211

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM