Scoping in custom lattice functions (group argument)

心不动则不痛 提交于 2019-12-18 07:09:00

问题


Please consider this function:

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
    }

Which you can run with:

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

What am I doing wrong in passing the groups argument to xyplot - why can't it be found? I can't figure out how it wants the group information. Thanks.

Update:

@agstudy's answer is very helpful, but if I add the panel function as in the original example, the groups are still not recognized (no grouping, but no error occurs either):

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
    }

Something is still missing... Thanks.


回答1:


You can use eval here since match.call returns symbols.

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
}



回答2:


One technique I use when I have trouble with scoping and calling functions within functions is to pass the parameters as strings and then construct the call within the function from those strings. Here's what that would look like here.

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") 

See this answer to one of my previous questions for another example of this: https://stackoverflow.com/a/7668846/210673.

Also see this answer to the sister question of this one, where I suggest something similar for use with aov: https://stackoverflow.com/a/14858614/210673



来源:https://stackoverflow.com/questions/14784302/scoping-in-custom-lattice-functions-group-argument

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!