[心得] 資料整理套件介紹-序章 magrittr
鑒於andrew大大的提議,現下剛好有閒就來寫一系列資料整理套件的文章
版上比我熟這些套件的人也不少,如果不足的部分,再麻煩幫忙補充
目前想要介紹的套件有 (後面列一些我常用的function)
- magrittr : pipe operator如 '%>%', '%<>%', '%T>%', '%$%'
- data.table: class 'data.table', dcast.data.table, melt, fread,
duplicated, transform, rbindlist, merge
- reshape2 : dcast, melt (required for data.table)
- plyr : name_rows, colwise, mapvalues
- dplyr : mutate, summarise, arrange, filter, distinct, group_by, n,
select, rowwise, tbl_dt, mutate_each, summarise_each
- tidyr : gather, separate, spread
這篇的重點放在 magrittr,因為後面我會大量使用pipe operator來寫程式碼
我盡量每一個operator用簡單一點的方式說明,如果不太了解再麻煩告知
程式碼部分,我都會用` R 跟 ` 做引號
1. '%>%'
這個operator用來傳遞數值,避免過多的nest造成閱讀上的困難
像是
a_list = list(1:6, 3:5, 4:7)
lapply(a_list, function(x) setdiff(sort(unique(unlist(a_list))), x))
第二行拆解閱讀是很困難的,但是寫成
a_list %>% unlist %>% unique %>% sort %>% {
lapply(a_list, setdiff, x = .)
}
閱讀上會容易很多
舉一個簡單的例子,來說明 '%>%'的用法
` R
a = 1
f = function(a) a + 1
f(a)
a %>% f
a %>% f()
a %>% f(.)
`
跑上面的程式可以發現,最後四個output都一樣
其實 %>% 做的就是把 左邊變數 放進 右邊函數裡做執行
也就是說 f(a) 等同於 a %>% f (或是上面其他三種)
另外,可能會覺得 `a %>% f(.)`會很奇怪
在magrittr中, `.`就是用來代表%>%前面的變數
所以 a %>% f(.) 程式會把.的位置換成a,變成 f(a)
`.` 在magrittr的應用中,會佔很大的比例
像是do.call, Reduce第一個input是function,第二個是list
我們通常傳入list,所以此時必須用 . 做位置的控制
再者,c, cbind, rbind會根據位置不同來決定是合併於何處
也是一個很重要的問題,因此,用 `.`做傳入位置的控制是必須的
針對這個,我給一段簡單的程式碼讓你去試試看
` R
a_list = list(1:5, 3:7, 6:10)
a_list %>% do.call(rbind, .)
a_list %>% Reduce(cbind, .)
1:5 %>% rbind(3:7, .)
1:5 %>% rbind(., 3:7)
f = function(x, a, b) a*x^2 + b
1:5 %>% f(., 2, 5) # 同 1:5 %>% f(2, 5)
1:5 %>% f(2, ., 5)
1:5 %>% f(2, 5, .)
`
再者,%>% 也可以傳入一個block (用{}括住的部分)
像是前面提到的
` R
a_list = list(1:6, 3:5, 4:7)
a_list %>% unlist %>% unique %>% sort %>% {
lapply(a_list, setdiff, x = .)
}
`
先說明怎麼閱讀 %>%的部分
a_list %>% unlist %>% unique %>% sort 就是
a_list把全部元素合併(unlist),然後取唯一(unique),接著排列所有元素(sort)
就照著%>%的順序去讀就可以順利解讀
再來就是block的部分
{}括住之後,裡面的只要不是其他%>%後面的 `.`都代表你前面傳入的值
這樣很難懂,舉個例子
` R
1:2 %>% {
list(
cbind(9:10, .),
3:4 %>% cbind(9:10, .)
)
}
`
output長這樣
[[1]]
.
[1,] 9 1
[2,] 10 2
[[2]]
.
[1,] 9 3
[2,] 10 4
可以看到第一個可以很直覺的解讀,9:10是跟傳入的1:2做行合併
而第二個`.`,因為前面有了一個新的 '%>%'
所以這一個`.`就被前面的 3:4取代
所以第二個output變成9:10跟3:4做行合併
2. '%<>%'
如果懂了 %>%, 這個就不難了
先看簡單的例子 (add是magrittr提供用在 %>%上的 `+` (這部分請看最後面的補充))
` R
a = 1
a %>% add(1) # 同 a %>% '+'(1) or a %>% '+'(., 1)
a # 1
a %<>% add(1)
a # 2
`
這個例子可以看的出來 %<>% 除了傳入變數之外,也會改變傳入變數的值
也就是可以把 a %<>% add(1) 看成 a = a + 1
你如果有一串要做最後賦值給你傳入的變數
只需要在第一個傳導變數的operator做改變即可,舉例來說:
` R
dat = data.frame(a = 1:3, b = 8:10)
dat = dat %>% rbind(dat)
dat2 = data.frame(a = 1:3, b = 8:10)
dat2 %<>% rbind(dat2)
all.eqaul(dat, dat2) # TRUE
`
3. '%T>%'
%T>% 只傳遞變數,不回傳值,通常用來傳遞到不回傳值的function上
像是plot, library, install.packages, plyr的 *_ply等
這個operator可以幫你把前面做好的值賦予一個變數
並且同時做後面function的動作,舉例來說:
` R
dat = data.frame(a = rep(1:3,2), b = rnorm(6))
dat2 = dat %>% {tapply(.$b, .$a, sum)} %>%
{ data.frame(a=names(.) %>% as.integer, b = .)
} %T>% plot(.$a, .$b)
`
這裡dat2就是一個新的data.frame,同時,我們也把a, b的scatter plot畫出來
這部分可以用dplyr的group_by以及summarise完成
還沒提到dplyr,所以我們先用替代方法做
這裡順便把第四個operator '%$%'一起說明
dat %>% {tapply(.$b, .$a, sum)} 會不會覺得很冗長,也很容易忘記要放'.$'
但是,'%$%'提供了直接把前面變數的元素 直接以名字做操作
再也不需要 .$name這麼麻煩,直接用 name做你想要的操作就好
因此,那行就可以簡單寫成 dat %$% tapply(b, a, sum)
是不是就變得簡單的很多?
4. '%$%'
前面提到了,這裡就給一個例子就好
` R
a = 3
b = -2
x = rnorm(100)
y = a + b * x + rnorm(100)
fit = lm(y ~ x)
sigma_hat = fit %$% {crossprod(residuals) / df.residual}
`
下一章應該會介紹data.table跟reshape2,後會有期。
補充:
magrittr提供很多其他function的別名
像是 '+', '*', '[', '[[', '<- rownames()'等等
有興趣請去magrittr的manual查看extract的部分
這個可以讓你寫pipe chain的時候更加順手
像是
vals = 1:3 %>% data.frame(a = ., b = .^2) %>% set_rownames(LETTERS[1:3]) %>%
lm(b ~ a, data = .) %>% predict
不然你可能會這樣寫
dat = 1:3 %>% data.frame(a = ., b = .^2)
rownames(dat) = LETTERS[1:3]
vals = dat %>% lm(b ~ a, data = .) %>% predict
你可能只是要vals這個變數,你卻還要多創一個dat這個暫存變數,而中斷chain
[關鍵字]: magrittr
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 123.205.27.107
※ 文章網址: https://www.ptt.cc/bbs/R_Language/M.1437452331.A.CD1.html
推
07/21 12:39, , 1F
07/21 12:39, 1F
推
07/21 12:47, , 2F
07/21 12:47, 2F
推
07/21 13:04, , 3F
07/21 13:04, 3F
推
07/21 14:20, , 4F
07/21 14:20, 4F
推
07/21 15:36, , 5F
07/21 15:36, 5F
推
07/21 16:41, , 6F
07/21 16:41, 6F
推
07/21 20:38, , 7F
07/21 20:38, 7F
推
07/21 23:38, , 8F
07/21 23:38, 8F
推
07/22 04:30, , 9F
07/22 04:30, 9F
推
07/22 10:11, , 10F
07/22 10:11, 10F
推
07/22 11:11, , 11F
07/22 11:11, 11F
推
07/22 11:27, , 12F
07/22 11:27, 12F
推
07/23 05:37, , 13F
07/23 05:37, 13F
推
07/24 13:06, , 14F
07/24 13:06, 14F
推
08/12 12:55, , 15F
08/12 12:55, 15F
推
08/19 00:56, , 16F
08/19 00:56, 16F
推
11/01 01:15, , 17F
11/01 01:15, 17F
※ 編輯: celestialgod (140.109.74.87), 12/31/2015 13:06:30
推
07/02 18:42, , 18F
07/02 18:42, 18F
推
08/14 17:43, , 19F
08/14 17:43, 19F
推
04/23 10:26, , 20F
04/23 10:26, 20F
推
06/23 23:36, , 21F
06/23 23:36, 21F
R_Language 近期熱門文章
PTT數位生活區 即時熱門文章