使用lapply或R中的用户定义函数中的非标准评估 [英] Non-standard evaluation in a user-defined function with lapply or with in R

查看:123
本文介绍了使用lapply或R中的用户定义函数中的非标准评估的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在ftable周围写了一个包装器,因为我需要计算许多变量的频率和百分比的平面表.由于类公式"的ftable方法使用非标准评估,因此包装程序依赖于do.callmatch.call来允许使用ftablesubset自变量(更多信息请参见

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
}

但是,我不能将此包装与lapplywith一起使用:

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.callmatch.call的包装器不能与lapplywith一起使用.
  • 没有do.callmatch.call的包装器不能使用ftablesubset参数.
  • The wrapper with do.call and match.call cannot be used with lapply or with.
  • The wrapper without do.call and match.call cannot use the subset argument of ftable.

我的问题总结:

  • 我该如何编写一个包装器,使其既可以使用ftablesubset参数,又可以与lapplywith一起使用?我有避免使用lapplywith的想法,但我希望了解并更正这些错误以提高对R的了解.
  • lapply的错误是否与?lapply中的以下注释相关?
  • How can I write a wrapper which allows both to use the subset argument of ftable and to be used with lapply and with? I have ideas to avoid the use of lapply and with, 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
}

我现在可以使用ftablesubset参数,并在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.

更重要的是,这些方法不能解决另一个问题:我不能将ftablesubset参数与mapply一起使用.

More importantly, these methods do not resolve another issue: I can not use the subset argument of ftable with mapply.

这篇关于使用lapply或R中的用户定义函数中的非标准评估的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆