使用lapply或R中的用户定义函数中的非标准评估 [英] Non-standard evaluation in a user-defined function with lapply or with in R
问题描述
我在ftable
周围写了一个包装器,因为我需要计算许多变量的频率和百分比的平面表.由于类公式"的ftable
方法使用非标准评估,因此包装程序依赖于do.call
和match.call
来允许使用ftable
的subset
自变量(更多信息请参见
I wrote a wrapper around ftable
because I need to compute flat tables with frequency and percentage for many variables. As ftable
method for class "formula" uses non-standard evaluation, the wrapper relies on do.call
and match.call
to allow the use of the subset
argument of ftable
(more details in my previous question).
mytable <- function(...) {
do.call(what = ftable,
args = as.list(x = match.call()[-1]))
# etc
}
但是,我不能将此包装与lapply
或with
一起使用:
However, I cannot use this wrapper with lapply
nor with
:
# example 1: error with "lapply"
lapply(X = warpbreaks[c("breaks",
"wool",
"tension")],
FUN = mytable,
row.vars = 1)
Error in (function (x, ...) : object 'X' not found
# example 2: error with "with"
with(data = warpbreaks[warpbreaks$tension == "L", ],
expr = mytable(wool))
Error in (function (x, ...) : object 'wool' not found
这些错误似乎是由于未在正确的环境中评估match.call
造成的.
These errors seem to be due to match.call
not being evaluated in the right environment.
由于该问题与我的上一个问题密切相关,因此以下是我的问题的总结:
As this question is closely linked to my previous one, here is a sum up of my problems:
- 具有
do.call
和match.call
的包装器不能与lapply
或with
一起使用. - 没有
do.call
和match.call
的包装器不能使用ftable
的subset
参数.
- The wrapper with
do.call
andmatch.call
cannot be used withlapply
orwith
. - The wrapper without
do.call
andmatch.call
cannot use thesubset
argument offtable
.
我的问题总结:
- 我该如何编写一个包装器,使其既可以使用
ftable
的subset
参数,又可以与lapply
和with
一起使用?我有避免使用lapply
和with
的想法,但我希望了解并更正这些错误以提高对R的了解. -
lapply
的错误是否与?lapply
中的以下注释相关?
- How can I write a wrapper which allows both to use the
subset
argument offtable
and to be used withlapply
andwith
? I have ideas to avoid the use oflapply
andwith
, but I am looking to understand and correct these errors to improve my knowledge of R. - Is the error with
lapply
related to the following note from?lapply
?
由于历史原因,lapply创建的调用未评估, 并以此为基础编写了代码(例如bquote).这 表示记录的呼叫始终为FUN(X [[i]],...)形式, 用我替换为当前(整数或双精度)索引.这不是 通常是一个问题,但可能是FUN使用sys.call或match.call 或者它是使用该调用的原始函数.这 意味着通常可以更安全地使用 包装器,例如lapply(ll,function(x)is.numeric(x))是 需要确保为is.numeric进行方法分派 正确.
For historical reasons, the calls created by lapply are unevaluated, and code has been written (e.g., bquote) that relies on this. This means that the recorded call is always of the form FUN(X[[i]], ...), with i replaced by the current (integer or double) index. This is not normally a problem, but it can be if FUN uses sys.call or match.call or if it is a primitive function that makes use of the call. This means that it is often safer to call primitive functions with a wrapper, so that e.g. lapply(ll, function(x) is.numeric(x)) is required to ensure that method dispatch for is.numeric occurs correctly.
推荐答案
感谢此问题,包装器变成:
# function 1
mytable <- function(...) {
do.call(what = ftable,
args = as.list(x = match.call()[-1]),
envir = parent.frame())
# etc
}
或者:
# function 2
mytable <- function(...) {
mc <- match.call()
mc[[1]] <- quote(expr = ftable)
eval.parent(expr = mc)
# etc
}
我现在可以使用ftable
的subset
参数,并在lapply
中使用包装器:
I can now use the subset
argument of ftable
, and use the wrapper in lapply
:
lapply(X = warpbreaks[c("wool",
"tension")],
FUN = function(x) mytable(formula = x ~ breaks,
data = warpbreaks,
subset = breaks < 15))
但是我不明白为什么我必须向do.call
提供envir = parent.frame()
,因为它是默认参数.
However I do not understand why I have to supply envir = parent.frame()
to do.call
as it is a default argument.
更重要的是,这些方法不能解决另一个问题:我不能将ftable
的subset
参数与mapply一起使用.
More importantly, these methods do not resolve another issue: I can not use the subset
argument of ftable
with mapply.
这篇关于使用lapply或R中的用户定义函数中的非标准评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!