在编写自己的函数时如何使用R的省略号功能? [英] How to use R's ellipsis feature when writing your own function?
问题描述
data.frame
可以使用任意数量的参数,每个参数都会成为结果数据表中列的数据。用法示例: > data.frame(letters = c(a,b,c),numbers = c(1,2,3),notes = c(do,re,mi))
字母数字笔记
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())
{
[函数定义]
}
我想编写一个类似的函数,取多个值并将它们合并成一个返回值(以及做一些其他处理)。为了做到这一点,我需要弄清楚如何从函数的函数参数中解开 ...
。我不知道该怎么做。 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)
编辑
似乎有两种可能的方式来做到这一点。它们是 as.list(substitute(list(...)))[ - 1L]
和 list(...)
。但是,这两者并不完全一样。 (有关差异,请参阅答案中的示例。)任何人都可以告诉我它们之间的实际区别是什么,以及我应该使用哪一个?
-
data.frame
使用list(...)
版本。代码片段:object< - as.list(substitute(list(...)))[ - 1L ]
mrn< - is.null(row.names)
x< - list(...)
object
被用来做列名的魔术,但是使用x
创建最终的data.frame
。
使用未评估的...
参数write.csv
代码其中match.call
被使用。 -
当你在评论结果中写Dirk答案不是列表列表。是长度为4的列表,其元素是
language
type。第一个对象是符号 -
list
,第二个是表达式1:10
等等。这解释了为什么需要[ - 1L]
:它从中提供的参数中移除了预期的
(因为它总是一个列表)。符号
...
如Dirk所述替代
返回parse tree未评估的表达式。
当您调用my_ellipsis_function(a = 1:10,b = 11:20,c = 21:30)
,则...
created参数列表:list(a = 1:10,b = 11:20,c = 21:30)
和替换
使它成为一个包含四个元素的列表:List of 4
$:符号列表
$ a:语言1:10
$ b:语言11:20
$ c:语言21:30
code>第一个元素没有名称,这是
[[1]] $ c $在Dirk答案中。我使用以下方法实现了这个结果:
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
分钟。第一曲。中位数均值3曲。最大。
1.00 3.25 5.50 5.50 7.75 10.00
$ b最小。第一曲。中位数均值3曲。最大。
11.0 13.2 15.5 15.5 17.8 20.0
$ c
最小值第一曲。中位数均值3曲。最大。
21.0 23.2 25.5 25.5 27.8 30.0
没关系。让我们看看
替换
版本: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)
符号列表
语言1:10
语言11:20
语言21:30
[[1]]
长度类模式
1名称名称
$ a
长度班级模式
3呼叫电话
$ b长度班级模式
3呼叫电话
$ c
长度班级模式
3 call call
不是我们所需要的。您需要额外的技巧来处理这些对象(如
write.csv
)。
如果你想使用 ...
那么你应该在Shane答案中使用它,由 list(。 ..)
。
The R language has a nifty feature for defining functions that can take a variable number of arguments. For example, the function data.frame
takes any number of arguments, and each argument becomes the data for a column in the resulting data table. Example usage:
> 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
The function's signature includes an ellipsis, like this:
function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE,
stringsAsFactors = default.stringsAsFactors())
{
[FUNCTION DEFINITION HERE]
}
I would like to write a function that does something similar, taking multiple values and consolidating them into a single return value (as well as doing some other processing). In order to do this, I need to figure out how to "unpack" the ...
from the function's arguments within the function. I don't know how to do this. The relevant line in the function definition of data.frame
is object <- as.list(substitute(list(...)))[-1L]
, which I can't make any sense of.
So how can I convert the ellipsis from the function's signature into, for example, a list?
To be more specific, how can I write get_list_from_ellipsis
in the code below?
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)
Edit
It seems there are two possible ways to do this. They are as.list(substitute(list(...)))[-1L]
and list(...)
. However, these two do not do exactly the same thing. (For differences, see examples in the answers.) Can anyone tell me what the practical difference between them is, and which one I should use?
I read answers and comments and I see that few things weren't mentioned:
data.frame
useslist(...)
version. Fragment of the code:object <- as.list(substitute(list(...)))[-1L] mrn <- is.null(row.names) x <- list(...)
object
is used to do some magic with column names, butx
is used to create finaldata.frame
.
For use of unevaluated...
argument look atwrite.csv
code wherematch.call
is used.As you write in comment result in Dirk answer is not a list of lists. Is a list of length 4, which elements are
language
type. First object is asymbol
-list
, second is expression1:10
and so on. That explain why[-1L]
is needed: it removes expectedsymbol
from provided arguments in...
(cause it is always a list).
As Dirk statessubstitute
returns "parse tree the unevaluated expression".
When you callmy_ellipsis_function(a=1:10,b=11:20,c=21:30)
then...
"creates" a list of arguments:list(a=1:10,b=11:20,c=21:30)
andsubstitute
make it a list of four elements:List of 4 $ : symbol list $ a: language 1:10 $ b: language 11:20 $ c: language 21:30
First element doesn't have a name and this is
[[1]]
in Dirk answer. I achieve this results using: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)
As above we can use
str
to check what objects are in a function.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
It's ok. Lets see
substitute
version: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
Isn't what we needed. You will need additional tricks to deal with these kind of objects (as in
write.csv
).
If you want use ...
then you should use it as in Shane answer, by list(...)
.
这篇关于在编写自己的函数时如何使用R的省略号功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!