R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

huangapple go评论106阅读模式
英文:

R ggplot2: Replacing aes_string() with aes() and .data[[varname]] when varname may be NULL

问题

我正在更新一些较旧的 R 代码,以便在 aes_string() 被弃用后使用 ggplot2 的 aes()。我承认我不完全理解整个整洁评估的细节,但根据我理解的部分内容,替代 aes_string(shape=shapevar) 的可能是 aes(shape=.data[[shapevar]]),或者可能是 aes(shape=!!sym(shapevar))。

这些替代方法的问题是,当 shapevar 为 NULL 时,它们不起作用,如下面的示例所示:

library('ggplot2')

set.seed(1)
dat <- data.frame(x=rnorm(25),y=rnorm(25),othervar=factor(sample(1:3,25,replace=T)))

make_scatter_string <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
  plt <- ggplot(plotdat,aes_string(x=xvar,y=yvar,color=colorvar,shape=shapevar)) + geom_point()
  ggsave(outfile,plt)
}

make_scatter_data <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
  plt <- ggplot(plotdat,aes(x=.data[[xvar]],y=.data[[yvar]],color=.data[[colorvar]],shape=.data[[shapevar]])) + geom_point()
  ggsave(outfile,plt)
}

make_scatter_sym <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
  plt <- ggplot(plotdat,aes(x=!!sym(xvar),y=!!sym(yvar),color=!!sym(colorvar),shape=!!sym(shapevar))) + geom_point()
  ggsave(outfile,plt)
}

make_scatter_string(dat,'test1.png',colorvar='othervar') # Works, aes_string can handle shapevar being NULL
make_scatter_data(dat,'test2.png',colorvar='othervar') # Gives error message "Error in `.data[[NULL]]`: ! Must subset the data pronoun with a string, not NULL."
make_scatter_sym(dat,'test3.png',colorvar='othervar') # Gives error message "Error in `sym()`: ! Can't convert NULL to a symbol."

如何正确向 aes() 提供类似 shapevar 的变量,该变量可能包含数据中的变量名称,也可能为 NULL?或者是否应该使用其他值来表示 "不要使用此美学",而不是 NULL?

英文:

I am working on updating some older R code to make it use ggplot2's aes() now that aes_string() is deprecated. I admit I don't understand all of the details of tidy evaluation, but from what I do understand it seems like the replacement for aes_string(shape=shapevar) would be aes(shape=.data[[shapevar]]), or possibly aes(shape=!!sym(shapevar)).

The problem with these replacements is that they do not work when shapevar is NULL, as shown in the example below:

library(&#39;ggplot2&#39;)

set.seed(1)
dat &lt;- data.frame(x=rnorm(25),y=rnorm(25),othervar=factor(sample(1:3,25,replace=T)))

make_scatter_string &lt;- function(plotdat,outfile,xvar=&#39;x&#39;,yvar=&#39;y&#39;,colorvar=NULL,shapevar=NULL) {
  plt &lt;- ggplot(plotdat,aes_string(x=xvar,y=yvar,color=colorvar,shape=shapevar)) + geom_point()
  ggsave(outfile,plt)
}

make_scatter_data &lt;- function(plotdat,outfile,xvar=&#39;x&#39;,yvar=&#39;y&#39;,colorvar=NULL,shapevar=NULL) {
  plt &lt;- ggplot(plotdat,aes(x=.data[[xvar]],y=.data[[yvar]],color=.data[[colorvar]],shape=.data[[shapevar]])) + geom_point()
  ggsave(outfile,plt)
}

make_scatter_sym &lt;- function(plotdat,outfile,xvar=&#39;x&#39;,yvar=&#39;y&#39;,colorvar=NULL,shapevar=NULL) {
  plt &lt;- ggplot(plotdat,aes(x=!!sym(xvar),y=!!sym(yvar),color=!!sym(colorvar),shape=!!sym(shapevar))) + geom_point()
  ggsave(outfile,plt)
}

make_scatter_string(dat,&#39;test1.png&#39;,colorvar=&#39;othervar&#39;) # Works, aes_string can handle shapevar being NULL
make_scatter_data(dat,&#39;test2.png&#39;,colorvar=&#39;othervar&#39;) # Gives error message &quot;Error in `.data[[NULL]]`: ! Must subset the data pronoun with a string, not NULL.&quot;
make_scatter_sym(dat,&#39;test3.png&#39;,colorvar=&#39;othervar&#39;) # Gives error message &quot;Error in `sym()`: ! Can&#39;t convert NULL to a symbol.&quot;

What is the correct way to give aes() a variable like shapevar that may contain the name of a variable in the data or may be NULL? Or is there some other value that should be used to say "don't use this aesthetic" instead of NULL?

答案1

得分: 1

我认为你可以根据is.null(.)的值直接添加个体aes(.)

make_scatter_data <- function(plotdat, xvar='x', yvar='y', colorvar=NULL, shapevar=NULL) {
  plt <- ggplot(plotdat, aes(x=.data[[xvar]],y =.data[[yvar]])) + geom_point()
  if (!is.null(colorvar)) plt <- plt + aes(color=.data[[colorvar]])
  if (!is.null(shapevar)) plt <- plt + aes(shape=.data[[shapevar]])
  plt
}
make_scatter_data(dat, colorvar='othervar')

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

类似地,

make_scatter_sym <- function(plotdat, xvar='x', yvar='y', colorvar=NULL, shapevar=NULL) {
  plt <- ggplot(plotdat, aes(x=!!sym(xvar), y=!!sym(yvar))) + geom_point()
  if (!is.null(colorvar)) plt <- plt + aes(color = !!sym(colorvar))
  if (!is.null(shapevar)) plt <- plt + aes(shape = !!sym(shapevar))
  plt
}
make_scatter_sym(dat, shapevar='othervar')

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

英文:

I think you can add individual aes(.) directly based on the value of is.null(.).

make_scatter_data &lt;- function(plotdat, xvar=&#39;x&#39;, yvar=&#39;y&#39;, colorvar=NULL, shapevar=NULL) {
  plt &lt;- ggplot(plotdat, aes(x=.data[[xvar]],y =.data[[yvar]])) + geom_point()
  if (!is.null(colorvar)) plt &lt;- plt + aes(color=.data[[colorvar]])
  if (!is.null(shapevar)) plt &lt;- plt + aes(shape=.data[[shapevar]])
  plt
}
make_scatter_data(dat, colorvar=&#39;othervar&#39;)

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

Similarly,

make_scatter_sym &lt;- function(plotdat, xvar=&#39;x&#39;, yvar=&#39;y&#39;, colorvar=NULL, shapevar=NULL) {
  plt &lt;- ggplot(plotdat, aes(x=!!sym(xvar), y=!!sym(yvar))) + geom_point()
  if (!is.null(colorvar)) plt &lt;- plt + aes(color = !!sym(colorvar))
  if (!is.null(shapevar)) plt &lt;- plt + aes(shape = !!sym(shapevar))
  plt
}
make_scatter_sym(dat, shapevar=&#39;othervar&#39;)

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

答案2

得分: 1

以下是您要翻译的内容:

How about:

    make_scatter_data <- function(plotdat, outfile, xvar = x, yvar = y,
                                  colorvar = NULL, shapevar = NULL) {
      plt <- ggplot(plotdat,
               aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) + 
        geom_point()
      ggsave(outfile, plt)
    }
    

    make_scatter_data(dat, "myfile.png")

[![enter image description here][1]][1]

    make_scatter_data(dat, "myfile.png", colorvar = othervar)

[![enter image description here][2]][2]

    make_scatter_data(dat, "myfile.png", shapevar = othervar)

[![enter image description here][3]][3]

    make_scatter_data(dat, "myfile.png", xvar = y, yvar = x, 
                      colorvar = othervar, shapevar = othervar)

[![enter image description here][4]][4]


  [1]: https://i.stack.imgur.com/wUvdN.png
  [2]: https://i.stack.imgur.com/lrVUt.png
  [3]: https://i.stack.imgur.com/7s7Nm.png
  [4]: https://i.stack.imgur.com/B4POd.png

-------

Or if you want to feed in quoted names:

    make_scatter_data <- function(plotdat, outfile, xvar = x, yvar = y,
                                  colorvar = NULL, shapevar = NULL) {
      xvar = sym(xvar)
      yvar = sym(yvar)
      if(!is.null(colorvar)) colorvar = sym(colorvar)
      if(!is.null(shapevar)) shapevar = sym(shapevar)
      
      plt <- ggplot(plotdat,
                    aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) + 
        geom_point()
      plt
      # ggsave(outfile,plt)
    }
    
    make_scatter_data(dat, "myfile.png", xvar = "y", yvar = "x", 
                      colorvar = "othervar")

请注意,代码部分未被翻译。

英文:

How about:

make_scatter_data &lt;- function(plotdat, outfile, xvar = x, yvar = y,
                              colorvar = NULL, shapevar = NULL) {
  plt &lt;- ggplot(plotdat,
           aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) + 
    geom_point()
  ggsave(outfile,plt)
}


make_scatter_data(dat, &quot;myfile.png&quot;)

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

make_scatter_data(dat, &quot;myfile.png&quot;, colorvar = othervar)

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

make_scatter_data(dat, &quot;myfile.png&quot;, shapevar = othervar)

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

make_scatter_data(dat, &quot;myfile.png&quot;, xvar = y, yvar = x, 
                  colorvar = othervar, shapevar = othervar)

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]


Or if you want to feed in quoted names:

make_scatter_data &lt;- function(plotdat, outfile, xvar = x, yvar = y,
                              colorvar = NULL, shapevar = NULL) {
  xvar = sym(xvar)
  yvar = sym(yvar)
  if(!is.null(colorvar)) colorvar = sym(colorvar)
  if(!is.null(shapevar)) shapevar = sym(shapevar)
  
  plt &lt;- ggplot(plotdat,
                aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) + 
    geom_point()
  plt
  # ggsave(outfile,plt)
}

make_scatter_data(dat, &quot;myfile.png&quot;, xvar = &quot;y&quot;, yvar = &quot;x&quot;, 
                  colorvar = &quot;othervar&quot;)

答案3

得分: 1

根据我的回答中的内容,在如何替代已弃用的 ggplot2 函数 aes_string:接受任意数量的命名字符串来指定美学映射?上,@r2evans的一种灵活和通用的方法可能如下所示。

基本上,我将函数的参数重命名为美学的名称,并使用...允许传递额外的美学,也可以与NULL一起使用:

library(ggplot2)

make_scatter_sym <- function(plotdat, outfile, x = "x", y = "y", ...) {
  args <- lapply(list(x = x, y = y, ...), function(x) if (!is.null(x)) sym(x))

  plt <- ggplot(plotdat, aes(!!!args)) +
    geom_point()

  ggsave(outfile, plt)

  plt
}

make_scatter_sym(dat, "test1.png", color = "othervar")
#> Saving 7 x 5 in image

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]


make_scatter_sym(dat, "test1.png", color = NULL, shape = NULL)
#> Saving 7 x 5 in image

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]

英文:

Adapting my answer on How to replace the deprecated ggplot2 function aes_string: accepting an arbitrary number of named strings to specify aesthetic mappings?, a flexible and generalized approach of the one by @r2evans may look like so.

Basically I renamed the functions arguments to the names of the aesthetics and used ... to allow to pass additional aesthetics and which also works with NULL:

library(ggplot2)

make_scatter_sym &lt;- function(plotdat, outfile, x = &quot;x&quot;, y = &quot;y&quot;, ...) {
  args &lt;- lapply(list(x = x, y = y, ...), function(x) if (!is.null(x)) sym(x))

  plt &lt;- ggplot(plotdat, aes(!!!args)) +
    geom_point()

  ggsave(outfile, plt)

  plt
}

make_scatter_sym(dat, &quot;test1.png&quot;, color = &quot;othervar&quot;)
#&gt; Saving 7 x 5 in image

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]<!-- -->


make_scatter_sym(dat, &quot;test1.png&quot;, color = NULL, shape = NULL)
#&gt; Saving 7 x 5 in image

R ggplot2: 用 aes() 替代 aes_string(),并在 varname 可能为 NULL 时使用 .data[[varname]]<!-- -->

huangapple
  • 本文由 发表于 2023年5月26日 10:15:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76337263.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定