網址
https://github.com/hadley/multidplyr
在做資料處理的時候
如果需要針對每個 group 做 window (block) function
在 dplyr 裡是 data %>% group_by(grp) %>% summarize or do
如果組數很多, 或是function太醜算太久
我們就需要平行, 讓每個group在多個核心跑function
在R裡快速平行化的方式是藉由 parallel package
cl <- makeCluster(8)
tmp <- parLapply(cl, a_list, to_this_fun, other_par)
stopCluster(cl)
然後通常是
tmp1 <- tmp %>% rbind_all() %>% distinct() %>% whatever_you_want
重點是那個"list", list哪裡來?
你可以 tmp_idx <- tmp %>% group_by(grp) %>% group_indices()
或者, 使用"裡"技
tmp %>% mutate(IID=group_indices_(., .dots=c("grp"))) %>% group_by(IID)
有了分組list, 你可以傳 "list+整份資料"
然後藉由list讓每個核心, 做一小部分,
但是資料量很大的時候, 根本不可能這樣做
改善的辦法是資料切割(by group)
tmp_sep <- tmp %>% split(.$IID)
注意, split只能切單一索引, 如果你是複合索引(EX:性別+年齡),
那就要照我上面的方法, 先把IID算出來再用IID切
### 方案一: split+parLapply
data <- data %>%
mutate(IID=group_indices_(., .dots=c("grp_a","grp_b"))) %>%
group_by(IID)
data_sep <- data %>% split(.$IID)
cl <- makeCluster(8)
out <- parLapply(cl, data_sep, to_this_fun, other_par)
stopCluster(cl)
out <- out %>% rbind_all() %>% distinct()
再來, 如果資料量大, 組數又多的時候, split 會做到天荒地老
這時候方案二出現了 mupltidplyr::partition & collect
他會在group_by的時候把資料平分到各個核心裡, 處理完之後再收回來黏起來
這個外掛還在開發中, 不知道有沒有靈異現象
另外很多function是parallel的wrap, 可能有些特別目的
### 方案二: partition & collect
cl <- create_cluster(8) ## 這兩行要寫, 似乎是會註冊到自己的env中
set_default_cluster(cl) ## 然後會自動回收
data_par <- data %>% partition(IID, cluster=cl) ## "cluster="要寫
cluster_assign_value(cluster=cl, "myfun", myfun) ## export function
out <- data_par %>% do(res=myfun(.)) %>% collect() ## 回收可能是collect觸發的