我想用ggplot2创建一个人口金字塔。有人问这个问题before,但是我相信解决方案必须简单得多。

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)

产生此图像。在我看来,创建人口金字塔的唯一缺少的步骤是将第一个构面的x轴反转,即从50变为0,同时保持第二个构面不变。有人可以帮忙吗?

最佳答案

这是一个没有多方面的解决方案。首先,创建数据框。我使用从1到20的值来确保所有值都不为负(使用人口金字塔,您不会得到负数/年龄)。

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

然后针对每个geom_bar()值分别组合两个g调用。对于F,计数按原样计算,但对于M,计数乘以-1以获得相反方向的柱线。然后scale_y_continuous()用于获取漂亮的axis值。
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()

更新

由于在最新的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()

08-24 16:14