【R資料科學讀書筆記】R語言中的管道操作
R語言中的管道操作
這是R資料科學的讀書筆記之一,《R資料科學》是一本教你如何用R語言進行資料分析的書。即便我使用R語言快2年多了,但是讀這本書還是受益頗多。
這一篇學習筆記對應第13章:使用magrittr進行管道操作。關於管道這個概念,我最早在Linux系統中接觸,它是Unix系統設計哲學的體現,“組合小功能完成大任務”,比如說BWA比對後排序用管道的寫法就是
bwa mem ref 1.fq 2.fq | samtools sort > align.bam
在R語言接觸管道符號"%>%"是在學習dplyr
包時候,那個時候我以為這個符號是 Hadley Wickham 創造出來的,其實是來源於Stefan Milton Bache開發的magrittr
中。
基礎部分
在沒有管道符號之前,如果我要對一個變數做一系列的分析的話,那麼寫法是下面這個樣子
# 先建立100個隨機數
nums <- rnorm(100)
# 分成兩列
nums_matrix <- matrix(nums, ncol = 2)
# 分別求兩列的均值
nums_mean <- Matrix::colMeans(nums_matrix)
這裡面我寫了很多中間變數,要多敲很多字,而且如果我要修改輸入的話的100個隨機數的話,我需要修改兩處。當然可以進行函式巢狀.
Matrix::colMeans(matrix(rnorm(100), ncol=2))
但是這種寫法不利於人的閱讀,當我讀到這個函式的時候,我需要先連續往大腦裡塞進去兩個函式後,才能抵達核心,然後再從裡往外解析。
但是有了管道符號之後一切就不一樣了,寫法就是
rnorm(100) %>% matrix(ncol=2) %>% Matrix::colMeans()
你會發現從左往右閱讀,程式碼讀起來非常的流暢。
雖然管道看起來很美好,但是在如下的場景中就不太適合了,
- 操作步驟特別的多,比如說10個,那麼你就需要用一些有意義的中間變數來存放中間結果,方便除錯
- 多輸入多輸出。比如說A和B輸入,輸出C和D
- 操作步驟構成了一張複雜關係的有向圖,比如說D結果依賴於B和C,而B和C依賴於A。
簡單點說,就是類似於A > B > C > D 這種場景用管道比較好。
除了%>%
這個好用的符號外,magrittr還提供了其他三個比較好用的符號,%$%
,%<>%
和%T>%
。
高階部分
上面都是常規操作,作為有一定基礎的R語言使用者,更希望探索點這個符號的本質。
首先明確一點,在R語言中一切符號本質上都是函式,比如說"+"也是一個函式,常規用法都是1 + 2
, 但是我們可以用函式的方式來寫哦
`+`(4,5)
# 9
因此rnorm(100) %>% matrix(ncol=2)
其實應該理解成
`%>%`(rnorm(100), matrix(ncol=2))
那麼我們就可以看看管道符號的原始碼了
?magrittr::`%>%`
function (lhs, rhs)
{
parent <- parent.frame()
env <- new.env(parent = parent)
chain_parts <- split_chain(match.call(), env = env)
pipes <- chain_parts[["pipes"]]
rhss <- chain_parts[["rhss"]]
lhs <- chain_parts[["lhs"]]
env[["_function_list"]] <- lapply(1:length(rhss), function(i) wrap_function(rhss[[i]],
pipes[[i]], parent))
env[["_fseq"]] <- `class<-`(eval(quote(function(value) freduce(value,
`_function_list`)), env, env), c("fseq", "function"))
env[["freduce"]] <- freduce
if (is_placeholder(lhs)) {
env[["_fseq"]]
}
else {
env[["_lhs"]] <- eval(lhs, parent, parent)
result <- withVisible(eval(quote(`_fseq`(`_lhs`)), env,
env))
if (is_compound_pipe(pipes[[1L]])) {
eval(call("<-", lhs, result[["value"]]), parent,
parent)
}
else {
if (result[["visible"]])
result[["value"]]
else invisible(result[["value"]])
}
}
}
這個程式碼的核心在於如下兩行
env[["_function_list"]] <- lapply(1:length(rhss), function(i) wrap_function(rhss[[i]],
pipes[[i]], parent))
env[["_fseq"]] <- `class<-`(eval(quote(function(value) freduce(value,
`_function_list`)), env, env), c("fseq", "function"))
這兩行乾的活其實是進行詞法轉換,也就是把我們之前的管道串聯起來的部分轉換成
my_pipe <- function(.){
. <- rnorm(.)
. <- matrix(., ncol = 2)
. <- Matrix::colMeans(.)
}
my_pipe(100)
多說兩句
考慮到在管道里面用"+"."-"這些函式時用到`+`或許會有點詭異,於是magrittr
給這些符號命名了對應的別名,如下
extract `[`
extract2 `[[`
inset `[<-`
inset2 `[[<-`
use_series `$`
add `+`
subtract `-`
multiply_by `*`
raise_to_power `^`
multiply_by_matrix `%*%`
divide_by `/`
divide_by_int `%/%`
mod `%%`
is_in `%in%`
and `&`
or `|`
equals `==`
is_greater_than `>`
is_weakly_greater_than `>=`
is_less_than `<`
is_weakly_less_than `<=`
not (`n'est pas`) `!`
set_colnames `colnames<-`
set_rownames `rownames<-`
set_names `names<-`
相關文章
- R語言中管道符號 %>% 的應用 及 舉例R語言符號
- 【R語言入門】R語言中的變數與基本資料型別R語言變數資料型別
- R語言中的生存分析R語言
- R 語言中取色器
- R語言學習筆記之一R語言筆記
- R語言中如何將科學計數法轉換為數值型R語言
- 【R語言學習筆記】文件讀取和型別修改R語言筆記型別
- R語言中的情感分析與機器學習R語言機器學習
- R語言中安裝 maptools 包R語言APT
- 【R語言學習筆記】若干排序問題R語言筆記排序
- R語言學習筆記:基礎知識R語言筆記
- 在R語言中,因子是什麼R語言
- 在資料科學領域,Python語言和R語言有何區別?資料科學PythonR語言
- 【譯文】R語言中的缺失值處理R語言
- R 語言中雙中括號 [[]]與資料型別列表的關係資料型別
- R語言data manipulation學習筆記之subset dataR語言筆記
- 關於R語言中文公開課R語言
- 如何輕鬆搞定資料科學麵試:Python&R語言篇資料科學PythonR語言
- R語言學習-高階資料管理R語言
- R語言中的迴圈函式(Grouping Function)R語言函式Function
- R語言中根據列名刪除指定的列R語言
- 資料科學大Battle,你站Python還是R資料科學BATPython
- R語言中提取檔名和檔名R語言
- 【R語言學習筆記】探索ggplot的排列組合(一)R語言筆記
- R語言資料探勘中的,“迴歸分析”是如何操作的?R語言
- 《論語》讀書筆記筆記
- R 語言程式設計藝術筆記程式設計筆記
- R語言中package ‘xxxx’ is not available (for R version 3.2.5)解決R語言PackageAI
- 在資料科學方面,python和R有何區別?資料科學Python
- 資料科學領域,你該選 Python 還是 R ?資料科學Python
- Python正在取代R,成為資料科學界新寵Python資料科學
- 最近看過的書(r10筆記第92天)筆記
- R:SNP資料篩選.R
- R語言中na.omit函式的應用 以及 在資料框中的應用R語言MIT函式
- R語言批量建立資料框R語言
- 資料分析與R語言01R語言
- R語言資料處理(一)R語言
- r語言資料處理(三)R語言