# A tibble: 3 × 2
fundraiser constituent
<chr> <chr>
1 Carol Charles Dickens
2 Bob Victor Hugo
3 Rachel Jane Austen
I use a series of scripts to generate regular reports, and I often want the process to pause at key points—either to check progress or to flag issues that need my attention. One common example involves a lookup table that maps each fundraiser to their team. I append that team information to my reports so I can easily segment the data by team and individual fundraiser.
But what happens when something changes? A new team member joins and isn’t in the lookup table yet. Someone gets married and their last name changes. Suddenly, that person is no longer associated with the correct team, and the report quietly becomes wrong. Here’s how I catch those issues before they slip through.
Build the Data
Portfolio
Lookup Table
Join the Data
Now, let’s see what happens when I join lookup to df.
# A tibble: 3 × 3
fundraiser constituent team
<chr> <chr> <chr>
1 Carol Charles Dickens Major Giving
2 Bob Victor Hugo <NA>
3 Rachel Jane Austen Annual Giving
If I wasn’t paying attention, I might keep going, produce a beautifully formatted report, save it to Excel, and only then realize that Bob isn’t connected with a team.
Stopping the Script
There are a few ways to have R stop the script. The basic structure is if a condition exists, then do something. Here, we check for empty strings or NA’s in the data and, if they’re found, stop and display the message.
Error:
! Someone is missing a team. Does the lookup table need to be updated?
This is a simple way to throw an error if something doesn’t look right, but we can take it a step further by listing the names of the fundraisers who are missing a team.
Error:
! These fundraisers have no team: Bob
Wrapping it in a Function
It is conceiveable that we might want to run similar checks on other columns in the data. Here is a function that does the same process, but wrapped in a more flexible package that can be pointed at any data set, name column, and target column.
check_missing <- function(data, name_col, target_col) {
# Convert column names to symbols
name_col <- rlang::ensym(name_col)
target_col <- rlang::ensym(target_col)
# Identify rows where the target column is blank or NA
missing_rows <- data |>
dplyr::filter(is.na(!!target_col) | !!target_col == "") |>
dplyr::pull(!!name_col)
# If any are missing, stop with a helpful message
if(length(missing_rows) > 0) {
stop(
paste(
"These entries have missing values in", rlang::as_string(target_col), "-", paste(missing_rows, collapse = ", ")
)
)
}
invisible(TRUE)
}check_missing(df, fundraiser, team)Error in `check_missing()`:
! These entries have missing values in team - Bob
