代码之家  ›  专栏  ›  技术社区  ›  Scransom

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

  •  3
  • Scransom  · 技术社区  · 7 年前

    我想创建一个plotting函数,在其中指定数据集,并将plotting参数指定为函数参数,其方式与在 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)
    

    将返回: wonderful plot

    但是它返回:

    > 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
    

    我知道 using aes_string instead of aes works ,例如:

    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")
    

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

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

    任何已知 而且相当简单 就这样?

    1 回复  |  直到 7 年前
        1
  •  11
  •   akrun    7 年前

    使用devel版本的 ggplot2 ,我们可以传递未引用的参数,将其转换为 quosure 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)
    

    对于带引号的字符串,将其转换为符号 sym (从 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")
    

    enter image description here


    如果我们要传递带引号或不带引号的内容,则将quosure改为character( quo_name ),然后转到符号( 赛姆 )和评价( !! )

    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