inst/doc/net-present-value.R

## ----include = FALSE----------------------------------------------------------
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

# Numeric notation in this document
# With thanks to https://stackoverflow.com/questions/18965637/set-global-thousand-separator-on-knitr/18967590#18967590
knitr::knit_hooks$set(
    inline = function(x) {
        if(!is.numeric(x)){
            x
        } else if(x<100) {
            prettyNum(round(x, 3), big.mark=",")
        } else {
            prettyNum(round(x, 0), big.mark=",")
        }
    }
)

## ----setup--------------------------------------------------------------------
library(dynamicpv)

## ----assume1------------------------------------------------------------------
# A simple cashflow
cashflow <- c(110, 120, 130, 140, 150)

# (Real) discount rate of 3\% per timestep (year)
disc <- 0.03
vt1 <- (1 + disc)^(-1 * (0:4))

## ----demo1--------------------------------------------------------------------
# Run dynpv calculation with full output
pv1 <- dynpv(payoffs=cashflow, discrate=disc)

summary(pv1)

## ----simpler------------------------------------------------------------------
sum(vt1 * cashflow)

## ----calc2a-------------------------------------------------------------------
# Set up price index
pinfl <- 0.01
pindex <- (1+pinfl)^(0:4)
pindex

# Nominal discount rate
nomdisc <- (1+disc)*1.025-1

# Calculate present value
pv2 <- dynpv(payoffs=cashflow, prices=pindex, discrate=nomdisc)

summary(pv2)

## ----calc2b-------------------------------------------------------------------
# Compare with more base calculations
vt2 <- (1+nomdisc)^(-1 * (0:4))
sum(vt2 * cashflow * pindex)

## ----calc3a-------------------------------------------------------------------
# Revise the price index to be 0.5 from year 4
pindex[4:5] <- 0.5
pindex

# Calculate present value
pv3 <- dynpv(payoffs=cashflow, prices=pindex, discrate=nomdisc)

summary(pv3)

## ----calc3b-------------------------------------------------------------------
# Compare with more base calculations
sum(vt2 * cashflow * pindex)

## ----uptake2------------------------------------------------------------------
# Uptake vector is (1, 1, 1, 1, 1)
uptakes1 <- rep(1, 5)

# NPV calculation
pv4 <- dynpv(payoffs=cashflow, uptakes=uptakes1, discrate=disc)

summary(pv4)

## ----verify2------------------------------------------------------------------
sum(vt1 * cumsum(cashflow))

## ----uptake3------------------------------------------------------------------
# Uptake vector is (1, 2, 3, 4, 5)
uptakes2 <- 1:5

# NPV calculation
pv5 <- dynpv(payoffs=cashflow, uptakes=uptakes2, discrate=disc)

summary(pv5)

## ----verify3------------------------------------------------------------------
# Verifying total NPV is now more complicated
checkpv <- rep(0, 5)
for (i in 1:5) {
  checkpv[i] <- sum(cashflow[1:i] * uptakes2[i:1] * vt1[i])
}
sum(checkpv)

## ----uptake4------------------------------------------------------------------
# NPV calculation
pv6 <- dynpv(payoffs=cashflow, uptakes=uptakes2, prices=pindex, discrate=nomdisc)

# Calculation results
pv6

# Total present value = sum of the pv column
sum(pv6$pv)

summary(pv6)

Try the dynamicpv package in your browser

Any scripts or data that you put into this service are public.

dynamicpv documentation built on Jan. 16, 2026, 1:07 a.m.