How can I include an if statement when calculating IRR in R?

This is a simple function that I use to calculate IRR. However, there are cases when all cash flows are negative and return "Error in uniroot (npv, c (0, 1), cf = cf): f () the values ​​at the endpoints do not have the opposite sign." Is there a way I can put an if statement so that when the IRR cannot be computed, R just 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) 
+3
r if-statement irr
source share
3 answers

You can 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, the uniroot function will execute as before.
+4
source share

It should be noted 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 } 

Regarding this example:

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

The problem is that the default values ​​for t=seq(along=cf) will allow you to reduce cash flows by 1:4 . Since the initial cash outflow of -123400 usually considered PV, you find yourself out of sync for discounting.

This should fix:

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

By providing you with the following:

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

But usually I would use financial or FinCal to calculate 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 
+1
source share

IRR may fail in several cases than when all cash flows are zero. To serve each of these scenarios, you might want to tryCatch errors 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) 
0
source share

All Articles