Unit 02.04: One operation, whole column -- and the recycling trap
R was built for columns. Almost anything you would write a loop for in another language is one line here.
The whole column at once — and the rule that bites
A vector is a sequence of values of one type, and a data frame column is exactly that. Arithmetic applies to every element: dividing a vector by a number divides each value. Comparison does the same and gives a logical vector back, which sum() then counts, because TRUE counts as one.
The complication is recycling. When two vectors differ in length, R repeats the shorter one to match. If the lengths divide evenly it does this silently. If they do not, it warns — but still returns a result.
Recycling is deliberate and useful when the short vector has length one. At any other length it is usually an accident.
This block shows vectorised division and comparison, then triggers recycling twice.
# One operation, whole column. No loop.
visits <- c(412, 455, 388, 401, 502, 498)
cat("Each value as a rate per 1000 residents:\n")
print(round(visits / 12.4, 1))
# Vectorised comparison gives a logical vector, which sum() then counts.
busy <- visits > 450
cat("\nDays over 450:", sum(busy), "of", length(visits), "\n")
# The recycling rule is the trap. R repeats the shorter vector silently
# when the lengths divide, and only warns when they do not.
staff <- c(3, 4)
cat("\nvisits / c(3, 4) recycles the 2 across the 6:\n")
print(round(visits / staff, 1))
result <- withCallingHandlers(
visits + c(1, 2, 3, 4),
warning = function(w) {
cat("\nWarning raised:", conditionMessage(w), "\n")
invokeRestart("muffleWarning")
}
)
cat("It still returned a result:", paste(result, collapse = " "), "\n")
Six visit counts become six rates in one operation, and sum(busy) reports 3 of 6 days over 450. Dividing by a length-2 vector recycles it three times with no warning at all — the output looks entirely reasonable and is meaningless. Adding a length-4 vector does warn, and the warning message is printed here, yet the result still comes back: 413 457 391 405 503 500.
The mistake this prevents
The mistake is a length mismatch that happens to divide evenly. R says nothing, the numbers look plausible, and the error can survive all the way into a published table.
Takeaway
Prefer vectorised operations to loops. Before combining two vectors, check they are the same length or that one has length one — and treat a recycling warning as an error, because a result was still returned.
