5.3 Example: List
Consider the following question from Homework 7.
Part 1: Coding Assignment
- (Public Question) Create a table called
crime_race_counts
that shows the number of crimes along with the percentage of crimes that were committed against victims of each race invictim_race
. Your percentages should be out of 100 and rounded to one decimal place. You should remove any rows that do not record the victim’s race.
The answer should look something like:
crime_race_counts <- crimeData_clean |>
filter(!is.na(vict_race)) |>
tabyl(vict_race) |>
adorn_pct_formatting()
Assume this question is worth 10 points and that crimeData_clean
was created in Question 1.
Then, the autograder code for this question could look like:
#Complete Autograder Code for Part 1 Question 3----------
#Initializing `test.results[3, ]`
test.results[3, ] <- c("Part 1 Question 3 (Public)", 0, 10, "Try again. Hint: Look at the function `janitor::tabyl()`.")
#Prerequisite Check
if(test.results[1, 2] == 0){
test.results[3, 4] <- "This question depends on Question 1 being correct. Try again."
#Name Check
} else if(is.error(crime_race_counts)){
test.results[3, 4] <- "`crime_race_counts` is not found. Please make sure the variable is named correctly."
#Structure Check (for a list)
} else if(!is.list(crime_race_counts)){
test.results[3, 4] <- "`crime_race_counts` is not a list. Make sure it is a list. Hint: Look at the function `janitor::tabyl()`."
#Named List Check (i.e., to make sure the list is named)
} else if(is.null(names(crime_race_counts))){
test.results[3, 4] <- "`crime_race_counts` has no names. Make sure it has names. Hint: Look at the function `janitor::tabyl()`."
#NA Check
} else if(NA %in% crime_race_counts$vict_race){
test.results[3, 4] <- "The column `vict_race` contains `NA` values. Remember to remove any rows which do not record the victim’s race."
#List Name Check (i.e., Column Name Check for a list)
} else if(!all(names(crime_race_counts_test) %in% names(crime_race_counts))){
test.results[3, 4] <- paste0(paste0(c("The following column name(s) should be in `crime_race_counts`, but they were not found in your answer:",
names(crime_race_counts_test)[!(names(crime_race_counts_test) %in% names(crime_race_counts))]),
collapse = " "), ". Hint: Look at the function `janitor::tabyl()`.")
} else if(!all(names(crime_race_counts) %in% names(crime_race_counts_test))){
test.results[3, 4] <- paste0(paste0(c("The following column name(s) should not be in `crime_race_counts`, but they were found in your answer:",
names(crime_race_counts)[!(names(crime_race_counts) %in% names(crime_race_counts_test))]),
collapse = " "), ". Hint: Look at the function `janitor::tabyl()`.")
#Expression Check (for % symbol)
} else if(any(!str_detect(crime_race_counts$percent, "%"))){
test.results[3, 4] <- "The `percent` column should be formatted as a percentage. Hint: Look at the function `janitor::adorn_pct_formatting()`."
#Expression Check (for 1 decimal place)
} else if(any(str_detect(crime_race_counts$percent, "\\.\\d{2,}"))){
test.results[3, 4] <- "The `percent` column should be formatted by 1 decimal place. Hint: Look at the argument `digits` in `janitor::adorn_pct_formatting()` (note its default value)."
#Row & Column Check (note: the Column Check is redundant here)
} else if(nrow(crime_race_counts) != nrow(crime_race_counts_test)){
test.results[3, 4] <- "`crime_race_counts` has the incorrect number of rows. Hint: Look at the `janitor::tabyl()` function."
} else if(ncol(crime_race_counts) != ncol(crime_race_counts_test)){
test.results[3, 4] <- "`crime_race_counts` has the incorrect number of columns. Hint: Look at the `janitor::tabyl()` function."
#Correct Check
} else if(isTRUE(all.equal(crime_race_counts |> ungroup() |>
select(names(crime_race_counts_test)) |>
arrange(across(everything())),
crime_race_counts_test |> ungroup() |>
select(names(crime_race_counts_test)) |>
arrange(across(everything())),
tolerance = 0.001,
check.attributes = F))){
test.results[3, 2] <- 10
test.results[3, 4] <- "Well done!"
}