根据ggplot2标准功能创建ggplot2函数并将参数指定为数据中的变量

Uma*_*mao 5 r ggplot2

我想创建一个绘图函数,我在其中指定数据集,并以类似的方式将绘图参数指定为函数参数ggplot2,即我们在没有数据集的情况下指定变量名称,例如hp代替mtcars$hp.

例如:

ggfun <- function(dat, x.var, y.var){

  ggp <- ggplot(data = dat,
                aes(x = x.var,
                    y = y.var)) +
    geom_point()

  return(ggp)
}


ggfun(dat = mtcars, x.var = drat, y.var = hp)
Run Code Online (Sandbox Code Playgroud)

会回来: 精彩的情节

然而它返回:

> ggfun(dat = mtcars, x.var = drat, y.var = hp)
Error in eval(expr, envir, enclos) : object 'drat' not found
In addition: Warning message:
In eval(expr, envir, enclos) : restarting interrupted promise evaluation
Run Code Online (Sandbox Code Playgroud)

我知道使用aes_string而不是aes作品,例如:

ggfun <- function(dat, x.var, y.var){

  ggp <- ggplot(data = dat,
                aes_string(x = x.var,
                    y = y.var)) +
    geom_point()

  return(ggp)
}

ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
Run Code Online (Sandbox Code Playgroud)

但我宁愿避免使用字符串形式.

其他尝试包括ggfun(dat = mtcars, x.var = mtcars$drat, y.var = mtcars$hp),它返回正确的图形但部分地违背了练习的目的,并产生标签"x.var"和"y.var"而不是"drat"和"hp".

任何已知且相当简单的方法?

akr*_*run 13

使用devel版本ggplot2,我们可以传递不带引号的参数,将其转换为quosure(with enquo)并对其进行求值(!!)

ggfun <- function(dat, x.var, y.var){
  x.var <- enquo(x.var)
  y.var <- enquo(y.var)
  ggp <- ggplot(data = dat,
                aes(x = !! x.var,
                    y = !! y.var)) +
    geom_point()

  return(ggp)
}

ggfun(dat = mtcars, x.var = drat, y.var = hp)
Run Code Online (Sandbox Code Playgroud)

对于带引号的字符串,使用sym(from rlang)将其转换为符号并进行评估

ggfun <- function(dat, x.var, y.var){
  x.var <- rlang::sym(x.var)
  y.var <- rlang::sym(y.var)
  ggp <- ggplot(data = dat,
                aes(x = !! x.var,
                    y = !! y.var)) +
    geom_point()

  return(ggp)
}

ggfun(dat = mtcars, x.var = "drat", y.var = "hp")
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


如果我们想要传递引用或不引用,则将quosure更改为character(quo_name),然后更改为symbol(sym)和evaluate(!!)

ggfun <- function(dat, x.var, y.var){
  x.var <- rlang::sym(quo_name(enquo(x.var)))
  y.var <- rlang::sym(quo_name(enquo(y.var)))
  ggp <- ggplot(data = dat,
                aes(x = !! x.var,
                    y = !! y.var)) +
    geom_point()

  return(ggp)
}

p1 <- ggfun(dat = mtcars, x.var = drat, y.var = hp)
p2 <- ggfun(dat = mtcars, x.var = "drat", y.var = "hp")

all.equal(p1, p2)
#[1] TRUE
Run Code Online (Sandbox Code Playgroud)


ncr*_*aig 3

rlang0.4.0 (2019-06-25) 开始,现在有了拥抱运算符 {{}}。使用拥抱运算符:

library(ggplot2)
data("mtcars")
Run Code Online (Sandbox Code Playgroud)

该运算符适用于函数参数中的列名称和标签。

scatter_plot <- function(data, x, y, title) {
  ggplot(data, aes({{x}}, {{y}})) +
    geom_point()+
    labs(title= {{title}})
}
Run Code Online (Sandbox Code Playgroud)
scatter_plot(mtcars, drat, hp, "Drat by HP")
Run Code Online (Sandbox Code Playgroud)

+可以像平常一样进一步定制绘图。

scatter_plot(mtcars, drat, hp, "Drat by HP with trend") +
  geom_smooth()
Run Code Online (Sandbox Code Playgroud)

其他资源

  • 这篇文章是我遇到该方法的地方。
  • 这个 SO答案提供了一些使用整洁评估和表格的额外非常相似的示例dplyr