R中如何并行遍历多组列表与矩阵调用ipsi函数处理多重插补数据
错误原因
parallel::parLapply 要求的输入格式为 parLapply(cl, 迭代对象, 执行函数, 其他参数),你在本应传入迭代对象的位置直接写了for循环,不符合函数参数要求,因此触发「FUN缺失」的报错。同时你仅向集群节点导出了d.seq变量,节点无法访问a/y/id等其他参数列表,即使语法修正后也会报变量不存在的错误。
修复代码
先修正并行调用逻辑,导出所有需要用到的变量,跑完后主动关闭集群释放资源:
n <- 500 T <- 4 time <- rep(1:T, n) time <- rep(list(time), 30) # 简化重复生成列表的写法,不用手动写30次 id <- rep(1:n, rep(T, n)) id <- rep(list(id), 30) x.trt <- matrix(rnorm(n * T * 5), nrow = n * T) x.trt <- rep(list(x.trt), 30) x.out <- matrix(rnorm(n * T * 5), nrow = n * T) x.out <- rep(list(x.out), 30) a <- rbinom(n * T, 1, .5) a <- rep(list(a), 30) y <- rnorm(n, mean=1) # 修正原代码的参数顺序错误 y <- rep(list(y), 30) d.seq <- seq(0.1, 5, length.out = 10) d.seq <- rep(list(d.seq), 30) set.seed(500, kind = "L'Ecuyer-CMRG") numcores <- future::availableCores() cl <- parallel::makeCluster(numcores) # 加载依赖包 parallel::clusterEvalQ(cl, { library(dplyr) library(npcausal) }) # 导出所有需要用到的变量到集群节点 parallel::clusterExport(cl, c("a","y","id","time","x.trt","x.out","d.seq"), envir = environment()) # 修正parLapply调用逻辑,迭代1:30,每次传入索引i执行ipsi new_element <- parallel::parLapply(cl, 1:30, function(i) { npcausal::ipsi(a = a[[i]], y = y[[i]], id = id[[i]], time = time[[i]], x.out = x.out[[i]], x.trt = x.trt[[i]], delta.seq = d.seq[[i]], nsplits = 10) }) # 运行结束后关闭集群,避免资源残留 parallel::stopCluster(cl)
额外优化提示
- 如果你30次插补用到的
delta.seq完全一致,不需要存为长度30的列表,直接在ipsi调用时传入固定值即可,无需随变量导出 - Linux/macOS系统可以将
makeCluster替换为makeForkCluster,无需手动导出变量,运行效率更高
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

