R ggplot2中更简单的人口金字塔
我想用ggplot2创建一个人口金字塔。有人问了这个问题,但我认为解决办法必须简单得多R ggplot2中更简单的人口金字塔,r,ggplot2,R,Ggplot2,我想用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) test这里是一个没有刻面的解决方案。首先,创建数据帧。我使用了从1到20的
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)
test这里是一个没有刻面的解决方案。首先,创建数据帧。我使用了从1到20的值来确保没有一个值是负的(使用人口金字塔,您不会得到负计数/年龄)
更新
由于参数subset=。
在最新的ggplot2
版本中被弃用,因此可以使用函数subset()
查看相同的结果
人口金字塔的通用ggplot代码模板(如下所示)
使用geom_col()
而不是geom_bar()
,后者具有更好的默认值stat
,并且避免了coord_flip()
通过在缩放功能中使用labels=abs
避免手动设置标签分隔符
具有相等的男性和女性水平轴(和标签),以便于性别之间的比较-使用lemon软件包中的scale\u x\u symmetric()
仅使用一个geom,避免了数据子集的需要;如果要在镶嵌面打印中创建多个棱锥体,这非常有用
正在创建数据
set.seed(100)
a <- seq(from = 0, to = 90, by = 10)
d <- data.frame(age = paste(a, a + 10, sep = "-"),
sex = rep(x = c("Female", "Male"), each = 10),
pop = sample(x = 1:100, size = 20))
head(d)
# age sex pop
# 1 0-10 Female 74
# 2 10-20 Female 89
# 3 20-30 Female 78
# 4 30-40 Female 23
# 5 40-50 Female 86
# 6 50-60 Female 70
扩展@gjabel的帖子,这里是一个更干净的人口金字塔,同样只使用ggplot2
popPy1 <- ggplot(data = venDemo,
mapping = aes(
x = AgeName,
y = ifelse(test = sex == "M", yes = -Percent, no = Percent),
fill = Sex2,
label=paste(round(Percent*100, 0), "%", sep="")
)) +
geom_bar(stat = "identity") +
#geom_text( aes(label = TotalCount, TotalCount = TotalCount + 0.05)) +
geom_text(hjust=ifelse(test = venDemo$sex == "M", yes = 1.1, no = -0.1), size=6, colour="#505050") +
# scale_y_continuous(limits=c(0,max(appArr$Count)*1.7)) +
# The 1.1 at the end is a buffer so there is space for the labels on each side
scale_y_continuous(labels = abs, limits = max(venDemo$Percent) * c(-1,1) * 1.1) +
# Custom colours
scale_fill_manual(values=as.vector(c("#d23f67","#505050"))) +
# Remove the axis labels and the fill label from the legend - these are unnecessary for a Population Pyramid
labs(
x = "",
y = "",
fill="",
family=fontsForCharts
) +
theme_minimal(base_family=fontsForCharts, base_size=20) +
coord_flip() +
# Remove the grid and the scale
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_text(family=fontsForCharts, size=20),
strip.text.x=element_text(family=fontsForCharts, size=24),
legend.position="bottom",
legend.text=element_text(size=20)
)
popPy1
popPy1我认为这更适合于前面关于同一主题的问题。有时人们不得不从ggplot2
@dmvianna迁移,我是一个狂热的ggplot2
用户,但当我最近不得不创建一个人口金字塔时,我最终放弃并使用了plotrix
软件包中的pyramid.plot
。这并不困难,结果完全可以被我的眼睛接受。坦白地说,这比使用ggplot
或我自己使用ggplot
的链接问题的结果要好得多。我得到了一个错误:“do.call(“layer”,list(mapping=mapping,data=data,stat=stat,:找不到函数”。“但是”+geom\bar(data=subset(test,g=“F”))'为我工作您可能需要使用library(plyr)
cool plot显式加载plyr
包。我收到一条警告:警告消息:In loop\u apply(n,do.ply):当ymin!=0时堆叠未定义好您知道它的含义吗?@ExpectoPatronum这是一个警告,因为我们在条形图中使用负值进行堆叠。发现错误“错误:未知参数:子集”在ggplot 2.1.0下。最好更新新版本的ggplot的答案。谢谢。在新版本的ggplot
2.1.0下工作。这是一个简单的方法,效果相当好。应该是最重要的答案。干净、简单和可扩展-这太棒了!很好的lemon
技巧!
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()
set.seed(100)
a <- seq(from = 0, to = 90, by = 10)
d <- data.frame(age = paste(a, a + 10, sep = "-"),
sex = rep(x = c("Female", "Male"), each = 10),
pop = sample(x = 1:100, size = 20))
head(d)
# age sex pop
# 1 0-10 Female 74
# 2 10-20 Female 89
# 3 20-30 Female 78
# 4 30-40 Female 23
# 5 40-50 Female 86
# 6 50-60 Female 70
library(ggplot2)
library(lemon)
ggplot(data = d,
mapping = aes(x = ifelse(test = sex == "Male", yes = -pop, no = pop),
y = age, fill = sex)) +
geom_col() +
scale_x_symmetric(labels = abs) +
labs(x = "Population")
popPy1 <- ggplot(data = venDemo,
mapping = aes(
x = AgeName,
y = ifelse(test = sex == "M", yes = -Percent, no = Percent),
fill = Sex2,
label=paste(round(Percent*100, 0), "%", sep="")
)) +
geom_bar(stat = "identity") +
#geom_text( aes(label = TotalCount, TotalCount = TotalCount + 0.05)) +
geom_text(hjust=ifelse(test = venDemo$sex == "M", yes = 1.1, no = -0.1), size=6, colour="#505050") +
# scale_y_continuous(limits=c(0,max(appArr$Count)*1.7)) +
# The 1.1 at the end is a buffer so there is space for the labels on each side
scale_y_continuous(labels = abs, limits = max(venDemo$Percent) * c(-1,1) * 1.1) +
# Custom colours
scale_fill_manual(values=as.vector(c("#d23f67","#505050"))) +
# Remove the axis labels and the fill label from the legend - these are unnecessary for a Population Pyramid
labs(
x = "",
y = "",
fill="",
family=fontsForCharts
) +
theme_minimal(base_family=fontsForCharts, base_size=20) +
coord_flip() +
# Remove the grid and the scale
theme(
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
axis.text.x=element_blank(),
axis.text.y=element_text(family=fontsForCharts, size=20),
strip.text.x=element_text(family=fontsForCharts, size=24),
legend.position="bottom",
legend.text=element_text(size=20)
)
popPy1