【问题标题】:Scoping in custom lattice functions (group argument)自定义格函数中的范围(组参数)
【发布时间】:2013-02-09 02:26:01
【问题描述】:

请考虑这个函数:

tf <- function(formula = NULL, data = NULL, groups = NULL) {

    grv <- eval(substitute(groups), data, environment(formula)) # the values
    grn <- as.character(match.call()$groups) # the name
    gr <- match.call()$groups # unquoted name

    p <- xyplot(formula, data, # draws the data but not in groups
# Try these options:
#   p <- xyplot(formula, data, groups, # can't find 'cat2' 
#   p <- xyplot(formula, data, groups = data[,grn], # can't fine grn
#   p <- xyplot(formula, data, groups = grv, # can't find grv
        panel = function(x, y) {
            panel.stripplot(x, y, jitter.data = TRUE, pch = 20)
            }
            )
    p
    }

你可以运行的:

tf(formula = mpg~vs, groups = am, data = mtcars)

在将 groups 参数传递给 xyplot 时我做错了什么 - 为什么找不到?我无法弄清楚它如何想要group 信息。谢谢。

更新:

@agstudy 的回答很有帮助,但是如果我像原来的例子一样添加面板功能,仍然无法识别组(没有分组,但也没有发生错误):

tf <- function(formula = NULL, data = NULL, groups = NULL) {
    ll <- as.list(match.call(expand.dots = FALSE)[-1])
    p <- xyplot(as.formula(ll$formula), 
              data = eval(ll$data), 
              groups = eval(ll$groups),
                panel = function(x, y) {
                panel.stripplot(x, y, jitter.data = TRUE, pch = 20)
                }
                )
    p
    }

有些东西还是不见了……谢谢。

【问题讨论】:

  • 关于这是否是lattice的“特征”;我确实相信这种行为是允许将变量名称作为groups 参数放入数据集中的功能的副产品。这需要一点 R 体操,我认为副产品是你想要在这里做的事情更加困难。我知道我之前至少曾为此挣扎过一次,并希望我现在有更多时间再次研究它;这是一个有趣的问题!
  • 谢谢。如您所知,这些范围界定问题经常让我烦恼!

标签: r lattice


【解决方案1】:

您可以在此处使用eval,因为match.call 返回符号。

tf <- function(formula = NULL, data = NULL, groups = NULL) {
  ll <- as.list(match.call(expand.dots = FALSE)[-1])
  p <- xyplot(as.formula(ll$formula), 
              data = eval(ll$data), 
              groups = eval(ll$groups),
              panel = function(x, y,...) { ## here ... contains groups and subscripts
                ## here you can transform x or y before giving them to the jitter
                panel.stripplot(x, y, jitter.data = TRUE, pch = 20,...)
              }
  )
  p
}

【讨论】:

  • 谢谢,这很有帮助。为什么你认为这是必要的?如果我不使用groups 公式并且数据直接传递到绘图中没有问题。当我添加groups 时,必须使用不同的技术。在lattice 代码中,我看到groups 的处理方式截然不同(而且处理方式很难理解)。为什么有一个简短的答案?此外,我编辑了原始问题,因为在我的真实示例中,我需要使用该面板功能(以及其他几个功能)。谢谢。
  • @BryanHanson 在我的代码组中的处理方式与其他参数一样。在您的抖动面板中,您没有给出组参数。查看我的更新。
  • 是的,我刚刚发现自己需要缺少的点。谢谢。
  • 我仍然很好奇/病态地着迷:在我原来的非工作函数中,一个完美的参数值不能直接用于第一个函数中的另一个函数。似乎违反了一些基本原则。也许是格子的“特征”?
  • (这是“信条”。)更支持的是,我同意 lattice 代码可能会造成混淆,因为某些变量被抽象和重命名,因此它们是特定于面板的,最终命名与您期望的不同成为。
【解决方案2】:

当我在函数内定义和调用函数时遇到问题时,我使用的一种技术是将参数作为字符串传递,然后根据这些字符串在函数内构造调用。这就是这里的样子。

panel2 <- function(x, y, ...) {panel.stripplot(x, y, jitter.data = TRUE, pch = 20, ...)}
tf <- function(formula, data, groups) {
  eval(call("xyplot", as.formula(formula), 
                      groups=as.name(groups), 
                      data=as.name(data),
                      panel=as.name("panel2")))
}

tf("mpg~vs", "mtcars", "am") 

有关此示例的另一个示例,请参阅我之前的一个问题的答案:https://stackoverflow.com/a/7668846/210673

另请参阅此问题的姊妹问题的答案,我建议与 aov 使用类似的东西:https://stackoverflow.com/a/14858614/210673

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-03-05
  • 2015-04-05
  • 2020-09-30
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-25
相关资源
最近更新 更多