利用R ggplot2包進行數據可視化(一)

一個好的可視化例子

各國家都喜愛哪些寵物?
by La Nación
作品地址
在這裏插入圖片描述

  該作品於2017年10月14日發表在《阿根廷國家報》上,並獲得了2018凱度信息之美獎藝術、娛樂與文化類獎項。該作品以GFK研究所對22個國家的網民進行的調查爲基礎。
  從該作品的圖表類型來看,可視爲簇狀條形圖。創作者採用人物和寵物的卡通形象巧妙地替代條形圖,極具趣味也不失直觀性,受衆能夠從中獲知的信息也比較充實,比如:魚在中國比其他地方更受歡迎,而貓是法國人最喜歡的寵物,其他國家的人們大多最喜歡狗;阿根廷和巴西的毛絨和羽毛寵物的喜歡人數多於其他國家。該作品較好地符合了“一張好的圖表應具有的基本特徵”:

  • 顯示數據:動物卡通圖片上標註了該動物受國民喜愛的佔比,並用虛線標註了該佔比數值在x軸上的刻度位置。
  • 讓讀者將注意力集中在圖表內容上,而不是製作程序上。總體來說該作品所要表達的信息比較明瞭直接,創意點也是圖表內容的一部分,既吸引了讀者的注意力,又突出了圖表內容。
  • 避免歪曲:座標軸標度合適,信息表達直觀準確。
  • 強調數據間的比較:對不同動物採取對比鮮明的色彩,使得無論是同一國家不同寵物之間的比較,還是不同國家間的比較都得到很好的突出。
  • 服務於一個明確的目的:該作品的目的在於展示研究者對各國國民的寵物偏好的調查結果。
  • 有對圖表的統計描述和文字說明:圖中缺少具體的描述和說明,但該作品作爲報刊插圖,配合文章內容可被較好地理解。

數據可視化的實現

  使用來自北大國家發展中心的數據中的數據表demographic_background,選取其中的三個變量進行研究:

  1. 年齡,定量變量。部分空值通過(調查年份-出生年份) 進行填補。
  2. 最高學歷,定性變量。
  3. 婚姻狀態,定性變量。

數據導入與處理:

library(foreign)
#導入數據
db_all<-read.dta("D:/4數據集四:北大國家發展中心數據/demographic_background/demographic_background.dta")
#選擇變量
db_data<-data.frame(age=db_all$ba004,edu=db_all$bd001,mrg=db_all$be001)
#利用出生年份計算受訪者受訪時的年齡以填補缺失
db_data$age[is.na(db_data$age)]<-(2012-db_all$ba002_1)[is.na(db_data$age)]
#查看數據缺失情況
library(mice)
md.pattern(db_data,plot=F)

數據缺失情況如下:

##       age mrg edu    
## 17650   1   1   1   0
## 23      1   1   0   1
## 1       1   0   1   1
## 8       1   0   0   2
## 2       0   1   1   1
## 21      0   0   0   3
##        23  30  52 105

  在填補後的數據中,絕大多數記錄不存在缺失。將仍存在缺失的記錄移除,得到17650條完整記錄。

單變量製圖:

對所調查人羣的最高學歷作圖:

  1. 條形圖
      爲了讀圖更直觀,將定型變量的各個水平用對應的中文表示。按照學歷水平從低到高對人羣的最高學歷分佈情況作條形圖:
library(ggplot2)
#最高學歷
levels(db_data$edu)<-c("文盲", "未讀完小學","私塾","小學","初中",
                    "高中","中專","大專","本科","碩士","博士")#用中文表述不同學歷水平
edu_table<-table(db_data$edu)
#條形圖
#R基礎作圖
barplot(edu_table,space = 1/2,ylim=c(0,5000),xlab = "最高學歷",ylab="人數")
#ggplot2
ggplot(db_data,aes(x=edu))+
  geom_bar(width = 2/3)+
  xlab( "最高學歷")+ylab("人數")

R基礎作圖:
在這裏插入圖片描述
ggplot2:
在這裏插入圖片描述
2. 餅圖
  按頻數從大到小順時針作餅圖:

#R基礎作圖工具
pie(sort(edu_table,T),clockwise=T,main = "所調查人羣最高學歷的頻數分佈情況")
#ggplot2
reorder_size <- function(x,descending=T) {#自定義函數對levels按照頻數進行重新排列
  factor(x, levels = names(sort(table(x),descending)))
}
label_per = paste(names(sort(table(db_data$edu),F)), "(",
                round(prop.table(table(reorder_size(db_data$edu,F))),4)*100,
                "%)", sep = "")#將百分比加到標籤文字上
ggplot(db_data,aes(x=factor(1),fill=reorder_size(edu,F))) + 
  geom_bar() + 
  coord_polar(theta = "y")+#變化爲極座標以形成餅圖 
  labs(x = "", y = "", title = "所調查人羣最高學歷的頻數分佈情況",
       fill='學歷水平')+ #去除餅圖旁邊的標籤
  theme(axis.ticks = element_blank()) + 
  theme(axis.text.x = element_blank(),axis.text.y = element_blank())+ #把原座標軸的刻度文字去掉
  theme(panel.grid=element_blank())+ # 去掉白色圓框和中間的座標線
  scale_fill_discrete(labels = label_per[-1]) #使用含有百分比的圖例

R基礎作圖工具:
在這裏插入圖片描述
ggplot2:
在這裏插入圖片描述

對所調查人羣的婚姻狀態作圖:

  1. 條形圖
      按照不同婚姻狀態頻數從多到少作條形圖:
#婚姻狀態
levels(db_data$mrg)<-c("已婚並同居","已婚但因工作暫分居","分居(不再作爲配偶)",
                       "離異","喪偶","從未結婚")#用中文表述不同婚姻狀態
mrg_table<-sort(table(db_data$mrg),T)
knitr::kable(t.data.frame(mrg_table), caption = "所調查人羣婚姻狀態的頻數分佈情況")
#條形圖
#R基礎作圖
barplot(mrg_table,space = 1/2,xlab = "婚姻狀態",ylab="人數")
#ggplot2
ggplot(db_data,aes(reorder_size(mrg)))+
  geom_bar(width = 2/3)+
  xlab("婚姻狀態")+ylab("人數")+
  theme(axis.text.x = element_text(size=8,angle = 60, hjust = 1, vjust = 1))
#旋轉x軸刻度標籤文字,以完整顯示

R基礎作圖工具:
在這裏插入圖片描述
ggplot2:
在這裏插入圖片描述
2. 餅圖
  按頻數從大到小順時針作餅圖:

#R基礎作圖工具
pie(sort(mrg_table,T),clockwise=T,main = "所調查人羣婚姻狀態的頻數分佈情況")
#ggplot2
label_per = paste(names(sort(table(db_data$mrg),F)), "(",
                round(prop.table(table(reorder_size(db_data$mrg,F))),4)*100,
                "%)", sep = "")#將百分比加到標籤文字上
ggplot(db_data,aes(x=factor(1),fill=reorder_size(mrg,F))) + 
  geom_bar() + 
  coord_polar(theta = "y")+#變化爲極座標以形成餅圖 
  labs(x = "", y = "", title = "所調查人羣婚姻狀態的頻數分佈情況",
       fill='婚姻狀態')+ #去除餅圖旁邊的標籤
  theme(axis.ticks = element_blank()) + 
  theme(axis.text.x = element_blank(),axis.text.y = element_blank())+ #把原座標軸的刻度文字去掉
  theme(panel.grid=element_blank())+ # 去掉白色圓框和中間的座標線
  scale_fill_discrete(labels = label_per) #使用含有百分比的圖例

R基礎作圖工具:
在這裏插入圖片描述
ggplot2:
在這裏插入圖片描述

對所調查人羣的年齡分佈作圖:

  1. 直方圖
      由於年齡數據的範圍是19-102,因而可在15-105歲的範圍內按每5歲爲1組進行分組,繪製直方圖。
summary(db_data$age)
#R基本繪圖工具hist
hist(db_data$age, breaks = seq(15,105,5), xlab = "年齡",main = "所調查人羣的年齡分佈直方圖")
#ggplot2
ggplot(db_data,aes(age))+
  geom_histogram(breaks=seq(15,105,5),color="white")+
  xlab("年齡")

R基本繪圖工具:
在這裏插入圖片描述
ggplot2:
在這裏插入圖片描述

對比R基礎作圖工具和ggplot2

聯繫

  同一數據的同一統計圖形繪製結果大體一致,都能夠根據數據準確地繪製相應圖形。

區別

  • 邏輯上的區別:基礎繪圖包所提供的函數主要通過調節參數對圖形進行繪製和修改,而ggplot2除了提供更豐富的參數外,最核心的特點是基於圖層進行繪圖。
  • 繪圖風格有所區別:基礎繪圖包的繪圖風格更爲簡潔,ggplot2的繪圖風格更爲精緻,且允許使用者進行豐富的個性化,如主題風格、背景、配色等。
  • 在本題繪製的幾種圖形中體現的具體的區別:
    • 條形圖:當x軸的刻度文字較長時,barplot()函數繪製的直方圖則不能顯示部分較長的文字,而ggplot2可通過theme函數調整文字的角度,從而完整展示文字。另外,barplot()所需的數據是頻數分佈表,而ggplot2可直接使用原始數據,對其進行頻數統計並作圖,對於頻數爲0的分類,如最高學歷爲博士的,barplot()會作出該類的條形圖,而geom_bar()不予顯示。
    • 餅圖:pie()函數所作的餅圖存在標籤文字的重疊,極大影響了使用者讀圖。ggplot2不直接提供餅圖工具,但通過將條形圖的座標軸修改爲極座標軸可繪製出餅圖,圖例的使用也可解決文字重疊的問題。
    • 直方圖:兩個包中的直方圖繪製函數中分組數目的默認設定有所區別,但都可通過修改breaks參數進行重新設置。

以兩個定性變量作爲分類變量繪製分面統計圖

facet_wrap 纏繞分面

  按單個分類變量進行分面。

  1. 按最高學歷進行分面繪製年齡分佈的直方圖:
ggplot(db_data,aes(age))+
  geom_histogram(breaks=seq(15,105,5),color="white")+
  xlab("年齡")+facet_wrap(~edu)

在這裏插入圖片描述
2. 按婚姻狀態進行分面繪製年齡分佈的直方圖:

ggplot(db_data,aes(age))+
  geom_histogram(breaks=seq(15,105,5),color="white")+
  xlab("年齡")+facet_wrap(~mrg)

在這裏插入圖片描述
3. 按婚姻狀態進行分面繪製最高學歷的條形圖:

ggplot(db_data,aes(x=edu,fill=edu))+
  geom_bar()+
  xlab("學歷")+facet_wrap(~mrg)+
  theme(axis.text.x = element_text(size=8,angle = 60, hjust = 1, vjust = 1))+
  guides(fill = guide_legend(title = NULL))

在這裏插入圖片描述

facet_grid 網格分面

可用多個標準(分類變量)進行分面。

ggplot(db_data,aes(age))+
  geom_histogram(breaks=seq(15,105,5))+
  xlab("年齡")+facet_grid(edu~mrg)

在這裏插入圖片描述

考察兩兩變量間的關係使用哪種圖?

定性變量&定性變量

  除了以表格形式呈現的列聯表之外,可以採用簇狀條形圖、堆積條形圖以及ggplot2中提供的geom_tile()函數繪製“熱圖”。

#列聯表
ctable<-table(db_data$edu,db_data$mrg)
#簇狀條形圖

#堆積條形圖
ggplot(db_data)+
  geom_bar(aes(x=edu,fill=mrg),position = "dodge")+
  xlab("學歷")+
  theme(axis.text.x = element_text(size=8,angle = 60, hjust = 1, vjust = 1))

#熱圖
library(reshape2)
melted_ctable <- melt(ctable)
ggplot(melted_ctable,aes(x=Var2, y=Var1,fill = value))+
  geom_tile()+ylab("最高學歷")+xlab("婚姻狀況")+
  theme(axis.text.x = element_text(size=8,angle = 60, hjust = 1, vjust = 1))

堆積條形圖:
在這裏插入圖片描述
熱圖:
在這裏插入圖片描述

定性變量&定量變量

  分別爲定性變量的不同水平繪製箱線圖。以婚姻狀況與年齡爲例:

ggplot(db_data, aes(x=mrg,y=age))+
  geom_boxplot()+
  xlab("婚姻狀態")+ylab("年齡")+
  theme(axis.text.x = element_text(size=8,angle = 60, hjust = 1, vjust = 1))

在這裏插入圖片描述

定量變量&定量變量

  可利用散點圖初步探究兩個定量變量之間的關係,以鳶尾花數據集(iris)中花瓣長度(Petal.Length)與花瓣寬度(Petal.Width)兩個定量變量爲例:

ggplot(iris, aes(x=Petal.Length,y=Petal.Width))+
  geom_point()

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章