Rya*_*son 175 parameters r function ellipsis variadic
R语言有一个很好的功能,用于定义可以采用可变数量参数的函数.例如,该函数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
Run Code Online (Sandbox Code Playgroud)
函数的签名包括省略号,如下所示:
function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,
stringsAsFactors = default.stringsAsFactors())
{
[FUNCTION DEFINITION HERE]
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个类似的函数,获取多个值并将它们合并为一个返回值(以及进行一些其他处理).为了做到这一点,我需要弄清楚如何...
从函数中的函数参数"解包" .我不知道该怎么做.功能定义中的相关行data.frame
是object <- as.list(substitute(list(...)))[-1L]
,我无法理解.
那么如何将省略号从函数的签名转换为例如列表呢?
更具体地说,我如何写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)
Run Code Online (Sandbox Code Playgroud)
似乎有两种可能的方法来做到这一点.他们是as.list(substitute(list(...)))[-1L]
和list(...)
.但是,这两者并没有完全相同.(有关差异,请参阅答案中的示例.)任何人都可以告诉我它们之间的实际区别是什么,我应该使用哪一个?
Mar*_*rek 109
我阅读了答案和评论,我发现很少有东西没有提到:
data.frame
使用list(...)
版本.代码片段:
object <- as.list(substitute(list(...)))[-1L]
mrn <- is.null(row.names)
x <- list(...)
Run Code Online (Sandbox Code Playgroud)
object
用于对列名做一些魔术,但x
用于创建final data.frame
.
要使用未评估的...
参数,请查看使用的write.csv
代码match.call
.
当您在评论结果中写入Dirk时,答案不是列表.是长度为4的列表,哪些元素是language
类型.第一个对象是symbol
- list
,第二个是表达式1:10
等等.这解释了为什么[-1L]
需要:它symbol
从提供的参数中删除预期...
(因为它总是一个列表).
随着德克州的substitute
回归"解析树无法评价的表达".
当你打电话my_ellipsis_function(a=1:10,b=11:20,c=21:30)
,然后...
"创建"的参数列表:list(a=1:10,b=11:20,c=21:30)
并substitute
使其四个元素的列表:
List of 4
$ : symbol list
$ a: language 1:10
$ b: language 11:20
$ c: language 21:30
Run Code Online (Sandbox Code Playgroud)
第一个元素没有名称,这是[[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)
Run Code Online (Sandbox Code Playgroud)如上所述,我们可以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
Run Code Online (Sandbox Code Playgroud)
没关系.让我们看看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
Run Code Online (Sandbox Code Playgroud)
不是我们需要的.您将需要额外的技巧来处理这些类型的对象(如write.csv
).
如果你想使用...
那么你应该像Shane的答案一样使用它list(...)
.
Sha*_*ane 37
您可以将省略号转换为列表list()
,然后对其执行操作:
> test.func <- function(...) { lapply(list(...), class) }
> test.func(a="b", b=1)
$a
[1] "character"
$b
[1] "numeric"
Run Code Online (Sandbox Code Playgroud)
所以你的get_list_from_ellipsis
功能无非就是list
.
一个有效的用例,这是在你想在一个未知的数量用于操作对象的传递情况下(如在你的例子c()
或data.frame()
)....
然而,当你事先知道每个参数时,使用它并不是一个好主意,因为它会给参数字符串增加一些模糊性和进一步的复杂性(并使任何其他用户都不清楚函数签名).参数列表是功能用户的重要文档.
否则,它对于您希望将参数传递给子函数而不将它们全部暴露在您自己的函数参数中的情况也很有用.这可以在功能文档中注明.
Ric*_*ton 31
只是为了补充Shane和Dirk的回答:比较有趣
get_list_from_ellipsis1 <- function(...)
{
list(...)
}
get_list_from_ellipsis1(a = 1:10, b = 2:20) # returns a list of integer vectors
$a
[1] 1 2 3 4 5 6 7 8 9 10
$b
[1] 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Run Code Online (Sandbox Code Playgroud)
同
get_list_from_ellipsis2 <- function(...)
{
as.list(substitute(list(...)))[-1L]
}
get_list_from_ellipsis2(a = 1:10, b = 2:20) # returns a list of calls
$a
1:10
$b
2:20
Run Code Online (Sandbox Code Playgroud)
就目前而言,任何一个版本似乎都适合您的目的my_ellipsis_function
,但第一个版本显然更简单.
Dir*_*tel 14
你已经给出了一半答案.考虑
R> my_ellipsis_function <- function(...) {
+ input_list <- as.list(substitute(list(...)))
+ }
R> print(my_ellipsis_function(a=1:10, b=2:20))
[[1]]
list
$a
1:10
$b
11:20
R>
Run Code Online (Sandbox Code Playgroud)
所以这需要两个参数a
并b
从调用中将其转换为列表.那不是你要的吗?
这按预期工作.以下是交互式会话:
> talk <- function(func, msg, ...){
+ func(msg, ...);
+ }
> talk(cat, c("this", "is", "a","message."), sep=":")
this:is:a:message.
>
Run Code Online (Sandbox Code Playgroud)
相同,除了默认参数:
> talk <- function(func, msg=c("Hello","World!"), ...){
+ func(msg, ...);
+ }
> talk(cat,sep=":")
Hello:World!
> talk(cat,sep=",", fill=1)
Hello,
World!
>
Run Code Online (Sandbox Code Playgroud)
如您所见,如果默认值不是您在特定情况下所需的值,则可以使用此参数将"额外"参数传递给函数中的函数.
归档时间: |
|
查看次数: |
51341 次 |
最近记录: |