Function Definition
In R, functions are defined using the function() keyword and can be reused by assigning them to a variable. Setting default values for arguments and using named arguments when calling functions makes code more readable and flexible.
Syntax
# -----------------------------------------------
# Basic function definition
# -----------------------------------------------
# Define a function with function() and assign it to a variable
func_name <- function(arg1, arg2) {
# body
return(return_value) # explicitly specify the return value
}
# -----------------------------------------------
# Default arguments
# -----------------------------------------------
# Set a default value for an argument (can be omitted when calling)
func_name <- function(arg1, arg2 = default_value) {
# When arg2 is omitted, the default value is used
}
# -----------------------------------------------
# Calling with named arguments
# -----------------------------------------------
# Specifying argument names allows passing in any order
func_name(arg2 = valueB, arg1 = valueA)
# -----------------------------------------------
# Multiple return values (return as a list)
# -----------------------------------------------
# R cannot return multiple values directly, so use list()
func_name <- function(arg) {
return(list(result1 = value1, result2 = value2))
}
Syntax / Function Reference
| Syntax / Function | Description |
|---|---|
f <- function(x) { ... } | Defines a function named f with x as its argument. |
return(value) | Explicitly specifies the return value and ends the function. If omitted, the last evaluated expression is returned. |
function(x = default_value) | Sets a default value for an argument. If omitted at call time, the default is used. |
f(arg_name = value) | Calls the function with named arguments. Arguments can be passed in any order. |
missing(arg_name) | Returns TRUE / FALSE indicating whether the argument was omitted at call time. |
list(name = value, ...) | Used when returning multiple values. Access with $name or [["name"]] at the call site. |
invisible(value) | Returns a value but suppresses automatic display to the console. Commonly used in functions with side effects. |
do.call(f, list) | Dynamically calls a function using an argument list. |
Sample Code
kof_function_basic.R
# kof_function_basic.R — sample to explore function definition and calls
# Uses THE KING OF FIGHTERS character data
# to check basic function definition, default arguments, and named arguments
# -----------------------------------------------
# Basic function definition and call
# -----------------------------------------------
# Define a function that builds an intro message for a character
introduce <- function(name, team) {
message <- paste0(name, " (", team, " Team) enters the tournament.")
return(message)
}
cat("=== THE KING OF FIGHTERS ===\n\n")
cat("--- Basic function call ---\n")
# Positional arguments — values are passed in the order of definition
cat(introduce("Terry Bogard", "Fatal Fury"), "\n")
cat(introduce("Robert Garcia", "Art of Fighting"), "\n")
cat("\n")
# -----------------------------------------------
# Default arguments
# -----------------------------------------------
# A function that evaluates a fighter and returns a message
# rank_label has a default value set
evaluate_fighter <- function(name, power, rank_label = "Rank B") {
# Override rank_label if power >= 90 (Rank S) or >= 80 (Rank A)
if (power >= 90) {
rank_label <- "Rank S"
} else if (power >= 80) {
rank_label <- "Rank A"
}
# Return a formatted string
return(sprintf(" %-24s Power: %3d Rating: %s", name, power, rank_label))
}
cat("--- Default argument (rank_label defaults to 'Rank B') ---\n")
# Omitting rank_label uses "Rank B"
cat(evaluate_fighter("Vanessa", 75), "\n") # default -> Rank B
# power exceeds the threshold so rank_label is overridden
cat(evaluate_fighter("Kyo Kusanagi", 92), "\n") # -> Rank S
cat(evaluate_fighter("Iori Yagami", 88), "\n") # -> Rank A
# rank_label can also be specified explicitly
cat(evaluate_fighter("Kula Diamond", 78, "Special"), "\n")
cat("\n")
# -----------------------------------------------
# Named arguments
# -----------------------------------------------
# A function to record match results (verify argument order)
match_result <- function(winner, loser, round, perfect = FALSE) {
prefix <- if (perfect) "[PERFECT] " else ""
return(sprintf(" %sRound %d: %s defeats %s", prefix, round, winner, loser))
}
cat("--- Named arguments (arguments can be passed in any order) ---\n")
# Standard positional argument call
cat(match_result("Kyo Kusanagi", "Iori Yagami", 1), "\n")
# Named arguments passed in a different order
cat(match_result(loser = "Terry Bogard", winner = "Vanessa", round = 2), "\n")
# perfect flag specified with a named argument
cat(match_result("Kula Diamond", "Robert Garcia", round = 3, perfect = TRUE), "\n")
cat("\n")
# -----------------------------------------------
# Multiple return values (using list)
# -----------------------------------------------
# A function that computes stats for a character and returns them as a list
calc_stats <- function(name, scores) {
# Combine multiple results into a list and return
return(list(
name = name,
total = sum(scores),
average = mean(scores),
best = max(scores),
wins = sum(scores >= 80)
))
}
cat("--- Multiple return values (return as list) ---\n")
# Match scores for each character
kyo_scores <- c(95, 88, 72, 91, 85)
iori_scores <- c(89, 94, 83, 78, 90)
# Call the function and receive the result list
kyo_stats <- calc_stats("Kyo Kusanagi", kyo_scores)
iori_stats <- calc_stats("Iori Yagami", iori_scores)
# Access each list element with $
for (stats in list(kyo_stats, iori_stats)) {
cat(sprintf(" %s: total=%d avg=%.1f best=%d wins(>=80)=%d\n",
stats$name,
stats$total,
stats$average,
stats$best,
stats$wins))
}
cat("\n")
# -----------------------------------------------
# Detecting omitted arguments with missing()
# -----------------------------------------------
# A function that uses a default move when special_move is omitted
announce_move <- function(name, special_move) {
if (missing(special_move)) {
# Handling when the argument was not passed
special_move <- "(no move registered)"
}
cat(sprintf(" %s's special move: %s\n", name, special_move))
}
cat("--- Detect omitted arguments with missing() ---\n")
announce_move("Kyo Kusanagi", "Yami Barai") # specify the move
announce_move("Terry Bogard", "Power Wave") # specify the move
announce_move("Vanessa") # omitted -> default message
cat("\n")
# -----------------------------------------------
# Passing a function as an argument (higher-order function)
# -----------------------------------------------
# A higher-order function that accepts an evaluation function as an argument
apply_evaluation <- function(fighters, eval_func) {
results <- character(length(fighters))
for (i in seq_along(fighters)) {
# Apply the passed evaluation function to each element
results[i] <- eval_func(fighters[[i]]$name, fighters[[i]]$power)
}
return(results)
}
# Prepare the roster to evaluate
roster <- list(
list(name = "Kyo Kusanagi", power = 92),
list(name = "Iori Yagami", power = 88),
list(name = "Terry Bogard", power = 85),
list(name = "Robert Garcia", power = 79),
list(name = "Kula Diamond", power = 81)
)
# Define an anonymous function that returns only the rank, then pass it
rank_only <- function(name, power) {
rank <- if (power >= 90) "S" else if (power >= 80) "A" else "B"
return(sprintf(" %-24s -> Rank %s", name, rank))
}
cat("--- Passing a function as an argument (higher-order function) ---\n")
evaluations <- apply_evaluation(roster, rank_only)
for (line in evaluations) {
cat(line, "\n")
}
cat("\n")
Rscript kof_function_basic.R === THE KING OF FIGHTERS === --- Basic function call --- Terry Bogard (Fatal Fury Team) enters the tournament. Robert Garcia (Art of Fighting Team) enters the tournament. --- Default argument (rank_label defaults to 'Rank B') --- Vanessa Power: 75 Rating: Rank B Kyo Kusanagi Power: 92 Rating: Rank S Iori Yagami Power: 88 Rating: Rank A Kula Diamond Power: 78 Rating: Special --- Named arguments (arguments can be passed in any order) --- Round 1: Kyo Kusanagi defeats Iori Yagami Round 2: Vanessa defeats Terry Bogard [PERFECT] Round 3: Kula Diamond defeats Robert Garcia --- Multiple return values (return as list) --- Kyo Kusanagi: total=431 avg=86.2 best=95 wins(>=80)=4 Iori Yagami: total=434 avg=86.8 best=94 wins(>=80)=4 --- Detect omitted arguments with missing() --- Kyo Kusanagi's special move: Yami Barai Terry Bogard's special move: Power Wave Vanessa's special move: (no move registered) --- Passing a function as an argument (higher-order function) --- Kyo Kusanagi -> Rank S Iori Yagami -> Rank A Terry Bogard -> Rank A Robert Garcia -> Rank B Kula Diamond -> Rank A
Overview
R functions are defined with the function() keyword and assigned to a variable. The return value is either specified explicitly with return(), or the last evaluated expression is returned automatically. Setting default values for arguments makes them optional at call time, and missing() can detect whether an argument was omitted. Named arguments allow passing values in any order, which is especially useful for functions with many parameters. When multiple values need to be returned, pack them into a list() and access them at the call site with $name. Because functions can be stored as objects in variables and passed as arguments to other functions (higher-order functions), they combine well with vectorized operations such as sapply() and lapply() for concise code. For further applications of functions, see for loops and List Basics.
Common Mistakes
Omitting return and having the last assignment expression become the return value
R functions return the value of the last evaluated expression. When an assignment expression such as result <- calculation() is last, the value of the assignment (the assigned value itself) is returned. Values can be returned unintentionally this way.
function_return_implicit.R
# When an assignment expression is last, the assigned value is returned
get_power <- function(name) {
power_table <- c("Son Goku" = 9001, "Vegeta" = 7500)
result <- power_table[name] # this result is returned
}
val <- get_power("Son Goku")
cat("Returned:", val, "\n") # 9001 is returned
# Using return() makes the intent explicit
get_power_explicit <- function(name) {
power_table <- c("Son Goku" = 9001, "Vegeta" = 7500)
return(power_table[name])
}
Returned: 9001
Failing to correctly pass ... (variadic arguments) to an inner function
... is used to pass variadic arguments to another function. To expand and pass the contents of ..., use ... as-is.
function_dots.R
# Use ... to pass extra arguments to mean()
average_power <- function(values, ...) {
mean(values, ...)
}
powers <- c(9001, NA, 7500, 8200)
cat("With NA:", average_power(powers), "\n")
cat("Without NA:", average_power(powers, na.rm = TRUE), "\n")
With NA: NA Without NA: 8233.667
If you find any errors or copyright issues, please contact us.