# This is a comment in a code cell. This comment not be executed.
print("This is code, in the code cell. This line will execute and print my text.")[1] "This is code, in the code cell. This line will execute and print my text."
In this course, we’ll use the R language, a programming language for statistical computing and data visualization. R has been widely adopted in the fields of data mining, bioinformatic, and data analysis.
In addition to the base features included in
R, there exists an extensive library of packages with datasets and additional features to improve functionality! We’ll learn more about using these packages as the course goes on.
One of the main ways to run the R programming language, will be with Jupyter Notebook, a tool to develop interactive data science projects, or R Studio, a tool specifically developed for writing and executing R code.
If you find yourself having trouble setting up Jupyter on your own device, SFU freely provides an online server to run Jupyter!
Jupyter is a free, open-source application that is one of many different ways to write, run, and present R code. It’s mainly run on Linux systems but has support on Windows and Mac as well.
Jupyter Notebooks allow us to compile all the aspects of a data project in one file, and shows the process of the project from start to finish. It’s a great format for data visualization.
There are mainly two types of cells in Jupyter: the Markdown and Code cell. You can change the cell type of any cell in Jupyter Notebook using the Toolbar. The default cell type is Code. By clicking outside of the cell, you can change it to Markdown by clicking the m key, or Code by hitting the y key.
# This is a comment in a code cell. This comment not be executed.
print("This is code, in the code cell. This line will execute and print my text.")[1] "This is code, in the code cell. This line will execute and print my text."
R is a programming language and free software environment, designed for statistical computing and graphics.
Logical data types are used to store Boolean data, which only takes on one of two values: TRUE or FALSE.
retired = TRUE
class(retired) # Returns the data type of a variable.[1] "logical"
Numeric data types are used to store numbers. Integers and floats (numeric values with decimals) are treated as the same data type in R.
integer = 1000
class(integer)[1] "numeric"
float = 1000.01
class(float)[1] "numeric"
Character data types store text data. Character variables can take on an infinite or very large set of possible values.
message = "hello world"
class(message)[1] "character"
Factor data types are used to represent categorical variables with a fixed set of values. For example, the Degree variable for an employee can only take on five possible values:
degree = as.factor(c("High School",
"Associates",
"Bachelor's",
"Master's",
"Ph.D"))
class(degree)[1] "factor"
R has developed its own special representation for dates, represented by the Date class.
birthday = as.Date("2000-01-01")
class(birthday)[1] "Date"
Vectors are a one-dimensional data structure that stores elements of the same type. As such, a vector cannot store a character element, and a numeric element together by design.
Vectors in R are used to group elements of the same type together, when they are related. Elements in a vector can easily be accessed by calling on their index using [].
The c() command combines objects of the same type by concatenation into a vector, which is simply a list of items that are of the same type.
v1 = c(5,6,7) # Creates a vector of length 3, assigned to variable v1
print(v1)[1] 5 6 7
# We can further append to that vector, increasing its length
v2 = c(v1, 8)
print(v2)[1] 5 6 7 8
# Obtaining the second element in v2 by calling on its index
v2[2][1] 6
# Obtaining the second and third element in v3 by calling on
# an index range
v2[2:3][1] 6 7
Vectors are defined as one-dimensional data structures, where elements in a vector are accessible through a single index. In comparison, matrices are similar to vectors, but are two dimensional, and are indexed by both the row and column numbers.
We can combine vectors into a matrix using 3 different methods:
matrix() creates a matrix from the given set of values. When using this method, its reccommended to specify how many rows and columns you would like.rbind(v1, v2, ...) combines vectors of the same length into a matrix, with the vectors as rows.cbind(v1, v2, ...) combines vectors of the same length into a matrix, with the vectors as columns.# By matrix command
m = matrix(c(1,2,3,4,5,6), nrow = 2, ncol = 3)
m [,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
# By rbind() function
v1 = c(1,2,3)
v2 = c(4,5,6)
m1 = rbind(v1,v2)
m1 [,1] [,2] [,3]
v1 1 2 3
v2 4 5 6
m1[1,2] # get element from row 1, column 2v1
2
# By cbind() function
c1 = c(1,4)
c2 = c(2,5)
c3 = c(3,6)
m2 = cbind(c1,c2,c3)
m2 c1 c2 c3
[1,] 1 2 3
[2,] 4 5 6
m2[1,2] # get element from row 1, column 2c2
2
length() returns the number of elements in a vector, including vectors with missing values.
v1 = c(2,3,4,5) # Numeric atomic vector
v2 = c(TRUE,TRUE,FALSE) # Logical atomic vector
v3 = c("R is fun!", "I hate R") # Character atomic vector
v4 = c(8,9,10, NA) # Numeric atomic vector with a missing value
# length(VectorName): returns the number of elements in the vector
c(length(v1), length(v2), length(v3), length(v4)) # Notice how v1 and v4 are both length 4[1] 4 3 2 4
sum() will sum all the elements in a vector. The data type must be numerical or logical.
c(sum(v1), sum(v2), sum(v4, na.rm = T)) # na.rm = ignore NA values[1] 14 2 27
mean() will find the average of the vector. The data type must be numerical or logical.
c(mean(v1), mean(v2), mean(v4,na.rm=T)) # na.rm = ignore NA values[1] 3.5000000 0.6666667 9.0000000
Vectors are one-dimensional, a matrix can be used to store two-dimensional data in R. However, like vectors, matrices can only store values of the same type. This means that we cannot store data employee data in a matrix, because that data set would contain a mix of numeric, character, and factor variables.
Syntax: matrix(data, nrow, ncol)
matrixData = c(1,2,3,4,5,6,7,8,9) # Define values that will fill the matrix
matrixExample = matrix(matrixData, 3, 3) # Create matrix
matrixExample [,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
Lists operate similarly to vectors, except a single list can store elements of different data types. We can initialize lists with the list() function:
Syntax: list(object1, object2, ...)
list_example = list(Nvec=c(1, 2, 3),
Lvec=c(TRUE, FALSE, TRUE),
Cvec=c("my", "second", "list"))
# Return the elements under the index 'Lvec'
list_example$Lvec[1] TRUE FALSE TRUE
The data frame is the primary data structure used to handle full data sets in R. Data frames are two-dimensional objects that van store values of different types, distinguishing it from matrices, which only store values of a single type. Behind the scenes, a data frame is actually just a list of vectors; each column is a vector, and those vectors are combined in a list to form a data frame.
studentID= c(100,121,142,156)
StatScore = c(90,100,80,70)
MathScore = c(90,87,67,92)
gender = c("F","F","M","M")
df = data.frame(studentID, StatScore,MathScore, sex=as.factor(gender))
df| studentID | StatScore | MathScore | sex |
|---|---|---|---|
| 100 | 90 | 90 | F |
| 121 | 100 | 87 | F |
| 142 | 80 | 67 | M |
| 156 | 70 | 92 | M |
class(df)[1] "data.frame"
A data frame has many characteristics such as the values, data types, dimensions, and more. These are viewable through functions such as dim(), str(), summary().
# Returns a length 2 vector where:
# The 1st element as the number of rows
# The 2nd as the number of columns
dim(df) [1] 4 4
# Returns the summary of elements in a data frame
str(df)'data.frame': 4 obs. of 4 variables:
$ studentID: num 100 121 142 156
$ StatScore: num 90 100 80 70
$ MathScore: num 90 87 67 92
$ sex : Factor w/ 2 levels "F","M": 1 1 2 2
# Returns the statistical summary of elements in a data frame
summary(df) studentID StatScore MathScore sex
Min. :100.0 Min. : 70.0 Min. :67.0 F:2
1st Qu.:115.8 1st Qu.: 77.5 1st Qu.:82.0 M:2
Median :131.5 Median : 85.0 Median :88.5
Mean :129.8 Mean : 85.0 Mean :84.0
3rd Qu.:145.5 3rd Qu.: 92.5 3rd Qu.:90.5
Max. :156.0 Max. :100.0 Max. :92.0
To access the column names of a data frame, we can call colnames() which returns a character vector of the column names. We are able to rename column names through the colnames function as well.
colnames(df) # Prints the column names in a character vector[1] "studentID" "StatScore" "MathScore" "sex"
colnames(df)[1] = 'new_name' # Renames the first column
colnames(df)[1] "new_name" "StatScore" "MathScore" "sex"
# Renames columns through 1-3
colnames(df)[1:3] = c('new_name1', 'new_name2', 'new_name3')
colnames(df)[1] "new_name1" "new_name2" "new_name3" "sex"
To access values in a data frame, we can retrieve all values in a specific column, and specific row using $ for the columns, and [] for the row.
df$new_name1 # Retrieves all data points in column new_name1[1] 100 121 142 156
df$new_name1[3] # Retrieves the data point in column new_name1, row 3[1] 142
A function in R is created using the keyword function. The basic syntax of an R function definition is as follows:
function_name <- function(arg1, arg2, ...) {
# Function body
}Function Name: The actual name of the function. Functions are stored in the R environment as an object with this name.
Arguments (i.e. arg1, arg2): An argument is a placeholder. When a function is called, you can pass a value to the argument. Arguments are also optional: that is, a function may contain no arguments. Additionally, arguments can have default values.
# Called without arguments.
no_args_function <- function(){}
# A function with default values does not require a call with arguments included.
# If it is called with arguments, the arguments will override the default values.
default_values_function <- function(arg1 = 0, arg2 = TRUE, arg3 = "string"){}Function Body: The function body contains a collection of statements that defines what the function does.
Return Value: After execution, a function will return the value in return(value), where value is a variable or operation. If there is no return() specified, the function will automatically return the value on the last expression in the function body.
# With return()
my_function <- function(x, y) {
return(x + y)
}
print(my_function(1,2))[1] 3
# Without return(), note the identical outputs.
my_function2 <- function(x, y) {
x + y
}
print(my_function2(1,2))[1] 3
# Example of a function that gives the mean and median of a vector.
mean_med <- function(x) {
mu = mean(x)
med = median(x)
return(list(mean = mu, median = med))
}
y = c(1,2,3,4,5,6)
result = mean_med(y)
print(result)$mean
[1] 3.5
$median
[1] 3.5
If we need a set of operations to be repeated several times, we can use what’s known as a loop. In loops, R will execute instructions a specified number of times or until a specified stopping condition is met, such as iterating through a vector until the end.
# Syntax for for() loop:
n = 10 # Specify a number of times to loop
for (i in 1:n) { # Loops n times
# Loop body involves i
}
# Looping through each element of a vector
x = c(1,2,3)
for (i in 1:length(x)) {
# Loop body involves i, in this example I will print each element in x
print(x[i])
}[1] 1
[1] 2
[1] 3
# Start looping from the third element
for(i in 3:n) {
# Loop body involves i
}We will often use time as a measure in our statistical tests, requiring R to include timing functionalities.
# We can write a function to put the system to sleep for 5 seconds.
sleep_for_5_seconds = function() {
Sys.sleep(5)
}
start_time = Sys.time() # Starting time
sleep_for_5_seconds() # Run function
end_time = Sys.time() # Ending time
# Obtaining total running time
running_time = end_time - start_time
print(running_time)Time difference of 5.075717 secs
Many R packages such as tidyverse and Stat2Data include datasets for us to work with. We can load them in by calling the data() function, view the variables through the str() function, and look at the first few rows through the head() function.
data(mtcars, package = "datasets") # Loads the mtcars data from the datasets package
str(mtcars)'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
head(mtcars, n = 10) # Display the first 10 rows of mtcars| mpg | cyl | disp | hp | drat | wt | qsec | vs | am | gear | carb | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Mazda RX4 | 21.0 | 6 | 160.0 | 110 | 3.90 | 2.620 | 16.46 | 0 | 1 | 4 | 4 |
| Mazda RX4 Wag | 21.0 | 6 | 160.0 | 110 | 3.90 | 2.875 | 17.02 | 0 | 1 | 4 | 4 |
| Datsun 710 | 22.8 | 4 | 108.0 | 93 | 3.85 | 2.320 | 18.61 | 1 | 1 | 4 | 1 |
| Hornet 4 Drive | 21.4 | 6 | 258.0 | 110 | 3.08 | 3.215 | 19.44 | 1 | 0 | 3 | 1 |
| Hornet Sportabout | 18.7 | 8 | 360.0 | 175 | 3.15 | 3.440 | 17.02 | 0 | 0 | 3 | 2 |
| Valiant | 18.1 | 6 | 225.0 | 105 | 2.76 | 3.460 | 20.22 | 1 | 0 | 3 | 1 |
| Duster 360 | 14.3 | 8 | 360.0 | 245 | 3.21 | 3.570 | 15.84 | 0 | 0 | 3 | 4 |
| Merc 240D | 24.4 | 4 | 146.7 | 62 | 3.69 | 3.190 | 20.00 | 1 | 0 | 4 | 2 |
| Merc 230 | 22.8 | 4 | 140.8 | 95 | 3.92 | 3.150 | 22.90 | 1 | 0 | 4 | 2 |
| Merc 280 | 19.2 | 6 | 167.6 | 123 | 3.92 | 3.440 | 18.30 | 1 | 0 | 4 | 4 |
R supports many built-in mathematical operations on vectors, such as sum(vector), which returns the sum of the vector by iteratively calculating through each element.
Given a vector of numerical variables, we can calculate the standard deviation using the sd(vector) function, or we can do it manually:
x = c(100,90,95,92,88,106)
# Manual calculation:
var.x = sum((x-mean(x))^2)/(length(x)-1) # Variance formula
sd.x = sqrt(var.x)
sd.x[1] 6.765107
# Compare the calculations with the sd() function:
sd(x)[1] 6.765107