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:
<- function(x) { # the formals/arguments
index
/mean(x) # The body
x
}
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.
<- function(x, f) {
index2
/f(x)
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.