sapply() 如何应用具有未定义(无默认)参数的函数

How does sapply() apply a function with undefined (with no default) parameters

以下摘自 chernan's sample REST queries 的代码块将 FUN 应用于参数列表,但未提供 "param_name"。这怎么可能?

rcurl_request <- function(service_url, parameters) {

# Collapse all parameters into one string
all_parameters <- paste(
    sapply(names(parameters), 
           FUN=function(param_name, parameters) {
               paste(param_name, paste(parameters[[param_name]], collapse=','), collapse='', sep='=')
           }, 
           parameters),
    collapse="&")

# Paste base URL and parameters
requested_url <- paste0(service_url, all_parameters)

# Encode URL (in case there would be any space character for instance)
requested_url <- URLencode(requested_url)

# Start request to service
response <- getURL(requested_url, .opts = list(ssl.verifypeer = FALSE))

return(response)
}

names(parameters) 正在传递给 param_name。一个更基本的例子:sapply(df1, mean)。言外之意是sapply(df1, function(x) mean(x))。在这种情况下,df1 的每个元素都作为参数 x 传递给 mean。应用函数采用第一个参数并将其传递给指定的函数(应用函数的第二个参数)

例如:

sapply(mtcars, mean)

       mpg        cyl       disp         hp       drat         wt       qsec 
 20.090625   6.187500 230.721875 146.687500   3.596563   3.217250  17.848750 
        vs         am       gear       carb 
  0.437500   0.406250   3.687500   2.812500 

此外,sapply() 构造为 sapply(x, FUN,...) ... 是传递给函数 FUN 的任何附加参数。在您的示例中,parameters 作为第二个参数传递(names(parameters) 隐含地是第一个)。

*apply 系列函数旨在将 FUN 应用于提供给相应 *apply 函数的对象的元素。

在您的示例中,应用 FUN 的元素是 names(parameters) 个元素。 sapply() 获取第一个元素 names(parameters)[1] 并将其作为第一个参数传递给 FUN。因此 param_name 用于指代 names(parameters)[1],然后是 names(parameters)[2],依此类推。

换句话说,sapply() 安排依次将 sapply() 的第一个参数的元素传递给 FUN,将这些元素作为 [=13= 的第一个参数提供].

您可以通过这个更简单的示例更清楚地看到这一点:

sapply(1:10, FUN = function(i) {writeLines(paste("working on", i)); i})

因此 i 依次取值 1、2、...、10,匿名函数对每个值起作用:

> sapply(1:10, FUN = function(i) {writeLines(paste("working on", i)); i})
working on 1
working on 2
working on 3
working on 4
working on 5
working on 6
working on 7
working on 8
working on 9
working on 10
 [1]  1  2  3  4  5  6  7  8  9 10