R:如何为此计算升级for循环?

时间:2016-04-20 09:04:52

标签: r for-loop

我有这个矩阵:

A <- matrix(c(1,2,4,3,5,7,5,7,6,6,9,
              5.9,9,11,8,4.5,5.5,7.9,
              21,6.7,13.6,3.5,5,6,6,
              7.9,1,67,4,2), ncol=3, byrow=T)

和这个载体:

B <- c(2 ,3, 4)

使用此代码(仅限for-loop)(感谢https://stackoverflow.com/users/4870695/jimbou中的How use (only) for-loop for this operation?):

res <- NULL
for (j in 1:3){
  for(i in 1:nrow(A)){
  if(i == 1) tmp2 <- NULL
  tmp <-   ifelse(( i-1+B[j] >nrow(A)),NA, sum(A[i:(i-1+B[j]),j])) 
  tmp2 <- rbind(tmp2,tmp);rownames(tmp2) <- NULL
  }
  res <- cbind(res,tmp2);colnames(res) <- NULL
}

我获得了这个预期的结果:

      [,1] [,2] [,3]
 [1,]  4.0 14.0 22.9
 [2,]  8.0 21.0 26.9
 [3,] 11.0 27.0 27.8
 [4,] 15.0 25.5 35.4
 [5,] 13.5 23.2 35.5
 [6,] 25.5 17.2 28.5
 [7,] 24.5 19.6 22.6
 [8,]  9.5 16.9   NA
 [9,] 73.0   NA   NA
[10,]   NA   NA   NA

现在我想在每个操作的循环中将我的矩阵A乘以该矩阵C的相应行:

C
       [,1] [,2] [,3]
 [1,]  1.0  4.0  5.0
 [2,]  2.0  7.0  6.0
 [3,]   NA  8.0  7.0
 [4,]   NA   NA  9.0

新的预期输出(例如仅针对第一列)是:

    [1]
[1] 7.0  # = 1*1+ 3*2 =A[1,1]*C[1,1]+A[2,1]*C[2,1]
[2] 13.0 # = 3*1+5*2 = A[2,1]*C[1,1]+A[3,1]*C[2,1]
[3] 17.0 # = 5*1+6*2 = A[3,1]*C[1,1]+A[4,1]*C[2,1]
.....
[9]  140 # = 6*1+67*2 = A[9,1]*C[1,1]+A[10,1]*C[2,1]
对于A列,C的所有列的

依此类推。

我尝试在前面的代码中插入C[,j],例如:

res <- NULL
    for (j in 1:3){
      for(i in 1:nrow(A)){
      if(i == 1) tmp2 <- NULL
      tmp <-   ifelse(( i-1+B[j] >nrow(A)),NA, sum(A[i:(i-1+B[j]),j]*C[,j])) 
      tmp2 <- rbind(tmp2,tmp);rownames(tmp2) <- NULL
      }
      res <- cbind(res,tmp2);colnames(res) <- NULL
    }

但这不是正确的代码......有些想法?

1 个答案:

答案 0 :(得分:1)

一个问题是C的子集,请注意我在下面的回答中将C更改为E

A <- matrix(
        c(1,   2,   4,   
          3,   5,   7,
          5,   7,   6,
          6,   9,   5.9,
          9,  11,   8,
          4.5, 5.5, 7.9,
         21,   6.7,13.6,
          3.5, 5,   6,
          6,   7.9, 1, 
         67,   4,   2), ncol=3, byrow=T)

B <- c(2 ,3, 4)

E <- matrix(c(
  1.0,  4.0,  5.0,
  2.0,  7.0,  6.0,
  NA ,  8.0,  7.0,
  NA ,   NA,  9.0), ncol=3,byrow=T)

# So what we are doing is taking row
# A[i:(i-1+B[j]) and summing it then multiplying it by
# the first column of C not including the NA's 
#
# It will create a matrix with the first three 
# rows like this
#  1+3, 2+5+7 , 4+7+6+5.9 
#  3+5, 5+7+9 , 7+6+5.9+8
#  5+6, 7+9+11, 6+5.9+8+7.9
# ...
#
# NAs are introduced at the bottom since the range
# of input exceeds the rows
#
#  The multiplication by C then has the typical dot
#  product form of 
#  1*1,  2*2+5*7+7*8 + ...
# ...

res <- NULL
for (j in 1:3){
 for(i in 1:nrow(A)){
   if(i == 1) tmp2 <- NULL
   tmp <-   ifelse(
     ( i-1+B[j] >nrow(A)),
     NA, 
     sum(A[i:(i-1+B[j]),j] * E[1:(1+j),j]) 
    )
    tmp2 <- rbind(tmp2,tmp)  
   }
 res <- cbind(res,tmp2)
 }

# easier to remove col and rownames at the end
colnames(res) <- NULL
rownames(res) <- NULL

最终输出如下:

  [,1]  [,2]  [,3]
[1,]   7.0  99.0 157.1
[2,]  13.0 141.0 184.3
[3,]  17.0 179.0 192.5
[4,]  24.0 157.0 255.2
[5,]  18.0 136.1 236.6
[6,]  46.5 108.9 172.1
[7,]  28.0 125.0 129.0
[8,]  15.5 107.3    NA
[9,] 140.0    NA    NA
[10,]    NA    NA    NA