利用ggplot2制作金字塔圖践美,展示人口結(jié)構(gòu)數(shù)據(jù)

人口金字塔圖是描述一個地區(qū)或國家人口結(jié)構(gòu)類型的常用圖示方式,今天我們介紹一下如何利用R語言制作金字塔圖找岖,快來看看如何作金字塔圖吧拨脉!

什么是人口金字塔圖?

人口金字塔是用類似古埃及金字塔的形象描繪人口年齡和性別分布狀況的圖形宣增。能表明人口現(xiàn)狀及其發(fā)展類型玫膀,比如看一個地區(qū)或國家的人口結(jié)構(gòu)類型是擴展型、穩(wěn)定型或者收縮型爹脾。

圖形的畫法是:按男女人口年齡自然順序自下而上在縱軸左右畫成并列的橫條柱帖旨,各條柱代表各個年齡組。底端標有按一定計算單位或百分比表示的人口數(shù)量灵妨。

下面我們介紹一下如何利用R畫出人口金字塔圖解阅。

用到哪些R包?

今天主要用到 dplyr包泌霍、reshape2包货抄、ggplot2包和cowplot包。 dplyr包和reshape2包用來進行數(shù)據(jù)整理朱转,ggplot2包和cowplot包用來畫圖和整合蟹地。

加載這些R包

library(dplyr)
## 
## 載入程輯包:'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(reshape2)
library(ggplot2)
library(cowplot)

數(shù)據(jù)處理

首先需要把我們手里的現(xiàn)有數(shù)據(jù)讀取到R工作環(huán)境,然后把數(shù)據(jù)調(diào)整為ggplot2包繪圖所需要的格式藤为。

我們看一下怪与,我們目前的數(shù)據(jù)結(jié)構(gòu)和變量基本信息吧,目前我們有一個數(shù)據(jù)框缅疟,數(shù)據(jù)框里有20列數(shù)據(jù)分别,第一列為性別(sex),其余分別為0遍愿,1,4~耘斩,...沼填,85+歲組各年齡組的人口數(shù)據(jù)。

pop  <- read.csv("pop.csv")
pop <- pop %>%
  #把合計人口數(shù)去掉只保留男性和女性人口
  filter(sex %in% c("男性","女性"))
head(pop)
##    sex     r0     r1      r5     r10     r15     r20     r25     r30     r35
## 1 男性 193565 924420 1186130 1158427 1130776 1254271 1426065 1291455 1279639
## 2 女性 176068 821772 1038768  991518 1002524 1162174 1365563 1235362 1208151
##       r40     r45     r50    r55    r60    r65    r70    r75    r80    r85
## 1 1322747 1338809 1145094 941395 812746 622679 440440 300147 183825 102596
## 2 1261624 1292094 1101333 918208 801106 635924 467743 342476 228937 164663

但是括授,ggplot2繪圖需要讀取縱向格式的數(shù)據(jù)倾哺,也就是說我們需要把目前的數(shù)據(jù)格式轉(zhuǎn)換成兩列,一列為性別刽脖,另一列為人口數(shù)羞海。因此,我們需要把目前的數(shù)據(jù)轉(zhuǎn)換成縱向結(jié)構(gòu)數(shù)據(jù)曲管。

reshape2包的melt函數(shù)可以把橫向數(shù)據(jù)轉(zhuǎn)換為縱向數(shù)據(jù)却邓,id.vars參數(shù)指定保留的變量名稱,其余的變量都轉(zhuǎn)職置為縱向結(jié)構(gòu)院水,轉(zhuǎn)換為兩列腊徙,一列存放變量名,一列存放變量值檬某。variable.name指定存放變量名的那一列的變量名撬腾,value.name指定存放變量值的那一列的變量名。

# 對橫向數(shù)據(jù)進行轉(zhuǎn)置恢恼,然后存入pop數(shù)據(jù)框
pop <- pop %>%
# reshape2包的melt函數(shù)轉(zhuǎn)置橫向數(shù)據(jù)
  melt(id.vars=c("sex"),
       variable.name="age",
       value.name = "pop")

現(xiàn)在來看看轉(zhuǎn)置后的數(shù)據(jù)吧

head(pop)
##    sex age     pop
## 1 男性  r0  193565
## 2 女性  r0  176068
## 3 男性  r1  924420
## 4 女性  r1  821772
## 5 男性  r5 1186130
## 6 女性  r5 1038768

然后把目前pop數(shù)據(jù)框的age變量值進行轉(zhuǎn)換民傻,因為它的值就是人口金字塔中顯示的年齡組的值。

pop<-pop%>%
  mutate(age=as.numeric(gsub("r","",age)),
         pop=ifelse(sex=="男性",-pop,pop))

繪制人口金字塔的時候场斑,橫條的長度采用跟年齡組人口數(shù)占相應(yīng)人口的百分比來表示漓踢,因此計算人口百分比數(shù)據(jù)。

age_label<- 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-")
pop <- pop%>%
  group_by(sex)%>%
  mutate(pop_rate=pop/sum(pop)*100)%>%
  mutate(pop_rate=ifelse(sex=="男性",-pop_rate,pop_rate))

然后把人口數(shù)據(jù)拆分成男性和女性兩個數(shù)據(jù)框漏隐,并把這個兩個數(shù)據(jù)框存入列表ct

ct <- pop%>%group_by(sex)%>%group_split()
ct
## <list_of<
##   tbl_df<
##     sex     : character
##     age     : double
##     pop     : integer
##     pop_rate: double
##   >
## >[2]>
## [[1]]
## # A tibble: 19 x 4
##    sex     age      pop pop_rate
##    <chr> <dbl>    <int>    <dbl>
##  1 男性      0  -193565   -1.13 
##  2 男性      1  -924420   -5.42 
##  3 男性      5 -1186130   -6.95 
##  4 男性     10 -1158427   -6.79 
##  5 男性     15 -1130776   -6.63 
##  6 男性     20 -1254271   -7.35 
##  7 男性     25 -1426065   -8.36 
##  8 男性     30 -1291455   -7.57 
##  9 男性     35 -1279639   -7.50 
## 10 男性     40 -1322747   -7.76 
## 11 男性     45 -1338809   -7.85 
## 12 男性     50 -1145094   -6.71 
## 13 男性     55  -941395   -5.52 
## 14 男性     60  -812746   -4.77 
## 15 男性     65  -622679   -3.65 
## 16 男性     70  -440440   -2.58 
## 17 男性     75  -300147   -1.76 
## 18 男性     80  -183825   -1.08 
## 19 男性     85  -102596   -0.602
## 
## [[2]]
## # A tibble: 19 x 4
##    sex     age     pop pop_rate
##    <chr> <dbl>   <int>    <dbl>
##  1 女性      0  176068     1.09
##  2 女性      1  821772     5.07
##  3 女性      5 1038768     6.41
##  4 女性     10  991518     6.11
##  5 女性     15 1002524     6.18
##  6 女性     20 1162174     7.17
##  7 女性     25 1365563     8.42
##  8 女性     30 1235362     7.62
##  9 女性     35 1208151     7.45
## 10 女性     40 1261624     7.78
## 11 女性     45 1292094     7.97
## 12 女性     50 1101333     6.79
## 13 女性     55  918208     5.66
## 14 女性     60  801106     4.94
## 15 女性     65  635924     3.92
## 16 女性     70  467743     2.88
## 17 女性     75  342476     2.11
## 18 女性     80  228937     1.41
## 19 女性     85  164663     1.02

為了使用方便喧半,我們編制一個函數(shù),并利用lapply函數(shù)把ct列表放入進去青责,這樣就可以自動生成橫向條形圖挺据。

制作金字塔圖的思路

我們先編寫一個函數(shù),實現(xiàn)對列表數(shù)據(jù)進行處理脖隶,判斷如果是男性數(shù)據(jù)的話則生成左側(cè)橫向條形圖扁耐,如果是女性數(shù)據(jù)的話則生成右側(cè)橫向條形圖,然后把利用cowplot把左側(cè)條形圖和右側(cè)條形圖組成一個金字塔圖浩村。

上程序:

# top_value <-  max(abs(pop$pop_rate)) 
p<- lapply(ct,function(x) {
  sexx <- x[1,c("sex")]
  abslabel <- function(x) {paste(abs(x),"%",sep="")}
  mycolor <- ifelse(sexx=="男性",paste("steelblue"),paste("red"))
  pp<-ggplot(x) + 
    geom_bar(aes(x=pop_rate,y=factor(age,labels=age_label)), stat = "identity",color="white",width=0.9,fill=ifelse(x$pop_rate>0,'#e31a1c','#1f78b4'))+
    scale_x_continuous(expand = expansion(),limits=c(0,9.9),labels=abslabel)+
    xlab(ifelse(sexx=="男性","男性","女性"))+
    theme_void()+
    theme(
      axis.title.y = element_blank(),
      panel.border = element_blank(),
      panel.grid=element_blank(),
      panel.grid.major =element_blank(),
      axis.ticks.y = element_blank(),
      axis.line.y=element_blank(),
      axis.text.x = element_text(face="bold"),
      axis.text.y =element_text(size=12),
      axis.title.x=element_text(size=12)
    )
  if (sexx=="男性"){ pp<- pp+ theme(axis.text.y =element_blank())+scale_x_continuous(expand = expansion(),limits=c(-9.9,0),labels=abslabel)
  }
  return(pp)
})

上面的程序有已經(jīng)把生成的左側(cè)和右側(cè)條形圖放入列表p做葵,下面把列表的第一個元素和第二個元素利用cowplot組合起來就是一個金字塔圖了。

# 利用plot_grid來組合p列表元素心墅,進行橫向拼接酿矢,存入pyramid
pyramid <- plot_grid(p[[1]],p[[2]],ncol=2,align="hv")

我們來看看最終的金字塔圖的吧。

pyramid
人口金字塔圖

小結(jié)

本篇文章介紹了如何利用R語言制作人口金字塔圖怎燥,利用本程序的思路瘫筐,稍微修改,可以批量制作金字塔圖铐姚。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末策肝,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子隐绵,更是在濱河造成了極大的恐慌之众,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件依许,死亡現(xiàn)場離奇詭異棺禾,居然都是意外死亡,警方通過查閱死者的電腦和手機峭跳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門膘婶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蛀醉,你說我怎么就攤上這事悬襟。” “怎么了拯刁?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵脊岳,是天一觀的道長。 經(jīng)常有香客問我垛玻,道長逸绎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任夭谤,我火速辦了婚禮棺牧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘朗儒。我一直安慰自己颊乘,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布醉锄。 她就那樣靜靜地躺著乏悄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪恳不。 梳的紋絲不亂的頭發(fā)上檩小,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音烟勋,去河邊找鬼规求。 笑死筐付,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的阻肿。 我是一名探鬼主播瓦戚,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼丛塌!你這毒婦竟也來了较解?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤赴邻,失蹤者是張志新(化名)和其女友劉穎印衔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姥敛,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡奸焙,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了徒溪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忿偷。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖臊泌,靈堂內(nèi)的尸體忽然破棺而出鲤桥,到底是詐尸還是另有隱情,我是刑警寧澤渠概,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布茶凳,位于F島的核電站,受9級特大地震影響播揪,放射性物質(zhì)發(fā)生泄漏贮喧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一猪狈、第九天 我趴在偏房一處隱蔽的房頂上張望箱沦。 院中可真熱鬧,春花似錦雇庙、人聲如沸谓形。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽寒跳。三九已至,卻和暖如春竹椒,著一層夾襖步出監(jiān)牢的瞬間童太,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留书释,地道東北人翘贮。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像征冷,于是被迫代替她去往敵國和親择膝。 傳聞我的和親對象是個殘疾皇子誓琼,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容