ggplot2堆积条形图,在顶部放置NA。

3

这里回答提供了许多有关在堆积条形图中订购条形部分的优秀信息。尝试了各种替代方案后,我基本上得到了想要的顺序,但NA总是出现在堆栈底部,这不是我想要的。

ggplot(df, aes(x=time, fill=forcats::fct_rev(factor(able, levels=rev(likely))))) + 
  geom_bar() + 
  theme(axis.text.x = element_text(angle = 315, hjust = 0), 
        plot.margin = margin(10, 40, 10, 10))

enter image description here

x轴上的NA值在末尾,这很好。通常将NA放在末尾可能是个不错的选择。但是对于堆叠条形图,我认为起点应该在底部,终点应该在顶部(因为底部的内容更容易比较)。

(Marimekko图表可能更好,但我放弃了尝试使用ggmosaic和其他一些工具后。)

编辑:我找到了一些代码,修改后制作了Marimekko图表(想要给出信用,但我忘记了我在哪里找到它)。它确实将NA值放在了顶部。

enter image description here

df %>%
group_by(satisfied, time) %>%
summarise(n = n()) %>%
mutate(x.width = sum(n)) %>%

ggplot(aes(x=satisfied, y=n)) +
geom_col(aes(width=x.width, fill=time),
         colour = "white", size=2, position=position_fill(reverse = T)) +
geom_text(aes(label=n),
           position=position_fill(vjust = 0.5)) +
facet_grid(~ satisfied, space = 'free', scales='free', switch='x') +
#scale_x_discrete(name="a") +
scale_y_continuous(labels=scales::percent) +
theme(axis.text.x = element_blank(),
      axis.ticks.x = element_blank(),
      axis.title.y = element_blank(),
      strip.text = element_text(angle = 270, hjust = 0),
      strip.background = element_blank(),
      panel.spacing = unit(0,'pt'))

在 @z-lin 的请求下序列化的数据:

> dput(df)
structure(list(explanatory = c(8L, 3L, 13L, 10L, 5L, 9L, NA, 
5L, 1L, 4L, 4L, 3L, 2L, 2L, 2L, NA, 2L, NA, 4L, 3L, 2L, NA, 6L, 
NA, 2L, 6L, 5L, 1L, 3L, 2L, 1L, NA, 3L, 2L, 5L, 6L, 3L, 7L, 13L, 
4L, 4L, 3L, 1L, 2L, 2L, NA, 7L, 1L, NA, 12L, 13L, 4L, 6L, 2L, 
3L, 1L, 1L, 1L, 3L, 9L, 6L, 4L, 5L, 2L, 10L, 4L, 7L, NA, 4L, 
5L, 1L, 7L, 12L, 4L, 1L, 2L, 5L, 3L, 13L, 6L, 13L, 4L, NA, 2L, 
7L, 4L, 12L, 3L, 2L, 5L, 9L, 6L, 13L, 2L, 12L, 4L, 13L, 2L, 7L, 
NA, NA, NA, 4L, 5L, NA, NA, 7L, 5L, 5L, NA, 2L, 4L, 5L, 13L, 
5L, 2L, 2L, 4L, 7L, 4L, 7L, 6L, 5L, 5L, NA, 3L, 2L, NA, 3L, 5L, 
11L, 2L, 2L, 3L, 3L, 9L, 1L, 2L, 3L, 5L, 12L, 2L, 5L, 3L, 5L, 
5L, 12L, 2L, 2L, 3L, 4L, 1L, 1L, 3L, 2L, 3L, 4L, 13L, 3L, 3L, 
NA, NA, 6L, 5L, 3L, 1L, 8L, 6L, 9L, 5L, 8L, 1L, 1L, 3L, 5L, 6L, 
3L, 1L, 1L, 8L, 4L, 13L, 13L, 4L, 2L, NA, 3L, 1L, 3L, 4L, 5L, 
1L, 5L, 8L, 1L, 4L, 5L, 4L, 4L, 12L, 9L, NA, 2L, NA, NA, 5L, 
4L, 1L, 12L, 6L, NA, NA, NA, 4L, 12L, NA, 4L, 2L, 11L, NA, 5L, 
2L, 2L, 1L, NA, 6L, NA, 12L, 3L, 2L, 4L, NA, 1L, 6L, 8L, NA, 
4L, 6L, 5L, 6L, NA, 4L, NA, 2L, 7L, 8L, 3L, 6L, NA, 4L, NA, 2L, 
6L, 4L, 5L, NA, 12L, 2L, 12L, 6L, 6L, 13L, NA, 3L, 4L, 2L, NA, 
11L, 12L, 4L, 8L, 5L, 1L, 5L, 1L, 1L, 7L, 4L, 1L, 2L, 7L, 2L, 
3L, 5L, NA, 5L, 4L, NA, 6L, 9L, 2L, 1L, NA, 5L, 4L, NA, 1L, 6L, 
5L, 2L, 9L, 4L, 5L, 3L, 5L, 10L, 6L, 4L, 12L, 3L, 12L, 2L, 1L, 
1L, 5L, 9L, 2L, 2L, 2L, NA, 11L, 4L, 9L, NA, 12L, 2L, 1L, 10L, 
4L, 3L, 5L, NA, 10L, 3L, 2L, 8L, 3L, 4L, 9L, 4L, 10L, 1L, 2L, 
6L, 13L, 8L, 4L, 4L, 9L, 1L, 2L, 4L, 1L, 8L, 5L, 9L, 9L, 4L, 
4L, 6L, 3L, 1L, 2L, 5L, 3L, 1L, 1L, 12L, 1L, 2L, 3L, 4L, 10L, 
2L, 2L, 4L, 5L, 7L, 7L, 5L, 4L, 3L, 4L, 6L, 13L, 3L, NA, 3L, 
2L, 2L, 1L, NA, NA, 1L, NA, 4L, 2L, 8L, 4L, 8L, 3L, NA, 2L, 8L, 
8L, 4L, 5L, 4L, 2L, 4L, 2L, 5L, 1L, 6L, 5L, 7L, 4L, 3L, 5L, 3L, 
3L, 2L, 4L, 3L, 1L, 6L, 4L, 2L, 13L, 13L, NA, 5L, 5L, 2L, 5L, 
2L, 8L), response = c(3L, 5L, 4L, 4L, 4L, 3L, NA, 4L, 5L, 5L, 
4L, 4L, 5L, 5L, 4L, NA, 4L, NA, 2L, 5L, 4L, 4L, 5L, 4L, 5L, 3L, 
4L, 5L, 5L, 3L, 5L, 4L, 5L, 5L, 5L, 4L, 5L, 4L, 4L, 4L, 4L, 5L, 
5L, 5L, 4L, 4L, 4L, 4L, 5L, 4L, 4L, 5L, 5L, 4L, 4L, 4L, 4L, 5L, 
4L, 3L, 5L, 4L, 5L, 4L, 4L, 5L, 4L, 4L, 4L, 5L, 4L, 4L, 2L, 5L, 
5L, 4L, 3L, 5L, 4L, 5L, 4L, 5L, 4L, 4L, 4L, 5L, 3L, 4L, 3L, 4L, 
3L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 4L, NA, NA, NA, 5L, 4L, NA, NA, 
4L, 4L, 4L, NA, 4L, 5L, 3L, 4L, 4L, 5L, 5L, 5L, 4L, 5L, 5L, 5L, 
5L, 5L, 2L, 4L, 4L, NA, 4L, 5L, 4L, 3L, 4L, 4L, 5L, 4L, 4L, 4L, 
3L, 4L, 4L, 5L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 4L, 4L, 3L, 2L, 
5L, 5L, 5L, 5L, 2L, 5L, NA, NA, 4L, 3L, 4L, 4L, 4L, 4L, 2L, 3L, 
4L, 4L, 4L, 4L, 5L, 5L, 4L, 5L, 4L, 4L, 4L, 5L, 5L, 5L, 4L, 4L, 
3L, 4L, 4L, 5L, 4L, 5L, 4L, 4L, 4L, 4L, 4L, 5L, 4L, 4L, 3L, NA, 
5L, NA, NA, 3L, 3L, 5L, 4L, 4L, NA, 4L, NA, 5L, 4L, NA, 4L, 5L, 
5L, 3L, 4L, 4L, 4L, 4L, NA, 5L, NA, 4L, 4L, 4L, 5L, 5L, 4L, 4L, 
4L, 5L, 5L, 4L, 4L, 5L, NA, 5L, NA, 4L, 5L, 4L, 4L, 1L, NA, 4L, 
NA, 4L, 5L, 2L, 5L, NA, 4L, 4L, 5L, 4L, 4L, 4L, NA, 4L, 5L, 4L, 
3L, 5L, 5L, 5L, 2L, 3L, 5L, 5L, 4L, 4L, 5L, 4L, 3L, 4L, 4L, 5L, 
4L, 5L, NA, 5L, 5L, NA, 5L, 4L, 4L, 5L, NA, 5L, 4L, NA, 5L, 5L, 
5L, 4L, 3L, 5L, 4L, 4L, 2L, 5L, 4L, 4L, 5L, 4L, 5L, 4L, 5L, 4L, 
4L, 4L, 4L, 4L, 5L, NA, 4L, 4L, 5L, NA, 4L, 4L, 4L, 3L, 3L, 5L, 
5L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 4L, 4L, 5L, 5L, 5L, 
4L, 3L, 4L, 5L, 4L, 4L, 5L, 5L, 4L, 5L, 5L, 4L, 5L, 4L, 3L, 3L, 
4L, 5L, 3L, 4L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 
5L, 4L, 3L, 5L, 5L, 4L, 4L, 5L, NA, 4L, 4L, 4L, 5L, 3L, NA, 3L, 
3L, 4L, 5L, 5L, 5L, 4L, 5L, NA, 5L, 5L, 5L, 4L, 4L, 2L, 4L, 4L, 
5L, 5L, 4L, 4L, 5L, 5L, 4L, 3L, 5L, 5L, 4L, 4L, 4L, 5L, 4L, 4L, 
5L, 5L, 4L, 5L, NA, 4L, 4L, 4L, 4L, 3L, 4L), time = structure(c(8L, 
3L, 13L, 10L, 5L, 9L, NA, 5L, 1L, 4L, 4L, 3L, 2L, 2L, 2L, NA, 
2L, NA, 4L, 3L, 2L, NA, 6L, NA, 2L, 6L, 5L, 1L, 3L, 2L, 1L, NA, 
3L, 2L, 5L, 6L, 3L, 7L, 13L, 4L, 4L, 3L, 1L, 2L, 2L, NA, 7L, 
1L, NA, 12L, 13L, 4L, 6L, 2L, 3L, 1L, 1L, 1L, 3L, 9L, 6L, 4L, 
5L, 2L, 10L, 4L, 7L, NA, 4L, 5L, 1L, 7L, 12L, 4L, 1L, 2L, 5L, 
3L, 13L, 6L, 13L, 4L, NA, 2L, 7L, 4L, 12L, 3L, 2L, 5L, 9L, 6L, 
13L, 2L, 12L, 4L, 13L, 2L, 7L, NA, NA, NA, 4L, 5L, NA, NA, 7L, 
5L, 5L, NA, 2L, 4L, 5L, 13L, 5L, 2L, 2L, 4L, 7L, 4L, 7L, 6L, 
5L, 5L, NA, 3L, 2L, NA, 3L, 5L, 11L, 2L, 2L, 3L, 3L, 9L, 1L, 
2L, 3L, 5L, 12L, 2L, 5L, 3L, 5L, 5L, 12L, 2L, 2L, 3L, 4L, 1L, 
1L, 3L, 2L, 3L, 4L, 13L, 3L, 3L, NA, NA, 6L, 5L, 3L, 1L, 8L, 
6L, 9L, 5L, 8L, 1L, 1L, 3L, 5L, 6L, 3L, 1L, 1L, 8L, 4L, 13L, 
13L, 4L, 2L, NA, 3L, 1L, 3L, 4L, 5L, 1L, 5L, 8L, 1L, 4L, 5L, 
4L, 4L, 12L, 9L, NA, 2L, NA, NA, 5L, 4L, 1L, 12L, 6L, NA, NA, 
NA, 4L, 12L, NA, 4L, 2L, 11L, NA, 5L, 2L, 2L, 1L, NA, 6L, NA, 
12L, 3L, 2L, 4L, NA, 1L, 6L, 8L, NA, 4L, 6L, 5L, 6L, NA, 4L, 
NA, 2L, 7L, 8L, 3L, 6L, NA, 4L, NA, 2L, 6L, 4L, 5L, NA, 12L, 
2L, 12L, 6L, 6L, 13L, NA, 3L, 4L, 2L, NA, 11L, 12L, 4L, 8L, 5L, 
1L, 5L, 1L, 1L, 7L, 4L, 1L, 2L, 7L, 2L, 3L, 5L, NA, 5L, 4L, NA, 
6L, 9L, 2L, 1L, NA, 5L, 4L, NA, 1L, 6L, 5L, 2L, 9L, 4L, 5L, 3L, 
5L, 10L, 6L, 4L, 12L, 3L, 12L, 2L, 1L, 1L, 5L, 9L, 2L, 2L, 2L, 
NA, 11L, 4L, 9L, NA, 12L, 2L, 1L, 10L, 4L, 3L, 5L, NA, 10L, 3L, 
2L, 8L, 3L, 4L, 9L, 4L, 10L, 1L, 2L, 6L, 13L, 8L, 4L, 4L, 9L, 
1L, 2L, 4L, 1L, 8L, 5L, 9L, 9L, 4L, 4L, 6L, 3L, 1L, 2L, 5L, 3L, 
1L, 1L, 12L, 1L, 2L, 3L, 4L, 10L, 2L, 2L, 4L, 5L, 7L, 7L, 5L, 
4L, 3L, 4L, 6L, 13L, 3L, NA, 3L, 2L, 2L, 1L, NA, NA, 1L, NA, 
4L, 2L, 8L, 4L, 8L, 3L, NA, 2L, 8L, 8L, 4L, 5L, 4L, 2L, 4L, 2L, 
5L, 1L, 6L, 5L, 7L, 4L, 3L, 5L, 3L, 3L, 2L, 4L, 3L, 1L, 6L, 4L, 
2L, 13L, 13L, NA, 5L, 5L, 2L, 5L, 2L, 8L), .Label = c("0-15 minutes", 
"15-30 minutes", "30-45 minutes", "45-60 minutes (1 hour)", "60 minutes (1 hour) - 75 minutes", 
"75-90 minutes", "90-105 minutes", "105-120 minutes (2 hours)", 
"120 minutes (2 hours) - 135 minutes", "135-150 minutes", "150-165 minutes", 
"165-180 minutes (3 hours)", "More than 3 hours"), class = "factor"), 
    able = c("Neither Agree nor Disagree", "Strongly Agree", 
    "Agree", "Agree", "Agree", "Neither Agree nor Disagree", 
    NA, "Agree", "Strongly Agree", "Strongly Agree", "Agree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Agree", NA, 
    "Agree", NA, "Disagree", "Strongly Agree", "Agree", "Agree", 
    "Strongly Agree", "Agree", "Strongly Agree", "Neither Agree nor Disagree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Neither Agree nor Disagree", 
    "Strongly Agree", "Agree", "Strongly Agree", "Strongly Agree", 
    "Strongly Agree", "Agree", "Strongly Agree", "Agree", "Agree", 
    "Agree", "Agree", "Strongly Agree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Agree", "Agree", "Agree", "Strongly Agree", "Agree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Agree", "Agree", 
    "Agree", "Agree", "Strongly Agree", "Agree", "Neither Agree nor Disagree", 
    "Strongly Agree", "Agree", "Strongly Agree", "Agree", "Agree", 
    "Strongly Agree", "Agree", "Agree", "Agree", "Strongly Agree", 
    "Agree", "Agree", "Disagree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Neither Agree nor Disagree", "Strongly Agree", 
    "Agree", "Strongly Agree", "Agree", "Strongly Agree", "Agree", 
    "Agree", "Agree", "Strongly Agree", "Neither Agree nor Disagree", 
    "Agree", "Neither Agree nor Disagree", "Agree", "Neither Agree nor Disagree", 
    "Agree", "Agree", "Agree", "Strongly Agree", "Strongly Agree", 
    "Strongly Agree", "Strongly Agree", "Agree", NA, NA, NA, 
    "Strongly Agree", "Agree", NA, NA, "Agree", "Agree", "Agree", 
    NA, "Agree", "Strongly Agree", "Neither Agree nor Disagree", 
    "Agree", "Agree", "Strongly Agree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Strongly Agree", 
    "Strongly Agree", "Strongly Agree", "Disagree", "Agree", 
    "Agree", NA, "Agree", "Strongly Agree", "Agree", "Neither Agree nor Disagree", 
    "Agree", "Agree", "Strongly Agree", "Agree", "Agree", "Agree", 
    "Neither Agree nor Disagree", "Agree", "Agree", "Strongly Agree", 
    "Agree", "Agree", "Agree", "Agree", "Agree", "Agree", "Strongly Agree", 
    "Strongly Agree", "Agree", "Agree", "Neither Agree nor Disagree", 
    "Disagree", "Strongly Agree", "Strongly Agree", "Strongly Agree", 
    "Strongly Agree", "Disagree", "Strongly Agree", NA, NA, "Agree", 
    "Neither Agree nor Disagree", "Agree", "Agree", "Agree", 
    "Agree", "Disagree", "Neither Agree nor Disagree", "Agree", 
    "Agree", "Agree", "Agree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Strongly Agree", "Agree", "Agree", "Agree", "Strongly Agree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Agree", "Neither Agree nor Disagree", 
    "Agree", "Agree", "Strongly Agree", "Agree", "Strongly Agree", 
    "Agree", "Agree", "Agree", "Agree", "Agree", "Strongly Agree", 
    "Agree", "Agree", "Neither Agree nor Disagree", NA, "Strongly Agree", 
    NA, NA, "Neither Agree nor Disagree", "Neither Agree nor Disagree", 
    "Strongly Agree", "Agree", "Agree", NA, "Agree", NA, "Strongly Agree", 
    "Agree", NA, "Agree", "Strongly Agree", "Strongly Agree", 
    "Neither Agree nor Disagree", "Agree", "Agree", "Agree", 
    "Agree", NA, "Strongly Agree", NA, "Agree", "Agree", "Agree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Agree", "Agree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Agree", "Strongly Agree", 
    NA, "Strongly Agree", NA, "Agree", "Strongly Agree", "Agree", 
    "Agree", "Strongly Disagree", NA, "Agree", NA, "Agree", "Strongly Agree", 
    "Disagree", "Strongly Agree", NA, "Agree", "Agree", "Strongly Agree", 
    "Agree", "Agree", "Agree", NA, "Agree", "Strongly Agree", 
    "Agree", "Neither Agree nor Disagree", "Strongly Agree", 
    "Strongly Agree", "Strongly Agree", "Disagree", "Neither Agree nor Disagree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Agree", "Strongly Agree", 
    "Agree", "Neither Agree nor Disagree", "Agree", "Agree", 
    "Strongly Agree", "Agree", "Strongly Agree", NA, "Strongly Agree", 
    "Strongly Agree", NA, "Strongly Agree", "Agree", "Agree", 
    "Strongly Agree", NA, "Strongly Agree", "Agree", NA, "Strongly Agree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Neither Agree nor Disagree", 
    "Strongly Agree", "Agree", "Agree", "Disagree", "Strongly Agree", 
    "Agree", "Agree", "Strongly Agree", "Agree", "Strongly Agree", 
    "Agree", "Strongly Agree", "Agree", "Agree", "Agree", "Agree", 
    "Agree", "Strongly Agree", NA, "Agree", "Agree", "Strongly Agree", 
    NA, "Agree", "Agree", "Agree", "Neither Agree nor Disagree", 
    "Neither Agree nor Disagree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Agree", "Agree", "Agree", "Agree", "Agree", "Strongly Agree", 
    "Strongly Agree", "Strongly Agree", "Strongly Agree", "Agree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Neither Agree nor Disagree", "Agree", "Strongly Agree", 
    "Agree", "Agree", "Strongly Agree", "Strongly Agree", "Agree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Strongly Agree", 
    "Agree", "Neither Agree nor Disagree", "Neither Agree nor Disagree", 
    "Agree", "Strongly Agree", "Neither Agree nor Disagree", 
    "Agree", "Neither Agree nor Disagree", "Agree", "Agree", 
    "Agree", "Agree", "Agree", "Agree", "Agree", "Agree", "Agree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Agree", "Neither Agree nor Disagree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Agree", "Strongly Agree", 
    NA, "Agree", "Agree", "Agree", "Strongly Agree", "Neither Agree nor Disagree", 
    NA, "Neither Agree nor Disagree", "Neither Agree nor Disagree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Strongly Agree", NA, "Strongly Agree", "Strongly Agree", 
    "Strongly Agree", "Agree", "Agree", "Disagree", "Agree", 
    "Agree", "Strongly Agree", "Strongly Agree", "Agree", "Agree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Neither Agree nor Disagree", 
    "Strongly Agree", "Strongly Agree", "Agree", "Agree", "Agree", 
    "Strongly Agree", "Agree", "Agree", "Strongly Agree", "Strongly Agree", 
    "Agree", "Strongly Agree", NA, "Agree", "Agree", "Agree", 
    "Agree", "Neither Agree nor Disagree", "Agree")), row.names = c(NA, 
-437L), class = "data.frame")

1
是的,我已经做了。似乎无论如何都没有什么区别。 - Sigfried
1
你需要将NA值设置为“NA”吗?如果不需要,你可以用因子水平“'NA'”替换它们,并像其他因子一样排序。 - divibisan
1
你能在你的问题中包含 dput(df) 的输出吗?那样会更容易进行故障排除。 - Z.Lin
好的,我做到了。您认为我是否应该更改问题/标题,以便我要求的答案是Marimekko图表?我可能会遇到相同的NA排序问题,但Marimekko图表比仅修复NA位置要更有帮助。 - Sigfried
@Sigfried,最好是提出一个新问题,然后关闭这个问题或者保持开放状态,以防有人比我们提供更好的答案。 - divibisan
显示剩余3条评论
1个回答

7
这里的问题在于factor()默认情况下会排除NA,需要手动覆盖默认设置。
这将把NA放在最上层进行绘制:
likely <- c(NA, "Strongly Disagree", "Disagree", "Neither Agree nor Disagree", 
            "Agree", "Strongly Agree") 
library(ggplot2)
ggplot(df, aes(x = time, fill = factor(able, levels = likely, exclude = NULL)
)) +
  geom_bar() +
  theme(axis.text.x = element_text(angle = 315, hjust = 0),
        plot.margin = margin(10, 40, 10, 10))

此外,NA也可以移到图例的顶部:

enter image description here

ggplot(df, aes(x = time, fill = factor(able, levels = likely, exclude = NULL)
)) +
  geom_bar() +
  theme(axis.text.x = element_text(angle = 315, hjust = 0),
        plot.margin = margin(10, 40, 10, 10)) +
  scale_fill_discrete(breaks = likely)

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接