重新排序堆叠的geom_bar

时间:2018-05-31 14:58:54

标签: r ggplot2 data-visualization geom-bar

我第一次在这里问一个问题所以请放轻松!正如您从我的示例代码中看到的那样,我也是R的新手(3个月)所以有点不好意思展示它! 我有一个非常具体的要求,但可能有一种更好的可视化方法。我们的区域内有多次回答问题的人,我们希望比较第一次和最近的回复。答案基本上是1-5级,但我把它作为罗嗦的答案(从完全不足到完全充分)。我希望将“更差”的答案显示为否定,将好的答案显示为正数,并将中间答案(“相当不足”)分成两半,以便中间点在情节上集中(我是否有意义? !下面有一个样本图。我也希望按地区分组,这是第一次还是最后一次回复。 如果我绘制2个独立的数据帧,那么图表看起来不错,但我无法订购图例。 如果我联合数据帧,图例看起来不错但图表出错了!请帮忙!

# Input load
`dataset` = readr::read_csv("FirstLast,AnswerCount,Answer,Region
                 First,10,Completely Insufficient,North
                 First,3,Completely Insufficient,South
                 Last,5,Completely Insufficient,North
                 Last,1,Completely Insufficient,South
                 First,8,Mostly Insufficient,North
                 First,2,Mostly Insufficient,South
                 Last,9,Mostly Insufficient,North
                 Last,2,Mostly Insufficient,South
                 First,14,Quite Insufficient,North
                 First,3,Quite Insufficient,South
                 Last,19,Quite Insufficient,North
                 Last,7,Quite Insufficient,South
                 First,26,Mostly Sufficient,North
                 First,9,Mostly Sufficient,South
                 Last,44,Mostly Sufficient,North
                 Last,17,Mostly Sufficient,South
                 First,8,Completely Sufficient,North
                 First,3,Completely Sufficient,South
                 Last,16,Completely Sufficient,North
                 Last,3,Completely Sufficient,South")
require("dplyr")
library(dplyr)
require("ggplot2")
library(ggplot2)
require("tidyr")
library(tidyr)
require("stringr")
library(stringr)
require("formattable")
library(formattable)

# split mid answer for First reviews
Reviews.First.four <- filter(Reviews.Sums, FirstLast == "First", Answer=="Quite Insufficient") %>% mutate(AnswerCount=as.numeric(AnswerCount/2))
Reviews.First.rest <- filter(Reviews.Sums, FirstLast == "First", Answer != "Quite Insufficient")
Reviews.First <- full_join(Reviews.First.four, Reviews.First.rest) %>% arrange(Answer)
Reviews.First <- mutate(Reviews.First, RegRev = paste(Region, FirstLast))

# split mid answer for Last reviews
Reviews.Last.four <- filter(Reviews.Sums, FirstLast == "Last", Answer=="Quite Insufficient") %>% mutate(AnswerCount=as.numeric(AnswerCount/2))
Reviews.Last.rest <- filter(Reviews.Sums, FirstLast == "Last", Answer !="Quite Insufficient")
Reviews.Last <- full_join(Reviews.Last.four, Reviews.Last.rest) %>% arrange(Answer)
Reviews.Last <- mutate(Reviews.Last, RegRev = paste(Region,FirstLast))

# Split data into negative and positive scores
Reviews.First.Neg <- Reviews.First %>% 
filter (Answer == "Completely Insufficient" | Answer == "Mostly Insufficient" | Answer == "Quite Insufficient") %>% 
mutate(AnswerCount = AnswerCount *-1)
Reviews.First.Pos <- Reviews.First %>% 
filter (Answer == "Quite Insufficient" | Answer == "Mostly Sufficient" | Answer == "Completely Sufficient") 

Reviews.Last.Neg <- Reviews.Last %>% 
filter (Answer == "Completely Insufficient" | Answer == "Mostly Insufficient" | Answer == "Quite Insufficient") %>% 
mutate(AnswerCount = AnswerCount *-1)
Reviews.Last.Pos <-Reviews.Last %>% 
filter (Answer == "Quite Insufficient" | Answer == "Mostly Sufficient" | Answer == "Completely Sufficient") 

# Reorder factors (or try to anyway!)
Reviews.First.Neg$Answer <- factor(Reviews.First.Neg$Answer, levels=c("Completely Insufficient", "Mostly Insufficient", "Quite Insufficient"))
Reviews.First.Pos$Answer <- factor(Reviews.First.Pos$Answer, levels=rev(c("Quite Insufficient", "Mostly Sufficient", "Completely Sufficient")))
Reviews.Last.Neg$Answer <- factor(Reviews.Last.Neg$Answer, levels=c("Completely Insufficient", "Mostly Insufficient", "Quite Insufficient"))
Reviews.Last.Pos$Answer <- factor(Reviews.Last.Pos$Answer, levels=rev(c("Quite Insufficient", "Mostly Sufficient", "Completely Sufficient")))
# Other thing I tried was to order both factors same before union-ing them - plot Reviews.all instead of the separate First.Pos and First.Neg and still no joy - sad smiley 
#Reviews.First.Neg$Answer <- factor(Reviews.First.Neg$Answer, levels=c("Completely Insufficient", "Mostly Insufficient", "Quite Insufficient", "Mostly Sufficient", "Completely Sufficient"))
#Reviews.First.Pos$Answer <- factor(Reviews.First.Pos$Answer, levels=c("Completely Insufficient", "Mostly Insufficient", "Quite Insufficient", "Mostly Sufficient", "Completely Sufficient"))
#Reviews.all <- union(Reviews.First.Neg, Reviews.First.Pos)
#Reviews.all$Answer = factor(Reviews.all$Answer, levels=c("Completely Insufficient", "Mostly Insufficient", "Quite Insufficient", "Mostly Sufficient", "Completely Sufficient"))

# and plot!
ggplot() + 
# geom_bar(data=Reviews.all, aes(x=RegRev, y=AnswerCount, fill=Answer), stat="identity", position = "stack") +
geom_bar(data=Reviews.First.Neg, aes(x=RegRev, y=AnswerCount, fill=Answer), stat="identity", position = "stack") +
geom_bar(data=Reviews.First.Pos, aes(x=RegRev, y=AnswerCount, fill=Answer), stat="identity", position = "stack") +
geom_bar(data=Reviews.Last.Neg, aes(x=RegRev, y=AnswerCount, fill=Answer), stat="identity", position = "stack") +
geom_bar(data=Reviews.Last.Pos, aes(x=RegRev, y=AnswerCount, fill=Answer), stat="identity", position = "stack") +
coord_flip() + 
theme_minimal() + 
scale_fill_manual(values = c("#d7191c","#fdae61","#ffffbf","#abdda4","#2b83ba"))+
theme(
legend.position = "top"
) +
guides(fill = guide_legend(nrow = 2, byrow=TRUE))

TLDR - 我在R很可怕。任何帮助都非常感激。

If I plot the 2 separate dataframes then the chart looks good but I can't order the legend.

If I union the dataframes (just for First in this case) the legend looks good but the chart goes wrong! Argh!

1 个答案:

答案 0 :(得分:0)

如果您还想要其他调整或其他内容,请告诉我。

    Reviews.comb <- bind_rows(Reviews.Last.Pos, Reviews.Last.Neg, Reviews.First.Pos, Reviews.First.Neg)

    cols <- c("#d7191c","#fdae61","#ffffbf","#abdda4","#2b83ba")
    ord <- c("Completely Insufficient", "Mostly Insufficient", "Quite Insufficient", "Mostly Sufficient", "Completely Sufficient")

    ggplot() + geom_bar(data=Reviews.comb, aes(x=RegRev, y=AnswerCount, fill=Answer), stat="identity", position = "stack") +
      coord_flip() + 
      theme_minimal() + 
      scale_fill_manual(breaks = ord, values = cols) +
      theme(
        legend.position = "top") +
      guides(fill = guide_legend(nrow = 2, byrow=TRUE)) + 
      labs(x = "Answer Count", y = "Reg Rev") + expand_limits(y = c(-50, 50))

<强>更新   我添加了expand_limits以尝试将条形图集中在0左右。

我还将你的union命令与bind_rows等价物(bind_rows(Reviews.First.Pos, Reviews.First.Neg))进行了比较;只有订单不同。这可能是改变图表顺序的原因。休息部分应该为您重新排序图表。