网址
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触发的