R语言批量修改绘图变量:复用柱状图生成多特征图表
批量生成特征追踪天数柱状图实现方案
问题背景
现有一份记录用户各特征追踪天数的DataFrame(结构见下方),已完成针对Distance_DaysTracked列的柱状图代码,包含均值线、使用该特征的用户数标注等元素。需要复用该逻辑,批量生成其余10个特征的同款图表,同时支持调整标注位置,减少重复代码。
数据结构示例:
Rows: 35 Columns: 12 Groups: Id [35] $ Id <chr> "1503960366", "1624580081", "1644430081", "1844505072", ... $ Distance_DaysTracked <int> 48, 49, 40, 28, 28, 42, 42, 38, 32, 42, ... $ LoggedActivity_DaysTracked <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... $ Calories_DaysTracked <int> 61, 62, 60, 62, 62, 62, 62, 62, 49, 62, ... $ Intensities_DaysTracked <int> 61, 62, 60, 33, 49, 62, 62, 43, 49, 62, ... $ MET_DaysTracked <int> 61, 61, 58, 61, 61, 62, 62, 61, 48, 62, ... $ Sleep_DaysTracked <int> 50, 0, 8, 7, 34, 1, 59, 1, 45, 0, ... $ Steps_DaysTracked <int> 61, 62, 60, 32, 48, 62, 62, 43, 49, 61, ... $ Weight_DaysTracked <int> 3, 0, 0, 0, 2, 0, 0, 0, 1, 4, ... $ Fat_DaysTracked <int> 2, 0, 0, 0, 0, 0, 0, 0, 1, 0, ... $ BMI_DaysTracked <int> 3, 0, 0, 0, 2, 0, 0, 0, 1, 4, ... $ HR_DaysTracked <int> 0, 0, 0, 0, 0, 42, 5, 0, 32, 0, ...
原有单特征绘图代码:
DaysTracked_All %>% ggplot() + geom_col(mapping = aes(x = Id, y = Distance_DaysTracked, fill = Distance_DaysTracked), width = 0.8) + theme_minimal() + theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = mean(DaysTracked_All$Distance_DaysTracked), colour = "plum2", linewidth = 1) + ylim(0, 65) + annotate("text", # 给均值线添加数值标注 x = 37, # 标注x位置 y = mean(DaysTracked_All$Distance_DaysTracked)+2, label = round(mean(DaysTracked_All$Distance_DaysTracked), digits = 1), colour = "plum2", fontface = "bold", size = 4) + coord_cartesian(clip = "off") + labs(tag = sprintf("nUsers: %i", # 添加使用该特征的用户数标签 DaysTracked_All %>% select(Id, Distance_DaysTracked) %>% filter(Distance_DaysTracked != 0) %>% nrow() )) + theme(plot.tag.position = c(0.83, 0.93), # 调整标签位置、颜色、大小 plot.tag = element_text(colour = "plum2", size = 14))
实现方案
1. 封装可复用绘图函数
把原有绘图逻辑封装成函数,将目标特征列名、标注位置等作为参数,灵活调整每个图表的细节:
library(ggplot2) library(dplyr) # 定义通用绘图函数 plot_days_tracked <- function(data, feature_col, annotate_x = 37, tag_pos = c(0.83, 0.93)) { # 计算当前特征的均值 feature_mean <- mean(data[[feature_col]], na.rm = TRUE) # 计算使用该特征的用户数 user_count <- data %>% select(Id, all_of(feature_col)) %>% filter(.data[[feature_col]] != 0) %>% nrow() data %>% ggplot() + geom_col(aes(x = Id, y = .data[[feature_col]], fill = .data[[feature_col]]), width = 0.8) + theme_minimal() + theme(axis.text.x = element_text(angle = 90)) + geom_hline(yintercept = feature_mean, colour = "plum2", linewidth = 1) + ylim(0, 65) + annotate("text", x = annotate_x, y = feature_mean + 2, label = round(feature_mean, digits = 1), colour = "plum2", fontface = "bold", size = 4) + coord_cartesian(clip = "off") + labs(title = feature_col, tag = sprintf("nUsers: %i", user_count)) + theme(plot.tag.position = tag_pos, plot.tag = element_text(colour = "plum2", size = 14), plot.title = element_text(hjust = 0.5)) }
2. 批量生成所有特征图表
提取所有需要绘图的特征列(排除Id列),遍历调用函数生成图表,可将图表存入列表方便查看或保存:
# 获取所有目标特征列名(排除第一列Id) feature_cols <- colnames(DaysTracked_All)[-1] # 批量生成图表并存入列表 plot_list <- lapply(feature_cols, function(col) { # 针对不同特征自定义标注位置,示例:给Sleep和Fat特征调整位置 annotate_x <- ifelse(col == "Sleep_DaysTracked", 35, 37) tag_pos <- ifelse(col == "Fat_DaysTracked", c(0.7, 0.93), c(0.83, 0.93)) plot_days_tracked(DaysTracked_All, col, annotate_x = annotate_x, tag_pos = tag_pos) }) # 给列表元素命名,方便识别 names(plot_list) <- feature_cols # 查看单个图表(示例:查看Sleep_DaysTracked的图) plot_list[["Sleep_DaysTracked"]] # 批量保存图表(可选) lapply(names(plot_list), function(name) { ggsave(filename = paste0(name, "_plot.png"), plot = plot_list[[name]], width = 12, height = 8) })
关键说明
- 使用
.data[[feature_col]]语法实现对传入列名的动态引用,避免硬编码 - 函数参数支持自定义标注的x位置和标签位置,可针对不同特征灵活调整
- 通过
lapply批量遍历特征列,一次性生成所有图表,大幅减少重复代码
内容的提问来源于stack exchange,提问作者Dean
相关产品推荐
相关产品推荐

