UpSetR中的行顺序

编程语言 2026-07-10

我想在UpSetR绘图中反转行的排序,使行按x 轴的频度排序。列的排序是正确的,但行并非如此。我已经看到这个问题的答案 Sorting sets in an Upset plot,然而即使我用 sets_ordered <- names(sort(colSums(df), decreasing = FALSE)) 对集合进行排序或手动按顺序列出集合,绘图还是没有改变。示例数据已包含。

    input <- c(
  Propofol                                    = 16,
  Ketamine                                    = 11,
  Midazolam                                   = 4, 
  Fentanyl                                    = 2,
  "Propofol&Fentanyl"                         = 97,
  "Propofol&Ketamine"                         = 5,
  "Propofol&Midazolam"                        = 4,
  "Propofol&Alfentanil"                       = 3,
  "Ketamine&Fentanyl"                         = 28,
  "Midazolam&Fentanyl"                        = 19,
  "Ketamine&Midazolam"                        = 1,
  "Midazolam&Alfentanil"                      = 1,
  "Ketamine&RemifentanilTCI"                  = 1,
  "PropofolTCI&RemifentanilTCI"               = 1,
  "Propofol&Midazolam&Fentanyl"               = 17,
  "Propofol&Ketamine&Fentanyl"                = 2,
  "Ketamine&Midazolam&Fentanyl"               = 4,
  "Propofol&Lorazepam&Fentanyl"               = 1,
  "Propofol&Alfentanil&Fentanyl"              = 1,
  "Propofol&Midazolam&Fentanyl&Ketamine"      = 1
)

df <- fromExpression(input)
upset_plot <- UpSetR::upset(
  df,
  sets = rev(sets_ordered),
  keep.order = TRUE,

  intersections = list(
    # ── Single agent ─────────────────────────────────────
    list("Fentanyl"),
    list("Propofol"),
    list("Ketamine"),
    list("Midazolam"),
    # ── Two agent ────────────────────────────────────────
    list("Propofol", "Fentanyl"),
    list("Ketamine", "Fentanyl"),
    list("Midazolam", "Fentanyl"),
    list("Propofol", "Ketamine"),
    list("Propofol", "Midazolam"),
    list("Propofol", "Alfentanil"),
    list("Ketamine", "RemifentanilTCI"),
    list("PropofolTCI", "RemifentanilTCI"),
    list("Ketamine", "Midazolam"),
    list("Midazolam", "Alfentanil"),
    # ── Three agent ───────────────────────────────────────
    list("Propofol", "Midazolam", "Fentanyl"),
    list("Ketamine", "Midazolam", "Fentanyl"),
    list("Propofol", "Ketamine", "Fentanyl"),
    list("Propofol", "Lorazepam", "Fentanyl"),
    list("Propofol", "Alfentanil", "Fentanyl"),
    # ── Four agent ────────────────────────────────────────
    list("Propofol", "Midazolam", "Fentanyl", "Ketamine")
  ),

  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)",

 queries = list(
   # ── Single agent ─────────────────────────────────────
   list(query = intersects, params = list("Fentanyl"),  color = col_single, active = TRUE),
   list(query = intersects, params = list("Propofol"),  color = col_single, active = TRUE),
   list(query = intersects, params = list("Ketamine"),  color = col_single, active = TRUE),
   list(query = intersects, params = list("Midazolam"), color = col_single, active = TRUE),
   # ── Two agent ────────────────────────────────────────
   list(query = intersects, params = list("Propofol", "Fentanyl"),           color = col_two, active = TRUE),
   list(query = intersects, params = list("Ketamine", "Fentanyl"),           color = col_two, active = TRUE),
   list(query = intersects, params = list("Midazolam", "Fentanyl"),          color = col_two, active = TRUE),
   list(query = intersects, params = list("Propofol", "Ketamine"),           color = col_two, active = TRUE),
   list(query = intersects, params = list("Propofol", "Midazolam"),          color = col_two, active = TRUE),
   list(query = intersects, params = list("Propofol", "Alfentanil"),         color = col_two, active = TRUE),
   list(query = intersects, params = list("Ketamine", "RemifentanilTCI"),    color = col_two, active = TRUE),
   list(query = intersects, params = list("PropofolTCI", "RemifentanilTCI"), color = col_two, active = TRUE),
   list(query = intersects, params = list("Ketamine", "Midazolam"),          color = col_two, active = TRUE),
   list(query = intersects, params = list("Midazolam", "Alfentanil"),        color = col_two, active = TRUE),
   # ── Three agent ───────────────────────────────────────
   list(query = intersects, params = list("Propofol", "Midazolam", "Fentanyl"),  color = col_three, active = TRUE),
   list(query = intersects, params = list("Ketamine", "Midazolam", "Fentanyl"),  color = col_three, active = TRUE),
   list(query = intersects, params = list("Propofol", "Ketamine", "Fentanyl"),   color = col_three, active = TRUE),
   list(query = intersects, params = list("Propofol", "Lorazepam", "Fentanyl"),  color = col_three, active = TRUE),
   list(query = intersects, params = list("Propofol", "Alfentanil", "Fentanyl"), color = col_three, active = TRUE),
   # ── Four agent ────────────────────────────────────────
   list(query = intersects, params = list("Propofol", "Midazolam", "Fentanyl", "Ketamine"),
        color = col_four, active = TRUE)
 )
)

upset_plot

当前输出:在此输入图片描述

换句话说,我希望fentanyl位于顶部,lorazepam位于底部。这是我正在努力实现的生成示例。

在此输入图片描述

非常感谢您的帮助。

解决方案

如果提供了交集,那么 Set_names 通过 unique((unlist(intersections))) 派生,且对 sets 的排序将被忽略。

如果你查看 UpSetR::upset 的第27-28行

if (is.null(intersections) == F) {
  Set_names <- unique((unlist(intersections)))

这个 Set_names 随后被传递给

Set_sizes <- FindSetFreqs(New_data, first.col, Num_of_set, 
                          Set_names, keep.order)

这随后按它对 temp_data 进行排序,并返回为频率数据

> UpSetR:::FindSetFreqs
function (data, start_col, num_sets, set_names, keep_order) 
{
    end_col <- as.numeric(((start_col + num_sets) - 1))
    temp_data <- data[, start_col:end_col]
    temp_data <- temp_data[set_names]

最终用于 Make_size_plot(Set_sizes,...

为了解决这个问题,你可以将

Set_names <- unique((unlist(intersections)))

替换为

Set_names <- sets

使用

fn <- UpSetR::upset                                      # copy function
body(fn)[[6]][[3]][[2]] <- str2lang("Set_names <- sets") # change line

并在本次会话的 {UpSetR} 命名空间中重新赋值

assignInNamespace("upset", value = fn, ns = "UpSetR")

代码

library(UpSetR)

input <- c(
  Propofol                                    = 16,
  Ketamine                                    = 11,
  Midazolam                                   = 4, 
  Fentanyl                                    = 2,
  "Propofol&Fentanyl"                         = 97,
  "Propofol&Ketamine"                         = 5,
  "Propofol&Midazolam"                        = 4,
  "Propofol&Alfentanil"                       = 3,
  "Ketamine&Fentanyl"                         = 28,
  "Midazolam&Fentanyl"                        = 19,
  "Ketamine&Midazolam"                        = 1,
  "Midazolam&Alfentanil"                      = 1,
  "Ketamine&RemifentanilTCI"                  = 1,
  "PropofolTCI&RemifentanilTCI"               = 1,
  "Propofol&Midazolam&Fentanyl"               = 17,
  "Propofol&Ketamine&Fentanyl"                = 2,
  "Ketamine&Midazolam&Fentanyl"               = 4,
  "Propofol&Lorazepam&Fentanyl"               = 1,
  "Propofol&Alfentanil&Fentanyl"              = 1,
  "Propofol&Midazolam&Fentanyl&Ketamine"      = 1
)

X <- UpSetR::fromExpression(input)

fn <- UpSetR::upset
body(fn)[[6]][[3]][[2]] <- str2lang("Set_names <- sets") # order sets-plot by sets (bottom to top)
assignInNamespace("upset", value = fn, ns = "UpSetR")

# Give set-order manually because "Lorazepam" & "PropofolTCI" are tied with count = 1
setsOrder <- c("Lorazepam", "PropofolTCI", "RemifentanilTCI", "Alfentanil", "Midazolam", "Ketamine", "Propofol", "Fentanyl")

UpSetR::upset(
  X,
  sets = setsOrder,
  keep.order = TRUE,

  intersections = list(
    # ── Single agent ─────────────────────────────────────
    list("Fentanyl"),
    list("Propofol"),
    list("Ketamine"),
    list("Midazolam"),
    # ── Two agent ────────────────────────────────────────
    list("Propofol", "Fentanyl"),
    list("Ketamine", "Fentanyl"),
    list("Midazolam", "Fentanyl"),
    list("Propofol", "Ketamine"),
    list("Propofol", "Midazolam"),
    list("Propofol", "Alfentanil"),
    list("Ketamine", "RemifentanilTCI"),
    list("PropofolTCI", "RemifentanilTCI"),
    list("Ketamine", "Midazolam"),
    list("Midazolam", "Alfentanil"),
    # ── Three agent ───────────────────────────────────────
    list("Propofol", "Midazolam", "Fentanyl"),
    list("Ketamine", "Midazolam", "Fentanyl"),
    list("Propofol", "Ketamine", "Fentanyl"),
    list("Propofol", "Lorazepam", "Fentanyl"),
    list("Propofol", "Alfentanil", "Fentanyl"),
    # ── Four agent ────────────────────────────────────────
    list("Propofol", "Midazolam", "Fentanyl", "Ketamine")
  ),
  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)"
  # omitted your queries 
)

因为现在又重新按照 sets-order的顺序来排列,所以得到你想要的结果。

注:setsOrder 的顺序随后会从下到上绘制。

结果

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章