Sometimes, we will be carrying out some set of operations repetitively each time with a new set of inputs. In such cases, it is easier if we can create a function that can take the inputs and perform the set of operations, thus removing the need for us to code the steps each time the operation is performed. Below is a simple example of a function

\[f(x) = x + x^3 \]

The way to create this function in R is as follows

f<- function(x){
print(x+x^3)
}

If we run the above lines of code, the function has only been defined. Here is how we would then call and use it.

print(f(3))
## [1] 30
## [1] 30
y<-f(5) + f(4)
## [1] 130
## [1] 68
print(y)
## [1] 198

An interesting question here is what would happen if I were to supply a vector or a matrix as an input to this function.

v<-c(2,3,4)
f(v)
## [1] 10 30 68
A<- cbind(c(1,2), c(3,4))
f(A)
##      [,1] [,2]
## [1,]    2   30
## [2,]   10   68

We can see that the function has been applied to each value in the vector or the matrix. As we become more familiar with R, we will know to expect this. In R using a function just reduces our effort of typing all the statements again and again. Calling the function is equivalent to just typing out the set of commands that are within the definition of the function. From our understanding of basic operations, we know that applying for example a “to the power 2” operation on a vector or matrix of numbers just applies the operation element-wise and then adding will do element-wise addition.

Let us now write a function to compute the maturity value of a bond with face value \(V\), a compound interest rate of \(r\) and term \(T\).

maturity_value<- function(V, r, T){
  maturity<- V* (1+r)^T
  print(maturity)
}

maturity_value(100, .1, 10)
## [1] 259.3742

Suppose we have a set of instruments with different parameter values for (face value, interest rate, term), then we could very easily apply the function with each vector as an input, knowing that the function will be applied elementwise.

maturity_value(c(100,200,300), c(.1,.2,.05), c(5,10,20))
## [1]  161.0510 1238.3473  795.9893

We can easily check that what the function is doing is to compute elementwise.

maturity_value(100,.1,5)
## [1] 161.051
maturity_value(200,.2,10)
## [1] 1238.347
maturity_value(5,.05,20)
## [1] 13.26649

What if I want to compute for all combinations of face value, interest rate and terms. Well! then we just need to supply the input accordingly. We need to create a cartesian product of the inputs and then call the function.

Vlist<- c(100,200,300)
rlist<- c(0.1, 0.2, 0.05)
Tlist<- c(5,10,20)

VrT<-expand.grid(Vlist, rlist, Tlist)

out<-maturity_value(VrT[,1], VrT[,2], VrT[,3])
##  [1]   161.0510   322.1020   483.1530   248.8320   497.6640   746.4960
##  [7]   127.6282   255.2563   382.8845   259.3742   518.7485   778.1227
## [13]   619.1736  1238.3473  1857.5209   162.8895   325.7789   488.6684
## [19]   672.7500  1345.5000  2018.2500  3833.7600  7667.5200 11501.2800
## [25]   265.3298   530.6595   795.9893
data.frame(Value=VrT[,1], Interest_rate=VrT[,2], Term=VrT[,3], Maturity=out)
##    Value Interest_rate Term   Maturity
## 1    100          0.10    5   161.0510
## 2    200          0.10    5   322.1020
## 3    300          0.10    5   483.1530
## 4    100          0.20    5   248.8320
## 5    200          0.20    5   497.6640
## 6    300          0.20    5   746.4960
## 7    100          0.05    5   127.6282
## 8    200          0.05    5   255.2563
## 9    300          0.05    5   382.8845
## 10   100          0.10   10   259.3742
## 11   200          0.10   10   518.7485
## 12   300          0.10   10   778.1227
## 13   100          0.20   10   619.1736
## 14   200          0.20   10  1238.3473
## 15   300          0.20   10  1857.5209
## 16   100          0.05   10   162.8895
## 17   200          0.05   10   325.7789
## 18   300          0.05   10   488.6684
## 19   100          0.10   20   672.7500
## 20   200          0.10   20  1345.5000
## 21   300          0.10   20  2018.2500
## 22   100          0.20   20  3833.7600
## 23   200          0.20   20  7667.5200
## 24   300          0.20   20 11501.2800
## 25   100          0.05   20   265.3298
## 26   200          0.05   20   530.6595
## 27   300          0.05   20   795.9893

A function can also return a list of quantities. A list unlike a vector can contain objects of different type, for example it can contain a number, a vector, a name and matrix as four different entries. Below is an example of a list and how to access elements of a list.

A<- rbind(data.frame(name="Tom", age="5"), data.frame(name="Jill", age="10"))
print(A)
##   name age
## 1  Tom   5
## 2 Jill  10
# list with a string , a number and a matrix as its entries
L<- list( name="Sam",  number_of_children=2, kid_details=A)

##To access name

L$name
## [1] "Sam"
## or
L[[1]]
## [1] "Sam"
## To access number of children
L[[2]]
## [1] 2
## TO access second kinds details
L[[3]][2,]
##   name age
## 2 Jill  10
## or

L$kid_details[2,]
##   name age
## 2 Jill  10

Finally let us take an example to show how afunction can output a list. Given a vector of inputs for face-value, interest rate and term, let us write a function to evaluate and output the maturity value for all combinations of inputs, as well as output the raw inputs.

maturity_value<- function(Vlist, rlist, Tlist){

VrT<- expand.grid(Vlist, rlist, Tlist)
V<-VrT[,1]
r<-VrT[,2]
T<-VrT[,3]

  out<- V* (1+r)^T
  
list(Vlist, rlist, Tlist, data.frame(Value=VrT[,1], Interest_rate=VrT[,2], Term=VrT[,3], Maturity=out))
}


out<-maturity_value(c(100,200), c(.1,.2,.3), Tlist=c(10))

out
## [[1]]
## [1] 100 200
## 
## [[2]]
## [1] 0.1 0.2 0.3
## 
## [[3]]
## [1] 10
## 
## [[4]]
##   Value Interest_rate Term  Maturity
## 1   100           0.1   10  259.3742
## 2   200           0.1   10  518.7485
## 3   100           0.2   10  619.1736
## 4   200           0.2   10 1238.3473
## 5   100           0.3   10 1378.5849
## 6   200           0.3   10 2757.1698
out[[4]]
##   Value Interest_rate Term  Maturity
## 1   100           0.1   10  259.3742
## 2   200           0.1   10  518.7485
## 3   100           0.2   10  619.1736
## 4   200           0.2   10 1238.3473
## 5   100           0.3   10 1378.5849
## 6   200           0.3   10 2757.1698