R 中的 function()-function "not"是否需要大括号?



我最近在我的R教程中遇到了这个例子:

sapply(list(runif (10), runif (10)), 
function(x) c(min = min(x), mean = mean(x), max = max(x))

我的印象是,在function()-函数中,您首先必须在括号内列出您的参数,然后在大括号内列出函数执行的操作。

在这个例子中,有"no"大括号,代码似乎无论如何都可以运行,这怎么可能?

这是一个单一的语句,因此不需要任何括号

sapply(0:5, function(x) x  + 5)

但是,如果函数需要多个语句,则可以在大括号内分隔每个语句

sapply(0:5, function(x) {
x <- sequence(x)
x1 <- x[x > 2]
c(mean = mean(x1), min = min(x1))
})

正如@qdread评论中提到的,一个好的做法是包括卷曲,尽管可能会有轻微的效率下降

library(microbenchmark)
microbenchmark(nocurly = sapply(0:1e6, function(x) x + 5),
curly = sapply(0:1e6, function(x) {x + 5}))
#Unit: milliseconds
#    expr      min       lq     mean   median       uq      max neval
# nocurly 666.2539 922.0929 928.6206 942.9065 966.8318 1113.828   100
#   curly 710.8450 925.7917 947.7641 955.2041 973.8009 1081.597   100

function是一个原始函数:

`function`
.Primitive("function")

它的第二个参数是主体,它是一个引用函数,这意味着第二个参数不会被计算。这些是等效的:

fun1 <- function(x) x + 5
fun2 <- `function`(NULL, x + 5)
formals(fun2) <- alist(x=)
fun3 <- do.call( 'function', list(as.pairlist(alist(x=)), quote(x+5)))
identical(fun1,fun2)
[1] TRUE
identical(fun1,fun3)
[1] TRUE

请参阅这个问题,解决为什么我们不能像使用其他函数那样使用函数function:如何调用"函数"函数?

用于fun1的语法是function(...) body,其中...将被映射到对列表。

{本身就是一个函数。与(不同,{从不被解析器特别处理。

因此,当你的表达式中只有一个调用时,不需要{,不是因为function的语法被设计得很灵活,而是因为它不是function语法的一部分。

我倾向于同意使用大括号保持一致性是一种很好的做法,当您想使用trace例如不一致很烦人时。不过,它通常几乎没有什么后果,并且它不是由基数 R 强制执行的:

mean
# function (x, ...) 
# UseMethod("mean")
# <bytecode: 0x000000000e146288>
# <environment: namespace:base>
body(mean)
# UseMethod("mean")

作为旁注,rlang有一个很好的功能,能够获得一致的身体输出:

rlang::fn_body(mean)
# {
#   UseMethod("mean")
# }

相关内容

最新更新