Problem
We want to control the stacking order of a stacked bar created with ggplot2.
- Original chart By default the bars are stacked in alphabetical order based on the variable passed on to the argument fill.
library(reshape2)
library(ggplot2)
ra.melt <- melt(ra)
p <- ggplot(ra.melt, aes(x = variable, y = value))
p + geom_bar(aes(fill = quality), stat = "identity") +
labs(x = "group", y = "percentage (%)")
We double-check the levels of the variable quality.
levels(ra.melt$quality)
[1] "A" "B" "C" "D" "E" "F"
[7] "G" "H" "I" "J" "K" "L"
[13] "M" "other"
- Data
ra <- structure(list(quality = structure(c(2L, 6L, 13L, 1L, 7L, 5L,
10L, 4L, 3L, 9L, 11L, 12L, 8L, 14L), .Label = c("A", "B", "C",
"D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "other"), class = "factor"), GY = c(25.5932389, 13.9567819, 11.7333, 8.6439, 7.8351008,
8.29, 6.059643, 3.8608517, 4.3277, 3.1710598, 1.2021144,
1.0986329, 0.9369271, 3.2907496), TH = c(23.0215577, 15.8975387,
10.5075, 7.8888, 8.8121504, 8.276, 6.4356378, 3.9147685,
5.4838, 3.9339386, 1.3921565, 0.742406, 0.8795013, 2.8142444
), SZ = c(21.217152, 16.0363831, 11.154, 8.5094, 7.945884,
10.2717, 5.4962929, 4.1381946, 5.1141, 3.4053352, 1.8472827,
1.0648934, 0.9792861, 2.820096), DZ = c(23.7548859, 14.4732136,
12.1292, 10.4722, 8.0838209, 7.0575, 5.144598, 4.174118,
5.4004, 3.1940577, 1.4427867, 1.1323864, 0.8986281, 2.6422047
), FP = c(19.9848602, 16.420735, 12.9683, 11.2059, 7.5143706,
6.8747, 5.8653262, 5.5412901, 4.182, 3.5347168, 1.3838249,
0.8811604, 0.8585596, 2.7842562)), .Names = c("quality",
"GY", "TH", "SZ", "DZ", "FP"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14"))
quality GY TH SZ DZ FP 1 B 25.5932389 23.0215577 21.2171520 23.7548859 19.9848602 2 F 13.9567819 15.8975387 16.0363831 14.4732136 16.4207350 3 M 11.7333000 10.5075000 11.1540000 12.1292000 12.9683000 4 A 8.6439000 7.8888000 8.5094000 10.4722000 11.2059000 5 G 7.8351008 8.8121504 7.9458840 8.0838209 7.5143706 6 E 8.2900000 8.2760000 10.2717000 7.0575000 6.8747000 7 J 6.0596430 6.4356378 5.4962929 5.1445980 5.8653262 8 D 3.8608517 3.9147685 4.1381946 4.1741180 5.5412901 9 C 4.3277000 5.4838000 5.1141000 5.4004000 4.1820000 10 I 3.1710598 3.9339386 3.4053352 3.1940577 3.5347168 11 K 1.2021144 1.3921565 1.8472827 1.4427867 1.3838249 12 L 1.0986329 0.7424060 1.0648934 1.1323864 0.8811604 13 H 0.9369271 0.8795013 0.9792861 0.8986281 0.8585596 14 other 3.2907496 2.8142444 2.8200960 2.6422047 2.7842562
Solution
- Stacked in the data frame's original order
ra.melt$quality <- factor(ra.melt$quality, levels = ra$quality)
p <- ggplot(ra.melt, aes(x = variable, y = value))
p + geom_bar(aes(fill = quality), stat = "identity") +
labs(x = "group", y = "percentage (%)")
factor(ra.melt$quality, levels = ra$quality)
[1] B F M A G E J D
[9] C I K L H other B F
[17] M A G E J D C I
[25] K L H other B F M A
[33] G E J D C I K L
[41] H other B F M A G E
[49] J D C I K L H other
[57] B F M A G E J D
[65] C I K L H other
Levels: B F M A G E J D C I K L H other
- In reverse order
ra.melt$quality <- factor(ra.melt$quality, levels = rev(ra$quality))
p <- ggplot(ra.melt, aes(x = variable, y = value))
p + geom_bar(aes(fill = quality), stat = "identity") +
labs(x = "group", y = "percentage (%)")
factor(ra.melt$quality, levels = rev(ra$quality))
[1] B F M A G E J D
[9] C I K L H other B F
[17] M A G E J D C I
[25] K L H other B F M A
[33] G E J D C I K L
[41] H other B F M A G E
[49] J D C I K L H other
[57] B F M A G E J D
[65] C I K L H other
Levels: other H L K I C D J E G A M F B
Alternatively we can use the function fct_rev
library(forcats)
p <- ggplot(ra.melt, aes(x = variable, y = value))
p + geom_bar(aes(fill = fct_rev(quality)), stat = "identity") +
labs(x = "group", y = "percentage (%)")
- If we'd like to reverse the stacked order but but keeping the order of the legend, we use the argument position_stack(reverse = TRUE)
p <- ggplot(ra.melt, aes(x = variable, y = value))
p + geom_bar(aes(fill = fct_rev(quality)), stat = "identity", position = position_stack(reverse = TRUE)) + labs(x = "group", y = "percentage (%)")
Referencias
Related posts
Gracias!! me estaba enloqueciendo, no hallaba respuesta en ningun lado.
ResponderEliminarA ti por dejar tu comentario. Saludos.
Eliminar