── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.2.1 ✔ readr 2.2.0
✔ forcats 1.0.1 ✔ stringr 1.6.0
✔ ggplot2 4.0.3 ✔ tibble 3.3.1
✔ lubridate 1.9.5 ✔ tidyr 1.3.2
✔ purrr 1.2.2
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
here() starts at /Users/kjhealy/Documents/courses/mptc
Example 07: Functions and Iteration
library(broom)Writing Functions
I mentioned in class that my add function didn’t have any error handling or guard clauses. Here’s an example of why it’s worth adding them.
my_adder <- function(x, add = 1) {
x + add
}
my_adder(10)[1] 11
my_adder(1:10) [1] 2 3 4 5 6 7 8 9 10 11
# This won't work
# my_adder("a")Guard clauses and error handling:
my_adder <- function(x, add = 1) {
if(!is.numeric(x)) {
return("Argument `x` must be numeric.")
}
x + add
}
my_adder("a")[1] "Argument `x` must be numeric."
my_adder <- function(x, add = 1) {
if(!is.numeric(x)) {
return("Argument `x` must be numeric.")
}
if(!is.numeric(add)) {
return("Argument `add` must be numeric.")
}
x + add
}Here I use return() in the guard clauses in order to make this example work as part of the pipeline that creates the site. But really I should use stop().
my_adder(1:10, 5) [1] 6 7 8 9 10 11 12 13 14 15
my_adder(1:10, "c")[1] "Argument `add` must be numeric."
One small point here: resist using else in clauses like this. Just use if to check a condition and if it fails, exit the function. The “happy path” is one that passes your guard clauses. Other paths should exit with an informative message.