版为了简化问题
我有两个矩阵:
预期成绩
统计
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) }
题:
如何矢量化此函数以避免循环 ?
数据样本
以下是用于试验解决方案的数据示例:
dput(matrix1) structure(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) structure(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))
最佳答案
提高处理效率的方法不是扔掉循环,而是检查循环的内在逻辑。在这种情况下,您似乎想使用 TARGET
中相交元素的数量。的列-i 与 mat
的 column-j 作为偏移量以在“IF_n”列中选取元素并将该项目放置在第 (5+i) 行和第 j 列中。我们应该能够摆脱所有这些 ifelse
以这种方式描述问题时的陈述。 (我经常发现花时间用尽可能清晰的自然语言重述问题是提高效率的关键。)在获取 0 结果以索引第五列时会涉及一些模数计算。
我在询问 df$TARGET[i] 与 mat-column 的交集长度时的逻辑也有问题。 df$TARGET[i] 只能是单个数字,因为您使用了向量索引而不是矩阵索引。 (df$TARGET 是一个矩阵,所以它应该是 df$TARGET[,i])
这是我的反建议。我认为它更符合预期的结果,并且可能至少快 5 倍,因为您可以完全消除所有这些 ifelse
胡闹。)
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
关于R - 比较两个数据集时如何避免循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26963480/