多面水平发散堆积条形图,包括使用 dplyr 和 ggplot 的负值

Jon*_*ley 5 r bar-chart ggplot2 dplyr likert

我希望这个例子会很清楚。我想在中间条跨越“0”的地方堆叠条,因为它代表一个中性值。这与李克特量表一起使用。为了重现性,我使用了钻石数据集。

以下示例与我的用例非常接近,并说明了我将“好”或“正”数据按正确顺序排列的困难(因此中性最接近 0)。

这是我的代码:

require(tidyverse)

diamonds_new <- diamonds %>%
  mutate(quality = fct_recode(cut, "Very poor" = "Fair", "Poor" = "Good", "Neutral" = "Very Good", "Good" = "Premium", "Excellent" = "Ideal")) %>% 
  select(color, clarity, quality) %>% 
  group_by(color, clarity, quality) %>% count()

diamonds_bad <- 
  diamonds_new %>% filter(quality %in% c("Very poor", "Poor", "Neutral")) %>% 
  mutate(n = ifelse(quality == "Neutral", -n/2, -n))

diamonds_good <- 
  diamonds_new %>% filter(quality %in% c("Neutral", "Good", "Excellent")) %>% 
  mutate(n = ifelse(quality == "Neutral", n/2, n)) # %>% 
#  arrange(color, clarity, desc(quality))  # this doesn't seem to make a difference

ggplot() + geom_col(data = diamonds_bad, aes(x=color, y = n, fill = quality)) +  
  geom_col(data = diamonds_good, aes(x=color, y = n, fill = quality)) + 
  facet_grid(. ~ clarity, scales = "free") + 
  coord_flip()
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明 我也尝试过使用,scale_fill_manual()但也没有找到可行的方法。

我相信这比一些现有的例子更复杂,这些例子没有负值的复杂性或需要span 0. 使用当前版本的 ggplot,我错过了什么?

另外,我是否正确地认为需要拆分正集和负集,或者至少这样做更容易?

CMi*_*ael 1

像这样的事情 - 我的关键改变是远离你可以自由控制开始和结束的geom_col地方geom_rectangle

diamonds_new <-  diamonds %>%
  mutate(quality = fct_recode(cut, "Very poor" = "Fair", "Poor" = "Good", "Neutral" =     "Very Good", "Good" = "Premium", "Excellent" = "Ideal")) %>% 
  select(color, clarity, quality) %>% 
  group_by(color, clarity, quality) %>% 
  count() %>% 
  group_by(color, clarity) %>% 
  arrange(quality) %>%
  mutate(end = cumsum(n)) %>%  
  mutate(start = end-n) %>%
  mutate(offset = (end[quality=="Neutral"] + start[quality=="Neutral"])/2) %>%   
  mutate(start = start - offset,
         end = end - offset) %>%
  mutate(colStart = as.numeric(color) + 0.25,
         colEnd = as.numeric(color) + 0.75)
Run Code Online (Sandbox Code Playgroud)

看到第二个答案(并且没有看到OP的任何输入)后,我还添加了一个替代的分面。

ggplot() + 
    geom_rect(data = diamonds_new, aes(xmin=colStart, xmax=colEnd, ymin=start, ymax=end, fill = quality)) +  
    facet_wrap(. ~ clarity, scales="free_x") +        
    coord_flip()
Run Code Online (Sandbox Code Playgroud)

WaltS 的答案保留了 y 轴上的因子水平,这当然更接近原始问题。然而,它需要对数据进行大量更改,因此我认为保留我的替代答案是有价值的。

在此输入图像描述

如果零需要在面板中居中,则需要进行xlim相应调整。