Functions (slide 7)

increment_power <- function(x, pwr = 2) {
  x <- x + 1
  return(x^pwr)
}
increment_power(1:4, pwr = 2)
## [1]  4  9 16 25

The vector 2 was recycled to a length four vector. The vector 1 was recycled to a length four vector and each component of 1:4 is incremented. Then a vectorized power function was applied. The above is equivalent to

(2:5)^c(2, 2, 2, 2)
## [1]  4  9 16 25

This is vectorized because ^ is a vectorized operator; the result is a vector where each component of the base is raised to the corresponding component of the exponent.

increment_power(2:5, pwr = c(2, 3))
## [1]   9  64  25 216

Similar situation: the shorter vector c(2, 3) is recycled to be length 4. The above is equivalent to

(2:5)^c(2, 3, 2, 3)
## [1]   4  27  16 125

Branching (slide 13)

noise <- function(animal) {
  if (animal == "cow") {
    return("moo")
  }
  else if (animal == "dog") {
    return("woof")
  }
  else if (animal == "pig") {
    return("oink")
  }
  else if (animal == "owl") {
    return("hoot")
  } else {
    return("Animal not recognized!")
  }
}

noise("pig")
## [1] "oink"
noise("hedgehog")
## [1] "Animal not recognized!"
noise("cow")
## [1] "moo"

Branching (slide 14)

parity <- function(x) {
  if (x %% 2 == 0) {
    return("even")
  } else if (x %% 2 == 1) {
    return("odd")
  } else {
    return("Not an integer!")
  }
}
parity(4)
## [1] "even"
parity(17)
## [1] "odd"
parity(12.43)
## [1] "Not an integer!"

Function with branch (slide 19)

parity_vec <- function(x) {
  result <- vector(length = length(x)) # initialize result
  for (i in seq_along(x)) {
    result[i] <- parity(x[i]) # call the previously defined function
  }
  result # last expression is automatically returned
}

parity_vec(c(12, 320, 598, 23))
## [1] "even" "even" "even" "odd"

We used seq_along(x) so that we have an index i to use with result.

Vectorized ifelse (slide 20)

parity_vec <- function(x) {
  ifelse(x %% 2, "odd", "even")
}
parity_vec(c(12, 320, 598, 23))
## [1] "even" "even" "even" "odd"

This takes advantage of the fact that numeric 0 is logically FALSE and 1 is logically TRUE. Actually, all numeric values other than 0 are TRUE. In view of this, the above is actually incorrect; we need to account for the "Not an integer!" case.

parity_vec <- function(x) {
  result <- ifelse(x %% 2, "odd", "even")
  not_int <- (x %% 1) != 0  # This is determines if x contains decimals (not int)
  result[not_int] <- "Not an integer!"
  result
}
parity_vec(c(12, 320.5, 599, 23.88))
## [1] "even"            "Not an integer!" "odd"             "Not an integer!"