英文:
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('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."
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')
类似地,
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')
英文:
I think you can add individual aes(.)
directly based on the value of is.null(.)
.
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')
Similarly,
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')
答案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 <- 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")
make_scatter_data(dat, "myfile.png", colorvar = othervar)
make_scatter_data(dat, "myfile.png", shapevar = othervar)
make_scatter_data(dat, "myfile.png", xvar = y, yvar = x,
colorvar = othervar, shapevar = othervar)
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")
答案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
make_scatter_sym(dat, "test1.png", color = NULL, shape = NULL)
#> Saving 7 x 5 in image
英文:
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 <- 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
<!-- -->
make_scatter_sym(dat, "test1.png", color = NULL, shape = NULL)
#> Saving 7 x 5 in image
<!-- -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论