何时决定使用括号调用 R 函数与不使用括号调用 R 函数

AJA*_*JAY 4 r

我正在学习 R。为什么 R 中的函数有时会用括号调用,比如 say myfunction()vs 有时调用时不带括号myfunction

我如何知道何时使用括号跟注而不使用括号?

我在 tidyverse 中看到很多没有括号的函数调用

All*_*ron 12

在 R 中,您可以将函数视为对象。该对象有两个组件:函数接受的参数(称为形式,以及大括号内的实际代码(称为函数体)

例如,让我们定义一个简单的函数,名为f

f <- function(x) { x + 1 }
Run Code Online (Sandbox Code Playgroud)

如果我们只是f在控制台中键入不带括号的内容,我们就可以看到这个新对象的形式和主体f

f
#> function(x) { x + 1 }
#> <bytecode: 0x000001f8dc3e3f50>
Run Code Online (Sandbox Code Playgroud)

我们可以通过执行以下操作来单独查看其形式:

f
#> function(x) { x + 1 }
#> <bytecode: 0x000001f8dc3e3f50>
Run Code Online (Sandbox Code Playgroud)

及其身体通过这样做:

formals(f)
#> $x

Run Code Online (Sandbox Code Playgroud)

所以函数实际上只是一个对象。但通常我们想使用该函数为我们做一些计算。我们通过调用来使用函数。这意味着我们为形式中的参数赋予一些值,这些值用于体内的计算。

当我们调用 函数时,通常将变量放在函数名称后面的括号中:

body(f)
#> {
#>     x + 1
#> }
Run Code Online (Sandbox Code Playgroud)

但这不是调用函数的唯一方法。我们可以为 R 提供函数名称和我们希望传递给它的参数,do.call例如:

f(1)
#> [1] 2
Run Code Online (Sandbox Code Playgroud)

我们甚至可以将调用构建为函数名称和参数的列表,然后让 R 直接对其求值:

eval(as.call(list(f, x = 1)))
#> [1] 2
Run Code Online (Sandbox Code Playgroud)

但最常见的方法是简单地将括号和参数放在函数名称后面。R 解析器将其识别为“使用这些参数调用该函数”的意思。请注意,该函数甚至不需要名称即可工作:

do.call(f, list(x = 1))
#> [1] 2
Run Code Online (Sandbox Code Playgroud)

我们有时会看到函数后面没有括号的原因是函数是对象,它们本身可以传递给其他函数。例如,假设我们有这个函数:

eval(as.call(list(f, x = 1)))
#> [1] 2
Run Code Online (Sandbox Code Playgroud)

我可以将任何我想要的函数传递给它,它会尝试使用我传递的数据来调用它:

(function(x){ x + 1 })(1)
#> [1] 2
Run Code Online (Sandbox Code Playgroud)

请注意,我使用的所有这些函数都没有括号。这本质上是 tidyverse 和 apply-type 函数内部发生的情况,您会看到函数名称后面没有括号。当您使用以下语法时也会发生这种情况:

call_func_with_data <- function(func, data) {
  do.call(func, list(data))
}
Run Code Online (Sandbox Code Playgroud)

这些只是调用函数的不同方式。

由reprex 包于 2022 年 1 月 29 日创建(v2.0.1)