这是一个数据框
DF <- data.frame(SchoolYear = c("2015-2016", "2016-2017"),
Value = sample(c('Agree', 'Disagree', 'Strongly agree', 'Strongly disagree'), 50, replace = TRUE))
我已创建此图表。
ggplot(DF, aes(x = Value, fill = SchoolYear)) +
geom_bar(position = 'dodge', aes(y = (..count..)/sum(..count..))) +
geom_text(aes(y = ((..count..)/sum(..count..)), label = scales::percent((..count..)/sum(..count..))),
stat = "count", vjust = -0.25, size = 2, position = position_dodge(width = 0.9)) +
scale_y_continuous(labels = percent) +
ylab("Percent") + xlab("Response") +
theme(axis.text.x = element_text(angle = 75, hjust = 1))
有没有办法让每个学年的数据加起来达到100%,但图中没有数据堆叠?
我知道这个问题类似于这个问题Create stacked barplot where each stack is scaled to sum to 100%,但我不希望图表堆叠。我无法弄清楚如何在我的问题中将解决方案应用于这种情况。此外,我不希望在绘图之前总结数据,因为我必须每次使用不同的数据多次制作此图表,并且不希望每次都必须汇总数据。
答案 0 :(得分:1)
我不确定如何在不转换数据的情况下创建所需的绘图。但是,如果要为多个数据集重用相同的代码,可以编写一个函数来转换数据并同时生成图:
plot.fun <- function (original.data) {
newDF <- reshape2::melt(apply(table(original.data), 1, prop.table))
Plot <- ggplot(newDF, aes(x=Value, y=value)) +
geom_bar(aes(fill=SchoolYear), stat="identity", position="dodge") +
geom_text(aes(group=SchoolYear, label=scales::percent(value)), stat="identity", vjust=-0.25, size=2, position=position_dodge(width=0.85)) +
scale_y_continuous(labels=scales::percent) +
ylab("Percent") + xlab("Response") +
theme(axis.text.x = element_text(angle = 75, hjust = 1))
return (Plot)
}
plot.fun(DF)
答案 1 :(得分:1)
重要免责声明:我高度建议您事先汇总数据,而不是尝试在ggplot
内进行这些计算。这不是ggplot
的意思。此外,它不仅不必要地使您的代码复杂化,而且可以轻松地引入错误/意外结果。
鉴于此,看起来你想要的是可行的(没有先总结)。通过在ggplot中进行计算得到你想要的东西的一种非常hacky方式是:
#Store factor values
fac <- unique(DF$SchoolYear)
ggplot(DF, aes(x = Value, fill = SchoolYear)) +
geom_bar(position = 'dodge', aes(y = (..count..)/stats::ave(..count.., get("fac", globalenv()), FUN = sum))) +
geom_text(aes(y = (..count..)/stats::ave(..count.., get("fac", globalenv()), FUN = sum), label = scales::percent((..count..)/stats::ave(..count.., get("fac", globalenv()), FUN = sum))),
stat = "count", vjust = -0.25, size = 2, position = position_dodge(width = 0.9)) +
scale_y_continuous(labels = percent) +
ylab("Percent") + xlab("Response") +
theme(axis.text.x = element_text(angle = 75, hjust = 1))
这会获取..count..
变量,并使用stats::ave
将其除以其各自组中的总和。请注意,这可能很容易搞砸极。
最后,我们检查情节实际上是否给了我们想要的东西。
#Check to see we have the correct values
d2 <- DF
d2 <- setDT(d2)[, .(count = .N), by = .(SchoolYear, Value)][, percent := count/sum(count), by = SchoolYear]