【问题标题】:R - How to avoid loops when comparing two datasets?R - 比较两个数据集时如何避免循环?
【发布时间】:2015-01-13 19:42:36
【问题描述】:

为了简化问题而编的

我有两个矩阵:

  • mat1:nrow=100 000; ncol=5
  • mat2 : nrow=500 000 ; ncol=5

预期结果

统计mat1的每一行与mat2的每一行之间相似数字的数量:

提案

   Intersection <- function(matrix1, matrix2){
        Intersection = matrix(nrow=nrow(matrix1), ncol=ncol(matrix2)) 
          for(i in 1:nrow(matrix3)) {
            for(j in 1:ncol(matrix3)) {
            Intersection[i,j] = length(intersect(matrix1[i,], matrix2[j,])
           } 
         }   
    return(Intersection) }

问题:

如何向量化这个函数以避免循环

数据样本

以下是用于试验解决方案的数据样本:

输入(矩阵1) 结构(c(1L, 20L, 2L, 1L, 7L, 2L, 22L, 12L, 2L, 27L, 3L, 35L, 16L, 3L, 32L, 4L, 37L, 35L, 17L, 33L, 5L, 38L, 46L, 27L, 49L), .Dim = c(5L, 5L))

输入(矩阵2) 结构(c(1, 14, 7, 1, 7, 2, 22, 12, 2, 27, 7, 35, 16, 3, 32, 14, 39, 35, 17, 32, 17, 38, 46, 20, 49), .Dim = c(5L, 5L))

【问题讨论】:

  • 我的建议是您将其缩小到可管理的大小以进行测试。
  • 我刚刚添加了一些数据进行测试。
  • 也许您可以编写一个与 apply 系列函数兼容的函数,但我不确定如何管理使用两组数据。
  • 我也不是:s 这就是为什么我要寻求你们的帮助! :)

标签: r loops vectorization


【解决方案1】:

提高处理效率的方法不是丢弃循环,而是检查循环的内部逻辑。在这种情况下,您似乎希望使用TARGET 的列-i 中的相交元素数和mat 的列-j 作为偏移量来选择“IF_n”列中的元素并将该项目放在第 (5+i) 行和第 j 列。当以这种方式描述问题时,我们应该能够摆脱所有那些ifelse 语句。 (我经常发现花时间以最清晰的自然语言重述问题是提高效率的关键。)在获取 0 结果以索引第五列时会涉及到一些模算术运算。

在询问 df$TARGET[i] 与 mat-column 的交集长度时,我的逻辑也有问题。 df$TARGET[i] 只能是单个数字,因为您使用了向量索引而不是矩阵索引。 (df$TARGET 是一个矩阵,所以应该是 df$TARGET[,i])

这是我的反建议。我认为它更符合预期的结果,并且可能至少快 5 倍,因为您可以完全消除所有 ifelse folderol。)

BDfunc <- function(df, mat){
  for  (i in 1:nrow(df)) {   # print(i)  (use for debugging)
    for (j in 1:ncol(mat)){  # print(j)
     mat[5+i, j]<- df[i , 2 + (
      (length(intersect(df$TARGET[,i], mat[,j])) ) %% 5 )]   }
  }
  return(mat)
}   
 mat <- BDfunc(df, mat)

> mat
          [,1]      [,2]      [,3]      [,4]      [,5]
 [1,] 1.000000 20.000000  2.000000  1.000000  7.000000
 [2,] 2.000000 22.000000 12.000000  2.000000 27.000000
 [3,] 3.000000 35.000000 16.000000  3.000000 32.000000
 [4,] 4.000000 37.000000 35.000000 17.000000 33.000000
 [5,] 5.000000 38.000000 46.000000 27.000000 49.000000
 [6,] 5.855105  2.216690  7.458434  3.120932  2.216690
 [7,] 6.381849  6.381849  6.630405  6.381849  6.630405
 [8,] 2.464372  2.464372  2.464372  5.993037  5.993037
 [9,] 1.614552  1.614552  1.614552  5.507400  1.614552
[10,] 2.088811  2.088811  2.088811  2.088811  5.974585

【讨论】:

  • df$TARGET 是向量而不是矩阵,这就是为什么我使用 df$TARGET[i] 而不是 df$TARGET[,i]
  • 感谢您的建议 BondedDust,但我想使用 vectorized 函数来优化此函数。
  • 有关信息,我编辑了描述以简化问题。这个问题现在更笼统了,重点放在了相似元素的数量上。
  • 如果您遇到n x n 问题,解决它的唯一方法是使用n x n 解决方案。我给了你有用的建议,但没有得到任何信任。洗手。
猜你喜欢
  • 2016-01-23
  • 1970-01-01
  • 1970-01-01
  • 2011-06-21
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-20
相关资源
最近更新 更多