Ggplot geom_bar: stack and center

I have a dataframe with percent fractions, columns representing different elements, builds the corresponding proportion of respondents answering in different categories. I want to create a complex barkar.

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") 

It looks ok, but I want a) to center the columns: the positive answers (very i and i) are up and the lower two classes (less than i, not i.) Down.
b) each category (very i, i, less than i, not i) having the same color.

Any help would be greatly appreciated.

+4
source share
2 answers

It is better to use category names as a separator instead of string names:

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

(The ordering of factor levels is performed taking into account what is laid out on the tablets (lowest: not i. , highest: very i. ).

 test.m <- melt(test) 

To answer your questions:

  • Folded flaps do not work well if some values ​​are higher and others are below zero. Therefore, two separate columns are created (one with negative values, one with positive values).
  • The new category column is used for the fill parameter to match each category with a different color.

Full code:

 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

+11
source

Another tool specifically designed for this purpose is likert() in the HH package. This sweet feature displays diverging stacked bar charts suitable for Likert data, semantic differential and rating.

 library(HH) # note use of t(test)[,4:1] to transpose and mirror dataframe for easy plotting # test dataframe is otherwise unaltered from OP 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

One particularly attractive feature of likert() is the ability to center a neutral response using the ReferenceZero argument. (Note how it uses the appropriate gray color for the reference response):

 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

(These examples use vertical columns, as usual, but horizontal=TRUE is often better, especially if you want to include question or scale names.)

+10
source

Source: https://habr.com/ru/post/1446498/


All Articles