ggplot2 + aes_string通过公式接口在函数内部

Bry*_*son 8 r facet ggplot2

交互式地,这个例子工作正常:

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")没有效果.建议?我不断被这些事情所困扰.谢谢!

Dav*_*son 6

你可以使用as.formulapaste:

p <- p + facet_grid(as.formula(paste(". ~", fac2)))
Run Code Online (Sandbox Code Playgroud)

在您的示例中,这给出了:

在此输入图像描述

  • 你甚至不需要转换为公式,`p < - p + facet_grid(paste(".〜",fac2))`就可以了! (2认同)

mne*_*nel 6

我用来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)

在此输入图像描述