首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >投资决策:净现值、内部收益率、净现值计算

投资决策:净现值、内部收益率、净现值计算
EN

Stack Overflow用户
提问于 2017-12-22 02:03:02
回答 2查看 3.3K关注 0票数 3

我试图计算不同数量项目的净现值(NPV)、内部收益率(IRR)和投资回收期(PB),以评估哪个投资项目提供最佳回报。

到目前为止,我可以在几行代码中分别为每个项目计算它。但我要做的是:编写一个函数,该函数接受一个包含许多不同项目及其现金流的矩阵,并自动返回NPV、IRR和PB。该函数应接受用于贴现现金流的无风险利率(利率)作为附加输入参数。

有谁有办法解决这个问题吗?关于如何编写一个函数来返回一个包含结果的矩阵?

计算每个度量本身的代码如下所示:

代码语言:javascript
复制
library(FinCal)

#NPV Project 1 & Project 2
NPV.Project1 <- NPV(-1000, c(1250, 10, 10, 20, 20), c(1:5), 0.06 ) 
NPV.Project2 <- NPV(-1000, c(-10, 0, 10, 20, 2000), c(1:5), 0.06 )

#Solution: NPV2 with 509 > NPV1 with 227 -> Pick Project 2

#IRR Project 1 & Project 2
IRR.Project1 <- IRR(-1000, c(1250, 10, 10, 20, 20), c(1:5))
IRR.Project2 <- IRR(-1000, c(-10, 0, 10, 20, 2000), c(1:5))
#Solution: IRR.Project1 with 28% > IRR.Project2 with 15% -> Pick Project 1

#PB Project 1 & Project 2
#PB Project 1
cf0 <- -1000
cf <- c(1250, 10, 10, 20, 20)
t <- 5

temp <- 0

#Calculating the Payback period
for (i in 1:5){
  temp[i]=sum(cf[1:i])
}
for (i in 1:5){
  if ((temp[i]+cf0) > 0){
    payback.Project1 <- i
    break
  }
  print(payback.Project1)
}

#PB Project 2
cf0 <- -1000
cf <- c(-10, 0, 10, 20, 2000)
t <- 5

temp <- 0

#Calculating the Payback period
for (i in 1:5){
  temp[i]=sum(cf[1:i])
}
for (i in 1:5){
  if ((temp[i]+cf0) > 0){
    payback.Project2 <- i
    break
  } 
  print(payback.Project2)
}
#Solution: Period for PB with Project 1 is way smaller (1 year) than with  Project 2 (5 years)
EN

回答 2

Stack Overflow用户

发布于 2017-12-22 06:50:44

您的数据:

代码语言:javascript
复制
cf_df <- data.frame(
  Project1 = c(-1000, 1250, 10, 10, 20, 20),
  Project2 = c(-1000, -10, 0, 10, 20, 2000)
)

以下是一些有用的函数,您可以考虑保留它们来处理资本预算问题:

代码语言:javascript
复制
dcf <- function(x, r, t0=FALSE){
  # calculates discounted cash flows (DCF) given cash flow and discount rate
  #
  # x - cash flows vector
  # r - vector or discount rates, in decimals. Single values will be recycled
  # t0 - cash flow starts in year 0, default is FALSE, i.e. discount rate in first period is zero.
  if(length(r)==1){
    r <- rep(r, length(x))
    if(t0==TRUE){r[1]<-0}
    }
  x/cumprod(1+r)
 }

npv <- function(x, r, t0=FALSE){
  # calculates net present value (NPV) given cash flow and discount rate
  #
  # x - cash flows vector
  # r - discount rate, in decimals
  # t0 - cash flow starts in year 0, default is FALSE
  sum(dcf(x, r, t0))
 }

pbp <- function(x, ...){
  # calculates payback period (PBP)
  #
  # x - cash flows vector
  # ... - ignored
  i <- match(1, sign(cumsum(x)))
  i-2+(-cumsum(x)[i-1]/x[i])
 }

dpbp <- function(x, r, t0=FALSE){
  # calculates discounted payback period (DPBP) given cash flow and discount rate
  #
  # x - cash flows vector
  # r - discount rate, in decimals
  # t0 - cash flow starts in year 0, default is FALSE
  pbp(dcf(x, r, t0))
 }

irr <- function(x, t0=FALSE, ...){
  # calculates internal rate of return (IRR) given cash flow 
  #
  # x - cash flows vector
  # t0 - cash flow starts in year 0, default is FALSE
tryCatch(uniroot(f=function(i){sum(dcf(x, i, t0))}, 
                 interval=c(0,1))$root,
         error=function(e) return(NA)
        )
  }

将这些功能与dplyr的强大功能相结合,您将拥有一个能够与首席财务官最喜欢的电子表格竞争的工具箱:

代码语言:javascript
复制
library(dplyr)
library(tidyr)
library(forcats)

cf_df %>%
  summarise_all(funs(NPV=npv,PBP=pbp, DPBP=dpbp, IRR=irr), r=0.06, t0=TRUE) %>% 
  gather(key=key, value = value) %>% 
  separate(key, into = c("Project", "Metric")) %>% 
  spread(key=Project, value=value) %>% 
  mutate(Metric=fct_relevel(Metric, "NPV", "IRR", "PBP", "DPBP"),
         Metric=fct_recode(Metric, 
                           `Net Present Value (NPV), USD mln`="NPV", 
                           `Internal Rate of Return (IRR), %`="IRR",
                           `Payback Period, years` = "PBP",
                           `Discounted Payback Period, years`="DPBP")) %>% 
  arrange(as.numeric(Metric))

#                            Metric    Project1    Project2
#1 Net Present Value (NPV), USD mln 227.3284770 509.3204496
#2 Internal Rate of Return (IRR), %   0.2808485   0.1508404
#3            Payback Period, years   0.8000000   4.4900000
#4 Discounted Payback Period, years   0.8480000   4.6592072
票数 4
EN

Stack Overflow用户

发布于 2017-12-22 03:25:41

代码语言:javascript
复制
 W=function(data,rate){
   NPV=apply(data,1,npv,r=rate)
   IRR=apply(data,1,irr)
   PB=apply(data,1,function(x)min(which(cumsum(x)[-1]>0)))
   data.frame(NPV=NPV,IRR=IRR,PB=PB)
 }

 funfun=function(data,r){
 mapply(apply,list(data),1,c(function(x)npv(r,x),irr,function(x)min(which(cumsum(x)[-1]>0))))
 }

W(dat,0.06)
       NPV       IRR PB
A 227.3285 0.2808516  1
B 509.3204 0.1508564  5

 funfun(dat,0.06)
      [,1]      [,2] [,3]
A 227.3285 0.2808516    1
B 509.3204 0.1508564    5

当然,您可以给出最终的矩阵列名。希望这能有所帮助

下面是使用的矩阵数据:

代码语言:javascript
复制
dat= structure(c(-1000, -1000, 1250, -10, 10, 0, 10, 10, 20, 20, 20, 
 2000), .Dim = c(2L, 6L), .Dimnames = list(c("A", "B"), NULL))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47930389

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档