R語言函數式編程purrr的應用
S語言的設計者、R語言核心團隊成員Chambers(2016)在Extending R一書中提到R語言中的三大理念。
Everything that exists in R is an object. OBJECT
Everything that happens in R is a function call.FUNCTIONInterfaces to other software are part of R. INTERFACE
在數據分析中,R語言函數式編程用的比較多。為此,Wickham等人編寫一個高級函數編程語言包purrr。
purrr enhances Rs functional programming (FP) toolkit by providing a complete and consistent set of tools for working with functions and vectors.
purrr在0.2.2版本之後有新的變化,變得更輕,更底層,分解為purrr和新的purrrlyr包。
purrr no longer depends on dplyr, lazyeval, or Rcpp. This makes the dependency graph of the tidyverse simpler, and makes purrr more suitable as a dependency of lower-level packages. This means that data-frame based mappers (dmap(), dmap_at(), dmap_if(), invoke_rows(), slice_rows(), map_rows(), by_slice(), by_row(), and unslice()) have been moved to a new package, purrrlyr. This is a bit of an aggressive change but it needed to be done, and in this case I think its better to rip the band aid off quickly.
R語言在運行時候速度確實一般,因此很多小夥伴得到的忠告就是避免使用循環,而是採用apply系列函數。(其實,在必要的時候,使用循環還是很方便的。)
- apply系列函數簡單應用
應用場景,求均值。分別採用了apply(mtcars,2,mean)、lapply(mtcars,mean)和sapply(mtcars,mean)。
> apply(mtcars,2,mean)n mpg cyl disp hp drat wt qsec vs am n 20.090625 6.187500 230.721875 146.687500 3.596563 3.217250 17.848750 0.437500 0.406250 n gear carb n 3.687500 2.812500 n> lapply(mtcars,mean)n$mpgn[1] 20.09062n$cyln[1] 6.1875n$dispn[1] 230.7219n$hpn[1] 146.6875n$dratn[1] 3.596563n$wtn[1] 3.21725n$qsecn[1] 17.84875n$vsn[1] 0.4375n$amn[1] 0.40625n$gearn[1] 3.6875n$carbn[1] 2.8125nn> sapply(mtcars,mean)n mpg cyl disp hp drat wt qsec vs am n 20.090625 6.187500 230.721875 146.687500 3.596563 3.217250 17.848750 0.437500 0.406250 n gear carb n 3.687500 2.812500 n
其實,這個時候採用函數式編程中常見的map也可以實現,上述的分析需求。R語言中的map需要大寫Map(函數,數據)。
> Map(mean,mtcars)n$mpgn[1] 20.09062n$cyln[1] 6.1875n$dispn[1] 230.7219n$hpn[1] 146.6875n$dratn[1] 3.596563n$wtn[1] 3.21725n$qsecn[1] 17.84875n$vsn[1] 0.4375n$amn[1] 0.40625n$gearn[1] 3.6875n$carbn[1] 2.8125n
- purrr包
library(purrr)nlibrary(listviewer)ndata("mtcars") n
- map
下面來看,map在數據進行標準化處理中的應用。
- map2
如果需要處理多個數據參數,就需要應用map2。
下面是生成多個正太分布隨機數。
- pmap
如果是更多的參數,那麼就需要pmap。
- modify
- 處理list等嵌套數據
生成嵌套數據
查看嵌套數據
提取嵌套數據這樣看起來是不是很繁瑣?那麼就轉成data.frame吧!- 其他
purrr包還有很多其他的功能,這裡只介紹一些常用的。
例如,同時生成多個不同分布函數的隨機數,此時會用到invoke_map()。
purrr提供了簡化匿名函數的寫法。不過,為了可讀性,前文在介紹時,沒有採用這種寫法。
# 匿名函數-----nmap_df(mtcars, ~ .x * 2)nmap_df(mtcars, function(x) x * 2)n
這兩種寫法均可以滿足需求。
purr還有一種應用場景就是多模型分析。這個放在下一個分享中。
————————
參考資料:
1.Chambers, John M. Extending R. CRC Press, 2016.
2.Lessons and Examples3.purrr function reference
分析環境
R version 3.4.0 (2017-04-21)n# devtools::install_github("tidyverse/purrr")nPackage: purrrnTitle: Functional Programming ToolsnVersion: 0.2.2.9000n
推薦閱讀:
※Erlang入門教程 - 8. 在終端上輸出
※編程範式與系統設計
※幻想中的Haskell - Compiling Combinator
※函數式又是函數式
※Python 為什麼不能序列化函數閉包?