作者memphis (让你喜欢这世界~)
看板R_Language
标题[心得] dplyr 外挂 multidplyr
时间Wed Apr 6 15:32:25 2016
网址
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触发的
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.109.73.10
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/R_Language/M.1459927948.A.57F.html
1F:推 Godkin: 推! 04/06 17:42
2F:推 micdebate: 请问%>%是什麽意思... 04/16 22:33
4F:推 micdebate: c大这网页无法显示 04/16 22:47
6F:推 micdebate: 请问一下,为何没有create_cluster的函数 04/17 21:25