Introduction

One advantage of writing programmes is that you can write your own functions to do things that you are likely to want to repeat. Once you have successfully completed a difficult piece of code, turn it into a function so that you do not have to write it again.

Like everything in R, a function is an object with particular characteristics. For example, if we wanted to write a function that would find the square of any number that we input,

square <- function(x) {
  x^2
}
square(2)
## [1] 4
square(3)
## [1] 9
square(4)
## [1] 16

Note the structure:

function name <- function(argument 1, argument 2){

function details (R code)
}

We could extend this to calculate a range of exponentials.

exponential <- function(x, y){
  x^y
}
exponential(2, 3)
## [1] 8
exponential(5,2)
## [1] 25

Financial values

We can write a function that will allow us to value a security.

Starting with £100 and an interest rate of 5%, we would expect to have

\[FV = PV \times (1 + R)^n\]

where FV is the future value, PV is the present value, R is the interest rate or rate of return and n is the number of years. This would be:

FV <- function(PV = 100, R, n = 1) {
  FV = PV*(1 + R)^n
}
a <- FV(R = 0.05)
a
## [1] 105
a <- FV(100, 0.06)
a
## [1] 106
a <- FV(R = 0.1, n = 2)
a
## [1] 121

The standard valuation of a financial asset is the present discounted value. The formula would be:

\[ PV = \frac{FV}{(1 + R)^n}\]

where PV is the present value, FV is the future value, R is the rate of return or the discount rate and n is the number of years into the future.

Practice

  1. See if you can write the function for the present value. This is just the present value re-arranged.

  2. Create a vector that has a range of discount rates (from 5% to 10%) and calculate the change in the present value for each of these rates.

Descriptive statistics function

The following function will calculate descriptive statistics, store them in a data frame and present the statistics in a clear format.

mystats <- function(x){
  x <- x[!is.na(x)]
  n <- length(x)
  m <- mean(x)
  s <- sd(x)
  med <- median(x)
  skew <- sum((x-m)^3/s^3)/n
  kurt <- sum((x-m)^4/s^4)/n - 3
  max <- max(x)
  min <- min(x)
  mydescriptive <- round(data.frame(
    "Number" = n,
    "Mean" = m,
    "Median" = med,
    "Std dev" = s,
    "Skew" = skew,
    "Kurtosis" = kurt,
    "Maximum" = max,
    "Minimum" = min), 2)
  return(mydescriptive)
}
mydata <- rnorm(100)
mystats(mydata)
##   Number Mean Median Std.dev Skew Kurtosis Maximum Minimum
## 1    100 0.02   0.01    0.99 0.06    -0.34     2.3   -2.65

Returns

Remember our code to calculate returns. We could turn this into a function.

myreturns <- function(x){
  returns <- c(x[1:length(x)-1]/x[2:length(x)] -1, NA)
  return(returns)
}
myseries <- 10:1
round(myreturns(myseries), 2)
##  [1] 0.11 0.12 0.14 0.17 0.20 0.25 0.33 0.50 1.00   NA

Practice

See if you can change the function to allow the function to work on data that runs from old to new.

Additional help

There are some examples and further information about functions here