我想创建一个GGPLOT2人口金字塔。 这个问题被问之前 ,但我相信,解决方案必须简单得多。
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()
用来获得相当值轴。
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
版本相同的结果可以用功能atchieved 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()
一般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()
请注意,如果你的数据是在个人层面,而不是由年龄和性别组总结,那么答案在这里也相当普遍意义。