x <- y <- 1:5
df = data.frame(m=x,n=y)
myfun <- function(data, var) {
library(dplyr)
select(data, var)
}
myfun(df, m)
eval(expr,envir,enclos)中的错误:object&#39; m&#39;找不到
答案 0 :(得分:2)
理查兹的答案可以绕过任意数量的参数。但要分别控制这种选择呼叫的每个参数,你必须知道:
在select(data, m)
中,m 不是此时具有指定值的变量!它只是一个符号,它在数据框“数据”的上下文中有一些含义。一旦使用参数myfun(df, m)
,m
将失败(在select-call中就是这种情况),因为m
没有值(或来自全局环境的值,你肯定不想要!)在内部,dplyr将使用substitute
函数将其转换为符号(而不是评估它)。将var转换为符号(或调用,例如m:n
等选项)后,您可以使用do.call
撰写和评估新的选择调用。
对于您的示例代码,这意味着:
x <- y <- 1:5
df = data.frame(m=x,n=y)
myfun <- function(data, var) {
library(dplyr)
var <- substitute(var)
do.call('select', list(data, var))
}
myfun(df, m)
对更多论点的概括是直截了当的。
对于要转换为符号或调用的任意数量的参数,您可以使用
myfun <- function(...) {
args <- substitute(list(...))
# Now args[i] is a symbol/call representing the i-th argument
}
答案 1 :(得分:0)
select
使用数据框架方法select.data.frame
。 select
的第二个参数是...
列表,以便可以将参数传递给其他方法。您的函数在其第二个参数中使用名称var
,并且由于dplyr
&#39; .()
函数,基本R方差函数var
正在传递给其他select
内的函数。
长话短说,改变你的论点名称。我会选择
myfun <- function(z, ...) select(z, ...)
myfun(df, x)
myfun(df, y)
您还可以使用select
方法
> select.myfun <- function(.data, ...) UseMethod("select")
> myfun(df, exclude = "x")
> methods(select)[6]
[1] "select.myfun"
作为一个无耻的插件,我会推荐你a question I asked about ...
arguments。答案中有两个非常好的解释。
编辑根据要求,查看.()
> `.`
function (..., .env = parent.frame())
{
structure(as.list(match.call()[-1]), env = .env, class = "quoted")
}
<environment: namespace:plyr>
> .(x)
List of 1
$ x: symbol x
- attr(*, "env")=<environment: R_GlobalEnv>
- attr(*, "class")= chr "quoted"