【发布时间】:2014-02-26 21:34:05
【问题描述】:
我正在尝试为函数编写一个包装器,以便将列表用作输入。我不能更改函数本身,因此我需要一个解决方法。我使用as.call(),它在没有可选参数的情况下工作,但是当我有向量作为可选参数时,我无法让它工作。
例子:
# function I cannot change
func <- function(..., opt=c(1,2)) {
cl <- match.call(expand.dots = FALSE)
names <- lapply(cl[[2]],as.character)
ev <- parent.frame()
classes <- unlist(lapply(names,function(name){class(get(name,envir=ev))}))
print(c(opt,names, classes))
}
a <- structure(1:3, class="My_Class")
b <- structure(letters[1:3], class="My_Class")
lst <- list(a, b)
names(lst) <- c("a","b")
# Normal result
func(a,b,opt=c(3,4))
# This should give the same but it doesn't
call <- as.call(append(list(func), list(names(lst), opt=c(3,4))))
g <- eval(call, lst)
我也尝试了c(),而不是list 作为可选参数,但这也不起作用。有人有建议或帮助页面吗? ?call 没有明确我的问题。
(我已经在这里问过关于该主题的上一个问题:R: How to use list elements like arguments in ellipsis?,但遗漏了有关可选参数的详细信息,现在无法弄清楚。)
【问题讨论】:
-
通常我会建议
do.call(func, c(lst, list(opt=c(3,4))))。但是,这不适用于您声称无法更改的功能。但是,将参数从列表传递给函数将是正常的方式。所以,你的函数可以被认为是以非标准的方式做事。 -
您可能无法更改
func,但您肯定可以编写一个新函数来执行您想要的操作。 -
使用
lists作为输入有什么重要之处?完全不清楚func应该采用什么样的参数,但是将list元素转换为其他类型的对象当然很容易,您可以在循环中将其提供给func或*apply。 -
Roland:我同意,但是因为我想使用这样实现的包,所以我唯一的选择是编写包维护者。我会这样做,但目前我想要一个可行的解决方案。但是感谢您指出应该如何使用它:这样我就可以提出一个改进功能的提议:)
-
Hong Ooi:确实是这样,但是因为有多个这样的功能,所以有点复制粘贴和重写整个包。在最坏的情况下,我会这样做。
标签: r list call optional-parameters