首页 > 解决方案 > ggplot 中的直方图按比例排序,仅取决于 R 中另一个变量的“是”值

问题描述

我有看起来像这样的数据

df <- data.frame (
cancer = c(1, 0, 1, 0, 0, 1, 0, 0, 0, 0),
CVD =    c(0, 1, 1, 0, 1, 0, 0, 0, 0, 0),
diab =   c(0, 0, 0, 1, 0, 1, 0, 0, 1, 0),
stroke = c(0, 1, 1, 0, 1, 0, 0, 0, 1, 0),
asthma = c(1, 1, 1, 0, 1, 1, 0, 0, 0, 0),
SR_hlt = c(1, 2, 2, 2, 1, 1, 2, 2, 2, 1))

我想要做的是制作一个条形图,仅适用于患有感兴趣疾病的人,其中条形图的条形按 SR_hlt == 1 的人的比例排序。

为了制作这个图,我使用以下代码

1) 收集数据

df_grp <- df %>%
gather(key = condition, value = Y_N, -SR_hlt) %>%
group_by(condition, Y_N, SR_hlt) %>%
summarise(count = n()) %>%
mutate(freq = round(count/sum(count) * 100, digits = 1))

2)绘制此数据

df_plot <- df_grp  %>%
filter(Y_N == 1) %>%
ggplot(aes(x = reorder(condition, -freq), y = freq, fill = factor(SR_hlt)), width=0.5) +
geom_bar(stat="identity", position = position_dodge(0.9))
df_plot

应该是对条进行排序的x = reorder(condition, -freq)东西,但我认为这在这种情况下不起作用,因为频率值取决于第三个变量 SR_hlt 的值。是否可以freq根据 SR_hlt == 1 的值对条形图进行排序?

标签: rggplot2geom-bar

解决方案


这可以使用方便的包来完成forcats,特别是fct_reorder2

df_plot <- df_grp  %>%
  filter(Y_N == 1) %>%
  ggplot(aes(x = fct_reorder2(condition, SR_hlt, -freq), 
             y = freq, fill = factor(SR_hlt)), width=0.5) +
  geom_bar(stat="identity", position = position_dodge(0.9))
df_plot

这是设置condition为一个因素,由于SR_hlt == 1感兴趣,我们从低到高排列SR_hlt,然后是-freq,或者从高到低排列freq


ggplot或者,您可以在调用前仅使用标准设置因子dplyr

df_plot <- df_grp  %>%
  ungroup() %>% 
  filter(Y_N == 1) %>%
  arrange(SR_hlt, desc(freq)) %>% 
  mutate(condition = factor(condition, unique(condition))) %>% 
  ggplot(aes(x = condition, y = freq, fill = factor(SR_hlt)), width=0.5) +
  geom_bar(stat="identity", position = position_dodge(0.9))
df_plot

在上面,我使用arrange对数据帧进行排序,以获得最高freqSR_hlt. 接下来,我mutate通过考虑出现的顺序来利用已排序的数据帧condition


推荐阅读