Exercise 1

Problem

What is the type of each vector below? Check your answer in R.

c(4L, 16, 0)
c(NaN, NA, -Inf)
c(NA, TRUE, FALSE, "TRUE")
c(pi, NaN, NA)

Solution

typeof(c(4L, 16, 0))
#> [1] "double"
typeof(c(NaN, NA, -Inf))
#> [1] "double"
typeof(c(NA, TRUE, FALSE, "TRUE"))
#> [1] "character"
typeof(c(pi, NaN, NA))
#> [1] "double"

Exercise 2

Problem

Write a conditional statement that prints “Can’t proceed NA or NaN present!” if a vector contains NA or NaN. Test your code with vectors x and y below.

x <- NA
y <- c(1:5, NaN, NA, sqrt(3))

Solution

x <- NA
y <- c(1:5, NaN, NA, sqrt(3))
if (any(is.na(x))) {print("Can't proceed NA or NaN present!")}
#> [1] "Can't proceed NA or NaN present!"
if (any(is.na(y))) {print("Can't proceed NA or NaN present!")}
#> [1] "Can't proceed NA or NaN present!"

Exercise 3

Problem

Create a list in R that has a similar structure as the JSON product-order data below.

[
 {
  "id": {
    "oid": "5968dd23fc13ae04d9000001"
  },
  "product_name": "sildenafil citrate",
  "supplier": "Wisozk Inc",
  "quantity": 261,
  "unit_cost": "$10.47"
 },
 
 {
  "id": {
    "oid": "5968dd23fc13ae04d9000002"
  },
  "product_name": "Mountain Juniperus ashei",
  "supplier": "Keebler-Hilpert",
  "quantity": 292,
  "unit_cost": "$8.74"
 }
]

Solution

x <- list(
  list(
    id           = list(oid = "5968dd23fc13ae04d9000001"),
    product_name = "sildenafil citrate",
    supplier     = "Wisozk Inc",
    quantity     = 261,
    unit_cost    = "$10.47"
  ),
  list(
    id           = list(oid = "5968dd23fc13ae04d9000002"),
    product_name = "Mountain Juniperus ashei",
    supplier     = "Keebler-Hilpert",
    quantity     = 292,
    unit_cost    = "$8.74"
  )
)

str(x)
#> List of 2
#>  $ :List of 5
#>   ..$ id          :List of 1
#>   .. ..$ oid: chr "5968dd23fc13ae04d9000001"
#>   ..$ product_name: chr "sildenafil citrate"
#>   ..$ supplier    : chr "Wisozk Inc"
#>   ..$ quantity    : num 261
#>   ..$ unit_cost   : chr "$10.47"
#>  $ :List of 5
#>   ..$ id          :List of 1
#>   .. ..$ oid: chr "5968dd23fc13ae04d9000002"
#>   ..$ product_name: chr "Mountain Juniperus ashei"
#>   ..$ supplier    : chr "Keebler-Hilpert"
#>   ..$ quantity    : num 292
#>   ..$ unit_cost   : chr "$8.74"

Exercise 4

Problem

Write a function called get_vector_properties() that takes an atomic vector and returns the following information in the format of a list: the vector’s type, length, and element names. Hint: element names can be retrieved with function names().

get_vector_properties(c(5, 10, -5, 8, 11, 0))
#> $data_type
#> [1] "double"
#> 
#> $length
#> [1] 6
#> 
#> $names
#> NULL
get_vector_properties(c(a = "-1", b = "0", c = "1"))
#> $data_type
#> [1] "character"
#> 
#> $length
#> [1] 3
#> 
#> $names
#> [1] "a" "b" "c"

Solution

get_vector_properties <- function(x) {
  
  list(data_type = typeof(x),
       length    = length(x),
       names     = names(x)
       )
}

Exercise 5

Problem

We have seen the group membership operator %in%. Write an infix function named %!in% that returns TRUE for each component in the left operand that is not in the right operand. For example,

x <- c(4, -4, 9, 33, 1)
y <- c(1, 44, 1, 0, 33, 10, 62)

x %!in% y
#> [1]  TRUE  TRUE  TRUE FALSE FALSE

Solution

`%!in%` <- function(a, b) {
  !(a %in% b)
}
x <- c(4, -4, 9, 33, 1)
y <- c(1, 44, 1, 0, 33, 10, 62)

x %!in% y
#> [1]  TRUE  TRUE  TRUE FALSE FALSE

Exercise 6

This function requires subsetting. If you can’t get this to work, that’s okay. We’ll cover subsetting next week.

Problem

Write a function called seq_fib(). Function seq_fib() should take one argument, n - an atomic numeric vector of length 1, and return the first n Fibonacci numbers as an atomic vector. Some examples of the function in action are given below.

Valid inputs

seq_fib(n = 1)
seq_fib(n = 2)
seq_fib(n = 7)
seq_fib(n = 10)
#> [1] 0
#> [1] 0 1
#> [1] 0 1 1 2 3 5 8
#>  [1]  0  1  1  2  3  5  8 13 21 34

Invalid inputs

seq_fib(n = -2)
#> Error in seq_fib(n = -2): n >= 1 is not TRUE
seq_fib(n = c(2, 3, 10))
#> Error in seq_fib(n = c(2, 3, 10)): length(n) == 1 is not TRUE

Did you remember to handle situations such as seq_fib(n = 4.9)?

Solution

seq_fib <- function(n) {
  # check for n to be greater than or equal to 1
  stopifnot(length(n) == 1, n >= 1, n %/% 1 == n)
  
  fib.vec <- c(0, 1)
  if (n <= 2) { # n = 1 or n = 2
    fib.vec <- fib.vec[1:n]
  } else {
     for (i in 3:n) { # n >= 3
       fib.vec[i] <- fib.vec[i - 2] + fib.vec[i - 1]
     }
  }
  return(fib.vec)
}