Skip to main content
R Programming
CHAPTER 07 Beginner

Functions in R

Updated: May 18, 2026
5 min read

# CHAPTER 7

Functions in R

1. Chapter Introduction

Functions are the core unit of reusability in R. This chapter covers function creation, argument handling, return values, anonymous functions, closures, and the apply family — the tools that make R programs clean, modular, and fast.

2. Creating Functions

r
1234567891011121314151617181920212223242526272829303132333435
# Basic function syntax
function_name <- function(arg1, arg2, ...) {
  # Function body
  result <- arg1 + arg2
  return(result)  # Explicit return
}

# Simple example
add <- function(x, y) {
  x + y  # Implicit return: last expression returned automatically
}
add(3, 7)   # 10

# Function with default arguments
greet <- function(name, greeting = "Hello", punctuation = "!") {
  cat(paste0(greeting, ", ", name, punctuation, "\n"))
}
greet("Alice")                     # Hello, Alice!
greet("Bob", "Good morning", ".") # Good morning, Bob.
greet(greeting = "Hi", name = "Carol")  # Named arguments, any order

# Multiple return values (use list)
stats_summary <- function(x) {
  list(
    mean   = mean(x),
    median = median(x),
    sd     = sd(x),
    min    = min(x),
    max    = max(x),
    n      = length(x)
  )
}
scores <- c(75, 82, 91, 68, 55, 88, 79)
result <- stats_summary(scores)
cat("Mean:", result$mean, "SD:", round(result$sd, 2), "\n")

3. Variable Arguments with ...

r
1234567891011121314151617181920212223
# ... (ellipsis) captures variable number of arguments
my_sum <- function(...) {
  args <- c(...)
  sum(args)
}
my_sum(1, 2, 3)        # 6
my_sum(10, 20, 30, 40) # 100

# Pass ... to another function
my_plot <- function(x, y, ...) {
  plot(x, y, pch=19, col="blue", ...)  # Extra args passed to plot()
}
# This allows users to pass main="Title", xlab="X" without hardcoding

# Checking arguments
calculate_discount <- function(price, discount_pct, min_price = 0) {
  stopifnot(is.numeric(price), price > 0)
  stopifnot(discount_pct >= 0, discount_pct <= 100)
  discounted <- price * (1 - discount_pct / 100)
  max(discounted, min_price)  # Cannot go below min_price
}
calculate_discount(1000, 20)      # 800
calculate_discount(1000, 20, 850) # 850 (floor applied)

4. Anonymous Functions

r
12345678910111213141516
# Anonymous function (lambda) — used without naming
(function(x) x^2)(5)   # 25

# In apply family
sapply(1:5, function(x) x^2)  # 1 4 9 16 25

# R 4.1+ shorthand: \(x) instead of function(x)
sapply(1:5, \(x) x^2)  # 1 4 9 16 25

# Practical: apply custom discount per product category
prices <- c(Laptop=1200, Phone=800, Tablet=450, Headphones=150)
discounts <- c(Laptop=0.15, Phone=0.10, Tablet=0.12, Headphones=0.20)
final <- mapply(\(p, d) p * (1 - d), prices, discounts)
print(round(final, 2))
# Laptop    Phone   Tablet Headphones
# 1020.00  720.00   396.00   120.00

5. Apply Family

r
12345678910111213141516171819202122
# sapply() — simplify result (preferred for vectors)
sapply(1:6, function(x) x^2)   # 1 4 9 16 25 36

# lapply() — always returns list
lapply(1:3, function(x) x * 10)  # list of 10, 20, 30

# apply() — apply over matrix margins
m <- matrix(1:12, nrow=3)
apply(m, 1, sum)  # Row sums
apply(m, 2, sum)  # Col sums

# tapply() — apply by groups
salaries <- c(75000, 85000, 62000, 90000, 55000, 78000)
depts    <- c("IT",  "IT",  "HR",  "IT",  "HR",  "Finance")
tapply(salaries, depts, mean)
# Finance      HR      IT
#   78000   58500   83333

# vapply() — type-safe sapply (specifies return type)
vapply(c("hello", "world"), nchar, integer(1))
# hello world
#     5     5

6. Common Mistakes

  • Modifying global variables inside functions: R uses lexical scoping with copy-on-modify. Functions get copies of arguments; use <<- only when you truly need global side effects (rare).
  • Forgetting return() in complex conditionals: R returns the last evaluated expression — but in if/else branches, this can be surprising. Use explicit return() in functions with multiple exit paths.

7. MCQs

Question 1

R function implicit return is?

Question 2

Default argument f(x, n=10) can be overridden by?

Question 3

... (ellipsis) in function arguments?

Question 4

sapply() returns?

Question 5

tapply(x, group, FUN) applies FUN?

Question 6

\(x) x^2 in R 4.1+ is?

Question 7

Multiple return values in R use?

Question 8

stopifnot() is for?

Question 9

mapply(FUN, ...) applies FUN?

Question 10

Lexical scoping in R means?

8. Interview Questions

  • Q: What is the difference between sapply(), lapply(), and vapply()?
  • Q: What is a closure in R?

9. Summary

Functions in R: function(args) { body }, implicit last-expression return. Default args with arg=value. Variable args with .... Multiple returns via list. Apply family: sapply() (simplify), lapply() (list), apply() (margins), tapply() (groups), mapply() (multivariate). R 4.1+ anonymous shorthand: \(x). Use stopifnot() for validation. R uses lexical scoping — functions see variables from where they were defined.

10. Next Chapter Recommendation

In Chapter 8: Vectors in R, we master R's most fundamental data structure — the atomic vector — and its powerful vectorized operations.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·