如何用ggplot实现含group分面的双重分组可视化?
解决方法:保留分组信息实现分面
你遇到的核心问题是聚合过程中丢失了group字段,导致没法用它来分面。其实只需要在group_by的时候把group也包含进去,就能在聚合结果中保留这个信息,进而直接用facet_wrap实现分面效果,不用逐个筛选生成多张图。
修正后的完整代码
library(tidyverse) # 你的原始数据生成代码 id = rep(1:33,3) year = rep(1:3,33) group = sample(c(1:3),99, replace=T) test_result = sample(c(TRUE,FALSE), size=99, replace = T) df = data.frame(id, year, group, test_result) df$year = as.factor(year) df$group = as.factor(group) # 优化后的可视化代码 df %>% group_by(id, year, group) %>% # 新增group到分组变量中,保留分组信息 summarize(x = sum(test_result), .groups = "drop") %>% # 清理分组结构,避免ggplot警告 ggplot() + geom_histogram(aes(fill = year, x = x), binwidth = 1, position = "dodge") + facet_wrap(~group) + # 按group分面展示 theme_minimal()
为什么这个方法有效?
你的原始聚合代码只按id和year分组,所以summarize后的数据框里没有group字段。而把group加入group_by后,每个聚合组对应id+year+group的组合,这样就能在结果中保留group的值,之后就可以直接用它来分面。
特殊情况:如果每个id的group是固定的
如果你的实际数据中,同一个id的group值不会随year变化(比如每个用户属于固定分组),可以先提取每个id对应的group,再合并到聚合结果中,这样更高效:
# 提取每个id的固定group id_group_map <- df %>% distinct(id, group) df %>% group_by(id, year) %>% summarize(x = sum(test_result), .groups = "drop") %>% left_join(id_group_map, by = "id") %>% # 合并group信息 ggplot() + geom_histogram(aes(fill = year, x = x), binwidth = 1, position = "dodge") + facet_wrap(~group) + theme_minimal()
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

