Colorado State University
Module 2: Functions in R
1. Basic Functions
Now that you have a basic understanding of how to give R commands, we can move beyond basic arithmetic. R contains a suite of functions that can be used to perform complicated tasks. The following are some useful functions that you will end up using frequently.
First, we need to generate some data. There are a few ways to do this. You can use the c() function to create a vector of numbers.
my_first_vector <- c(1, 2, 3, -6, 320.57, 4 + 4, my_second_object)
my_first_vector
## [1] 1.00 2.00 3.00 -6.00 320.57 8.00 -1740.00
If you want to look at one element of a vector, you can use [] for indexing.
# What is the 5th element in the vector?
my_first_vector[5]
## [1] 320.57
# What is the 2nd element?
my_first_vector[2]
## [1] 2
The c() function is flexible in what you can include, but what if you want to create a really long vector? The : operator lets you create a sequence of integers, and the seq() function lets you create a sequence with a defined increment.
6:30
## [1] 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
Within the seq() function, there are arguments from, to, and by that specify the starting number, ending number, and increment. As you can see above, you can choose to type in the arguments or not. If you explicitly type in the arguments, you can include them in any order.
seq(by = 0.5, to = 5, from = -5)
## [1] -5.0 -4.5 -4.0 -3.5 -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0
## [16] 2.5 3.0 3.5 4.0 4.5 5.0
If you do not explicitly type the arguments, R will use the default order built into the function.
seq(0.5, 5, -5)
## Error in seq.default(0.5, 5, -5) : wrong sign in 'by' argument
To see the default order of arguments, as well as an explanation of the inner workings of a function, you can type ? before an empty function, run the line, and the documentation for the function should appear in the Help pane in the bottom right of RStudio.
?seq()
## starting httpd help server ... done
2. Matrix Algebra
For those familiar with some linear algebra, it is important to note that R will not follow the rules of matrix algebra unless specified. When using the operators for basic arithmetic on vectors, R uses element-wise execution. For example:
integer_vector <- 1:8
integer_vector - 1
integer_vector / 2
[1] 0 1 2 3 4 5 6 7
[1] 0.5 1.0 1.5 2.0 2.5 3.0 3.5 4.0
As you can see, R is applying the arithmetic to each element of the vector individually.
If you try to multiply two vectors together, R will line up the two vectors and multiply the first element of the first vector with with first element of the second vector, and so on.
integer_vector * integer_vector
[1] 1 4 9 16 25 36 49 64
If you try to multiply two vectors of different lengths, R will repeat the shorter vector as long as it is a multiple of the longer vector.
integer_vector * 1:2
[1] 1 4 3 8 5 12 7 16
R can still perform matrix algebra, you just have to use the special operators. For example, %*% is used for inner multiplication and %o% is used for outer multiplication.
integer_vector %*% integer_vector
## [,1]
## [1,] 204
integer_vector %o% integer_vector
## [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] 1 2 3 4 5 6 7 8
## [2,] 2 4 6 8 10 12 14 16
## [3,] 3 6 9 12 15 18 21 24
## [4,] 4 8 12 16 20 24 28 32
## [5,] 5 10 15 20 25 30 35 40
## [6,] 6 12 18 24 30 36 42 48
## [7,] 7 14 21 28 35 42 49 56
## [8,] 8 16 24 32 40 48 56 64
You can create matrices using the matrix() function.
# Two simple 2x2 matrices
A <-matrix(c(10, 8,
5, 12), ncol = 2, byrow = TRUE)
A
B <-matrix(c( 5, 3,
15, 6), ncol = 2, byrow = TRUE)
B
A %*% B
Try it out!
​
Similar to finding a specific element of a vector, you can find a specific element of a matrix with [ , ]. The first index corresponds to a row, and the second index corresponds to a column. If I wanted to find the number in the first row and second column of the matrix A, I would type:
A[1,2]
Leaving one of the index slots blank will return everything from that row or column.
A[1,]
The dim() function tells you the dimension of a matrix. You can also easily take the transpose, t(), and determinant, det(), of matrices.
dim(A)
t(A)
det(A)
A nice list of operators and functions relating to matrices can be found here: https://www.statmethods.net/advstats/matrix.html
3. Write your own functions
Occasionally you may find yourself repeating the same process several times within a script. Copying and pasting the same code over an over within a script is not only cumbersome, but you will produce code that is unnecessarily long and difficult to read. One remedy for this problem is creating your own function that performs a defined set of tasks.
​
As a simple example, we will generate a function that emulates rolling a pair of dice. The process should look something like this:
# Create a vector that contains the possible values of a single die
die<-1:6
# Randomly sample from the possible values twice WITH replacement
dice<-sample(die, size=2, replace=TRUE)
# Sum the samples values for the total value of the dice roll
sum(dice)
Now that we know the process, we can create the function. R functions have three parts: a name, a body of code, and a set of arguments. To make our function, we need to replicate the process in an R object, which we will do with the function() function. To do this, call function() and follow it with a pair of braces, {}:
roll <- function() {
die<-1:6
dice<-sample(die, size=2, replace=TRUE)
return(sum(dice))
}
By default, function() will only return the last evaluated value unless specified otherwise with return().
roll()
## [1] 6
You can think of the parentheses as the "trigger" that causes R to run the function. If you type in a function's name without the parentheses, R will show you the code that is stored inside the function. If you type in the name with the parentheses, R will run that code.
4. For loops
Although the replicate() function offered an easy way to simulate some dice rolling, this task can also be accomplished using a for loop. A for loop repeats a chunk of code many times for each element in a set of input. A trivial example would be:
for (i in 1:10) {
print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
You specify the arguments in the parentheses following for, then a chunk of code within the braces that you need repeated.
fruits <- c("apple", "banana", "cherry")
for (var in fruits) {
print(var)
}
​## [1] "apple"
## [1] "banana"
## [1] "cherry"