# title: area of rectangle
# description: calculates the area of a rectangle
# inputs:
# - len length of the rectangle (numeric)
# - wid width of the rectangle (numeric)
# output: computed area
<- function(len = 1, wid = 1) {
rect_area if (len < 0) {
stop("len must be positive")
}if (wid < 0) {
stop("wid must be positive")
}= len * wid
area return(area)
}
Practice: Functions and if-else statements (part 2)
Stat 133
- Create functions
- Use conditional statements in your functions
- Use
stop()
to stop execution of a function when applicable - Use
warning()
to provide a warning message when applicable - Include comments to document a function
In this module you will practice writing simple functions, and some basic examples to make sure that the functions work as expected. In addition to writing the functions, you should also practice documenting your functions. Writing this type of documentation should become second nature.
1 Toy Example
Here’s an example of a function rect_area()
that computes the area of a rectangle. Notice the structure of the code below: the first lines correspond to documentation comments to indicate things such as the title, description, inputs, and outputs:
Once the function has been created, we can test it with a couple of basic examples:
# default
rect_area()
[1] 1
# len=2, wid=3
rect_area(len = 2, wid = 3)
[1] 6
# bad len
rect_area(len = -2, wid = 3)
Error in rect_area(len = -2, wid = 3): len must be positive
1.1 Roxygen Comments
Roxygen comments are a special style for writing a function’s documentation.
From time to time, you will encounter code in R that use a special type of comments to define the documentation of a function: so-called roxygen comments. These comments follow a specific syntax, and they are commonly used when writing functions for an R package. Here’s an example:
#' @title area of rectangle
#' @description calculates the area of a rectangle
#' @param len length of the rectangle (numeric)
#' @param wid width of the rectangle (numeric)
#' @return computed area
<- function(len = 1, wid = 1) {
rect_area if (len < 0) {
stop("len must be positive")
}if (wid < 0) {
stop("wid must be positive")
}<- len * wid
area return(area)
}
Once the function has been created, we can test it with a couple of basic examples:
# default
rect_area()
[1] 1
# len=2, wid=3
rect_area(len = 2, wid = 3)
[1] 6
# bad len
rect_area(len = -2, wid = 3)
Error in rect_area(len = -2, wid = 3): len must be positive
# bad wid
rect_area(len = 2, wid = -3)
Error in rect_area(len = 2, wid = -3): wid must be positive
2 Area of a circle
Consider a circle with radius = 2
. The area of this circle can be computed in R as:
# area of circle with radius 2
= 2
r = pi * r^2
area area
[1] 12.56637
2.1 Your Turn: circle_area()
version 1
Write a function circle_area()
that calculates the area of a circle.
This function must take one argument
radius
.Give
radius
a default value of 1.Include comments to document your function! You can use regular comments, or if you feel brave enough try using roxygen comments.
Show answer
#' @title area of circle
#' @description computes the area of a circle of given radius
#' @param radius numeric value
#' @return area
<- function(radius = 1) {
circle_area * radius^2
pi }
Test your function with:
- no specified arguments: i.e.
circle_area()
; - with
radius = 3
# default (radius 1)
circle_area()
[1] 3.141593
# radius 3
circle_area(radius = 3)
[1] 28.27433
2.2 Your Turn: circle_area()
version 2
Modify your circle_area()
function in order to include a stop()
statement. If radius
is negative, then the function should stop with a meaningful error message, perhaps something like: "radius cannot be negative"
.
Show answer
#' @title area of circle
#' @description computes the area of a circle of given radius
#' @param radius numeric value
#' @return area
<- function(radius = 1) {
circle_area if (radius < 0) {
stop('radius cannot be negative')
}* radius^2
pi }
Test your modified circle_area()
with radius = -2
; the function should return a stop message:
# bad radius
circle_area(radius = -2)
Error in circle_area(radius = -2): radius cannot be negative
3 Area of a Cylinder
For a given cylinder of radius \(r\) and height \(h\) the surface area \(A\) is given in the following diagram:
For example. Say you have a cylinder with radius = 2, and height = 3.
# inputs
= 2 # radius
r = 3 # height
h
# output: area of cylinder
2 * pi * r * h + 2 * pi * r^2
[1] 62.83185
Notice that the formula of the area of a cylinder includes the area of a circle: \(\pi r^2\).
3.1 Your Turn: cylinder_area()
function
Write a function cylinder_area()
, that calls circle_area()
, to compute the area of a cylinder.
This function must take two arguments:
radius
andheight
,Give both arguments a default value of 1.
The function should stop if any of
radius
orheight
are negative. Since you are callingcircle_area()
, you already have astop()
statement for a negativeradius
.Include documentation comments.
Show answer
#' @title area of cylinder
#' @description computes the area of a cylinder
#' @param radius numeric value
#' @param height numeric value
#' @return area
<- function(radius = 1, height = 1) {
cylinder_area if (height < 0) {
stop('height must be positive')
}<- 2 * pi * radius * height
lateral_area <- 2 * circle_area(radius)
base_areas + base_areas
lateral_area }
For instance:
# default (radius 1, height 1)
cylinder_area()
[1] 12.56637
# radius 2, height 3
cylinder_area(radius = 2, height = 3)
[1] 62.83185
These should return a meaningful error message:
# bad radius
cylinder_area(radius = -2, height = 1)
Error in circle_area(radius): radius cannot be negative
# bad height
cylinder_area(radius = 2, height = -1)
Error in cylinder_area(radius = 2, height = -1): height must be positive
4 Even and Odd Numbers
Any number that can be exactly divided by 2 is called an even number. R provides the modulo operator, "%%"
that can be used to determine if a number is even or odd.
To be more precise, the modulo operator returns the remainder or signed remainder of a division.
For example, 4 %% 2
evaluates to 0, because 4 divided by 2 has a quotient of 2 and a remainder of 0:
# 4 is exactly divisible by 2
4 %% 2
[1] 0
In contrast, 5 %% 2
would evaluate to 1, because 5 divided by 2 has a quotient of 2 and a remainder of 1
# 5 is not exactly divisible by 2
5 %% 2
[1] 1
4.1 Your Turn: is_even()
function
Write a function is_even()
that determines whether a number is even (i.e. multiple of 2).
If the input number is even, the output should be
TRUE
.If the input number is odd, the output should be
FALSE
.If the input is not a number, the output should be
NA
Include documentation comments.
Show answer
#' @title is even
#' @description test if a given number is even
#' @param x numeric value
#' @return whether the input is even
<- function(x) {
is_even if (is.numeric(x)) {
return(x %% 2 == 0)
else {
} return(NA)
} }
Test your function:
# even number
is_even(10)
[1] TRUE
# odd number
is_even(33)
[1] FALSE
# not a number
is_even('a')
[1] NA
4.2 Your Turn: is_odd()
function
Use your function is_even()
to write a function is_odd()
that determines if a number is odd (i.e. not a multiple of 2).
If a number is odd, the output should be
TRUE
;If a number is even the output should be
FALSE
;If the input is not a number the output should be
NA
Include documentation comments.
Show answer
#' @title is odd
#' @description test if a given number is odd
#' @param x numeric value
#' @return whether the input is odd
<- function(x) {
is_odd !is_even(x)
}
Test is_odd()
with the following cases:
# odd number
is_odd(1)
[1] TRUE
# even number
is_odd(4)
[1] FALSE
# not a number
is_odd('a')
[1] NA