In a previous post we considered writing a simple function to calculate the volume of a cylinder by specifying the height and radius of the cylinder. The function did not have any checking of the validity of the function arguments which we will consider in this post.
Fast Tube by Casper
R has various functions that we can use to test certain conditions in our function. These include the functions stop, warning and conditional statements such as if statements combined with stop or warning.
As an example consider extending the function to calculate volumes to test whether either the height or radius has not been submitted when the function is called. We will make use of the missing function that tests whether a specific argument has been provided with the function call. The new function is:
cylinder.volume.2 = function(height, radius) { if (missing(height)) stop("Need to specify height of cylinder for calculations.") if (missing(radius)) stop("Need to specify radius of cylinder for calculations.") volume = pi * radius * radius * height volume } |
We use the if statement to test whether each of the arguments is missing and when they are the function is stopped and an error message is written to the console. Here are a couple of examples of the function being halted when insufficient information is provided:
> cylinder.volume.2(height = 7) Error in cylinder.volume.2(height = 7) : Need to specify radius of cylinder for calculations. > > cylinder.volume.2(radius = 10) Error in cylinder.volume.2(radius = 10) : Need to specify height of cylinder for calculations. |
So this handles one particular type of problem with the function but there are other checks that we might want to make. For example, negative values for the height or radius are not sensible and should also lead to an error. We can check this condition using an if statement in the function:
cylinder.volume.3 = function(height, radius) { if (missing(height)) stop("Need to specify height of cylinder for calculations.") if (missing(radius)) stop("Need to specify radius of cylinder for calculations.") if (height < 0) stop("Negative height specified.") if (radius < 0) stop("Negative radius specified.") volume = pi * radius * radius * height volume } |
An example of the function in action:
> cylinder.volume.3(10, -4) Error in cylinder.volume.3(10, -4) : Negative radius specified. |
These are a couple of basic examples of validation that we can include in our function that will hopefully allow us to catch erratic behaviour in software which is more of an issue as programs get larger and more complicated.
Other useful resources are provided on the Supplementary Material page.
An interesting twist would be to use default value for arguments:
cylinderVolume <- function(height=1, radius=1) pi*radius^2*height
So, if an argument is missing in the function call, the default value is used instead. One can also use default values for a subset of arguments. For instance:
cylinderVolume <- function(height, radius=1) pi*radius^2*height
Default arguments are a good suggestion and can be useful as long as they are sensible for a particular application. There is, however, the possibility that they could introduce unexpected behaviour if the function is nested inside a more extensive program.
it was really helpful for me:)