Functions: Questions

Function Arguments

Look at the help file for the function mean().

How many arguments does the function have?

What types of vectors are accepted?

What is the default setting for dealing with NA values?

Use the function mean() to calculate the mean of the following values:

Note

note the NA and use named argument matching

c(1, 2, NA, 6)

Do Q2 again but rearrange the arguments.

Do Q2 again using positional matching.

Determine the class of mean() using class().

Determine the class of mean() using str().

Determine the class of the value output in Q4 using class().

Determine the class of the value output in Q4 using str().

Function environment and scoping

For each of the following sets of commands, give the value that will be returned by the last command. Try to answer without using R.

w <- 5
f <- function(y) {
  return(w + y)
}
f(y = 2)
w <- 5
f <- function(y) {
  w <- 4
  return(w + y)
}
f(y = 2)

Among the variables w, d, and y, which are global to f() and which are local? What is the value of z when executing f(w)

w <- 2
f <- function(y) {
  d <- 3
  h <- function(z) {
    return(z + d)
  }
  return(y * h(y))
}

Do the following in R:

  1. Try:
myFun1 <- function(a) {
  b <- 3
  myFun2(a)
}

myFun2 <- function(y) {
  return(y + a + b)
}

myFun1(10)

What happens?

  1. Now try:
a <- 1
b <- 2
myFun1(10)

What happens?

if(), else, and ifelse() and Vectorization

Write a function called ‘evenOrOdd’ involving if and else that takes an argument x and returns “Even” or “Odd” depending on whether or not x is divisible by 2. (Do not use the ifelse() function).

Is your function ‘evenOrOdd’ vectorized? Check by passing it the vector:

w <- c(3, 6, 6, 4, 7, 9, 11, 6)

Another way to determine if each element of a vector is even or odd is to use the ifelse() function, which serves as a vectorized version if and else. Use ifelse() to obtain “Even” or “Odd” for each element of w.

Terminating a function with returns, errors, and warnings

The functions warning() and stop() are used to print a warning message and to stop the execution of the function call and print an error message. For example:

noNegMean <- function(x) {
  if(all(x < 0)) {
    stop("All values in x are negative")
  }
  
  if(any(x < 0)) {
    x[x < 0] <- 0
    warning("Negative values in x replaced by zero")
  }
  
  return(mean(x))
}

Copy the above code and then pass noNegMean() a vector containing some negative and some positive values. What happens?

What happens when you pass noNegMean() a vector containing all negative values?

Write a function ratio() that takes two arguments, x and y, and attempts to compute the ratio x/y.

If both x == 0 & y == 0, the function should stop and print an error message about dividing 0 by 0.

If y == 0 (but not x), the function should print a warning message about dividing by 0, and then return x/y (which will be Inf).

In all other cases, it should return x/y.

Test your ratio() function first using two nonzero values for x and y, then using a nonzero x but y = 0, and finally using x = 0 and y = 0.

Looping using for() loops and the apply functions

Copy this is a function to determine if a number is a prime number:

isPrime <- function(num){
  if (num == 2) {
    return(TRUE)
  }
  if(num > 1) {
    for(i in 2:(num-1)) {
      if ((num %% i) == 0) {
        return(FALSE)
      }
    }
  } else {
    return(FALSE)
  }
  
  return(TRUE)
}

Copy this matrix for which we would like to check if a number is a prime number:

mat <- matrix(1:100, nrow=10)

Use the apply() function to calculate the prime number for each number in the matrix.

What numbers from 1 until 100 are prime numbers?

Copy the following command to create a list containing two generations of the famous Kennedy family:

Kennedys <- list(
    JosephJr = character(0),
    John = c("Caroline", "JohnJr", "Patrick"),
    Rosemary = character(0),
    Kathleen = character(0),
    Eunice = c("RobertIII", "Maria", "Timothy", "Mark", "Anthony"),
    Patricia = c("Christopher", "Sydney", "Victoria", "Robin"),
    Robert = c("Kathleen", "JosephII", "RobertJr", "David", 
               "MaryC", "Michael", "MaryK", "Christopher", 
               "Matthew", "Douglas", "Rory"),
    Jean = c("Stephen", "William", "Amanda", "Kym"),
    Edward = c("Kara", "EdwardJr", "Patrick")
)

Use a for() loop to loop over the list of the first generation of Kennedys, keeping track of how many children each one has in a vector.

Now, using the lapply() function, loop over the list of the first generation of Kennedys and keep track of how many children each Kennedy has. What is the class of the output?

Answer Question 20 again using the sapply() function. What is the class of the output?

Load the “diamonds” dataset from the ggplot2 package by running library(gglot2) and calculate the average price of diamonds by color and clarity using the tapply() function.