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

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

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 时,它们不起作用,如下面的示例所示:

  1. library('ggplot2')
  2. set.seed(1)
  3. dat <- data.frame(x=rnorm(25),y=rnorm(25),othervar=factor(sample(1:3,25,replace=T)))
  4. make_scatter_string <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
  5. plt <- ggplot(plotdat,aes_string(x=xvar,y=yvar,color=colorvar,shape=shapevar)) + geom_point()
  6. ggsave(outfile,plt)
  7. }
  8. make_scatter_data <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
  9. plt <- ggplot(plotdat,aes(x=.data[[xvar]],y=.data[[yvar]],color=.data[[colorvar]],shape=.data[[shapevar]])) + geom_point()
  10. ggsave(outfile,plt)
  11. }
  12. make_scatter_sym <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
  13. plt <- ggplot(plotdat,aes(x=!!sym(xvar),y=!!sym(yvar),color=!!sym(colorvar),shape=!!sym(shapevar))) + geom_point()
  14. ggsave(outfile,plt)
  15. }
  16. make_scatter_string(dat,'test1.png',colorvar='othervar') # Works, aes_string can handle shapevar being NULL
  17. 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."
  18. 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:

  1. library(&#39;ggplot2&#39;)
  2. set.seed(1)
  3. dat &lt;- data.frame(x=rnorm(25),y=rnorm(25),othervar=factor(sample(1:3,25,replace=T)))
  4. make_scatter_string &lt;- function(plotdat,outfile,xvar=&#39;x&#39;,yvar=&#39;y&#39;,colorvar=NULL,shapevar=NULL) {
  5. plt &lt;- ggplot(plotdat,aes_string(x=xvar,y=yvar,color=colorvar,shape=shapevar)) + geom_point()
  6. ggsave(outfile,plt)
  7. }
  8. make_scatter_data &lt;- function(plotdat,outfile,xvar=&#39;x&#39;,yvar=&#39;y&#39;,colorvar=NULL,shapevar=NULL) {
  9. plt &lt;- ggplot(plotdat,aes(x=.data[[xvar]],y=.data[[yvar]],color=.data[[colorvar]],shape=.data[[shapevar]])) + geom_point()
  10. ggsave(outfile,plt)
  11. }
  12. make_scatter_sym &lt;- function(plotdat,outfile,xvar=&#39;x&#39;,yvar=&#39;y&#39;,colorvar=NULL,shapevar=NULL) {
  13. plt &lt;- ggplot(plotdat,aes(x=!!sym(xvar),y=!!sym(yvar),color=!!sym(colorvar),shape=!!sym(shapevar))) + geom_point()
  14. ggsave(outfile,plt)
  15. }
  16. make_scatter_string(dat,&#39;test1.png&#39;,colorvar=&#39;othervar&#39;) # Works, aes_string can handle shapevar being NULL
  17. 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;
  18. 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(.)

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

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

类似地,

  1. make_scatter_sym <- function(plotdat, xvar='x', yvar='y', colorvar=NULL, shapevar=NULL) {
  2. plt <- ggplot(plotdat, aes(x=!!sym(xvar), y=!!sym(yvar))) + geom_point()
  3. if (!is.null(colorvar)) plt <- plt + aes(color = !!sym(colorvar))
  4. if (!is.null(shapevar)) plt <- plt + aes(shape = !!sym(shapevar))
  5. plt
  6. }
  7. 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(.).

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

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

Similarly,

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

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

答案2

得分: 1

以下是您要翻译的内容:

  1. How about:
  2. make_scatter_data <- function(plotdat, outfile, xvar = x, yvar = y,
  3. colorvar = NULL, shapevar = NULL) {
  4. plt <- ggplot(plotdat,
  5. aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) +
  6. geom_point()
  7. ggsave(outfile, plt)
  8. }
  9. make_scatter_data(dat, "myfile.png")
  10. [![enter image description here][1]][1]
  11. make_scatter_data(dat, "myfile.png", colorvar = othervar)
  12. [![enter image description here][2]][2]
  13. make_scatter_data(dat, "myfile.png", shapevar = othervar)
  14. [![enter image description here][3]][3]
  15. make_scatter_data(dat, "myfile.png", xvar = y, yvar = x,
  16. colorvar = othervar, shapevar = othervar)
  17. [![enter image description here][4]][4]
  18. [1]: https://i.stack.imgur.com/wUvdN.png
  19. [2]: https://i.stack.imgur.com/lrVUt.png
  20. [3]: https://i.stack.imgur.com/7s7Nm.png
  21. [4]: https://i.stack.imgur.com/B4POd.png
  22. -------
  23. Or if you want to feed in quoted names:
  24. make_scatter_data <- function(plotdat, outfile, xvar = x, yvar = y,
  25. colorvar = NULL, shapevar = NULL) {
  26. xvar = sym(xvar)
  27. yvar = sym(yvar)
  28. if(!is.null(colorvar)) colorvar = sym(colorvar)
  29. if(!is.null(shapevar)) shapevar = sym(shapevar)
  30. plt <- ggplot(plotdat,
  31. aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) +
  32. geom_point()
  33. plt
  34. # ggsave(outfile,plt)
  35. }
  36. make_scatter_data(dat, "myfile.png", xvar = "y", yvar = "x",
  37. colorvar = "othervar")

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

英文:

How about:

  1. make_scatter_data &lt;- function(plotdat, outfile, xvar = x, yvar = y,
  2. colorvar = NULL, shapevar = NULL) {
  3. plt &lt;- ggplot(plotdat,
  4. aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) +
  5. geom_point()
  6. ggsave(outfile,plt)
  7. }
  8. make_scatter_data(dat, &quot;myfile.png&quot;)

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

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

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

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

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

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

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


Or if you want to feed in quoted names:

  1. make_scatter_data &lt;- function(plotdat, outfile, xvar = x, yvar = y,
  2. colorvar = NULL, shapevar = NULL) {
  3. xvar = sym(xvar)
  4. yvar = sym(yvar)
  5. if(!is.null(colorvar)) colorvar = sym(colorvar)
  6. if(!is.null(shapevar)) shapevar = sym(shapevar)
  7. plt &lt;- ggplot(plotdat,
  8. aes(x={{xvar}}, y={{yvar}}, color={{colorvar}}, shape={{shapevar}})) +
  9. geom_point()
  10. plt
  11. # ggsave(outfile,plt)
  12. }
  13. make_scatter_data(dat, &quot;myfile.png&quot;, xvar = &quot;y&quot;, yvar = &quot;x&quot;,
  14. colorvar = &quot;othervar&quot;)

答案3

得分: 1

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

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

  1. library(ggplot2)
  2. make_scatter_sym <- function(plotdat, outfile, x = "x", y = "y", ...) {
  3. args <- lapply(list(x = x, y = y, ...), function(x) if (!is.null(x)) sym(x))
  4. plt <- ggplot(plotdat, aes(!!!args)) +
  5. geom_point()
  6. ggsave(outfile, plt)
  7. plt
  8. }
  9. make_scatter_sym(dat, "test1.png", color = "othervar")
  10. #> Saving 7 x 5 in image

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

  1. make_scatter_sym(dat, "test1.png", color = NULL, shape = NULL)
  2. #> 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:

  1. library(ggplot2)
  2. make_scatter_sym &lt;- function(plotdat, outfile, x = &quot;x&quot;, y = &quot;y&quot;, ...) {
  3. args &lt;- lapply(list(x = x, y = y, ...), function(x) if (!is.null(x)) sym(x))
  4. plt &lt;- ggplot(plotdat, aes(!!!args)) +
  5. geom_point()
  6. ggsave(outfile, plt)
  7. plt
  8. }
  9. make_scatter_sym(dat, &quot;test1.png&quot;, color = &quot;othervar&quot;)
  10. #&gt; Saving 7 x 5 in image

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

  1. make_scatter_sym(dat, &quot;test1.png&quot;, color = NULL, shape = NULL)
  2. #&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:

确定