我有两个矩阵:
计算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(矩阵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))
dput(矩阵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))
答案 0 :(得分:2)
提高处理效率的方法不是抛弃循环而是检查循环的内部逻辑。在这种情况下,您似乎希望使用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
文件夹。)
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