【问题标题】:Avoid the use of for loops避免使用 for 循环
【发布时间】:2023-03-27 14:58:01
【问题描述】:

我正在使用R,我有这样的代码:

for (i in 1:10)
   for (j in 1:100)
        if (data[i] == paths[j,1])
            cluster[i,4] <- paths[j,2]

在哪里:

  • data 是一个100行1列的向量
  • paths 是一个 100 行 5 列的矩阵
  • cluster 是一个 100 行 5 列的矩阵

我的问题是:如何避免使用“for”循环来遍历矩阵?我不知道apply 函数(lapplytapply...)在这种情况下是否有用。

例如j=10000时会出现这个问题,因为执行时间很长。

谢谢

【问题讨论】:

  • 我觉得这里的翻译有些遗漏了?
  • 您真的打算将最后匹配的“路径”保存在“集群”中吗?
  • 是的,Musa 和 wkmor1 说的……你真的是想让我达到 10……只测试 100 项向量数据中的前 10 项吗? --- 你的问题的一般答案是你必须开始思考向量而不是单个项目。只要有意义,就有更快的方法来做你正在做的事情。
  • 谢谢你们。我想要做的是当“数据”中的值等于“路径”中的值时,将路径第 2 列的第 4 列值保存在集群中,并避免使用“for”语句,因为当我有很多观察值时,计算时间会大大增加
  • 当它们不相等时你想做什么?......它们只是被忽略了?......或者集群第4列已经设置为不会改变的东西,除非这个条件满足。 (听起来像一个简单的 ifelse() 命令——没有循环——查看帮助)

标签: optimization r loops


【解决方案1】:

内循环可以向量化

cluster[i,4] <- paths[max(which(data[i]==paths[,1])),2]

但请查看 Musa 的评论。我想你缩进了别的东西。

第二个(外)循环也可以通过复制向量进行向量化,但是

  1. 如果 i 只有 100,你的加速不要太大
  2. 它将需要更多 RAM

[编辑] 据我了解您的评论可以只使用逻辑索引吗?

indx <- data==paths[, 1]
cluster[indx, 4] <- paths[indx, 2]

【讨论】:

    【解决方案2】:

    我认为这两个循环都可以使用以下方法进行矢量化:

    cluster[na.omit(match(paths[1:100,1],data[1:10])),4] = paths[!is.na(match(paths[1:100,1],data[1:10])),2]
    

    【讨论】:

    • 我想知道矢量化解决方案的性能与循环替代方案相比如何。
    • @Guido 在这种特殊情况下,很难说原始循环和 gd047 解决方案的结果不同,但一般来说循环和矢量化代码之间的差异可能很大。查看我对stackoverflow.com/questions/2908822/… 的回答,您可以从几小时到不到一秒。
    • @Marek 使用随机测试矩阵,我使用这两种方法得到了相等的聚类矩阵。我使用all.equal(loop_sol,vect_sol)检查了结果,您使用了哪些测试矩阵并给出了不同的结果?
    • @gd047 检查此sites.google.com/site/fsh9rss8heh(评论太长),我使用 R-2.10.1
    • @Marek 谢谢。你说的对。在我的示例中,data[i] 和 paths[j,1] 之间的匹配项不超过一个。在超过一个的一般情况下,占主导地位的是最后检查的那个。我不确定哪一个在矢量化方式中占主导地位。你有什么想法吗?
    猜你喜欢
    • 1970-01-01
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2020-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多