我想用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,同时保持第二个不变。有人可以帮忙吗?
答案 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()
答案 1 :(得分:20)
一般的ggplot代码
subset
或需要其他套餐(例如plyr)。如果要在构面图中创建多个金字塔,这可能特别有用。geom_bar()
一次,如果您想要方面,则会有用。 limits = max(df0$Population) * c(-1,1)
...如果不需要,请删除代码中的行。创建数据......
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()
请注意,如果您的数据是个人级别而不是按年龄 - 性别组进行汇总,则答案here也非常普遍。
答案 2 :(得分:-1)