Control Flow

Mini-Lecture 7

Ben Baumer

Smith College

2024-09-24

Slack review

CRAN content

I’m wondering what topics of R packages are CRAN material? I was looking at the list of CRAN packages, most of them seem to be statistically inclined. What other topics does CRAN tend to like?

  • CRAN doesn’t judge the content of your package
  • It only cares about whether your package is compliant
  • CRAN is still maintained by humans!!

Test files

Getting an error message when I run the check saying that there’s no test files found for my package… any suggestions?

  • You have a testthat infrastructure but no actual tests
  • usethis::use_test("something") to create one OR
  • just ignore the error for now

NextMethod()

helium <- function(x,...) {
  UseMethod("helium")
}

helium.default <- function(x,...) {
  print("hi")
}

helium.first <- function(x,...) {
  message("this is the first method")
  message(emoji::emoji("hot"))
  NextMethod()
}

helium.second <- function(x,...) {
  message("this is the second method")
  message(emoji::emoji("balloon"))
}

Method dispatch

x <- "whatever"
class(x) <- c("first", class(x))
class(x)
[1] "first"     "character"
helium(x)
this is the first method
😳
[1] "hi"
sloop::s3_dispatch(helium(x))
=> helium.first
   helium.character
-> helium.default

Method dispatch 2

class(x) <- c("first", "second", class(x))
class(x)
[1] "first"     "second"    "first"     "character"
helium(x)
this is the first method
🌭
this is the second method
🎈
sloop::s3_dispatch(helium(x))
=> helium.first
-> helium.second
 * helium.first
   helium.character
 * helium.default

Recursion?

helium.second <- function(x,...) {
  message("this is the second method")
  emoji::emoji("balloon")
  NextMethod()
}
helium(x)
this is the first method
🔥
this is the second method
this is the first method
🫠
[1] "hi"
sloop::s3_dispatch(helium(x))
=> helium.first
-> helium.second
-> helium.first
   helium.character
-> helium.default

Control Flow

Vectorized conditionals

ifelse(mtcars$am == 1, "man", "auto")
 [1] "man"  "man"  "man"  "auto" "auto" "auto" "auto" "auto" "auto" "auto"
[11] "auto" "auto" "auto" "auto" "auto" "auto" "auto" "man"  "man"  "man" 
[21] "auto" "auto" "auto" "auto" "auto" "man"  "man"  "man"  "man"  "man" 
[31] "man"  "man" 
dplyr::case_when(
  mtcars$am == 1 ~ "man", 
  mtcars$am == 0 ~ "auto"
)
 [1] "man"  "man"  "man"  "auto" "auto" "auto" "auto" "auto" "auto" "auto"
[11] "auto" "auto" "auto" "auto" "auto" "auto" "auto" "man"  "man"  "man" 
[21] "auto" "auto" "auto" "auto" "auto" "man"  "man"  "man"  "man"  "man" 
[31] "man"  "man" 

Loops

  • for \(\subset\) while \(\subset\) repeat

  • I’ve never used a repeat loop

  • I’ve very rarely used a while loop

  • I now never use for loops

  • Remember: R is vector-based, so many operations don’t require loops!

Replace for loops with map()

  • In general,
y <- list()
for (i in seq_along(x)) {
  y[[i]] <- my_fun(i) 
}
  • Can become
y <- map(x, my_fun)
  • shorter, cleaner, easier to read
  • more expressive!
  • likely more efficient (makes fewer copies)

Now

Work on

  • Lab #5: Control Flow

  • Reading quiz on Moodle by Monday night at 11:59 pm