Solutions

Exercise #1

Create a Custom Function with Conditions

grade_score <- function(score, max_score = 100){
  stopifnot(is.numeric(score))
  stopifnot(score >= 0, score <= max_score)

  # Convert to percent in case max_score is not 100
  pct <- (score / max_score) * 100

  if (pct >= 90){
    grade <- "A"
  } else if (pct >= 80){
    grade <- "B"
  } else if (pct >= 70){
    grade <- "C"
  } else {
    grade <- "F"
  }

  grade
}

grade_score(95)
grade_score(72)
# grade_score(150)  # Uncomment to see the error

Bonus: return multiple values in a list

grade_score2 <- function(score, max_score = 100){
  stopifnot(is.numeric(score))
  stopifnot(score >= 0, score <= max_score)

  pct <- (score / max_score) * 100

  if (pct >= 90){
    grade <- "A"
    msg <- "Excellent work."
  } else if (pct >= 80){
    grade <- "B"
    msg <- "Good job."
  } else if (pct >= 70){
    grade <- "C"
    msg <- "Passing, but room to improve."
  } else {
    grade <- "F"
    msg <- "Not passing yet—review and try again."
  }

  list(grade = grade, percent = pct, message = msg)
}

grade_score2(88)

Exercise #2

Write a Loop with a Condition

for (i in 1:20){
  if (i %% 3 == 0 && i > 10){
    print(i)
  }
}

Bonus: print a message instead of the number

for (i in 1:20){
  if (i %% 3 == 0 && i > 10){
    print("Divisible by 3")
  }
}

Bonus: using ifelse()

x <- 1:20
out <- ifelse(x %% 3 == 0 & x > 10, x, NA)
out[!is.na(out)]

Bonus: using sapply()

x <- 1:20
sapply(x, function(i){
  if (i %% 3 == 0 && i > 10) print(i)
})

Optional Challenge (Advanced)

Apply Function Practice

m <- matrix(1:25, nrow = 5)
m

# Row means and column sums using apply()
apply(m, 1, mean)
apply(m, 2, sum)

# Compare to built-ins
rowMeans(m)
colSums(m)

Extra Challenge: list + lapply/sapply

set.seed(1)
lst <- list(a = rnorm(5), b = rnorm(10), c = rnorm(3))

lapply(lst, sd)
sapply(lst, sd)