如何按集合排序UpSet图组合矩阵及ggupset数据输入方法
解决UpSetR自定义交集排序与ggupset数据输入问题
一、UpSetR实现按指定集合优先的交集排序
当使用fromList()将命名向量列表转换为宽格式后,要实现类似"先展示含Action的集合/组合"的自定义排序,需手动生成交集顺序并配合upset()的参数控制:
转换数据并提取交集组合
先将命名向量列表转为UpSetR兼容的宽格式数据框,再筛选出所有非空交集的组合:library(UpSetR) # 示例命名向量列表 movie_genres <- list( Action = c("Movie1", "Movie2", "Movie3", "Movie4"), Animation = c("Movie2", "Movie4", "Movie5"), Comedy = c("Movie3", "Movie5", "Movie6") ) # 转为宽格式数据框 upset_df <- fromList(movie_genres) # 提取所有非空交集的集合标识 comb_matrix <- upset_df[rowSums(upset_df[, names(movie_genres)]) > 0, names(movie_genres)] comb_strings <- apply(comb_matrix, 1, function(x) paste(names(x)[x], collapse = "+"))自定义交集排序规则
按"含Action的组合优先"、"组合长度从短到长"、"名称字典序"的规则排序:sorted_combs <- comb_strings[order( !grepl("Action", comb_strings), # 含Action的排前面(FALSE在前,TRUE在后) nchar(comb_strings), # 组合长度短的优先 comb_strings # 同长度按名称排序 )]绘制自定义排序的UpSet图
在upset()中关闭默认排序,启用自定义顺序:upset(upset_df, sets = c("Action", "Animation", "Comedy"), # 设置集合的显示顺序 order.by = "none", # 禁用默认的频率/度数排序 keep.order = TRUE, # 保持手动生成的交集顺序 mainbar.y.label = "交集元素数量", sets.x.label = "集合元素数量" )
二、ggupset的命名向量列表输入方法
ggupset要求输入长格式数据框(每个元素-集合对占一行),需先将命名向量列表转换为该格式:
转换命名向量列表为长格式
使用tidyverse工具将列表展开为长格式:library(ggupset) library(tidyverse) # 示例数据同前 movie_genres <- list( Action = c("Movie1", "Movie2", "Movie3", "Movie4"), Animation = c("Movie2", "Movie4", "Movie5"), Comedy = c("Movie3", "Movie5", "Movie6") ) # 转成长格式数据框:每行对应一个元素及其所属集合 long_df <- enframe(movie_genres, name = "Genre", value = "Movie") %>% unnest(Movie)基础UpSet图绘制
用scale_x_upset()指定集合顺序和交集显示规则:ggplot(long_df, aes(x = Genre)) + geom_bar(fill = "#2E86AB") + scale_x_upset( sets = c("Action", "Animation", "Comedy"), # 集合的显示顺序 n_intersections = 5, # 最多显示5个交集 keep_empty = FALSE # 隐藏空交集 ) + labs(x = "Genre组合", y = "元素数量") + theme_bw()自定义交集排序(含Action优先)
若要实现和UpSetR一致的排序逻辑,先计算交集频率并生成排序规则,再传入intersection_order参数:# 计算每个交集的出现次数并排序 intersection_counts <- long_df %>% group_by(Movie) %>% summarise(Genres = list(sort(Genre))) %>% mutate(Genre_comb = map_chr(Genres, paste, collapse = "+")) %>% count(Genre_comb, sort = TRUE) %>% # 按含Action优先、数量从多到少排序 arrange(!str_detect(Genre_comb, "Action"), desc(n)) # 绘制自定义排序的ggupset图 ggplot(long_df, aes(x = Genre)) + geom_bar(fill = "#2E86AB") + scale_x_upset( sets = c("Action", "Animation", "Comedy"), intersection_order = intersection_counts$Genre_comb # 传入自定义排序的交集 ) + labs(x = "Genre组合", y = "元素数量") + theme_bw()
内容的提问来源于stack exchange,提问作者Hidroxiapatito
相关产品推荐
相关产品推荐

