2

我想通过减少迭代来创建一个对称矩阵,即sol[i, j]sol[j, i].

到目前为止我的代码:

# Prepare input
subss <- list(a = c(1, 2, 4), b = c(1, 2, 3), c = c(4, 5))
A <- matrix(runif(25), ncol = 5, nrow = 5)
# Pre allocate memory
sol <- matrix(nrow = length(subss), ncol = length(subss), 
          dimnames = list(names(subss), names(subss))) 
x <- 0
for (i in seq_along(subss)) {
    # Omit for the subsets I already calculated ?
    for (j in seq_along(subss)) {
        x <- x + 1
        message(x)

        # The function I use here might result in a NA
        sol[i, j] <- mean(A[subss[[i]], subss[[j]]]) 
        sol[j, i] <- sol[i, j] # Will overwrite when it shouldn't
    }
}

将使用 9 次迭代,我怎样才能避免它们并且只进行 6 次迭代?

我需要计算对称值,所以这个问题不适用。另外这个不起作用,因为可能有很多组合,并且在某些时候它无法在内存中分配向量。

4

3 回答 3

1

循环通常forouter. 尝试对循环进行字节编译或在 Rcpp 中实现它。

subss <- list(a = c(1, 2, 4), b = c(1, 2, 3), c = c(4, 5))
set.seed(42)
A <- matrix(runif(25), ncol = 5, nrow = 5)

#all combinations of indices
ij <- combn(seq_along(subss), 2)

#add all i = j
ij <- matrix(c(ij, rep(seq_along(subss), each = 2)), nrow = 2)

#preallocate
res <- numeric(ncol(ij))

#only one loop
for (k in seq_len(ncol(ij))) {

    message(k)

    res[k] <- mean(A[subss[[ij[1, k]]], subss[[ij[2, k]]]]) 
}
#1
#2
#3
#4
#5
#6

#create symmetric sparse matrix    
library(Matrix)
sol <- sparseMatrix(i = ij[1,], j = ij[2,],
                    x = res, dims = rep(length(subss), 2), 
                    symmetric = TRUE, index1 = TRUE)
#3 x 3 sparse Matrix of class "dsCMatrix"
#                                  
#[1,] 0.7764715 0.6696987 0.7304413
#[2,] 0.6696987 0.6266553 0.6778936
#[3,] 0.7304413 0.6778936 0.5161089
于 2017-04-06T11:14:34.090 回答
0

我找到了一种使用普通 for 循环的方法:

x <- 0
for (i in seq_along(subss)) {
    for (j in seq_len(i)) { # or for (j in 1:i) as proposed below
        x <- x + 1
        message(x)

        sol[i, j] <- mean(A[subss[[i]], subss[[j]]]) 
        sol[j, i] <- sol[i, j]
    }
}
于 2017-04-06T12:04:06.253 回答
0
for (i in 1:length(subss)) {
  for (j in 1:i) {
    message(i, ' ', j, ' - ', mean(A[subss[[i]], subss[[j]]]) ) # Check iterations and value
    sol2[i, j] <- sol2[j, i] <- mean(A[subss[[i]], subss[[j]]]) 
  }
}

我检查了您的脚本值并且不是对称的:

1 1 - 0.635455905252861
1 2 - 0.638608284398086
1 3 - 0.488700995299344
2 1 - 0.568414432255344
2 2 - 0.602851431118324
2 3 - 0.516099992596234
3 1 - 0.595461705311512
3 2 - 0.656920690399905
3 3 - 0.460815121419728

我的价值观(与@Llopis 相同):

1 2 - 0.638608284398086
1 3 - 0.488700995299344
2 2 - 0.602851431118324
2 3 - 0.516099992596234
3 2 - 0.656920690399905
3 3 - 0.460815121419728
于 2017-04-06T14:40:00.940 回答