Data wrangling and visualization
I. 緣由
As title, 隨著處理資料的技能越點越多,基本上在每一次的分析裡不可能只用到一個data table,一定還會伴隨著很多合併(merge)、角力(wrangling)的過程;進行EDA的時候也一定會使用到視覺化的技術,好讓資料看起來能更加的能夠溝通。
這篇文章會以R for data science為基礎,介紹裡面關於R是如何處理關聯資料集(relational data) 與 資料視覺化(data visualization ) 的相關技巧。
同時,在我學習python的時候也提醒自己不要忘記R的語法~~~
II. tidy data
Tidy data 是由 R Studio 之神 Hadley Wickham(不誇張,真的) 所提出,是一種「資料架構標準」,有分析經驗的朋友們都知道,資料角力會花上的時間遠比建模來的多,然而,傳統的方式把資料清理乾淨,有時不一定利於分析,例如Excel的樞紐分析,因此Hadley Wickham題出了以結構化的方式整理資料更有利於後續分析,就是所謂的 tidy data。
4. unite
一言以蔽之呢~就是
III. relational data
1. Concept of "key"
如前言所提,資料分析不會只涉及單一一個資料表,面對多個表格,必須將他們結合起來,用來連接每對資料表的變數,我們便稱為他的鍵(Key)。
鍵值又分為兩種
(a) 主鍵(primary key)
唯一識別自己資料表(在這裡假設為A)中的一個觀察變數(X),能夠識別資料裡所有的個案
(b) 外鍵(foreign key)
用來其他資料表的鍵,我們稱為外鍵
2. Join
在這裡以簡單的例子說明join的整理與功能
(a) inner_join
(b) left_join
(c) right_join
(d) full_join
其實不用硬記,看看這張圖什麼都能一目了然了呢~
3. compare with SQL and merge function
了解join的功能後,別忘了R也有merge的功能,兩者的功用差不多,最多是在語法上做調整
可以參考下列表格~
其實很多程式的語法都會想盡辦法和SQL有直接關連(畢竟是最普遍的資料庫系統),以下整理出語法的比較:
IV. visualization with ggplot2
R語言擁有強大的視覺化工具,ggplot2套件,以下會簡單介紹詳細的使用語法,ggplot2現在也已經被包含在萬用package tidyverse裡,因此我們只需要安裝 tidyverse package即可使用,再次感謝大神 Hadly Wickham~~~~~
(1)決定資料集,變數
(2)選擇geom_function: 例如geom_histogram、geom_bar、geom_jitter
可以多重stack上去,取決於圖需要多少元素向閱覽者溝通
(3)coord_funciton: coord_flip()橫向翻轉;coord_polar() 南丁格爾玫瑰圖
(4) facet_function : facet_grid
大致上的文法架構已經明瞭後,剩下的就是不斷練習,並且經驗各個geom function專有的規矩和調整,很複雜,pratice makes perfect 是永遠不變的道理!
以下,讓我們一起來探討ggplot畫圖功能的強大吧~
ggplot 將資料集以及變數指定完成,再加上geom_histogram決定要劃長條圖,
而同樣是histogram, 只需要在position 的地方加上dodge,就可以將不同類別錯開。
類似的語法,加上facet_grid(.~Sex)+
就能夠以Sex為分類將兩種性別分開
透過ggplotly()函數,我們更可以了解到每一筆資料的詳細情況了!!!
本篇簡易的介紹了資料角力常用技巧以及R常用的畫圖技巧
有任何意見想討論都可以直接於下方留言唷~~~~~
As title, 隨著處理資料的技能越點越多,基本上在每一次的分析裡不可能只用到一個data table,一定還會伴隨著很多合併(merge)、角力(wrangling)的過程;進行EDA的時候也一定會使用到視覺化的技術,好讓資料看起來能更加的能夠溝通。
這篇文章會以R for data science為基礎,介紹裡面關於R是如何處理關聯資料集(relational data) 與 資料視覺化(data visualization ) 的相關技巧。
同時,在我學習python的時候也提醒自己不要忘記R的語法~~~
II. tidy data
而一個 Tidy Dataset 會滿足以下三個條件(如下圖所示):
- 每個變數 (variable) 都會形成一個 column
- 每個觀察個體 (observation) 都會形成一個 row
- 每一種類型的觀察個體會形成一個 table,比如說:地區特徵跟個體資料應該存成兩個不同的資料表格。
介紹一下幾種常用的功能:
1. gather
head(table4a)
# A tibble: 3 x 3
country `1999` `2000`
<chr> <int> <int>
1 Afghanistan 745 2666
2 Brazil 37737 80488
3 China 212258 213766
table4a %>%
gather(`1999`, `2000`, key = "year", value = "cases")
# A tibble: 6 x 3
country year cases
<chr> <chr> <int>
1 Afghanistan 1999 745
2 Brazil 1999 37737
3 China 1999 212258
4 Afghanistan 2000 2666
5 Brazil 2000 80488
6 China 2000 213766
1999、2000都是屬於年份,將其tidy後,兩者靠在同一個column了~。
2. spread
table2
# A tibble: 12 x 4
country year type count
<chr> <int> <chr> <int>
1 Afghanistan 1999 cases 745
2 Afghanistan 1999 population 19987071
3 Afghanistan 2000 cases 2666
4 Afghanistan 2000 population 20595360
table2 %>%
spread(key = type, value = count)
# A tibble: 6 x 4
country year cases population
<chr> <int> <int> <int>
1 Afghanistan 1999 745 19987071
2 Afghanistan 2000 2666 20595360
3 Brazil 1999 37737 172006362
4 Brazil 2000 80488 174504898
5 China 1999 212258 1272915272
6 China 2000 213766 1280428583
spread()則是能把同一個Column內的變數拓展到外面,形成每行一個變數
3. seperate
> table3
# A tibble: 6 x 3
country year rate
* <chr> <int> <chr>
1 Afghanistan 1999 745/19987071
2 Afghanistan 2000 2666/20595360
3 Brazil 1999 37737/172006362
4 Brazil 2000 80488/174504898
5 China 1999 212258/1272915272
6 China 2000 213766/1280428583
table3 %>%
separate(rate, into = c("cases", "population"), sep = "/")
# A tibble: 6 x 4
country year cases population
<chr> <int> <chr> <chr>
1 Afghanistan 1999 745 19987071
2 Afghanistan 2000 2666 20595360
3 Brazil 1999 37737 172006362
4 Brazil 2000 80488 174504898
5 China 1999 212258 1272915272
6 China 2000 213766 1280428583
4. unite
table5
# A tibble: 6 x 4
country century year rate
* <chr> <chr> <chr> <chr>
1 Afghanistan 19 99 745/19987071
2 Afghanistan 20 00 2666/20595360
3 Brazil 19 99 37737/172006362
4 Brazil 20 00 80488/174504898
5 China 19 99 212258/1272915272
6 China 20 00 213766/1280428583
> table5 %>%
+ unite(new, century, year, sep="")
# A tibble: 6 x 3
country new rate
<chr> <chr> <chr>
1 Afghanistan 1999 745/19987071
2 Afghanistan 2000 2666/20595360
3 Brazil 1999 37737/172006362
4 Brazil 2000 80488/174504898
5 China 1999 212258/1272915272
6 China 2000 213766/1280428583
一言以蔽之呢~就是
- gather(): 將「寬」資料變「長」
- spread(): 將「長」資料變「寬」
- separate(): 將單一欄位切分成多個欄位
- unite(): 將多個欄位合併成單一欄位
III. relational data
如前言所提,資料分析不會只涉及單一一個資料表,面對多個表格,必須將他們結合起來,用來連接每對資料表的變數,我們便稱為他的鍵(Key)。
鍵值又分為兩種
(a) 主鍵(primary key)
唯一識別自己資料表(在這裡假設為A)中的一個觀察變數(X),能夠識別資料裡所有的個案
(b) 外鍵(foreign key)
用來其他資料表的鍵,我們稱為外鍵
2. Join
在這裡以簡單的例子說明join的整理與功能
x <- tribble(
~key, ~val_x,
1, "x1",
2, "x2",
3, "x3"
)
y <- tribble(
~key, ~val_y,
1, "y1",
2, "y2",
4, "y3"
)
> x
# A tibble: 3 x 2
key val_x
<dbl> <chr>
1 1 x1
2 2 x2
3 3 x3
> y
# A tibble: 3 x 2
key val_y
<dbl> <chr>
1 1 y1
2 2 y2
3 4 y3
我們可以看到對x而言,key即為主鍵,y的key為x的外鍵(a) inner_join
x %>%
inner_join(y, by = "key")
key val_x val_y
<dbl> <chr> <chr>
1 1 x1 y1
2 2 x2 y2
x且y都具備的key為1, 2,因此inner_join後顯示的即為1/2兩個key(b) left_join
> x %>% + left_join(y, by = "key") # A tibble: 3 x 3 key val_x val_y <dbl> <chr> <chr> 1 1 x1 y1 2 2 x2 y2 3 3 x3 NAleft_join保留了x的key
(c) right_join
x %>% + right_join(y, by = "key") # A tibble: 3 x 3 key val_x val_y <dbl> <chr> <chr> 1 1 x1 y1 2 2 x2 y2 3 4 NA y3保留y
(d) full_join
x %>% + full_join(y, by = "key") # A tibble: 4 x 3 key val_x val_y <dbl> <chr> <chr> 1 1 x1 y1 2 2 x2 y2 3 3 x3 NA 4 4 NA y3通通保留~~~~
其實不用硬記,看看這張圖什麼都能一目了然了呢~
3. compare with SQL and merge function
了解join的功能後,別忘了R也有merge的功能,兩者的功用差不多,最多是在語法上做調整
可以參考下列表格~
dplyr | merge |
---|---|
inner_join(x, y) | merge(x, y) |
left_join(x, y) | merge(x, y, all.x = TRUE) |
right_join(x, y) | merge(x, y, all.y = TRUE) , |
full_join(x, y) | merge(x, y, all.x = TRUE, all.y = TRUE) |
其實很多程式的語法都會想盡辦法和SQL有直接關連(畢竟是最普遍的資料庫系統),以下整理出語法的比較:
dplyr | SQL |
---|---|
inner_join(x, y, by = "z") | SELECT * FROM x INNER JOIN y USING (z) |
left_join(x, y, by = "z") | SELECT * FROM x LEFT OUTER JOIN y USING (z) |
right_join(x, y, by = "z") | SELECT * FROM x RIGHT OUTER JOIN y USING (z) |
full_join(x, y, by = "z") | SELECT * FROM x FULL OUTER JOIN y USING (z) |
IV. visualization with ggplot2
R語言擁有強大的視覺化工具,ggplot2套件,以下會簡單介紹詳細的使用語法,ggplot2現在也已經被包含在萬用package tidyverse裡,因此我們只需要安裝 tidyverse package即可使用,再次感謝大神 Hadly Wickham~~~~~
ggplot(data = <DATA>,aes(x= , y=)) +
<GEOM_FUNCTION>(
stat = <STAT>,
position = <POSITION>
) +
<COORDINATE_FUNCTION> +
<FACET_FUNCTION>
以上是ggplot完整作畫的基礎步驟,(1)決定資料集,變數
(2)選擇geom_function: 例如geom_histogram、geom_bar、geom_jitter
可以多重stack上去,取決於圖需要多少元素向閱覽者溝通
(3)coord_funciton: coord_flip()橫向翻轉;coord_polar() 南丁格爾玫瑰圖
(4) facet_function : facet_grid
大致上的文法架構已經明瞭後,剩下的就是不斷練習,並且經驗各個geom function專有的規矩和調整,很複雜,pratice makes perfect 是永遠不變的道理!
以下,讓我們一起來探討ggplot畫圖功能的強大吧~
ggplot(full[1:891,], aes(Age,fill = factor(Survived)))+
geom_histogram(bins = 40)+
theme_few()+
xlab("Age")+
scale_fill_discrete(name = "Survived")+
ggtitle("Age / Survived")
ggplot(full[1:891,], aes(Sex,fill = factor(Survived)))+
geom_bar(stat = "count",position = "dodge")+
theme_bw()+
xlab("sex")+
ylab("count")+
scale_fill_discrete(name = "survived")+
ggtitle("Sex / Survived")
ggplot 將資料集以及變數指定完成,再加上geom_histogram決定要劃長條圖,
而同樣是histogram, 只需要在position 的地方加上dodge,就可以將不同類別錯開。
ggplot(full[1:891,], aes(Age, fill = factor(Survived))) +
geom_histogram(bin = 30)+
theme_few()+
xlab("Age")+
ylab("count")+
facet_grid(.~Sex)+
scale_fill_discrete(name = "survived")+
theme_few()+
ggtitle("Age/Sex/Survived")
類似的語法,加上facet_grid(.~Sex)+
就能夠以Sex為分類將兩種性別分開
ggplot(data,aes(x=displ, y = hwy))+geom_point(aes(color=class))+
geom_smooth(data=filter(mpg,class=="subcompact"),se=FALSE)
也可以將兩種geom畫在一起,可以更加促進圖表的溝通能力
V. shiny 與 plotly的視覺畫呈現*
雖然有了強大的ggplot函數,R現在有shiny與plotly的實作功能了圖表溝同能力無限up
library(plotly)
g<-ggplot(data,aes(x=displ, y = hwy))+geom_point(aes(color=class))+
geom_smooth(data=filter(mpg,class=="subcompact"),se=FALSE)
ggplotly(g)
透過ggplotly()函數,我們更可以了解到每一筆資料的詳細情況了!!!
本篇簡易的介紹了資料角力常用技巧以及R常用的畫圖技巧
有任何意見想討論都可以直接於下方留言唷~~~~~
留言
張貼留言