ggplot geom_bar:堆栈和中心

时间:2012-11-16 17:04:02

标签: r ggplot2 bar-chart

我有一个数据框,其中的份额为百分比,列代表不同的项目,各行的受访者在不同的类别中回答。我想制作一个堆积的条形图。

library(ggplot2)
library(reshape2)
 test<-data.frame(i1=c(16,40,26,18),
               i2=c(17,46,27,10),
               i3=c(23,43,24,10),
               i4=c(19,25,20,36))
 rownames(test)<-c("very i.","i.","less i.","not i.")

test.m<-melt(test)

ggplot(test.m, aes(x=variable, y=value, fill=value)) + 
   geom_bar(position="stack", stat="identity")

看起来o.k.,但我想要 a)将条形图集中:正面答案(非常i。和i)向上和底部两个类别(减去i。而不是i。)向下。
b)具有相同颜色的每个类别(非常我,我,少我,不是我)。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:12)

最好使用类别名称作为分隔符而不是行名称:

test$category <- factor(c(3,4,2,1), labels=c("very i.","i.","less i.","not i."))

(因子水平的排序是通过对堆积的条形图进行的(最低:not i.,最高:very i.)。

test.m <- melt(test)

回答你的问题:

  1. 如果某些值高于其他值且其他值低于零,则堆积的条形图不能正常工作。因此,创建了两个单独的条形图(一个具有负值,一个具有正值)。
  2. 新列category用于fill参数,以便将每个类别映射为不同的颜色。
  3. 完整的代码:

    ggplot(test.m, aes(x=variable, fill=category)) + 
          geom_bar(data = subset(test.m, category %in% c("less i.","not i.")),
                   aes(y = -value), position="stack", stat="identity") +
          geom_bar(data = subset(test.m, !category %in% c("less i.","not i.")), 
                   aes(y = value), position="stack", stat="identity")
    

    enter image description here

答案 1 :(得分:10)

为此目的而设计的另一个工具是HH包中的likert()。这个甜蜜的功能绘制了适合于李克特,语义差异和评级量表数据的不同堆叠条形图。

library(HH)
# note use of t(test)[,4:1] to transpose and mirror dataframe for easy plotting
# test dataframe is otherwise unaltered from OP's question

likert(t(test)[,4:1], horizontal = FALSE,
       main = NULL, # or give "title",
       xlab = "Percent", # becomes ylab due to horizontal arg
       auto.key = list(space = "right", columns = 1,
                     reverse = TRUE))

enter image description here

likert()的一个特别吸引人的功能是能够使用ReferenceZero参数使中性响应居中。 (注意它如何使用适当的灰色进行参考响应):

likert(t(test)[,4:1], horizontal=FALSE,
       main = NULL, # or give "title",
       xlab = "Percent", # becomes ylab due to horizontal arg
       ReferenceZero = 3,
       auto.key=list(space = "right", columns = 1,
                     reverse = TRUE))

likert data centered on one response

(这些示例通常使用竖线,但horizontal=TRUE通常更好,特别是如果想要包含问题或比例名称。)