資料視覺化

單元摘要 :學習使用R語言,用以來進行一系列數據圖像化,講出商業好故事。

為甚麼資料需要視覺化?

  • 易於閱讀,找出亮點
  • 可輕易判斷趨勢變化
  • 將數據由繁化簡

我們在這邊先教大家最家喻戶曉的圖像化工具,分別是ggplot2d3heatmap以及pheatmap套件。

【大綱】

  1. 圖的基本介紹

  2. GGPlot2 Packages
  • GGPlot2 建圖架構[圖層與函式]
  • 各種圖的函數寫法
  • point/bar/col/histogram/line/density
  1. D3heatmap Packages/pheatmap packages
導入使用工具
#rm(list=ls())
options(scipen = 200)
devtools::install_github("ropenscilabs/icon")
## Skipping install of 'icon' from a github remote, the SHA1 (a5bc1cc9) has not changed since last install.
##   Use `force = TRUE` to force installation
pacman::p_load(devtools,dplyr, ggplot2, readr, plotly, googleVis,ggthemes,d3heatmap,magrittr,pheatmap)
load("camp.Rdata")

各式圖的介紹與用法

【基礎圖法】

  • 點狀圖
    當X、Y軸皆是連續變數時,可以藉此使用來觀察整體分布集中度。

  • 盒鬚圖
    用來判斷特定變數的樣態分布,盒鬚圖主要可以馬上判斷出最小值、四分位數與最大值,並可以藉由線與線的距離判斷分布的密集程度。

  • 長條圖(長柱圖、柱狀圖)
    查看每個類別所出現的頻率(縣市的鄉鎮市區數量)或是特定類別在特定變數上所出現的值(國家、GDP)。

  • 直方圖
    觀察特定變數的分布狀態(各年度高雄市遷出人口數),或是用來比較不同觀察值之相同變數分布差異(高雄市、台北市自然增加人數)。

  • 折線圖
    相較於其他圖類能更輕易的觀察到趨勢的變化。

  • 熱圖
    藉由類似馬賽克的圖形,利用顏色深淺劃分程度,通常X、Y軸都會是類別變數,而顏色的數值則是連續數值。

  • 圓餅圖
    判斷類別變數中的各個類別佔據的比例。

【進階圖法】

library(googleVis)
#op = options(gvis.plot.tag='chart')
df[,c(-2,-3)] %>% group_by(year,縣市名稱) %>% 
  summarise_if(is.numeric,mean) -> df1 
df2=df1 %>% as.data.frame()
gvisMotionChart(df2,"縣市名稱","year") %>% plot
## starting httpd help server ... done

圖層說明與ggplot2函數說明

首先我們先講到ggplot2套件,只要講到R語言視覺化工具,首當其衝一定想到它,最為入門,也是最有彈性的一個套件,套件中可以將各式各樣的圖(Ex:點狀圖、直方圖、直條圖、盒鬚圖等等),並且我們還會比較R語言內建的plot與ggplot差異 而它之所以簡單且好用,是因為他在轉換這些圖形時,它的函式都有一定的規律在:

1.ggplot內容可以像洋蔥一樣一層一層的來劃分:
- 資料來源(data):指定原始資料來源的 data frame。
- 美學對應(aesthetic):指定原始資料與圖形之間的對應關係,例如哪一個變數要當作x座標變數,而哪一個要當作y座標變數 ,還有資料繪圖時的樣式等。
- 幾何圖案(geometry):要用什麼幾何圖形繪製資料,例如點、線條、多邊形等。
- 繪圖面(facet):指定如何將資料分散在多張子圖形中繪製,以利互相比較。
- 統計轉換(statistical transformation):指定如何以將資料轉換為各種統計量,例如將連續型資料轉為離散型的類別。
- 座標系統(coordinate system):指定繪圖時所使用的座標系統,除了常見的笛卡兒直角座標系統,也可以使用極坐標或地圖投影(map projection)。
- 主題(theme):控制資料以外的繪圖組件,例如座標軸、說明文字等。

資料來源:https://blog.gtwang.org/r/ggplot2-tutorial-basic-concept-and-qplot/
ggplot圖表結構分層圖

2.函式表現
ggplot( data ,aes(x = __ , y = __ ,...)) +geom_[chart]()

aes() 負責將素材綁定至 X 軸與 Y 軸,這是 aesthetic mappings 的縮寫;接著我們還要告訴 ggplot 物件要用什麼樣的外觀呈現,這時接著利用 geom_() 指定繪圖的類型,這是 geometric objects 的縮寫,底線後面加上繪圖名稱。

ggplot2各圖函數

Point(點狀圖)

觀察遷出人口以及綜合所得的關係

df %>% group_by(縣市名稱) %>% 
  summarize(綜合所得總額=mean(綜合所得總額),總遷出人口數=mean(遷出人口數)) ->df1 

ggplotly(ggplot(df1,aes(綜合所得總額,總遷出人口數,colour=縣市名稱))+geom_point())



問題與討論:放火同學想知道各縣市粗出生率以及薪資淨所得的關係,請您以點狀圖來呈現這項資料。


boxplot (盒鬚圖)

df %>% group_by(year,縣市名稱) %>% 
summarize(總遷入人口數=mean(遷入人口數),總遷出人口數=mean(遷出人口數))  %>% ggplot(aes(year,總遷出人口數,group=year))+geom_boxplot() 



問題與討論:放水同學想知道全台灣各縣市的「各類所得金額薪資所得」之盒鬚圖,請你幫幫他。


line(折線圖)

df %>% group_by(year,縣市名稱) %>% 
  summarize_if(is.numeric,mean) %>% 
  ggplot(aes(year,各類所得金額薪資所得,color=縣市名稱))+geom_line() ->df1 
ggplotly(df1)

問題與討論:放狗同學想知道新北市在各年度(x)之「各類所得金額利息所得」(y)的線性趨勢變化,快救救他Q^Q


bar(長條圖I)

各縣市的鄉鎮數量

df %>% group_by(year,縣市名稱,鄉鎮市區名稱) %>% 
  summarize(村里數量=n()) %>% 
  ggplot(aes(縣市名稱)) + 
  geom_bar()+theme(axis.text.x = element_text(angle = 45))


col(長條圖II)

df %>% group_by(year,縣市名稱,鄉鎮市區名稱) %>% 
  summarize(村里數量=n()) %>% 
  ggplot(aes(縣市名稱,村里數量))+
  geom_col()+theme(axis.text.x = element_text(angle = 45))


問題與討論:放鳥同學想知道各縣市(x)的「老年人戶數」(y),你能夠以直條圖呈現嗎~


直條圖Igeom_bar與直條圖IIgeom_col差異:

geom_bar geom_col
主要分別 計算x類別之數量 觀察x與y的變化
使用差異 只能設定x軸 可以設定x與y軸

histogram(直方圖)

(y軸可為次數..count..或是機率..density..)
臺灣整體粗出生率分布

df %>% group_by(year,縣市名稱)  %>% 
  ggplot(aes(粗出生率,..count..))+
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

df %>% group_by(year,縣市名稱)  %>% 
  ggplot(aes(粗出生率,..count..,fill=縣市名稱))+
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.


直條圖與直方圖比較

ANSWER: bar的y軸只能放count,col的y軸則沒有限定。

直條圖 直方圖
樣態 類別之間有縫隙 類別之間連接
使用時機 判斷數量 判斷分布

ggplot2進階應用

ggplot還有很多奇奇怪怪的配置可以供使用,但我們在這邊只先講較常碰到的使用。

1.size,col

df1=df %>% mutate(year=as.character(df$year)) %>% filter(year>104)
df1 %>% group_by(year,縣市名稱) %>% 
  summarize_if(is.numeric,mean) %>%
  ggplot(aes(粗結婚率,粗出生率,fill=縣市名稱,shape=year,size=綜合所得總額))+
  geom_point()


2.facet,coord_flip

df %>% group_by(year,縣市名稱,鄉鎮市區名稱) %>% 
  summarize(村里數量=n()) %>%  
  ggplot(aes(x=縣市名稱,村里數量))+
  geom_col()+theme(axis.text.x = element_text(angle = 45)) + coord_flip() 


df %>% 
  filter(year>103,縣市名稱 %in% c("臺北市","新北市","桃園市","臺中市","臺南市","高雄市")) %>%
  group_by(year,縣市名稱) %>% 
  summarize_if(is.numeric,mean) %>% 
  ggplot(aes(自然增加人數,社會增加人數)) +
  geom_point()+
  facet_grid(year ~ 縣市名稱 )


df %>% group_by(year,縣市名稱) %>% 
  summarize_if(is.numeric,mean) %>% 
  ggplot(aes(year,粗出生率)) +
  geom_line()+
  facet_wrap( ~縣市名稱)

3.相關性

df %>% group_by(year,縣市名稱) %>% 
  summarize_if(is.numeric,mean) %>% .[,c(2,6,7,21,41)] ->df1
df1=df1 %>% filter(縣市名稱 %in% c("臺北市","新北市","新竹市","新竹縣"))
df1 %>%
  GGally::ggpairs(aes(colour = df1$縣市名稱), columns =2:5) %>%
  ggplotly(tooltip = c("x", "y", "colour")) %>%
  highlight("plotly_selected")
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## Warning: All elements of `...` must be named.
## Did you want `key = c(key)`?

## Warning: All elements of `...` must be named.
## Did you want `key = c(key)`?
## Warning: Can only have one: highlight
## Warning: All elements of `...` must be named.
## Did you want `key = c(key)`?
## Warning: Can only have one: highlight
## Warning: All elements of `...` must be named.
## Did you want `key = c(key)`?
## Warning: Can only have one: highlight
## Setting the `off` event (i.e., 'plotly_deselect') to match the `on` event (i.e., 'plotly_selected'). You can change this default via the `highlight()` function.

d3heatmap/pheatmap

每個縣市之薪資淨所得隨時間變化之熱圖

pheatmap

df %>% group_by(year,縣市名稱) %>% 
  summarize(薪資淨所得合計=mean(薪資淨所得)) %>% 
  data.table::dcast( 縣市名稱~ year) ->df1
## Using '薪資淨所得合計' as value column. Use 'value.var' to override
annotation_row = data.frame("臺灣地區" = factor(c("北","東","離","中","南","中","北","南","北","離","中","北","北","北","中","中","中","中","北","東","南","離")));
row.names(annotation_row)=df1$縣市名稱
row.names(df1)=df1$縣市名稱
df1=df1[,-1]
df1[is.na(df1)]= rowMeans(df1[7,],na.rm=T)
df1 %>% 
  pheatmap(cluster_cols = F,annotation_row =annotation_row )

d3heatmap

!!!格式限制 matrix.data.frame!!!

df1 %>%  
  as.data.frame.matrix() %>% 
  d3heatmap(T,F,color = colorRampPalette(c("#00007F", "blue", "#007FFF", "cyan",
                     "#7FFF7F", "yellow", "#FF7F00", "red", "#7F0000"))(100))
df1%>%  
  as.data.frame.matrix() %>% 
   {./rowSums(.)}  %>% 
  d3heatmap(T,F,color = colorRampPalette(c("#00007F", "blue", "#007FFF", "cyan",
                     "#7FFF7F", "yellow", "#FF7F00", "red", "#7F0000"))(100))

程式碼總結

  • Base tools: plot(x,y,...) “p” for points, “l” for lines, “h” for ‘histogram’ like (or ‘high-density’) vertical lines,

  • GGPlot2 Packages: ggplot(data,aes(x = __ , y = __ ,...)) +geom_[chart]()
    qplot(x,y,color,facets=,...)

  • d3heatmap packages: d3heatmap(matrix)
  1. 要是矩陣的格式 2.`d3heatmap(matrix,…)