【问题标题】:R ggplot2 problems with stacked barplot with 3 variables mixed with mirror density chartR ggplot2问题与堆叠条形图与3个变量与镜像密度图混合
【发布时间】:2020-06-03 14:20:05
【问题描述】:

尊敬的 Stackoverflow 社区,

再一次,我有一个关于 R 的 ggplot2 可能性的问题。 在我开始解释我的问题之前,下面提供了一个数据框示例:

age <- c(12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15)
anticoagulation <- c(0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1)
atc <- c(1, 0, 2, 0, 1, 2, 1, 0, 2, 0, 1, 2, 1, 0, 2, 0, 1, 2, 0, 0)
df <- data.frame(age, anticoagulation, atc)
  • 抗凝编码:0 = 未抗凝,1 = 接受抗凝
  • atc 编码:0 = 呋喃妥因,1 = 磷霉素,2 = 甲氧苄啶

我想可视化每个年龄组和每个 atc 组的抗凝处方差异。到目前为止我做了什么:

frame <- aggregate(df$anticoagulation, by=list(df$age), FUN=length)
frame$age <- frame$Group.1
frame$n <- frame$x
frame <- frame [,3:4]

my_table<- table(df$age, df$anticoagulation)
table <- as.data.frame.matrix(my_table)
frame$n_noanti <- table$"0"
frame$n_yesanti <- table$"1"

frame$per_yesanti <- (frame$n_yesanti/frame$n)*100 # percentage
frame$per_noanti <- (frame$n_noanti/frame$n)*100 # percentage


ggplot(frame, aes(x=x) ) +
  geom_bar( aes(x = reorder (age, -per_yesanti), y =per_yesanti), stat="identity", fill="#69b3a2" ) +
  geom_label(aes(x=15, y=100, label="Used anticoagulants"), color="#69b3a2")+
  geom_bar( aes( x =reorder (age, -per_noanti), y=-per_noanti), stat="identity", fill="#404080" ) +
  geom_label( aes(x=15, y=-100, label="No anticoagulants"), color="#404080") +
  theme(axis.text.x=element_blank()) + 
  xlab ("Age") + 
  ylab ("Percentages of how many women used anticoagulants")+
  ggtitle("Distribution of anticoagulants per age")+
  theme(plot.title = element_text(hjust = 0.5), text = element_text(size=15))

输出 Output of ggplot mirror density here above

但是,我想要一个这样的图表,但有这样的堆积条: Example of stacked bars

堆叠部分基于 atc 编码。我试图只制作一个堆叠图,但失败得很惨。

我已经尝试使用代码“聚合”,但我不知道要使用什么以及要合并什么。

frame2 <- aggregate(frame$anticoagulation, by=list(frame$age, frame$atc), FUN=length)

但是,这个聚合代码使用起来太长了。

我也尝试过,为 atc vs age 使用单独的聚合代码并将其添加到“框架”。

atc2<- table(df$age, df$atc)
t_atc2 <- as.data.frame.matrix(atc2)
frame$n_nitro <- t_atc2$"0"
frame$n_fosfo <- t_atc2$"1"
frame$n_trim <- t_atc2$"2"

但是,我仍然无法让堆叠功能工作。我尝试做一个只有抗凝百分比=yes(编码=1)的堆叠条=

    ggplot(frame, aes(fill = n_nitro+n_fosfo+n_trim, y=per_yesanti, x=age)) + 
  geom_bar(position="stack", stat="identity") +
  ggtitle("Anticoagulation per age")

graph: No distinction between the 2 atc groups

我希望有人可以将这两个图表混合在一起。如果这是非常不可能的,那么只有抗凝百分比 = 1 (per_yesanti) 的堆叠图也很好。

所以,简而言之,如果混合图是非常困难的。如何制作以下图表(因此只有 1 个图表):

  • 仅使用抗凝剂的详细信息 = 1/ 是
  • 抗凝剂的详细信息必须以百分比表示(按总抗凝剂是/否计算)
  • x 轴是每个年龄
  • de bar 必须由 atc 填写

像这样: enter image description here

提前致谢!

【问题讨论】:

  • 为什么anticoagulation == 0 的观察有一个atc coding 的条目而不是NA?我原以为没有接受抗凝处方的人没有收到他们收到的抗凝处方的信息。
  • 说实话,我不太明白你的意思。原始数据集(以及我为 stackoverflow 制作的数据集)中没有 NA。目前尚不清楚患者服用了哪种抗凝剂。只是他们接受或没有接受抗凝剂,这就是我需要知道的。

标签: r ggplot2 stacked-chart stackedbarseries


【解决方案1】:

我仍然不确定如何处理您的数据,但我尝试给出答案。直接在ggplot2 中根据由另一个变量分组的百分比来获取条形图有点困难。因此,最简单的解决方案是预先计算百分比,然后使用geom_col 绘制这些。

使用dplyr,您可以group_by age 和您希望对其进行堆叠分隔的其他变量:

age <- c(12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15)
anticoagulation <- c(0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1)
atc <- c(1, 0, 2, 0, 1, 2, 1, 0, 2, 0, 1, 2, 1, 0, 2, 0, 1, 2, 0, 0)
df <- data.frame(age, anticoagulation, atc)

library(dplyr)
library(ggplot2)

df_summary <- df %>% 
  group_by(age, anticoagulation) %>% 
  summarise(count = n()) %>% 
  mutate(percentage = count / sum(count) * 100)


ggplot(df_summary, aes(x = factor(age), y = percentage, fill = factor(anticoagulation))) +
         geom_col()

df_summary_2 <- df %>% 
  group_by(age, atc) %>% 
  summarise(count = n()) %>% 
  mutate(percentage = count / sum(count) * 100)

ggplot(df_summary_2, aes(x = factor(age), y = percentage, fill = factor(atc))) +
  geom_col()


编辑

我已经调整了我的图表。我无法想出一个解决方案来一次性计算所有内容。因此,我首先计算total_count_info 中每个年龄组的计数。这使我可以稍后计算每个年龄组的百分比。然后我计算atc 每个ageanticoagulation 的出现次数:

total_count_info <- df %>% 
  group_by(age) %>% 
  summarise(count_age = n())

df_summary_3 <- df %>% 
  group_by(age, anticoagulation, atc) %>% 
  summarise(count = n()) %>% 
  left_join(total_count_info) %>% 
  mutate(percentage = count / count_age * 100)


ggplot(df_summary_3 %>% filter(anticoagulation == 1),
aes(x = factor(age), y = percentage, fill = factor(atc))) +
  geom_col() +
  ylab("percentage of anticoagulation == 1")

【讨论】:

  • 感谢您回答我的问题!我看到您制作了 2 个不同的图表:1 个带有年龄与抗凝的图表,1 个带有年龄和 atc 的图表。是对的吗?如果是这样,是否有可能将它们结合起来?要在 x 轴上显示年龄,用 atc 除/填充的抗凝量百分比 (=yes)?
猜你喜欢
  • 2014-12-08
  • 2016-11-30
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
相关资源
最近更新 更多