3.11 Calculation Check (S)
Purpose: Checks whether the values in a numeric column of the student’s tibble have been scaled correctly.
Motivation: Some questions involve the multiplying of a column by a certain factor or formula (e.g., 1000
, the log()
function, Fahrenheit to Celsius conversion). This Check detects a specific, improper scale for a column (e.g., accidentally inverting a formula) and can hint at its correct transformation.
#Calculation Check Examples
#Example 1: Checking if a column is unscaled (it should have been scaled by 1000)
else if(isTRUE(all.equal((variable_name$column_name * 1000) |> sort(na.last = T),
variable_name_test$column_name |> sort(na.last = T),
tolerance = 0.001,
check.attributes = F))){
test.results[2, 4] <- "The values of `column_name` are incorrect. Hint: Did you scale this column by 1000? (Any additional feedback as needed.)"
}
#Example 2: Checking if a column inversely applied a subtraction formula
else if(isTRUE(all.equal((variable_name$column_name * -1) |> sort(na.last = T),
variable_name_test$column_name |> sort(na.last = T),
tolerance = 0.001,
check.attributes = F))){
test.results[2, 4] <- "The values of `column_name` are incorrect. Hint: Did you flip the subtraction formula when calculating this column? (Any additional feedback as needed.)"
}
Technicals
Since the Calculation Check assumes that the student’s answer has the correct column name, it is essential that the Column Name Check is placed beforehand.
This Check also relies on the student’s column being numeric, so the numeric Type Check should be placed before as well.
- For instance, in Example 1, the column must be numeric for this line
variable_name$column_name * 1000
to work.
This is a subset of the Value Check. That is, if the Calculation Check is triggered, so too will the Value Check (but not the other way around).
Thus, for the Calculation Check to be effective, it should be placed before the Value Check (if both are implemented). In tandem, the Calculation Check first alerts the student to the use of a specific, improper scale (e.g., an unscaled column), then the Value Check alerts them to whether they have used any improper scale. In this way, the feedback can be more personalized.
- For example, what if a column conversion has multiple steps? Using both Checks can allow us to target our feedback more effectively.
Alternatively, the Calculation Check can be implemented within the Value Check, as shown below.
#Calculation Check combined with Value Check Example (with example hints)
#Value Check
else if(!isTRUE(all.equal(variable_name$column_name |> sort(na.last = T), variable_name_test$column_name |> sort(na.last = T)))){
#Calculation Check
if(isTRUE(all.equal((variable_name$column_name / 100) |> sort(na.last = T),
variable_name_test$column_name |> sort(na.last = T), tolerance = 0.001))){
test.results[2, 4] <- "The values of `column_name` are incorrect. Hint: Did you convert `column_name` to percentage format?"
}
else{
test.results[2, 4] <- "The values of `column_name` are incorrect. Hint: (a) Look at the function `lead()`. (b) Did you use the appropriate `.by` argument when constructing `column_name`?"
}
}
Please note that the Calculation Check does not have to be implemented alongside the Value Check, however, its scope is far more limited.