UpSetR 如何按集合总频数调整行顺序,让 Fentanyl 位于顶部?
可以。对于这组数据,删除 intersections,再用 sets 和 keep.order = TRUE 指定行顺序即可。集合名称需要按图中从下到上的顺序传入。Lorazepam 与 PropofolTCI 的总频数相同,还需明确指定两者的先后位置。
为什么原来的排序没有生效?
在所核对的 UpSetR 源码中,只要提供了 intersections,函数就会通过下面的表达式取得集合名称:
Set_names <- unique(unlist(intersections))
这个分支不会采用传入的 sets。此时,keep.order = TRUE 保留的是集合名称在 intersections 中首次出现的顺序,所以反复调整 sets_ordered 不会改变行顺序。参见 UpSetR 的 upset() 源码。
矩阵中的第一个集合对应底部位置。因此,要让总频数最大的集合显示在顶部,应按总频数升序传入集合名称。参见 UpSetR 矩阵坐标的实现。
修改示例
原问题的 intersections 已列出示例数据中全部 20 个实际出现的组合,可以让 UpSetR 直接从数据计算交集,并用 nintersects = NA 显示全部交集。
在原问题的 input 定义之后运行:
library(UpSetR)
df <- fromExpression(input)
# df 仅包含集合的 0/1 指示列,列和就是各集合总频数
set_sizes <- colSums(df)
# 按总频数从小到大排列,对应图中从下到上的顺序
# 频数相同时,将 Lorazepam 放在前面,确保它位于底部
sets_bottom_to_top <- names(set_sizes)[
order(set_sizes, names(set_sizes) != "Lorazepam")
]
upset_plot <- upset(
df,
sets = sets_bottom_to_top,
keep.order = TRUE,
nintersects = NA,
order.by = c("freq", "degree"),
decreasing = c(TRUE, FALSE),
mb.ratio = c(0.6, 0.4),
text.scale = c(1.2, 1.1, 1, 1, 1.1, 1),
point.size = 3,
line.size = 1,
mainbar.y.label = "Number receiving drug (n)",
sets.x.label = "Total number given drug (n)"
)
upset_plot
不要再对 sets_bottom_to_top 使用 rev(),否则频数较大的集合会被放到底部。
根据输入数据求和,各集合总频数为:
| 集合 | 总频数 |
|---|---|
| Fentanyl | 172 |
| Propofol | 146 |
| Ketamine | 53 |
| Midazolam | 51 |
| Alfentanil | 5 |
| RemifentanilTCI | 2 |
| PropofolTCI | 1 |
| Lorazepam | 1 |
上述排序在图中从上到下与表中顺序一致。最后两个集合的频数并列,代码中的第二排序条件会把 Lorazepam 固定在底部。
原有的交集排序和着色怎么处理?
order.by 和 decreasing 控制交集列排序,sets 和 keep.order 控制集合行排序。示例继续使用原调用默认的交集排序规则;频数和交集集合数都相同时,列之间的先后顺序并未显式指定。
可以将原有的 queries = list(...) 加回绘图调用,以保留交集着色。需要先定义原代码引用的 col_single、col_two、col_three 和 col_four,这些颜色变量未包含在输入材料中。
如果实际数据还包含其他组合,而你只想显示 intersections 中指定的部分组合,删除该参数会扩大显示范围。上述简化方案适用于本题列出全部实际交集的情况;如果仍需保留交集筛选,应结合安装版本的实现处理,不能假定同时设置 sets 就能覆盖该分支的集合顺序。
备注:内容仅供参考。
