使用ggplot2和dplyr(而不是plyr)绘制人口金字塔图

4
我正在尝试使用ggplot2和dplyr(而不是plyr)来复制Simpler population pyramid in ggplot2中的简单人口金字塔。
以下是使用plyr和种子的原始示例。
set.seed(321)
test <- data.frame(v=sample(1:20,1000,replace=T), g=c('M','F'))

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

Pyramid plot with ggplot2 and plyr

运行正常。

但我该如何使用 dplyr 生成相同的图形呢?示例中在 subset = .(g == 语句中使用了 plyr

我尝试使用 dplyr::filter 进行以下操作,但出现错误:

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

Error in get(x, envir = this, inherits = inh)(this, ...) : 
  Mapping should be a list of unevaluated mappings created by aes or aes_string
3个回答

6
您可以通过在geom_bar中指定参数data来避免错误:
ggplot(data = test, aes(x = as.factor(v), fill = g)) + 
  geom_bar(data = dplyr::filter(test, g == "F")) + 
  geom_bar(data = dplyr::filter(test, g == "M"), aes(y = ..count.. * (-1))) + 
  scale_y_continuous(breaks = seq(-40, 40, 10), labels = abs(seq(-40, 40, 10))) + 
  coord_flip() 

5

最近的ggplot2版本使得在制作人口金字塔时可以避免使用dplyrplyr

如果你有年龄-性别组大小的计数,可以参考这里的答案。

如果你的数据是个体级别的(就像你的数据一样),请使用以下方法:

set.seed(321)
test <- data.frame(v=sample(1:20,1000,replace=T), g=c('M','F'))
head(test)
#    v g
# 1 20 M
# 2 19 F
# 3  5 M
# 4  6 F
# 5  8 M
# 6  7 F

library("ggplot2")
ggplot(data = test, aes(x = as.factor(v), fill = g)) + 
  geom_bar(data = subset(test, g == "F")) + 
  geom_bar(data = subset(test, g == "M"), 
           mapping = aes(y = - ..count.. ),
           position = "identity") +
  scale_y_continuous(labels = abs) +
  coord_flip()

enter image description here


我得到了类似的结果,只是y轴没有排序...(实际上是按字母顺序排序的:1,10,11,12,13,14,15,16,17,18,19,2,20,21,...) - RockScience
1
v 替换 as.factor(v) 可以解决问题:现在它的顺序正确了。 - RockScience
1
@gjabel,你能用这种方法将计数转换为百分比吗? - Prometheus

0

要使用个人数据或微观数据构建年龄金字塔,您可以使用以下方法:

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

ggplot(data = test, aes(x = v, fill = g)) + 
  geom_histogram(data = subset(test, g == "F"), binwidth = 5, color="white", position = "identity") +
  geom_histogram(data = subset(test, g == "M"), binwidth = 5, color="white", position = "identity", 
                 mapping = aes(y = - ..count.. )) +
  scale_x_continuous("Age", breaks = c(seq(0, 100, by=5))) +
  scale_y_continuous("Population", breaks = seq(-30, 30, 10), labels = abs) +
  scale_fill_discrete(name = "Sex") +
  coord_flip() +
  theme_bw()
 

在 geom_histogram() 中更改 binwidth 可以将您的数据分组为更宽的类别。

enter image description here

将binwidth更改为10并调整轴间断点:

ggplot(data = test, aes(x = v, fill = g)) + 
  geom_histogram(data = subset(test, g == "F"), binwidth = 10, color="white", position = "identity") +
  geom_histogram(data = subset(test, g == "M"), binwidth = 10, color="white", position = "identity", 
                 mapping = aes(y = - ..count.. )) +
  scale_x_continuous("Age", breaks = c(seq(0, 100, by = 10))) +
  scale_y_continuous("Population", breaks = seq(-100, 100, 10), labels = abs) +
  scale_fill_discrete(name = "Sex") +
  coord_flip() +
  theme_bw()

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接