首页 文章

R - 比较两个数据集时如何避免循环?

提问于
浏览
5

版本是为了简化问题

我有两个矩阵:

  • mat1:nrow = 100 000; NcoI位= 5

  • mat2:nrow = 500 000; NcoI位= 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) }

问题:

How to vectorize this function in order to avoid loops

数据样本

以下是为了试验解决方案而提供的数据示例:

dput(matrix1)结构(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))dput(matrix2)结构(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))

1 回答

  • 2

    提高处理效率的方法不是抛弃循环而是检查循环的内部逻辑 . 在这种情况下,您似乎希望使用 TARGET 的column-i中的交叉元素的数量与 mat 的列-j作为偏移量来选择"IF_n"列中的元素并将该项目放在(5 i)-th中第j行和第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
    

相关问题