8 Function Writing
Writing functions allows us to condense a process into a single function.
8.1 Univariate Case
If we wanted to index a variable by its mean, we could simply type x/mean(x), where x is our vector. However, what if there were a function called index() that makes this process more clear? There is not one inherently in R, but we are able to create it:
index <- function(x) { # the formals/arguments
x/mean(x) # The body
}
index(mtcars$mpg)## [1] 1.0452636 1.0452636 1.1348577 1.0651734 0.9307824 0.9009177 0.7117748
## [8] 1.2144968 1.1348577 0.9556696 0.8859854 0.8163011 0.8610981 0.7565718
## [15] 0.5176544 0.5176544 0.7316846 1.6126925 1.5131436 1.6873542 1.0701509
## [22] 0.7715041 0.7565718 0.6620003 0.9556696 1.3588427 1.2941359 1.5131436
## [29] 0.7864365 0.9805569 0.7466169 1.0651734
We can cast this new function over all columns in mtcars with sapply().2
# Get only a few rows.
head(sapply(mtcars, index))## mpg cyl disp hp drat wt qsec
## [1,] 1.0452636 0.9696970 0.6934756 0.7498935 1.0843688 0.8143601 0.9221934
## [2,] 1.0452636 0.9696970 0.6934756 0.7498935 1.0843688 0.8936203 0.9535682
## [3,] 1.1348577 0.6464646 0.4680961 0.6340009 1.0704666 0.7211128 1.0426500
## [4,] 1.0651734 0.9696970 1.1182295 0.7498935 0.8563733 0.9993006 1.0891519
## [5,] 0.9307824 1.2929293 1.5603202 1.1930124 0.8758363 1.0692361 0.9535682
## [6,] 0.9009177 0.9696970 0.9752001 0.7158074 0.7673994 1.0754526 1.1328524
## vs am gear carb
## [1,] 0.000000 2.461538 1.0847458 1.4222222
## [2,] 0.000000 2.461538 1.0847458 1.4222222
## [3,] 2.285714 2.461538 1.0847458 0.3555556
## [4,] 2.285714 0.000000 0.8135593 0.3555556
## [5,] 0.000000 0.000000 0.8135593 0.7111111
## [6,] 2.285714 0.000000 0.8135593 0.3555556
8.2 Multivariate Case
In the univariate case, we indexed a vector by its mean. What if we wanted to use the median instead? We would simply need to replace mean with median. Alternatively, we can add an additional input into our function that specifies what aggregation function to use in the indexing.
index2 <- function(x, f) {
x/f(x)
}Now we can use any function in the f input.
head(index2(mtcars$mpg, mean)) # show only a few elements## [1] 1.0452636 1.0452636 1.1348577 1.0651734 0.9307824 0.9009177
head(index2(mtcars$mpg, median)) # show only a few elements## [1] 1.0937500 1.0937500 1.1875000 1.1145833 0.9739583 0.9427083
head(index2(mtcars$mpg, max)) # show only a few elements## [1] 0.6194690 0.6194690 0.6725664 0.6312684 0.5516224 0.5339233
Our index2 function is actually special in that it is not only a multivariate function but a functional, which is a function that takes another function as an input–see the Functionals chapter for more details.