R - 函数
R 语言:函数
Section titled “R 语言:函数”函数是执行特定任务的可重用代码块。在 R 语言中,函数是一等公民对象,这意味着你可以像使用任何其他变量一样使用它们。使用函数对于编写整洁、高效且易于维护的代码至关重要。
你可以使用 function 关键词创建 R 函数。基本语法如下:
function_name <- function(argument_1, argument_2, ...) { # 要执行的代码(函数体) return_value # 最后求值的表达式会自动返回}函数组成部分
Section titled “函数组成部分”- 函数名称:你用来调用函数的名称(例如,
function_name)。它作为对象存储在 R 环境中。 - 参数(Arguments):传递给函数的数据的占位符。它们可以有默认值,从而变为可选。
- 函数体(Function Body):定义函数执行操作的一系列 R 语句。
- 返回值(Return Value):函数的结果。在 R 中,函数内部最后求值的表达式的值会自动返回。你也可以显式使用
return()。
最佳实践:纯函数
Section titled “最佳实践:纯函数”一个纯函数是指,对于相同的输入,它总是返回相同的输出,并且没有可观察的副作用(例如打印到控制台或修改全局变量)。尽可能编写纯函数是一种最佳实践,因为它们更易于测试和理解。
让我们重构原始示例以遵循此原则。我们的函数将返回一个平方数的向量,而不是在循环内部打印平方值(这是一个副作用)。
# 一个用户定义函数,用于计算数字序列的平方。# 这是一个“纯”函数:它返回一个值且没有副作用。calculate_squares <- function(n) { # 输入验证:检查 n 是否是单个正整数 if (!is.numeric(n) || length(n) != 1 || n < 1) { stop("Argument 'n' must be a single positive integer.") } # 'sapply' 函数是 R 中对向量应用函数的一种更符合习惯的方式 sapply(1:n, function(x) x^2)}
# 调用函数并存储结果squared_numbers <- calculate_squares(6)
# 现在,打印结果(副作用在函数外部)print(squared_numbers)当我们执行上述代码时,它会产生一个整洁的向量作为输出:
[1] 1 4 9 16 25 36参数匹配:按位置和按名称
Section titled “参数匹配:按位置和按名称”你可以通过参数的位置或显式命名它们来向函数提供参数。命名参数通常更清晰且不易出错。
# 一个具有多个参数的简单函数calculate_result <- function(a, b, c) { result <- a * b + c return(result)}
# 按位置调用 (5*3 + 11)print(calculate_result(5, 3, 11))
# 按名称调用(顺序无关紧要)print(calculate_result(c = 3, a = 11, b = 5))这会产生以下结果:
[1] 26[1] 58你可以为参数提供默认值,使它们在函数被调用时成为可选。
# 一个带默认参数的函数create_greeting <- function(name, greeting = "Hello") { paste(greeting, name, sep = ", ")}
# 调用函数,使用默认问候语print(create_greeting("Alice"))
# 调用函数,覆盖默认值print(create_greeting("Bob", greeting = "Goodbye"))这会产生以下结果:
[1] "Hello, Alice"[1] "Goodbye, Bob"现代用法:管道操作符
Section titled “现代用法:管道操作符”管道操作符 %>%(来自 magrittr 包,或 R 4.1+ 中原生的 |>)是一个强大的工具,可以提高代码的可读性。它将左侧表达式的结果作为第一个参数传递给右侧的函数。
library(magrittr) # 或 library(dplyr)
# 不使用管道print(round(mean(1:10)))
# 使用管道:读起来像一句话“取 1:10,然后求均值,然后四舍五入,然后打印”1:10 %>% mean() %>% round() %>% print()两个表达式产生相同的结果,但管道版本对于复杂的操作链通常更容易理解。
[1] 6[1] 6进一步学习:函数式编程
Section titled “进一步学习:函数式编程”R 是一种非常适合函数式编程的语言。tidyverse 中的 purrr 包提供了一套完整且一致的工具,用于处理函数和向量。这是掌握基础知识后的绝佳下一步。例如,purrr::map() 是 loops 或 sapply() 的强大替代方案。