问题
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