R 使用ggplot2绘制发散堆积条形图

R 使用ggplot2绘制发散堆积条形图,r,ggplot2,R,Ggplot2,是否有一种方法可以使用ggplot2创建不同的堆叠条形图,如下图右侧的条形图 可复制示例的数据 库(ggplot2) 图书馆(比例尺) 图书馆(重塑) dat当然,正值叠加为正值,负值叠加为负值。不要使用位置填充。只要把你想要的定义为负值,然后把它们变成负值。你的例子只有正面的分数。例如 ggplot(datm, aes(x = variable, y = ifelse(ind %in% 1:2, -value, value), fill = ind)) + geom_col() +

是否有一种方法可以使用
ggplot2
创建不同的堆叠条形图,如下图右侧的条形图

可复制示例的数据
库(ggplot2)
图书馆(比例尺)
图书馆(重塑)

dat当然,正值叠加为正值,负值叠加为负值。不要使用位置
填充
。只要把你想要的定义为负值,然后把它们变成负值。你的例子只有正面的分数。例如

ggplot(datm, aes(x = variable, y = ifelse(ind %in% 1:2, -value, value), fill = ind)) + 
    geom_col() +
    coord_flip()

如果还希望缩放到1,则需要进行一些预处理:

library(dplyr)
datm %>% 
  group_by(variable) %>% 
  mutate(value = value / sum(value)) %>% 
  ggplot(aes(x = variable, y = ifelse(ind %in% 1:2, -value, value), fill = ind)) + 
  geom_col() +
  coord_flip()

一种极端的方法可能是自己计算方框。这里有一个方法

dd <- datm %>% group_by(variable) %>% 
  arrange(desc(ind)) %>% 
  mutate(pct = value/sum(value), right = cumsum(pct), left=lag(right, default=0))
要得到左边的图。为了得到正确的答案,你只需稍微移动一下盒子。这将对齐ind 3框的所有右边缘

ggplot(dd %>% group_by(variable) %>% mutate(left=left-right[ind==3], right=right-right[ind==3])) + 
  geom_rect(aes(xmin=right, xmax=left, ymin=as.numeric(variable)-.4, ymax=as.numeric(variable)+.4, fill=ind)) + 
  scale_y_continuous(labels=levels(dd$variable), breaks=1:nlevels(dd$variable))


因此,这里可能有过多的杀伤力,但通过这种方式,您可以进行大量的控制。

是的,如果目标是填充到1并叠加pos和neg,我很确定您需要进行预先计算。但我认为,你们应该仍然能够将所有级别缩放一次到1,然后改为负数并用位置堆栈进行绘图。不需要几何校正,这似乎是对的。老实说,我不知道ggplot如何处理负值条的堆叠。我只是想证明你基本上可以画出你想要的任何东西,也可以画出你想要的样子。公平地说,IIRC负叠加在某个点上发生了变化,可能是一年前吧?同意只要事情没有按您想要的方式发展,您就可以绘制基本体,如
rect
!可能重复的
ggplot(dd) + 
  geom_rect(aes(xmin=right, xmax=left, ymin=as.numeric(variable)-.4, ymax=as.numeric(variable)+.4, fill=ind)) + 
  scale_y_continuous(labels=levels(dd$variable), breaks=1:nlevels(dd$variable))
ggplot(dd %>% group_by(variable) %>% mutate(left=left-right[ind==3], right=right-right[ind==3])) + 
  geom_rect(aes(xmin=right, xmax=left, ymin=as.numeric(variable)-.4, ymax=as.numeric(variable)+.4, fill=ind)) + 
  scale_y_continuous(labels=levels(dd$variable), breaks=1:nlevels(dd$variable))