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(.)))))