如何根据分面包装中的 2 个组中的 1 个对条形图进行排序?

Posted

技术标签:

【中文标题】如何根据分面包装中的 2 个组中的 1 个对条形图进行排序?【英文标题】:How to sort bars according to 1 of 2 groups in a facet wrap? 【发布时间】:2021-10-01 03:10:14 【问题描述】:

我希望有人可以帮助我解决以下问题: 我想显示 2 个不同组 (gruppe) 的不同实验室参数 (parameter) 的值 (avg)。此外,我想根据 3 个不同方面随时间的变化(性能)绘制此信息。 这里是数据集的一部分:

# A tibble: 402 x 4
# Groups:   gruppe, parameter [134]
   gruppe parameter                      performance     avg
   <chr>  <chr>                          <chr>         <dbl>
 1 DGE    ACPA(citrull. Prot.-Ak) EIA/Se change_t1t0 NaN    
 2 DGE    ACPA(citrull. Prot.-Ak) EIA/Se change_t2t0  37.6  
 3 DGE    ACPA(citrull. Prot.-Ak) EIA/Se change_t3t0 NaN    
 4 Fasten Apolipoprot. A1 HP             change_t1t0  41.2 
 5 DGE    Apolipoprot. A1 HP             change_t2t0 NaN    
 6 DGE    Apolipoprot. A1 HP             change_t3t0 NaN    
 7 DGE    Apolipoprotein B               change_t1t0 NaN    
 8 DGE    Apolipoprotein B               change_t2t0 NaN    
 9 Fasten Apolipoprotein B               change_t3t0 NaN    
10 DGE    aPTT Pathromtin SL             change_t1t0   0.571
# … with 392 more rows

使用此代码完全可以正常工作:

#Create labels for 3 facets
lab_labels <- c("Change from Baseline to Day 7 [%]",
                "Change from Baseline to Week 6 [%]",
                "Change from Baseline to Week 12 [%]")

names(lab_labels) <- c("change_t1t0",
                       "change_t2t0",
                       "change_t3t0")

labor_summ_long %>%
  filter(parameter %in% c("Hämatokrit (l/l)","Hämoglobin", "Leukozyten","MCV", "MCH", "MCHC", "RDW-CV", "Thromobzyten","MPV")) %>%
  arrange(desc(avg))%>%
  group_by(gruppe, performance)%>%
  ggplot(aes(x=reorder(parameter,avg), y=avg, group=gruppe, fill = gruppe))+
  geom_col(position = position_dodge())+
  facet_wrap(~performance, 
             scales ="free_y", 
             dir="v",
             labeller = labeller(performance = lab_labels))+
  ylab("") + 
  xlab("") + 
  labs(color="", linetype="")+
  theme_pubclean()+
  theme(strip.background=element_rect(fill="lightgrey"),
        strip.text = element_text(face="bold"),
        legend.position = "bottom",
        legend.title=element_blank())+
  theme(axis.text.x = element_text(angle=45, hjust=1, vjust = 1))+
  scale_x_discrete(labels = c("Hämoglobin"="Hemoglobin", "Leukozyten" = "Leucocytes",
                              "MCV", "MCH", "MCHC", "RDW-CV", "Thromobzyten"="Thrombocytes",
                              "MPV", "Hämatokrit (l/l)"="Hematocrite"))+
  scale_fill_discrete(labels=c('DGE', "Fasten"='Fasting'))

This is how the plot looks like

我缺少什么并且无法找到以下解决方案: 我想订购酒吧...

按照从高到低的平均值 禁食组(蓝条) 从基线到第 7 天的表现 (change_t1t0),也就是第一个方面。

我玩弄了排列、排序等,但无法将上述所有条件放在一起。

你有什么想法吗? 提前非常感谢!

【问题讨论】:

为了帮助我们帮助您,您是否介意通过将您的数据样本共享为dput() 来重现您的问题?见how to make a minimal reproducible example。只需在控制台中输入dput(NAME_OF_DATASET) 并将以structure(.... 开头的输出复制并粘贴到您的帖子中。如果您的数据集有很多观察结果,您可以对前 20 行数据执行 dput(head(NAME_OF_DATASET, 20)) 起首 @stefan 以获得以下答案。他比我快了大约 5 分钟 :) ... @Anika:用 ggplot 绘制数据帧的一件烦人的事情是,您在屏幕上看到的(排序)不是数据项的固有顺序。因此,要解决的方法是创建此订单。如果您有多个条件,reorder() 可能会变得很麻烦。您始终可以创建一个新的因子列来实现您所追求的排序......或者使用像 stefan 提出的处理多个条件并在内部创建这个“因子”(在示例byby 中)内部的函数 ggplot() . 感谢 stefan 和 Ray 的快速而有帮助的回复!我之前没有看到 stefan 标记的其他查询。我会尝试两种方式(新因子列/功能),看看我更喜欢哪一种:)非常感谢! @stefan:感谢您提供有关数据卫星的提示。下次会这样做! 【参考方案1】:

问题在于 reorder 通过取每个 parameter 的所有值的平均值来重新排序,而不考虑任何分组。

根据您的情况调整this 的答案并使用一些随机示例数据来模拟您的真实数据,这可以像这样实现:

帮助函数reorder_where 允许通过附加条件对类别进行排序,例如在您的情况下,gruppe == "Fasten" &amp; performance == "change_t1t0"TRUE

library(dplyr)
library(ggplot2)

reorder_where <- function (x, by, where, fun = mean, ...) 
  xx <- x[where]
  byby <- by[where]
  byby <- tapply(byby, xx, FUN = fun, ...)[x]
  reorder(x, byby)


labor_summ_long %>%
  filter(parameter %in% c("Hämatokrit (l/l)","Hämoglobin", "Leukozyten","MCV", "MCH", "MCHC", "RDW-CV", "Thromobzyten","MPV")) %>%
  ggplot(aes(x=reorder_where(parameter, -avg, gruppe == "Fasten" & performance == "change_t1t0"), y=avg, group=gruppe, fill = gruppe))+
  geom_col(position = position_dodge())+
  facet_wrap(~performance, 
             scales ="free_y", 
             dir="v",
             labeller = labeller(performance = lab_labels))+
  ylab("") + 
  xlab("") + 
  labs(color="", linetype="")+
  #theme_pubclean()+
  theme(strip.background=element_rect(fill="lightgrey"),
        strip.text = element_text(face="bold"),
        legend.position = "bottom",
        legend.title=element_blank())+
  theme(axis.text.x = element_text(angle=45, hjust=1, vjust = 1))+
  scale_x_discrete(labels = c("Hämoglobin"="Hemoglobin", "Leukozyten" = "Leucocytes",
                              "MCV", "MCH", "MCHC", "RDW-CV", "Thromobzyten"="Thrombocytes",
                              "MPV", "Hämatokrit (l/l)"="Hematocrite"))+
  scale_fill_discrete(labels=c('DGE', "Fasten"='Fasting'))

数据

set.seed(42)

labor_summ_long <- data.frame(
  parameter = sample(c("Hämatokrit (l/l)","Hämoglobin", "Leukozyten","MCV", "MCH", "MCHC", "RDW-CV", "Thromobzyten","MPV"), 100, replace = TRUE),
  gruppe = sample(c("DGE", "Fasten"), 100, replace = TRUE),
  performance = sample(c("change_t1t0",
                         "change_t2t0",
                         "change_t3t0"), 100, replace = TRUE),
  avg = runif(100, 0, 50)
)
labor_summ_long <- dplyr::distinct(labor_summ_long, parameter, gruppe, performance, .keep_all = TRUE)

【讨论】:

以上是关于如何根据分面包装中的 2 个组中的 1 个对条形图进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

R语言ggplot2可视化分面图(faceting)并设置每一个分面中的条形图都是排序的(bars are in order in each per facet of facet_warp)

绘制带有分面换行的条形图

R-4组中的分组条形图,3个子组

正则表达式匹配 4 个组中的 2 个

在 Java 正则表达式中匹配 y 个组中的 x 个

如何根据列中的颜色为条形图着色