ggplot2中更简单的人口金字塔

我想用ggplot2创build一个人口金字塔。 这个问题之前被问到过 ,但我相信解决scheme一定要简单得多。

test <- (data.frame(v=rnorm(1000), g=c('M','F'))) require(ggplot2) ggplot(data=test, aes(x=v)) + geom_histogram() + coord_flip() + facet_grid(. ~ g) 

产生这个图像。 在我看来,创build人口金字塔的唯一步骤就是将第一个方面的x轴倒置,以便从50到0,而保持第二个方面不变。 谁能帮忙?

人口金字塔

这是一个没有方面的解决scheme。 首先,创build数据框。 我使用从1到20的值,以确保没有任何值是负值(人口金字塔,你不会得到负面的计数/年龄)。

 test <- data.frame(v=sample(1:20,1000,replace=T), g=c('M','F')) 

然后为每个g值分别组合两个geom_bar()调用。 对于F计数按原样计算,但M计数乘以-1得到反方向的小节。 然后使用scale_y_continuous()来获得轴的漂亮值。

 require(ggplot2) require(plyr) ggplot(data=test,aes(x=as.factor(v),fill=g)) + geom_bar(subset=.(g=="F")) + geom_bar(subset=.(g=="M"),aes(y=..count..*(-1))) + scale_y_continuous(breaks=seq(-40,40,10),labels=abs(seq(-40,40,10))) + coord_flip() 

UPDATE

作为参数subset=. 在最新的ggplot2版本中被弃用,相同的结果可以通过函数subset()

 ggplot(data=test,aes(x=as.factor(v),fill=g)) + geom_bar(data=subset(test,g=="F")) + geom_bar(data=subset(test,g=="M"),aes(y=..count..*(-1))) + scale_y_continuous(breaks=seq(-40,40,10),labels=abs(seq(-40,40,10))) + coord_flip() 

在这里输入图像描述

比Didzis Elferts更加通用的版本

  1. 避免横轴上的标签中断的一些摆弄
  2. 避免subset或需要额外的包(plyr)
  3. 仅使用geom_bar()一次。
  4. 具有相等的男性和女性横轴( limits = max(df0$Population) * c(-1,1) …如果不需要删除)

创build数据…

 set.seed(1) df0 <- data.frame(Age = factor(rep(x = 1:10, times = 2)), Gender = rep(x = c("Female", "Male"), each = 10), Population = sample(x = 1:100, size = 20)) head(df0) # Age Gender Population # 1 1 Female 27 # 2 2 Female 37 # 3 3 Female 57 # 4 4 Female 89 # 5 5 Female 20 # 6 6 Female 86 

剧情代码…

 library("ggplot2") ggplot(data = df0, mapping = aes(x = Age, fill = Gender, y = ifelse(test = Gender == "Male", yes = -Population, no = Population))) + geom_bar(stat = "identity") + scale_y_continuous(labels = abs, limits = max(df0$Population) * c(-1,1)) + labs(y = "Population") + coord_flip() 

在这里输入图像描述

请注意,如果您的数据是在个人层面上,而不是年龄 – 性别群体的总结,那么这里的答案也是相当一般化的。