2017-06-18 33 views
1

我在写一个调用另一个函数的函数(例如lm),并且我想使用省略号将其他 参数传递给它(...)。但是,在全球环境中要使用的数据不是 ,而是在列表中。小例子:编写一个包装函数,以成功通过省略号(...)添加参数(如子集)

L <- list(data = chickwts, other = 1:5) 

wrapper <- function(list, formula = NULL, ...){ 
    if (missing(formula)) formula <- formula(weight~feed) 
    lm(formula, data = list$data, ...) 
} 

wrapper(L, subset = feed != "casein") #fails 

我可以使它工作使用attach但我敢肯定有通过指定评估框架做的更有效的方法...?

wrapper2 <- function(list, formula = NULL, ...){ 
    if (missing(formula)) formula <- formula(weight~feed) 
    attach(list$data) 
    m <- lm(formula, ...) 
    detach(list$data) 
    return(m) 
} 

wrapper2(L, subset = feed != "casein") #works 

我以前使用的另一种解决方案是使用list(...),并处理手动参数,但是在实际情况下,将是不实际的。

我可以看到这是相当基本的,但我找不到解决方案。我们将赞赏对特定问题的任何建议,以及对一般环境的良好概念性解释的链接。

+0

的'model.frame'代码(这是'lm'在你的例子调用)是可怕的。我不建议让它工作,而是建议事先将数据分组。 –

+0

这不是重点,这只是一个真实情况的简单例子(这更复杂)。问题是一样的:如何将参数从'...'传递给另一个函数内的函数,而不需要使用'attach(list $ data)'。而不是'subset',它可以是任何在数据中使用变量名的任意参数。 – sparrow

+0

问你真实的问题,而不是假装。 –

回答

0

我们需要构建一个calleval它。

wrapper <- function(list, formula = NULL, ...){ 
    if (missing(formula)) formula <- weight ~ feed 
    cl <- match.call() 
    cl$list <- NULL 
    cl$formula <- formula 
    cl$data <- quote(list$data) 
    cl[[1]] <- quote(stats::lm) 
    eval(cl) 
    } 

重复的例子:

L <- list(data = trees, other = 1:5) 
wrapper(L, Height ~ Girth, subset = Volume > 20) 
+0

是的,谢谢。这比使用'attach'我的原始解决方案更高效吗? – sparrow

+0

@sparrow我不知道。你说你不想附加分离,然后我写了这个答案。如果你认为attach-detach效率低下/缓慢,那么这个不是。 –

+0

@sparrow说实话,我认为我的原始编辑中的标题更清晰。对于大多数函数,只需使用...或list(...)就足以编写包装器。但是依靠model.frame的模型拟合例程是特殊的,并且match.call方法是必需的。如果您将标题更改为我的编辑,它将更具信息性,重要的是帮助那些想要包装lm(),glm(),gam()等的人快速找到这篇文章。 (另外,你是否乐意投我的答案?) –