利用Rmd代码选项输出动态金字塔图

R

科研作图

人口金字塔图可以形象的展示人口结构,而动态人口金字塔则可以直观的展示历年人口结构的变化情况,从而可以直观的对人口数据进行质量控制,本篇博文讲介绍如何利用R语言Rmd文档输出动态人口金字塔图。

首先,我们先看一下需要准备的人口数据结构,数据集包含某个地区男性和女性每年的不同年龄组的人口数(5岁一组),年份变量为year,性别变量为sex,人口数据分别为r0、r1、r5、r10、… 、r85等。

data<-read.csv("population.csv")
head(data)
  year  sex   r0    r1    r5   r10   r15   r20   r25   r30   r35   r40   r45
1 2009 男性 5992 22345 25843 26164 43929 54912 58033 47602 54539 50224 40894
2 2009 女性 5857 22146 24908 25507 48444 47977 52270 46133 48743 44852 39429
3 2010 男性 6583 39619 42627 39820 45037 54131 34227 34382 42964 47668 38828
4 2010 女性 5484 30619 32323 31418 40701 56864 36506 34890 42224 48566 40392
5 2011 男性 5798 33931 40512 38334 47433 49693 33125 34833 47700 50181 42654
6 2011 女性 4983 29613 34439 33614 43799 51384 34154 35228 45182 47480 40500
    r50   r55   r60   r65   r70  r75  r80  r85
1 40855 29236 18125 13376 10564 6242 2369  577
2 39600 28104 18908 14984 11186 6425 3363 1408
3 28353 32932 24141 16239 11913 8333 4241 1970
4 28425 32685 23329 16139 12245 9821 5835 3879
5 33943 33498 22853 15307 12274 8428 4032 1694
6 32253 32249 22456 15207 12998 9966 5459 3507

1 作图思路

首先把现有的数据从宽数据转换为长数据,然后对数据进行简单处理,最后利用for循环和ggplot2输出多个年份的人口金字塔图,然后利用code chunk 选项输出动态图片。

2 数据处理

library(dplyr)
library(tidyr)
data <- data %>%
  ## 把宽数据转换为长数据
  gather("agegrp","rks",-year,-sex)%>%
  ## 整理年龄组变量,添加标签转换显示格式
  mutate(agegrp=as.numeric(gsub("[^0-9]", "", agegrp)),
         agegrp=factor(agegrp,labels = c("0","1-4","5-9","10-14","15-19","20-24","25-29","30-34","35-39","40-44","45-49","50-54","55-59","60-64","65-69","70-74","75-79","80-84","85+")))%>%
  group_by(year)%>%
  ## 把男性人口数转换为负值,以是条图显示在左侧
  mutate(rks=round(rks/sum(rks),4),
         rks=ifelse(sex=="男性",-rks,rks))

3 Rmd code chunk 选项

利用Rmd文档可以输出成很多种格式的输出结果,比如word、ppt、网页、pdf等,本篇博文介绍的为输出到网页显示动态图片。

在Rmd文档中插入r语言代码块,代码块的选项设置为fig.show=‘animate’,animation.hook=‘gifski’,当代码块内的语句生成多个图片的时候,会自动设置为动画播放。

4 利用for循环和ggplot2制作金字塔图

在代码块内部,使用for循环和ggplot2生成多个年份的人口金子塔图即可。

## 加载ggplot2包
library(ggplot2)
## 建立for循环
for (i in 2011:2017) {
 data %>% 
    filter(year==i) %>%
  ggplot(aes(x=factor(agegrp),y=rks,fill=sex)) +
  geom_bar(stat = "identity",position = "identity",color="black",linewidth=0.25)+
  geom_text(aes(label=paste0(abs(rks) * 100, '%')))+
  coord_flip()+
  theme_classic()+
  xlab("")+
  ylab("")+
  scale_y_continuous(limits = c(-0.08,0.08),breaks=seq(-0.08,0.08,0.02),labels = function(x) paste0(abs(x) * 100, '%'))+
  labs(title="历年人口金字塔变化情况",subtitle=paste(i))+
  theme(legend.position = c(0.1,0.9),
        legend.title = element_blank(),
        strip.text = element_text(size=10, face="bold.italic"),
        strip.background = element_rect(color="white", size=0),
        axis.text=element_text(size=10),
        axis.title=element_text(size=12, face="bold"),
        plot.title = element_text(face="bold", size=14, hjust = 0.5),
        plot.subtitle=element_text(face="bold",size=20,hjust=0.8))->p
  plot(p)
}
Warning: The `size` argument of `element_rect()` is deprecated as of ggplot2 3.4.0.
ℹ Please use the `linewidth` argument instead.
Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
3.5.0.
ℹ Please use the `legend.position.inside` argument of `theme()` instead.

陈琼博士

陈 琼

博士 副主任医师

他从事肿瘤登记与人群流行病学研究,编写肿瘤登记年报,并开发和维护个人网站。他撰写博文,分享数据分析方法、可视化技巧和自动化报告解决方案,同时学习 R 语言,开发 R 包,不断探索高效的数据处理与展示方式。 🚀

回到顶部