交互式地,这个例子工作正常:
p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + facet_grid(. ~ vs)
Run Code Online (Sandbox Code Playgroud)
现在,使用公式接口创建一个函数并使用aes_string它做同样的事情,它不起作用(错误是:) Error in layout_base(data, cols, drop = drop) : At least one layer must contain all variables used for facetting:
tf <- function(formula, data) {
res <- as.character(formula[[2]])
fac2 <- as.character(formula[[3]][3])
fac1 <- as.character(formula[[3]][2])
# p <- ggplot(aes_string(x = fac1, y = res), data = data)
# p <- p + geom_point() # original attempt
p <- ggplot() # This is Joran's trick, but it doesn't work here
p <- p + geom_point(aes_string(x = fac1, y = res), data = data)
p <- p + facet_grid(.~fac2) # comment this out, and it works but
# of course is not faceted
}
p <- tf(formula = wt ~ am*vs, data = mtcars)
Run Code Online (Sandbox Code Playgroud)
通过Joran的伎俩我在这里引用,这是我最近发布的类似问题.在这种情况下ggplot2,没有看到我的分面请求.使它facet_grid(".~fac2")没有效果.建议?我不断被这些事情所困扰.谢谢!
你可以使用as.formula和paste:
p <- p + facet_grid(as.formula(paste(". ~", fac2)))
Run Code Online (Sandbox Code Playgroud)
在您的示例中,这给出了:

我用来formula.tools操纵公式.
我认为你应该为faceting公式提供一个单独的参数,否则你将不得不创建自己的解析器来解决wt ~ am*vs在faceting方面的意义
像格子分组的想法可能是有用的
wt~am | vs
但你必须深入研究格子,看看他们如何解析他们的公式(看看latticeParseFormula- 复杂!)
更容易分开这两个公式.您可以将facet参数的rhs和lhs字符变量列表传递给facet_grid
我也用过environment = parent.frame()我的小测试
library(formula.tools)
tf <- function(formula, faceting = NULL, data, print = TRUE) {
y <- rhs(formula)
x <- lhs(formula)
p <- ggplot(environment = parent.frame())
p <- p + geom_point(aes_string(x = x, y = y), data = data)
if (! is.null(faceting)){
rhsfacet <- all.vars(rhs(faceting))
lhsfacet <- all.vars(lhs(faceting))
if(length(lhsfacet)==1 & any(lhsfacet %in% '.')) {lhsfacet <- NULL}
if(length(rhsfacet)==1 & any(rhsfacet %in% '.')) {rhsfacet <- NULL}
p <- p+ facet_grid(facet = list( lhsfacet, rhsfacet))}
if(print) {print(p)}
p
}
tf(wt~mpg, faceting = ~am, data = mtcars, print = TRUE)
Run Code Online (Sandbox Code Playgroud)
