Exploring functions in R
A function is a collection of statements in the form of an object that receives an (optional) input, completes a specific task, and (optionally) generates an output. We may or may not be interested in how a function achieves the task and produces the output. When we only care about utilizing an existing function, which could be built-in and provisioned by R itself or pre-written by someone else, we can treat it as a black box and pass the required input to obtain the output we want. Examples include the sum()
and mean()
functions we used in the previous exercise. We can also define our own function to operate as an interface that processes a given input signal and produces an output. See Figure 1.9 for an illustration:
Figure 1.9 – Illustration of a function’s workflow
A function can be created using the function
keyword with the following format:
function_name = function(argument_1, argument_2, …){ some statements }
A function can be decomposed into the following parts:
- Function name: The name of the functional object registered and stored in the R environment. We use this name followed by a pair of parentheses and (optionally) input arguments within the parentheses to call the function.
- Input argument: A placeholder used to receive input value when calling the function. An argument can be optional (with a default value assigned) or compulsory (with no default value assigned). Setting all arguments as optional is the same as requiring no compulsory input arguments for the function. However, we will need to pass a specific value to a compulsory argument in order to call the function. In addition, the optional argument can also appear after the compulsory argument, if any.
- Function body: This is the area where the main statement is executed to complete a specific action and fulfill the purpose of the function.
- Return value: The last statement to be evaluated within the function body, usually explicitly wrapped within the
return()
function.
Let’s go through an exercise on creating a user-defined function.
Exercise 1.19 – creating a user-defined function
Now, let’s try it out:
- Create a function named
test_func
to receive an input and print out"(input) is fun"
. Allow the option to print the message in uppercase:test_func = function(x, cap=FALSE){ msg = paste(x,"is fun!") if(cap){ msg = toupper(msg) } return(msg) }
Note that we used the
=
sign instead of<-
to assign the functional object to thetest_func
variable. However, the latter is more commonly observed when creating functions in R. In the input, we created two arguments: the compulsory argument,x
, to receive the message to be printed, and the optional argument,cap
, to determine whether the message needs to be converted into uppercase. The optional argument means that the user can either go with the default setting (that is, a lowercase message) by not supplying anything to this argument or overwrite the default behavior by explicitly passing in a value.In the function body, we first create a
msg
variable and assign the message content by calling thepaste()
function, a built-in function to concatenate the two input arguments. If thecap
argument isFALSE
, theif
statement will evaluate toFALSE
andmsg
will be directly returned as the function’s output. Otherwise, the statement within theif
clause will be triggered to convert themsg
variable into uppercase using thetoupper()
function, another built-in function in R. - Let’s see what happens after calling the function in different ways:
>>> test_func("r") "r is fun!" >>> test_func("r",cap=TRUE) "R IS FUN!" >>> test_func() Error in paste(x, "is fun!") : argument "x" is missing, with no default
The first two cases work as expected. In the third case, we did not supply any value to the
x
argument, defined as a compulsory argument. This leads to an error and fails to call the function.