這是我自己在PTT PO的文,詳細介紹tidyr,以下是正文~~
本篇是最後一篇,主要介紹tidyr,以下是要介紹的內容:
data.table:::dcast.data.table
data.table:::melt
tidyr:::gather
tidyr:::spread
tidyr:::separate
這一章主要講述注重在資料的呈現方式 - 橫表跟直表的呈現
還有一些表格整合的問題
- dcast.data.table
dcast提供直表加總的函數
學過統計的話,應該是contingency table (列聯表)
或是熟悉EXCEL,知道樞紐分析表,它其實就是樞紐分析表
Y就是列聯表中的列變數,X就是行變數
製作列聯表也可以說它的應用之一
這個function,需要先require(reshape2)
有人可能會問reshape2就有dcast為啥要用dcast.data.table
原因很簡單,因為dcast.data.table快更多!!
速度直接?dcast.data.table下面例子就有,直接來簡介怎麼用
第一個input是data.table,第二個是給一個公式
舉例來說,如果公式是 Y ~ X,Y的元素會展開在列,X就會在行
第三個input是加總函數,你如果有相同類別的X, Y
它會把相同類別的值用這個函數做加總,預設是length
先用一個簡單例子來說明
1 | set.seed(100) |
產生資料的函數、operator,我們都講過了,往前找找看
我們專注到第一個dcast,dcast.data.table(DT, col1~col2)
可以看的出來 col1就在列,col2就在行展開,然後計算col1, col2有相同類別的length
第二個dcast就是把有相同的類別,把values做總和
但是,我們怎麼知道它加總的是values
它會告訴你自動找尋data.table,然後選定values做為加總的column
至於改法就是修改value.var這個input,舉例來說
1 | DT[, values2 := rpois(8, 3)] |
dcast.data.table說明到此
- melt
dcast做直表加總,melt做橫表轉直表
舉個簡單的例子
我們有數個病人,每個病人有數個觀察值
表格紀錄的樣子是
id O1 O2
P1 12 18
P2 13 15
.. .. ..
我們想要轉成直表長這樣:
id O V
P1 O1 12
P1 O1 18
P2 O2 13
P2 O2 15
.. .. ..
那麼在R code可以這樣做:
1 | (DT = data.table(id = paste0("P", 1:2), O1 = c(12,13), O2 = c(18,15))) |
melt的第一個input是data.table (註一)
第二個input是id.vars,也就是你要展開的變數名稱
第三個input是measure.vars,你要展開的變數名稱
前面例子未指定的情況下,就是全部的column
前面我還有用到variable.name 跟 value.name
variable.name是指定集合其他columns之後的column name
在前例就是把 O1, O2兩個columns集合之後的變數名稱,我改成了”O”
value.name是你集合其他columns之後那些變數值的column
在前例就是把 O1, O2兩個columns集合之後的變數值,我改成了”V”
註一:此指data.table:::melt,跟reshape2:::melt的差異部分
請看data.table:::melt的help
我們再看一個複雜一點的例子
1 | DT = data.table(ID1 = paste0("ID1_", 1:20), |
- gather
其實就是melt,只是比較好寫
我們把melt的例子改成用gather寫
只是melt一次到位的指令用gather寫之後
要用select跟filter做 (但是我覺得gather比較好寫)
1 | (DT = data.table(id = paste0("P", 1:2), O1 = c(12,13), O2 = c(18,15))) |
- spread
提供gather的反向操作
1 | DT = data.table(id = paste0("P", 1:2), O1 = c(12,13), O2 = c(18,15)) |
- separate
把特定column做strsplit,並設定成新的變數
一個簡單的例子
1 | DT = data.table(x = paste0(sample(LETTERS, 5), ",", sample(LETTERS, 5))) |
這個函數要注意的是以下的程式是會出現錯誤的
1 | DT = data.table(x = paste0(sample(LETTERS, 5), sample(LETTERS, 5))) |
separate無法分開沒有間隔字元的字串
你要分開這個只能做適當的轉換,像是:
1 | DT = data.table(x = paste0(sample(LETTERS, 5), sample(LETTERS, 5))) |
如果有人有更好的方法,麻煩告知我一下,謝謝
資料介紹套件就到這裡結束
有任何問題,歡迎在板上回文詢問,我有看到都會回覆
(麻煩盡量不要用私信,希望可以讓板眾一起看問題該怎麼解決)
有任何補充或是建議也歡迎推文或回文,感謝大家
我並沒有講到plyr的 aply, lply, dply, rply系列
其實他們跟apply, lapply, tapply, replicate相對應,只是output型式不同
如果未來有機會寫有關*ply系列函數時,我再好好介紹plyr