ggplot2中更简单的人口金字塔

时间:2013-02-04 03:47:40

标签: r ggplot2

我想用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,同时保持第二个不变。有人可以帮忙吗?

Population pyramid

3 个答案:

答案 0 :(得分:54)

这是一个没有刻面的解决方案。首先,创建数据框架。我使用了从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()用于获取轴的漂亮值。

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()

enter image description here

答案 1 :(得分:20)

一般的ggplot代码

  1. 避免一些摆弄水平轴上的标签断裂
  2. 避免subset或需要其他套餐(例如plyr)。如果要在构面图中创建多个金字塔,这可能特别有用。
  3. 仅使用geom_bar()一次,如果您想要方面,则会有用。
  4. 雄性和雌性水平轴相等;人口统计学家常用的limits = max(df0$Population) * c(-1,1) ...如果不需要,请删除代码中的行。
  5. 创建数据......

    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()
    

    enter image description here

    请注意,如果您的数据是个人级别而不是按年龄 - 性别组进行汇总,则答案here也非常普遍。

答案 2 :(得分:-1)

扩展@gjabel的帖子,这里是一个更加干净的人口金字塔,再次使用ggplot2。

abc.ptt.net/tt1/portreport  ------------>  tesla.ptt.net/porteport/login.jsp
abc.ptt.net/tt1/zoom  ------------>  tesla.ptt.net/zoom/login.jsp

Population Pyramid

相关问题