How can I incorporate if statement when calculating IRR in R?

爷,独闯天下 提交于 2019-12-12 13:24:31

问题


This is a simple function I use to calculate IRR. However, there are incidences when all cash flows are negative and return "Error in uniroot(npv, c(0, 1), cf = cf) : f() values at end points not of opposite sign." Is there any way I can put if statement so that when IRR can't be computed, R simply returns 0?

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)

回答1:


You could use the all function:

irr <- function(cf) {
              if(all(cf < 0)) return(0)
              uniroot(npv, c(0,1), cf=cf)$root
       }
  • If the all function returns TRUE, the return function will return 0 and then exit the function.
  • If the all function returns FALSE, then the uniroot function will run as it did previously.



回答2:


I should mention that even after the accepted answer your functions seem to contain a small error:

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
}

Which considering this example:

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

The problem is that the defaults for t=seq(along=cf) will make you discount the cash flows by 1:4. Since the initial cash outflow of -123400 is usually considered a PV, you end up out of sync for the discounting.

This should fix things:

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

Giving you this:

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

But generally I would use financial or FinCal for computing IRR or NPV (or 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



回答3:


IRR may fail in may more instances than just when all cash flows are zero. To cater for every one of those scenarios you may want to tryCatchthe error, instead.

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)


来源:https://stackoverflow.com/questions/37707952/how-can-i-incorporate-if-statement-when-calculating-irr-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!