将字符传递给facet_grid:ggplot2

23

在ggplot2中,您可以使用aes_string将字符参数传递到用户定义的函数中。对于需要使用公式而不是aes的facet grid,您如何执行相同的操作?

FUN <- function(data, x, y, fac1, fac2) {
     ggplot(data = data, aes_string(x=x, y=y)) +
     geom_point() + facet_grid(as.formula(substitute(fac1 ~ fac2)))
}


FUN(mtcars, 'hp', 'mpg', 'cyl', 'am')

5
as.formula(paste(fac1,"~", fac2)) - baptiste
2个回答

38

reformulate() 看起来运行良好。

FUN <- function(data, x, y, fac1, fac2) {
      ggplot(data = data, aes_string(x=x, y=y)) +
      geom_point() + facet_grid(reformulate(fac2,fac1))
}

FUN(mtcars, 'hp', 'mpg', 'cyl', 'am')

在此输入图片描述


太好了。我之前不知道有reformulate这个函数。 - Tyler Rinker
6
如果你只想水平或垂直切割,可以使用类似于 reformulate(fac1, ".") 的方法。 - naco

5

借助rlang的魔法和新版ggplot2 v3.0.0的特性,您可以做到:

FUN <- function(data, x, y, fac1, fac2) {
  ggplot(data = data, aes(x = !!ensym(x), y = !!ensym(y))) +
    geom_point() + 
    facet_grid(eval(expr(!!ensym(fac1) ~ !!ensym(fac2))))
}

FUN(mtcars, 'hp', 'mpg', 'cyl', 'am')

请注意,我们不再使用已被软弃用的 aes_string 。
个人认为,在这些情况下,我喜欢使用一个我称之为 glue_formula 的函数(引用包)。
glue_formula <- function(.formula, .envir = parent.frame(), ...){
  formula_chr <- gsub("\\n\\s*","",as.character(.formula)[c(2,1,3)])
  args <- c(as.list(formula_chr), .sep=" ", .envir = .envir)
  as.formula(do.call(glue::glue, args),env = .envir)
}

FUN2 <- function(data, x, y, fac1, fac2) {
  ggplot(data = data, aes(x = !!ensym(x), y = !!ensym(y))) +
    geom_point() + facet_grid(glue_formula({fac1} ~ {fac2}))
}

FUN2(mtcars, 'hp', 'mpg', 'cyl', 'am')

虽然它没有得到tidyverse的批准(在这里查看有趣的讨论),但它对我非常有用。


3
谢谢更新。对于你的解决方案,我没有任何批评(特别是粘合剂部分),但是reformulate(fac2,fac1)eval(expr(!!ensym(fac1) ~ !!ensym(fac2)))更简洁易懂,并且更容易理解。 - Tyler Rinker
我同意,这种方法更加灵活,尤其是当你有一个更复杂的公式时(这可能与facet_grid无关),而且这个方法来自lionel。Github问题并没有关闭,所以他们可能会提出更令人满意的解决方案。 - moodymudskipper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接