如何在ggplot自定义函数内通过传入变量指定aes中的color参数?
解决ggplot自定义函数中用传入变量指定color参数的图例问题
问题根源
你原来的函数里把传入的y.name对应列重命名成了y,随后在aes(color = y)中直接引用这个新列名,ggplot会默认把图例标题显示为列名y,而非你传入的原始变量名(比如vs)。而函数外的代码手动新增了与原始变量名一致的列,所以能显示正确图例。
解决方案
以下提供几种可行的解决方式,按需选择:
方法1:用整洁评估({{}})直接引用原始变量(推荐)
无需重命名列,直接用{{}}将传入的变量名注入ggplot的aes中,既不用修改数据列名,图例也会自动使用原始变量名:
library(ggplot2) library(dplyr) myplot <- function(data, x.name, y.name){ dat <- data %>% dplyr::select(all_of(c(y.name, x.name))) %>% na.omit() if(is.numeric(dat[[x.name]])){ p_plot<-ggplot(dat, aes(x = {{x.name}}, y = {{y.name}})) + geom_point(na.rm = TRUE, aes(color = {{y.name}})) + geom_smooth(method = glm, method.args = list(family = binomial), na.rm = TRUE, formula = {{y.name}} ~ {{x.name}})+ labs(x = x.name, y = y.name ) + theme_bw()+ theme(legend.position = "top") } return(p_plot) } # 调用函数 myplot(y.name = "vs", x.name = "disp", data = mtcars)
方法2:保留列重命名逻辑,手动指定图例标题
如果一定要保留重命名列的操作,只需在labs()里手动将color的标题设置为传入的y.name即可:
library(ggplot2) library(dplyr) myplot <- function(data, x.name, y.name){ dat <- data %>% dplyr::select(all_of(c(y.name, x.name))) %>% na.omit() colnames(dat) <- c("y", "x") if(is.numeric(dat$x)){ p_plot<-ggplot(dat, aes(x, y)) + geom_point(na.rm = TRUE, aes(color = y)) + geom_smooth(method = glm, method.args = list(family = binomial), na.rm = TRUE, formula = y ~ x)+ labs(x = x.name, y = y.name, color = y.name ) + # 手动指定color图例标题 theme_bw()+ theme(legend.position = "top") } return(p_plot) } # 调用函数 myplot(y.name = "vs", x.name = "disp", data = mtcars)
方法3:用sym()和!!进行变量引用(兼容旧版tidyverse)
如果你的tidyverse版本较低,不支持{{}}语法,可以用rlang::sym()把字符串转成符号,再用!!注入到表达式中:
library(ggplot2) library(dplyr) library(rlang) myplot <- function(data, x.name, y.name){ x_sym <- sym(x.name) y_sym <- sym(y.name) dat <- data %>% dplyr::select(all_of(c(y.name, x.name))) %>% na.omit() if(is.numeric(dat[[x.name]])){ p_plot<-ggplot(dat, aes(x = !!x_sym, y = !!y_sym)) + geom_point(na.rm = TRUE, aes(color = !!y_sym)) + geom_smooth(method = glm, method.args = list(family = binomial), na.rm = TRUE, formula = !!y_sym ~ !!x_sym)+ labs(x = x.name, y = y.name ) + theme_bw()+ theme(legend.position = "top") } return(p_plot) } # 调用函数 myplot(y.name = "vs", x.name = "disp", data = mtcars)
内容的提问来源于stack exchange,提问作者Kate
相关产品推荐
相关产品推荐

