Basic programming statements

Practical issues

R automatically saves the command history. You can find it in the Rhistory file in your home directory (open Rstudio, issue getwd() and you get the path to your home directory).

Otherwise, it is usually a good practice to write a script instead of always typing the commands interactively in the console. Open a new R script file, and you get a window with an empty file. This makes it possible to write the commands first, and run them afterwards whenever you want. Ctrl+Enter sends the active line into the console, while Ctrl+Shift+Enter sends the whole script into the console. You can save the sript file (extension is .R) to have access to it later later as well.

Conditionals

Sometimes it is useful to make the commands conditional on something. “If it rains, bring umbrella, else do not.” The same logic could be easily implemented in any programming language.

x <- 3
if (x > 3) {
    print("x is larger than 3")
} else {
    print("x is not larger than 3")
}
## [1] "x is not larger than 3"

Loops

Sometimes we would like to do the same thing for many objects. We could issue the same command over and over again, but that is really prone to errors. It is better to use a loop.

For example, how to count the first 1000 numbers? One way is to issue 1 + 2 + 3 + ... + 1000 but that is really cumbersome. Let’s iterate through the first 1000 numbers and add them.

sum <- 0
for (i in 1:1000) {
    sum <- sum + i
}
sum
## [1] 500500

(In R you can get the same result by simply issue sum(1:1000), but you get the logic.)

What if you want to add the first 2000 numbers?

Functions

You can write your own function as well. Function is an object itself, so you can assign a name to it with the same assignment operator.

add_first_n_numbers <- function(n) {
    sum <- 0
    for (i in 1:n) {
        sum <- sum + i
    }
    return(sum)
}


add_first_n_numbers
## function(n) {
##     sum <- 0
##     for (i in 1:n) {
##         sum <- sum + i
##     }
##     return(sum)
## }
add_first_n_numbers(1000)
## [1] 500500
add_first_n_numbers(2000)
## [1] 2001000

Functions are easily testable.

is_larger_than_three <- function(number) {
    if (number > 3) {
        print("number is larger than 3")
    } else {
        print("number is not larger than 3")
    }
}

for (i in 1:10) {
    print(i)
    is_larger_than_three(i)
}
## [1] 1
## [1] "number is not larger than 3"
## [1] 2
## [1] "number is not larger than 3"
## [1] 3
## [1] "number is not larger than 3"
## [1] 4
## [1] "number is larger than 3"
## [1] 5
## [1] "number is larger than 3"
## [1] 6
## [1] "number is larger than 3"
## [1] 7
## [1] "number is larger than 3"
## [1] 8
## [1] "number is larger than 3"
## [1] 9
## [1] "number is larger than 3"
## [1] 10
## [1] "number is larger than 3"

(Again, this task could be solved easier by (1:10 > 3), but the point is to illustrate. how functions, loops and conditionals work. Later, we are going to see more complicated examples as well.)

Sometimes it makes sense to store the result of each iteration of a loop. In this cases, lapply() is your friend. This function takes a list and a function as input, applies the function on to each element of the list and returns the result in a list.

my_result <- lapply(1:10, is_larger_than_three)
## [1] "number is not larger than 3"
## [1] "number is not larger than 3"
## [1] "number is not larger than 3"
## [1] "number is larger than 3"
## [1] "number is larger than 3"
## [1] "number is larger than 3"
## [1] "number is larger than 3"
## [1] "number is larger than 3"
## [1] "number is larger than 3"
## [1] "number is larger than 3"
str(my_result)
## List of 10
##  $ : chr "number is not larger than 3"
##  $ : chr "number is not larger than 3"
##  $ : chr "number is not larger than 3"
##  $ : chr "number is larger than 3"
##  $ : chr "number is larger than 3"
##  $ : chr "number is larger than 3"
##  $ : chr "number is larger than 3"
##  $ : chr "number is larger than 3"
##  $ : chr "number is larger than 3"
##  $ : chr "number is larger than 3"

You can define the function within lapply()

my_result <- lapply(1:10, function(x) {x + 1})
str(my_result)
## List of 10
##  $ : num 2
##  $ : num 3
##  $ : num 4
##  $ : num 5
##  $ : num 6
##  $ : num 7
##  $ : num 8
##  $ : num 9
##  $ : num 10
##  $ : num 11

Exercise

Write a function which gives the first n square numbers.

# Version 1 (returns list)
square_numbers <- function(n) {
    lapply(1:n, function(i) i^2)
}

# Version 2 (returns vector)
square_numbers <- function(n) {
    square_numbers <- c()
    for (i in 1:n) {
        square_numbers <- c(square_numbers, i^2)
    }
    return(square_numbers)
}

Load in a raw data file

You have more options (as always in R):

  • use function read.csv()
  • click “Tools/Import Dataset/From Text File…”: this essentially issues the read.csv() command
  • take a look at package readr, and use its read_csv() command (it has some advantages over the simple read.csv(): it is faster, it does not convert characters to strings automatically, etc.)