【问题标题】:How to Parallelize Loop to substitute cells in R如何并行化循环以替换 R 中的单元格
【发布时间】:2021-07-02 08:42:20
【问题描述】:

我正在尝试并行化一个嵌套循环,在该循环中,我在其中的每个国家 (v5) 内的两个数据集之间替换公共变量 (changevars),每个观察都使用其 id (v3)。我必须使用国家+id,因为国家之间的 id 是重复的。

我的循环代码是:

for (var in changevars) {

print(var)

for (i in unique(int2006$v5)) {

print(i)

for (id in unique(int2006$v3)) {

x2006r[x2006r$v5 == i & x2006r$v3 == id, var] <- int2006[int2006$v5 == i & int2006$v3 == id, var]    

}

}

}

我想并行化它。

虽然有效,但速度确实很慢。而且我不明白从for 更改为foreach 循环和dopar 背后的逻辑。我试图理解其他答案,但我的尝试都失败了。

数据集的可重现示例:

  1. 源数据集
> dput(int2006)
structure(list(v3 = c(10001, 10002, 10003, 10004, 10005, 10006, 
10007, 10008, 10009, 10010, 10011, 10012, 10013, 10014, 10015, 
10016, 10017, 10018, 10019, 10020), v5 = c(36, 36, 36, 36, 36, 
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36), 
    v7 = c(3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 
    3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 3606, 
    3606), v8 = c(1, 1, 2, 1, NA, NA, 1, 2, 2, 2, NA, 2, 2, 1, 
    1, 1, 2, 2, 1, 2), v9 = c(NA, 2, 1, 2, 1, 1, 1, 2, 4, 1, 
    NA, 1, NA, 1, 1, 1, 1, 1, 1, 2)), row.names = c(NA, 20L), class = "data.frame")
  1. 目标数据集(应将 1 的单元格复制到的数据集):
    > dput(x2006r)
structure(list(v3 = c(10001, 10002, 10003, 10004, 10005, 10006, 
10007, 10008, 10009, 10010, 10011, 10012, 10013, 10014, 10015, 
10016, 10017, 10018, 10019, 10020), v5 = c(36, 36, 36, 36, 36, 
36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36), 
    v7 = c("3606", "3606", "3606", "3606", "3606", "3606", "3606", 
    "3606", "3606", "3606", "3606", "3606", "3606", "3606", "3606", 
    "3606", "3606", "3606", "3606", "3606"), v8 = c(1, 1, 2, 
    1, NA, NA, 1, 2, 2, 2, NA, 2, 2, 1, 1, 1, 2, 2, 1, 2), v9 = c(NA, 
    2, 1, 2, 1, 1, 1, 2, 4, 1, NA, 1, NA, 1, 1, 1, 1, 1, 1, 2
    )), row.names = c(NA, 20L), class = "data.frame")
  1. 要迭代的变量
changevars <- c("v7","v8","v9")

有人可以帮助我吗?我真的被困住了。另外,我不确定并行化这个循环是否会帮助我提高速度。

非常感谢!

【问题讨论】:

  • 嗨,你能为你的数据集格式提供一个最小的可复制示例吗?见这里stackoverflow.com/questions/5963269/…
  • 当然。添加。谢谢!
  • 谢谢,但是 changevars 是什么?也请在未来的时间包括更小的和易于理解的例子。太大的数据集可能更难查看...
  • 你添加的不是一个最小的例子。如果我们能够更轻松地找出您想要完成的工作,我们将更容易帮助您进行调试。尽量保持reprex 中的数据尽可能小(比如,只有你绝对需要的尽可能多的行和列)
  • 此外,由于"cumulation" 不在一个数据集中 (int2006a),因此我们无法重现您想要的内容。

标签: r dataframe parallel-processing doparallel


【解决方案1】:

这是一种称为“更新连接”的常见操作。一个新的dplyr 实用函数让它变得非常简单:

library(dplyr)
join_vars <- c("v3", "v5")
changevars <- c("v7","v8","v9")
result <- rows_update(x = x2006r, y = int2006[c(join_vars, changevars)], by = join_vars)

如果您确实想自己动手,请至少开始 with a join。你可以看到几个dplyr-based implementations here。我相信data.table 在这方面也做得很好。

【讨论】:

  • 由于我的声望不够,就不出现了。这是一个正确的答案,它比我的嵌套循环快得多。非常感谢你,你真的让我很开心。谢谢你们!你为我节省了很多时间。 :)
猜你喜欢
  • 2020-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-13
  • 2020-02-29
  • 1970-01-01
  • 2021-06-16
相关资源
最近更新 更多