R / CHAPTER 07
Functions and controlled iteration
IntermediateWrite reusable functions with clear scalar decisions and empty-input behavior.
By the end of this chapter
- Define and call functions
- Distinguish scalar and vector conditions
- Iterate safely over possibly empty input
The idea
An R function receives arguments in its own evaluation environment and returns the last evaluated expression unless return is used earlier. Keep its input assumptions and output shape clear. A function that produces one number should do so on every supported path, including empty input. Local working names help isolate a calculation, while returning the result lets a caller decide how to display or combine it.
An if condition must provide one nonmissing logical value. Use vectorized comparisons to create a selector, or a loop when each step needs a separate decision. seq_along(x) creates valid positions even when x is empty; the expression 1:length(x) does not. Choose && for a short-circuit scalar condition and & when you need an elementwise logical operation.
positive_total <- function(x) {
total <- 0
for (i in seq_along(x)) {
if (!is.na(x[i]) && x[i] > 0) total <- total + x[i]
}
total
}
cat(positive_total(c(4, -2, NA, 3)), "
", sep = "")
cat(positive_total(numeric(0)), "
", sep = "")7 0
The function adds the two positive known entries. For empty input, seq_along produces no positions and the initialized total is returned unchanged.
Try it yourself
Write a function returning the first index of a negative known value, or NA_integer_ when none exists.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
CHECK YOUR UNDERSTANDING