我想绘制一个(多面的)堆叠条形图,其中 X 轴以百分比表示。频率标签也显示在条内。
经过相当多的工作并在 stackoverflow 上查看了许多不同的问题后,我找到了一个关于如何使用 ggplot2 解决此问题的解决方案。但是,我不直接使用 ggplot2 执行此操作,而是通过表调用手动聚合数据。我以一种复杂的方式进行这种手动聚合,还使用临时变量手动计算百分比值(参见源代码注释“手动聚合数据”)。
如何在不手动和复杂的数据聚合的情况下以更好的方式绘制相同的图?
library(ggplot2)
library(scales)
library(gridExtra)
library(plyr)
##
## Random Data
##
fact1 <- factor(floor(runif(1000, 1,6)),
labels = c("A","B", "C", "D", "E"))
fact2 <- factor(floor(runif(1000, 1,6)),
labels = c("g1","g2", "g3", "g4", "g5"))
##
## STACKED BAR PLOT that scales x-axis to 100%
##
## manually aggregate data
##
mytable <- as.data.frame(table(fact1, fact2))
colnames(mytable) <- c("caseStudyID", "Group", "Freq")
mytable$total <- sapply(mytable$caseStudyID,
function(caseID) sum(subset(mytable, caseStudyID == caseID)$Freq))
mytable$percent <- round((mytable$Freq/mytable$total)*100,2)
mytable2 <- ddply(mytable, .(caseStudyID), transform, pos = cumsum(percent) - 0.5*percent)
## all case studies in one plot (SCALED TO 100%)
p1 <- ggplot(mytable2, aes(x=caseStudyID, y=percent, fill=Group)) +
geom_bar(stat="identity") +
theme(legend.key.size = unit(0.4, "cm")) +
theme(axis.text.x = element_text(angle = 60, hjust = 1)) +
geom_text(aes(label = sapply(Freq, function(x) ifelse(x>0, x, NA)), y = pos), size = 3) # the ifelse guards against printing labels with "0" within a bar
print(p1)
..
最佳答案
制作数据后:
fact1 <- factor(floor(runif(1000, 1,6)),
labels = c("A","B", "C", "D", "E"))
fact2 <- factor(floor(runif(1000, 1,6)),
labels = c("g1","g2", "g3", "g4", "g5"))
dat = data.frame(caseStudyID=fact1, Group=fact2)
您可以使用 position_fill
自动制作您想要的那种无标签图:
ggplot(dat, aes(caseStudyID, fill=Group)) + geom_bar(position="fill")
不知道有没有办法自动生成文本标签。如果您想使用 ggplot 计算的内容而不是单独计算,可以使用 ggplot_build
访问堆叠图中的位置和计数。
p = ggplot(dat, aes(caseStudyID, fill=Group)) + geom_bar(position="fill")
ggplot_build(p)$data[[1]]
这将返回一个数据帧(除其他外),count
,x
,y
,ymin
和 ymax
变量,可用于创建定位标签。
如果您希望标签在每个类别中垂直居中,请首先创建一列,其值介于 ymin
和 ymax
之间。
freq = ggplot_build(p)$data[[1]]
freq$y_pos = (freq$ymin + freq$ymax) / 2
然后使用annotate
将标签添加到图表中。
p + annotate(x=freq$x, y=freq$y_pos, label=freq$count, geom="text", size=3)
关于r - 如何在 ggplot2 中绘制(复杂的)堆叠条形图,而无需复杂的手动数据聚合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25518741/