如何在自定义ggplot函数间传递变量?
实现ggplot自定义函数间的参数共享
问题场景
现有两个自定义ggplot函数:my_ggplot负责创建基础散点图,my_geom负责添加平滑线和均值竖线。当前调用需要重复传递数据集、变量名和颜色参数,希望实现my_geom()自动继承my_ggplot的参数,同时保留my_geom独立调用的能力。
原始代码:
library(ggplot2) my_ggplot <- function(dat, x, y, cols) { ggplot(dat, aes(!!sym(x), !!sym(y))) + geom_point(color = cols$dots) } my_geom <- function(dat, x, cols) { xmean <- mean(dat[[x]], na.rm = T) exit <- list( geom_smooth(aes(color = cols$line), method = "loess", se = FALSE), geom_vline(xintercept = xmean, color = cols$line) ) } mycolors <- list(dots = "blue", line = "red")
期望调用方式:
my_ggplot(mpg, 'displ', 'hwy', mycolors) + my_geom()
解决方案
通过给my_ggplot返回的ggplot对象附加自定义元数据,同时改造my_geom使其自动从现有ggplot对象中提取参数(未手动传参时),实现参数共享。
步骤1:改造my_ggplot,附加共享参数
在返回ggplot对象前,添加自定义属性存储需要共享的数据集、变量名和颜色配置:
my_ggplot <- function(dat, x, y, cols) { p <- ggplot(dat, aes(!!sym(x), !!sym(y))) + geom_point(color = cols$dots) # 附加自定义元数据,供my_geom读取 p$extra <- list(dat = dat, x = x, cols = cols) p }
步骤2:改造my_geom,支持自动提取参数
修改my_geom的参数默认值,当未传参时,通过last_plot()获取当前ggplot对象,从中提取所需数据和参数:
my_geom <- function(dat = NULL, x = NULL, cols = NULL) { # 未传参时,从最近的ggplot对象中提取信息 if (is.null(dat)) { current_plot <- last_plot() dat <- current_plot$data # 自动提取x变量名(从ggplot的映射中) if (is.null(x)) { x <- rlang::as_name(current_plot$mapping$x) } # 从自定义属性中提取颜色配置 if (is.null(cols)) { cols <- current_plot$extra$cols } } # 原有计算逻辑 xmean <- mean(dat[[x]], na.rm = TRUE) list( geom_smooth(aes(color = cols$line), method = "loess", se = FALSE), geom_vline(xintercept = xmean, color = cols$line) ) }
验证调用
场景1:继承my_ggplot参数
my_ggplot(mpg, 'displ', 'hwy', mycolors) + my_geom()
场景2:独立调用my_geom
保留原有的手动传参能力,可直接用于原生ggplot对象:
ggplot(mpg, aes(displ, hwy)) + geom_point(color = mycolors$dots) + my_geom(mpg, "displ", mycolors)
内容的提问来源于stack exchange,提问作者teoten
相关产品推荐
相关产品推荐

