使用purrr package學functional programming的觀念(二):map family

map family是purrr package中很重要的一群函數,本質上用來取代R base中的apply, lapply , vapply, sapply等,基本功能就是一個可以使用另一個function作為參數的函數,而使用這參數所代表的函數來針對特定資料結構(主要是vector和list)中的element作處理,然後輸出成vector或是list的資料格式。

主要有:map_lgl(), map_chr(), map_dbl(),map_int(), map_if(), map_at(), map2_chr(), pmap()

map_lgl(), map_chr(), map_dbl(),map_int()這四組函數的差別,主要是固定輸出的資料格式,分別就輸出成logical、 numeric、 character 、 integer.

map_lgl(c(1,2,3), is_even)
#[1] FALSE TRUE FALSE
map_chr(c(1,2,3), is_even)
#[1] "FALSE" "TRUE" "FALSE"
map_dbl(c(1,2,3), sqrt)
#[1] 1.000 1.414 1.732
map_int(c(1,2,3), is_even)

map_at則是可以指定針對哪幾個element來使用參數中的函數來modify,輸出成一個list,而map_if則是先對每一個element使用一個邏輯判斷的函數(prediction function),再來看是否使用最後參數的函數來modify。

map_at(c(1,2,3,4), c(2), square)
# [[1]]
# [1] 1
# 
# [[2]]
# [1] 4
# 
# [[3]]
# [1] 3
# 
# [[4]]
# [1] 4
 map_if(c(1,2,3,4),function(x){x>2},square)
# [[1]]
# [1] 1
# 
# [[2]]
# [1] 2
# 
# [[3]]
# [1] 9
# 
# [[4]]
# [1] 16
[/code


map2則針對兩個以上不同的資料格式,一起使用參數中的function來處理。

map2(c(1,2,3),c("a","b","c"),paste)
# [[1]]
# [1] "1 a"
# 
# [[2]]
# [1] "2 b"
# 
# [[3]]
# [1] "3 c"

進階一點的使用方法是搭配dplyr的處理邏輯來使用,可以參考一下的寫法:

1:10 %>%
map(rnorm, n = 10) %>%
map_dbl(mean)
# Or use an anonymous function
1:10 %>%
map(function(x) rnorm(10, x))
# Or a formula
1:10 %>%
map(~ rnorm(10, .x))
# A more realistic example: split a data frame into pieces, fit a
# model to each piece, summarise and extract R^2
mtcars %>%
split(.$cyl) %>%
map(~ lm(mpg ~ wt, data = .x)) %>%
map(summary) %>%
map_dbl("r.squared")
# Use map_lgl(), map_dbl(), etc to reduce to a vector.
# * list
mtcars %>% map(sum)
# * vector
mtcars %>% map_dbl(sum)
# If each element of the output is a data frame, use
# map_df to row-bind them together:
mtcars %>%
split(.$cyl) %>%
map(~ lm(mpg ~ wt, data = .x)) %>%
map_df(~ as.data.frame(t(as.matrix(coef(.)))))

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s