并行计算,在dplyr中完成tidyr::complete的哪种替代方案?
我正在试着使一根管子平行。 在管道中有一个tidyr命令(“tidyr::complete”)。这会在并行运行时分解代码,因为无法识别对象类 dplyr中是否有其他选项需要完成并行计算,在dplyr中完成tidyr::complete的哪种替代方案?,r,dplyr,parallel-processing,multidplyr,R,Dplyr,Parallel Processing,Multidplyr,我正在试着使一根管子平行。 在管道中有一个tidyr命令(“tidyr::complete”)。这会在并行运行时分解代码,因为无法识别对象类 dplyr中是否有其他选项需要完成 library(dplyr) library(tidyr) library(zoo) test <- tibble(year=c(1,2,3,4,5,5,1,4,5), var_1=c(1,1,1,1,1,1,2,2,2), var_2=c(1,1,
library(dplyr)
library(tidyr)
library(zoo)
test <- tibble(year=c(1,2,3,4,5,5,1,4,5),
var_1=c(1,1,1,1,1,1,2,2,2),
var_2=c(1,1,1,1,1,2,3,3,3),
var_3=c(0,5,NA,15,20,NA,1,NA,NA))
max_year <- max(test$year,na.rm = T)
min_year <- min(test$year,na.rm = T)
Multidplyr允许您:
partition()
collect()
结果complete
需要知道输入数据中所有可能的值,以便创建缺少的行,这意味着此操作作为一个整体无法拆分,这就是为什么没有可用的方法
在您提供的示例中,每个节点将接收一个var_1,var_2
对,而不知道其他节点得到了什么,这不允许并行实现预期结果
但是,正如您已经知道的那样,year=seq(minu_year,max_year)
,您可以仅为该变量并行化complete
任务,通过var_1
拆分任务,例如使用furr
包:
library(furrr)
plan(multiprocess)
test_parallel <- test %>%
group_by(var_1,var_2) %>%
complete(var_1) %>% split(.$var_1) %>%
furrr::future_map(~{
complete(.x, year = seq(min_year,max_year)) %>%
dplyr::mutate(
var_3 = na.approx(var_3,na.rm = FALSE),
var_3 = if(all(is.na(var_3))) NA else na.spline(var_3,na.rm = FALSE))
}) %>% bind_rows()
> identical(c(test_serial$var_1,test_serial$var_2,test_serial$var_3,test_serial$year),
+ c(test_parallel$var_1,test_parallel$var_2,test_parallel$var_3,test_parallel$year))
[1] TRUE
库(furr)
计划(多进程)
测试单元并行%
分组依据(变量1,变量2)%>%
完成(var_1)%%>%拆分(.$var_1)%%>%
未来地图(~{
完成(.x,年=序号(最小年,最大年))%>%
dplyr::突变(
var_3=近似值(var_3,na.rm=假),
var_3=if(all(is.na(var_3)))na else na.spline(var_3,na.rm=FALSE))
})%%>%bind_行()
>相同(c(测试序列$var_1、测试序列$var_2、测试序列$var_3、测试序列$year),
+c(测试并行$var_1、测试并行$var_2、测试并行$var_3、测试并行$year))
[1] 真的
要在更大的数据集上进行测试以衡量潜在的改进。但是,如果我能够为每个节点分配一个完整的组来完成(比如var_1),那么我是否能够使用complete?我得到了以下警告:#警告消息:[一次性警告]分叉处理(“多核”)在将来被禁用(>=1.13.0)从RStudio运行R时,因为它被认为是不稳定的。因此,计划(“多核”)将退回计划(“顺序”),计划(“多进程”)将退回计划(“多段”)——而不是过去的计划(“多核”)。有关更多详细信息,如何控制分叉处理与否,以及如何在将来的R会话中消除此警告,请参阅?future::supportsMulticoreAs proof,system.time()显示,Furr解决方案比标准的oneMultitasking慢4倍。在小示例数据集上,多任务处理通常要慢,因为您需要打开任务,将数据传输给他们并收集结果,这比直接处理数据花费的时间要多出15行,请参见我的最后一句;-)
devtools::install_github("hadley/multidplyr")
library(multidplyr)
cl <- new_cluster(2)
cluster_copy(cl, c("test","max_year","min_year"))
cluster_library(cl, c("dplyr","tidyr","zoo"))
test_parallel <- test %>% group_by(var_1,var_2) %>% partition(cl)
test_parallel <- test_parallel %>%
dplyr::group_by(var_1,var_2) %>%
tidyr::complete(var_1, year = seq(min_year,max_year)) %>%
dplyr::mutate(
var_3 = na.approx(var_3,na.rm = FALSE),
var_3 = if(all(is.na(var_3))) NA else na.spline(var_3,na.rm = FALSE)) %>%
collect()
Error in UseMethod("complete_") :
no applicable method for 'complete_' applied to an object of class "multidplyr_party_df"
library(furrr)
plan(multiprocess)
test_parallel <- test %>%
group_by(var_1,var_2) %>%
complete(var_1) %>% split(.$var_1) %>%
furrr::future_map(~{
complete(.x, year = seq(min_year,max_year)) %>%
dplyr::mutate(
var_3 = na.approx(var_3,na.rm = FALSE),
var_3 = if(all(is.na(var_3))) NA else na.spline(var_3,na.rm = FALSE))
}) %>% bind_rows()
> identical(c(test_serial$var_1,test_serial$var_2,test_serial$var_3,test_serial$year),
+ c(test_parallel$var_1,test_parallel$var_2,test_parallel$var_3,test_parallel$year))
[1] TRUE