【问题标题】:R: how to assign A[B[, j], j] without for-loopR:如何在没有 for 循环的情况下分配 A[B[, j], j]
【发布时间】:2017-01-26 06:13:53
【问题描述】:

我想用另一个值替换矩阵A 中的某些值:在这种情况下是1。对于A 的第 j 列,需要替换的行索引是B 的第 j 列中的行索引。下面我举个例子,赋值是通过for循环实现的。

我的问题是:如何更简单、更高效和/或不使用 for 循环来实现此分配?

set.seed(4521)
n <- 10
p <- 5

A <- matrix(rep(NaN,n*p),n,p)

B <- replicate(p, sample(n))
B <- B[1:5,]

for (j in 1:n){      
  A[B[,j],j] <- 1      
}

print(B)
print(A)

B:

      [,1] [,2] [,3] [,4] [,5]
[1,]    5   10    7    6    5
[2,]   10    2    9    9    2
[3,]    7    9    3   10    4
[4,]    9    4    1    3    3
[5,]    4    8    6    4    9

A:

        [,1] [,2] [,3] [,4] [,5]
 [1,]   NaN  NaN    1  NaN  NaN
 [2,]   NaN    1  NaN  NaN    1
 [3,]   NaN  NaN    1    1    1
 [4,]     1    1  NaN    1    1
 [5,]     1  NaN  NaN  NaN    1
 [6,]   NaN  NaN    1    1  NaN
 [7,]     1  NaN    1  NaN  NaN
 [8,]   NaN    1  NaN  NaN  NaN
 [9,]     1    1    1    1    1
 [10,]    1    1  NaN    1  NaN

【问题讨论】:

    标签: r for-loop matrix vectorization assign


    【解决方案1】:

    我们可以使用矩阵索引:

    i <- as.numeric(B)
    j <- rep(1:ncol(B), each = nrow(B))
    A[cbind(i,j)] <- 1
    

    或者将它们放在一行中:

    A[cbind(as.numeric(B), rep(1:ncol(B), each = nrow(B)))] <- 1
    

    正如 OP 本人后来指出的那样,我们可以将 rep(1:ncol(B), each = nrow(B)) 替换为更短的 as.numeric(col(B))。我知道,但我从不这样做,因为它使用的内存是我建议的内存的两倍。使用哪一个只是个人喜好。仅在处理大型矩阵时才重要。

    【讨论】:

      【解决方案2】:

      恕我直言,@Zheyuan Li 的代码在做什么更清楚。我更喜欢他的解决方案。
      只是为了展示另一种选择:使用一维索引,您可以这样做:

      An <- nrow(A)
      Bp <- ncol(B)
      offset <- rep(seq(0, An*(Bp-1), by=An), each=Bp)
      A[B + offset] <- 1
      

      一行:

      A[B + rep(seq(0, nrow(A)*(ncol(B)-1), by=nrow(A)), each=ncol(B))] <- 1
      

      【讨论】:

        【解决方案3】:

        简单的解决方案:

        A[cbind(as.numeric(B), as.numeric(col(B)))] <- 1
        

        感谢(和 +1)李哲元的第一个答案中的错字,其中有 col 而不是 ncol

        【讨论】:

          猜你喜欢
          • 2021-12-17
          • 2021-04-09
          • 2021-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-11
          • 1970-01-01
          • 2020-05-07
          相关资源
          最近更新 更多