Learn Without Walls
← Back to R Practice Labs
Lab 4 of 10

Functions & Control Flow

Writing reusable, intelligent R code

← Lab 3: dplyr Lab 4 of 10 Lab 5: Strings →
⏳ Loading R... (first load takes ~15 seconds)

📖 Concept Recap

Functions are the building blocks of reusable R code. Control flow lets your code make decisions and repeat actions.

R returns the last expression in a function automatically — no explicit return() needed (though you can use it for early returns).

👀 Worked Example

A function with input validation, default arguments, and a named list return:

calculate_stats <- function(x, na.rm = TRUE) { if (!is.numeric(x)) stop("Input must be numeric") list( n = length(x), mean = mean(x, na.rm = na.rm), median = median(x, na.rm = na.rm), sd = sd(x, na.rm = na.rm), range = range(x, na.rm = na.rm) ) } scores <- c(88, 92, 75, 95, 84, 91, 78, NA) stats <- calculate_stats(scores) cat("N:", stats$n, "\n") cat("Mean:", round(stats$mean, 2), "\n") cat("Median:", stats$median, "\n") cat("SD:", round(stats$sd, 2), "\n")
✏️ Guided

Exercise 1 — Grade Converter

Complete the score_to_grade() function using if/else, then test it on a vector of scores with sapply().

Output will appear here...
💡 Hint: sapply(vector, function_name) applies the function to each element and returns a vector of results. table() counts how many times each unique value appears.
💪 Independent

Exercise 2 — Vector Descriptor

Write a function describe_vector(x) that prints: N, mean, range (min–max), standard deviation, and count of outliers (values more than 2 SD from the mean). Test it on three different numeric vectors.

Output will appear here...
💡 Hint: Outliers: sum(abs(x - mean(x)) > 2 * sd(x)). Use cat() to format output. Range: range(x) returns a 2-element vector — use range(x)[1] and range(x)[2] for min and max.
🔥 Challenge

Exercise 3 — FizzBuzz & Higher-Order Functions

Part A: Write fizzbuzz_r(n) that returns a character vector of length n: “FizzBuzz” for multiples of 15, “Fizz” for 3, “Buzz” for 5, otherwise the number as a string. Part B: Write run_multiple(fn, values) that applies fn to each element of values and prints the results. Use it to call fizzbuzz_r on c(10, 20, 30).

Output will appear here...
💡 Hint: Use ifelse() vectorized: ifelse(x %% 15 == 0, "FizzBuzz", ifelse(x %% 3 == 0, "Fizz", ...)). For run_multiple, use for (v in values) or lapply(values, fn).
🏆 Mini Project — Analysis Toolkit

Build a 4-Function Analysis Toolkit

Write and test all four functions below, then demonstrate them working together on a sample dataset.

  1. clean_vector(x) — removes NAs and values > 3 SD from the mean, returns cleaned vector
  2. compare_groups(data, group_col, value_col) — returns a data frame with mean, sd, and n per group
  3. flag_outliers(x) — returns a logical vector: TRUE where value is > 2 SD from mean
  4. full_report(x, label) — prints a formatted report using the other functions
Output will appear here...
💡 Hint: Functions can call other functions you defined earlier in the same script. Build and test each function individually before combining them in full_report().

✅ Lab 4 Complete!

You can now write reusable, intelligent R functions with input validation, default arguments, control flow, and the apply family. These skills transform scripts into maintainable analysis tools.

Continue to Lab 5: String Manipulation →

← Lab 3: dplyr Lab 4 of 10 Lab 5: Strings →