如何将ggplot2高亮条形图最大值的两个函数合并为单个函数?
问题
我正在为流行病学团队开发内部R包,目标是简化仅填充最大值条形的条形图制作流程。目前已经实现了两个可用函数,但希望进一步精简为单个函数,却不清楚如何传递ggplot()的数据与映射参数。我了解gghighlight包,但希望自行实现,期望的调用方式如下:
ggplot(data = df, aes(x = locations, y = scores, fill = scores)) + geom_col() + theme_classic() + highlight_max_value(pal = "London Pink", highlight = scores)
现有代码如下:
library(ggplot2) highlight_max <- function(col){ if(!inherits(col, c("numeric","integer"))){ stop("Input data not a number/integer.") } out = rank(-col) %in% 1 return(out) } scale_fill_highlight <- function(pal = NULL){ highlight_combos = list( `London Pink` = c("FALSE"="#cccccc","TRUE"="#9E0059"), Mustard = c("FALSE"="#cccccc","TRUE"="#DCA000"), Blue = c("FALSE"="#cccccc","TRUE"="#00577D") ) discrete_scale("fill", "cd", palette = colorRampPalette(highlight_combos[[pal]])) } df <- data.frame( locations = letters[1:5], scores = c(89,62,74,88,89.5) ) ggplot(data = df, aes(x = locations, y = scores, fill = highlight_max(scores), label = scores)) + geom_col() + theme_classic() + scale_fill_highlight(pal = "London Pink") + scale_y_continuous(expand = c(0,0), limits = c(0,100))
解决方案
要实现单个highlight_max_value函数,需将最大值判断逻辑与自定义填充刻度整合,同时兼容ggplot的语法规则。核心步骤如下:
- 解析传入的映射变量,实现非标准求值
- 内部完成“是否为最大值”的判断,替换原fill映射
- 整合配色逻辑,生成自定义填充刻度
实现代码
library(ggplot2) library(rlang) highlight_max_value <- function(pal = "London Pink", highlight){ # 定义预设配色组合 highlight_combos <- list( `London Pink` = c("FALSE"="#cccccc","TRUE"="#9E0059"), Mustard = c("FALSE"="#cccccc","TRUE"="#DCA000"), Blue = c("FALSE"="#cccccc","TRUE"="#00577D") ) # 校验配色有效性 if(!pal %in% names(highlight_combos)){ stop(sprintf("配色'%s'不存在,可选值:%s", pal, paste(names(highlight_combos), collapse = ", "))) } # 解析传入的高亮变量 highlight_var <- enquo(highlight) # 返回ggplot元素列表:包含映射替换和刻度设置 list( aes(fill = !!highlight_var == max(!!highlight_var, na.rm = TRUE)), discrete_scale( "fill", "highlight_max", palette = function(n) highlight_combos[[pal]], labels = c("非最大值", "最大值"), guide = guide_legend(title = NULL) ) ) } # 测试数据 df <- data.frame( locations = letters[1:5], scores = c(89,62,74,88,89.5) ) # 调用示例(匹配期望语法) ggplot(data = df, aes(x = locations, y = scores)) + geom_col() + theme_classic() + highlight_max_value(pal = "London Pink", highlight = scores) + scale_y_continuous(expand = c(0,0), limits = c(0,100))
关键细节
- 用
rlang::enquo()处理传入的highlight参数,支持ggplot的映射语法 - 函数返回列表,可直接添加到ggplot对象链中,无需拆分调用
- 保留原有的最大值判断逻辑(
max()自动识别唯一最大值,若有多个相同最大值会全部高亮) - 增加配色校验和图例优化,提升函数鲁棒性和可视化体验
内容的提问来源于stack exchange,提问作者SeniorAthlete
相关产品推荐
相关产品推荐

