如何在R中不借助包计算IRR?牛顿迭代代码报错求助
IRR计算问题排查与修复
警告原因:向量长度不匹配
你遇到的警告是因为代码中指数或系数向量的长度和现金流向量长度不一致,R会自动循环短向量匹配长向量,导致计算逻辑错误和警告。
具体问题点:
0:length(cashflows)-1生成的向量长度是length(cashflows)+1(比如现金流长度为3时,生成-1,0,1,2),而现金流是3个元素,两者长度不匹配。- 一阶、二阶导数计算中,系数和分母的指数向量长度也存在类似不匹配问题,比如二阶导数分母用了
2:length(cashflows),长度比现金流少1。
修复后的代码
IRR <- function(cashflows) { rate <- 0.1 max_iterations <- 1000 tolerance <- 0.0001 n <- length(cashflows) t <- 0:(n-1) # 时间点向量,长度和现金流完全一致 npv <- sum(cashflows / (1 + rate)^t) for (i in 1:max_iterations) { # 一阶导数:NPV对折现率的导数公式 npv_derivative <- sum(-t * cashflows / (1 + rate)^(t + 1)) # 二阶导数:用于判断收敛性 npv_second_derivative <- sum(t*(t+1) * cashflows / (1 + rate)^(t + 2)) rate <- rate - npv / npv_derivative if (abs(npv) < tolerance) { return(rate) } if (npv_second_derivative < 0) { return(NA) } npv <- sum(cashflows / (1 + rate)^t) } # 迭代至最大次数仍未收敛,返回NA return(NA) }
关键修改说明
- 统一时间点向量
t:提前生成0:(n-1),确保和现金流长度一致,彻底解决长度不匹配问题。 - 修正导数公式:
- 一阶导数严格按照NPV的求导逻辑,系数
t和分母指数t+1均与现金流长度匹配。 - 二阶导数修正了分母指数为
t+2,保证向量长度一致,同时公式更准确。
- 一阶导数严格按照NPV的求导逻辑,系数
- 补充边界处理:迭代到最大次数仍未收敛时返回NA,避免函数无输出。
测试示例
用标准现金流测试:
cashflows <- c(-100, 30, 40, 50) IRR(cashflows) # 输出约0.1066,无警告
内容的提问来源于stack exchange,提问作者Anand
相关产品推荐
相关产品推荐

