在 R 中计算 IRR 时如何合并 if 语句?
How can I incorporate if statement when calculating IRR in R?
这是我用来计算 IRR 的一个简单函数。然而,当所有现金流量都是负数并且 return "Error in uniroot(npv, c(0, 1), cf = cf) : f() values at end points not of opposite sign." 有什么方法可以放置 if 语句以便当无法计算 IRR 时,R 只是 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)
您可以使用 all
函数:
irr <- function(cf) {
if(all(cf < 0)) return(0)
uniroot(npv, c(0,1), cf=cf)$root
}
- 如果
all
函数return为TRUE,return
函数将return0然后退出函数。
- 如果
all
函数 return 为 FALSE,则 uniroot
函数将 运行 和以前一样。
我应该提一下,即使在接受答案之后,您的函数似乎也包含一个小错误:
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
但通常我会使用 financial
或 FinCal
来计算 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
IRR 可能会在更多情况下失败,而不仅仅是当所有现金流量为零时。为了迎合每一种情况,您可能需要 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)
这是我用来计算 IRR 的一个简单函数。然而,当所有现金流量都是负数并且 return "Error in uniroot(npv, c(0, 1), cf = cf) : f() values at end points not of opposite sign." 有什么方法可以放置 if 语句以便当无法计算 IRR 时,R 只是 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)
您可以使用 all
函数:
irr <- function(cf) {
if(all(cf < 0)) return(0)
uniroot(npv, c(0,1), cf=cf)$root
}
- 如果
all
函数return为TRUE,return
函数将return0然后退出函数。 - 如果
all
函数 return 为 FALSE,则uniroot
函数将 运行 和以前一样。
我应该提一下,即使在接受答案之后,您的函数似乎也包含一个小错误:
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
但通常我会使用 financial
或 FinCal
来计算 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
IRR 可能会在更多情况下失败,而不仅仅是当所有现金流量为零时。为了迎合每一种情况,您可能需要 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)