R 语言有一个很好的特性来定义可以接受可变数量参数的函数。例如,该函数data.frame采用任意数量的参数,每个参数成为结果数据表中一列的数据。示例用法:
data.frame
> data.frame(letters=c("a", "b", "c"), numbers=c(1,2,3), notes=c("do", "re", "mi")) letters numbers notes 1 a 1 do 2 b 2 re 3 c 3 mi
该函数的签名包括一个省略号,如下所示:
function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, stringsAsFactors = default.stringsAsFactors()) { [FUNCTION DEFINITION HERE] }
我想编写一个执行类似操作的函数,获取多个值并将它们合并为一个返回值(以及进行一些其他处理)。为了做到这一点,我需要弄清楚如何...从函数内的函数参数中“解包”。我不知道该怎么做。函数定义中的相关行data.frame是object <- as.list(substitute(list(...)))[-1L],我无法理解。
...
object <- as.list(substitute(list(...)))[-1L]
那么如何将函数签名中的省略号转换为例如列表?
更具体地说,我如何get_list_from_ellipsis在下面的代码中编写?
get_list_from_ellipsis
my_ellipsis_function(...) { input_list <- get_list_from_ellipsis(...) output_list <- lapply(X=input_list, FUN=do_something_interesting) return(output_list) } my_ellipsis_function(a=1:10,b=11:20,c=21:30)
似乎有两种可能的方法可以做到这一点。它们是as.list(substitute(list(...)))[-1L]和list(...)。但是,这两个做的事情并不完全相同。(有关差异,请参见答案中的示例。)谁能告诉我它们之间的实际区别是什么,我应该使用哪一个?
as.list(substitute(list(...)))[-1L]
list(...)
我阅读了答案和评论,发现没有提到几件事:
mrn <- is.null(row.names) x <- list(…)
object用于对列名做一些魔术,但x用于创建 final data.frame。 要使用未评估的...参数,请查看使用的write.csv代码match.call。
object
x
write.csv
match.call
language
symbol
list
1:10
[-1L]
substitute
my_ellipsis_function(a=1:10,b=11:20,c=21:30)
list(a=1:10,b=11:20,c=21:30)
List of 4
$ : symbol list $ a: language 1:10 $ b: language 11:20 $ c: language 21:30
第一个元素没有名称,这是[[1]]Dirk 的答案。我使用以下方法实现了这个结果:
[[1]]
my_ellipsis_function <- function(...) { input_list <- as.list(substitute(list(...))) str(input_list) NULL } my_ellipsis_function(a=1:10,b=11:20,c=21:30)
str
my_ellipsis_function <- function(...) { input_list <- list(...) output_list <- lapply(X=input_list, function(x) {str(x);summary(x)}) return(output_list)
} my_ellipsis_function(a=1:10,b=11:20,c=21:30) int [1:10] 1 2 3 4 5 6 7 8 9 10 int [1:10] 11 12 13 14 15 16 17 18 19 20 int [1:10] 21 22 23 24 25 26 27 28 29 30 $a Min. 1st Qu. Median Mean 3rd Qu. Max. 1.00 3.25 5.50 5.50 7.75 10.00 $b Min. 1st Qu. Median Mean 3rd Qu. Max. 11.0 13.2 15.5 15.5 17.8 20.0 $c Min. 1st Qu. Median Mean 3rd Qu. Max. 21.0 23.2 25.5 25.5 27.8 30.0
没关系。来看substitute版本:
my_ellipsis_function <- function(...) { input_list <- as.list(substitute(list(...))) output_list <- lapply(X=input_list, function(x) {str(x);summary(x)}) return(output_list) } my_ellipsis_function(a=1:10,b=11:20,c=21:30) symbol list language 1:10 language 11:20 language 21:30 [[1]] Length Class Mode 1 name name $a Length Class Mode 3 call call $b Length Class Mode 3 call call $c Length Class Mode 3 call call
不是我们需要的。您将需要额外的技巧来处理这些类型的对象(如 中write.csv)。
如果你想使用...,那么你应该像 Shane 的回答那样使用它,by list(...)。