2016-06-08 46 views
3

这是一个用来计算IRR的简单函数。然而,当所有的现金流量都是负数时会出现这样的情况,并且返回“uniroot(npv,c(0,1),cf = cf)中的误差:f()在不是相反符号的端点处的值”。有没有什么办法可以把语句放到IRR无法计算的时候,R只返回0?如何在计算R中的IRR时加入陈述?

npv<-function(i,cf,t=seq(along=cf)) sum (cf/(1+i)^t) 
irr <- function(cf) {uniroot(npv, c(0,1), cf=cf)$root } 
irr(cf) 

回答

4

您可以使用all功能:

irr <- function(cf) { 
       if(all(cf < 0)) return(0) 
       uniroot(npv, c(0,1), cf=cf)$root 
     } 
  • 如果all函数返回TRUE,则return函数将返回0,然后退出功能。
  • 如果all函数返回FALSE,那么uniroot函数将像以前一样运行。
1

我应该指出,即使是公认的答案后,你的功能似乎包含一个小错误:

npv<-function(i,cf,t=seq(along=cf)) sum (cf/(1+i)^t) 
irr <- function(cf) { 
    if(all(cf < 0)) return(0) 
    uniroot(npv, c(0,1), cf=cf)$root 
} 

哪些考虑这个例子:

> npv(c(-123400, 36200, 54800, 48100), i = 0.025) 
[1] 8528.911 

的问题是,对于违约t=seq(along=cf)将使您的现金流量折扣1:4。由于-123400的初始现金流出通常被认为是PV,因此您最终不再同意折扣。

这应该解决的事情:

npv<-function(i,cf,t=seq(along=cf)-1) sum (cf/(1+i)^t) 

给你这个:

> npv(c(-123400, 36200, 54800, 48100), i = 0.025) 
[1] 8742.134 

但一般来说,我会用financialFinCal计算IRR或NPV(或MIRR):

> require(financial) 
> cf(c(-123400, 36200, 54800, 48100), i = 2.5) 

Cash Flow Model 

Flows: 
     1  2  3  4 
-123400 36200 54800 48100 

IRR%: 5.96 
NPV Extremes at I%: 

    I%  NPV  NFV  NUS 
1 2.5 8742.13 9414.32 3060.95 

> require(FinCal) 
> npv(c(-123400, 36200, 54800, 48100), r = 0.025) 
[1] 8742.134 
> irr(c(-123400, 36200, 54800, 48100)) 
[1] 0.05959787 
0

在更多情况下,内部收益率可能会比所有现金流为零时都失败。为了迎合每种情况,您可能需要tryCatch错误,而不是。

npv<-function(i,cf,t=seq(along=cf)) sum (cf/(1+i)^t) 
irr <- function(cf) {tryCatch(uniroot(npv, c(0,1), cf=cf)$root, 
     error=function(e) return(NA)) 
     } 

irr(cf)