Programming

Writing Custom Functions and Control Flow

As your scripts grow, repeating code becomes unmanageable. Custom functions and control flow (loops and conditionals) let you write reusable, organized, and readable R code.

1. Writing Your First Function

greet <- function(name) {{
  message <- paste("Hello,", name, "! Welcome to R.")
  return(message)
}}

greet("Alice")   # "Hello, Alice ! Welcome to R."

2. Default Argument Values

calculate_bonus <- function(salary, rate = 0.10) {{
  return(salary * rate)
}}

calculate_bonus(50000)        # uses default rate of 0.10
calculate_bonus(50000, 0.15)  # overrides the default

3. Multiple Return Values via a List

summarize_vector <- function(x) {{
  list(
    mean = mean(x),
    sd = sd(x),
    range = range(x)
  )
}}

result <- summarize_vector(c(4, 8, 15, 16, 23, 42))
result$mean
Pro Tip: R functions automatically return the value of the last evaluated expression, but using explicit return() improves readability, especially for early exits.

4. Conditionals — if / else

check_grade <- function(score) {{
  if (score >= 90) {{
    "A"
  }} else if (score >= 75) {{
    "B"
  }} else if (score >= 60) {{
    "C"
  }} else {{
    "F"
  }}
}}

check_grade(82)  # "B"

5. Vectorized Conditionals — ifelse()

For applying a condition across an entire vector at once (much faster than looping):

scores <- c(95, 60, 82, 45, 71)
ifelse(scores >= 60, "Pass", "Fail")
# "Pass" "Pass" "Pass" "Fail" "Pass"

6. for Loops

for (i in 1:5) {{
  cat("Iteration:", i, "\n")
}}

total <- 0
for (value in c(10, 20, 30)) {{
  total <- total + value
}}
print(total)  # 60

7. while Loops

count <- 1
while (count <= 5) {{
  cat("Count is:", count, "\n")
  count <- count + 1
}}

8. Loop Control — break and next

for (i in 1:10) {{
  if (i == 5) next    # skip this iteration
  if (i == 8) break   # exit the loop entirely
  print(i)
}}
Production Reality: R loops are often slower than vectorized operations. Before reaching for a for loop, ask: can this be done with a vectorized expression or the apply family (next lesson)?

9. Anonymous (Lambda) Functions

square <- \(x) x^2         # modern shorthand syntax (R 4.1+)
square(5)                # 25

(function(x) x * 2)(10)   # traditional anonymous function, called immediately

10. Production-Ready Checklist

  • ✅ Write functions for any repeated logic — DRY (Don't Repeat Yourself).
  • ✅ Use default arguments — for flexible, backward-compatible functions.
  • ✅ Prefer ifelse()/vectorized logic — over loops for large vectors.
  • ✅ Use break/next carefully — and document why in comments.
Pro Tip: Well-named functions are self-documenting. calculate_monthly_bonus(salary) is far clearer at a glance than an inline block of raw arithmetic.

Ready to master R Programming?

Build real-world data analysis and visualization projects with hands-on training, mentor-led sessions, and placement support.

Explore Course