如何将向量中的元素块定义为零并遍历下一个块?

时间:2018-06-22 10:19:29

标签: r loops

我有一个大向量,我想与一个矩阵相乘。这在r中很容易做到。这里的问题是,我想将向量中的某些元素块定义为零,将其与矩阵相乘,然后创建一个向量,然后对下一个元素块重复,使第一个块保留原始值。 / p>

我举一个我想做的事的小例子。 “ a”是向量,“ b”是矩阵:

a <- c(1:6)
b <- matrix(1:36, nrow = 6, ncol = 6)

a
[1] 1 2 3 4 5 6

b

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    7   13   19   25   31
[2,]    2    8   14   20   26   32
[3,]    3    9   15   21   27   33
[4,]    4   10   16   22   28   34
[5,]    5   11   17   23   29   35
[6,]    6   12   18   24   30   36

在此示例中,“ a”有3个零块:

a1 <- c(0 , 0, a[3:6])              #giving              [1] 0 0 3 4 5 6
a2 <- c(a[1:2], 0, 0, a[5:6])       #giving              [1] 1 2 0 0 5 6
a3 <- c(a[1:4], 0, 0)               #giving              [1] 1 2 3 4 0 0

我想做的是将所有三个块与矩阵相乘,并将结果绑定到一个矩阵中:

c <- rbind(a1 %*% b, a2 %*% b, a3 %*% b)

得出矩阵c:

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   86  194  302  410  518  626
[2,]   66  150  234  318  402  486
[3,]   30   90  150  210  270  330

当然,我的代码很笨拙,不可能与很大的向量/矩阵一起使用。是否有循环代码可以快速进行这些计算?

1 个答案:

答案 0 :(得分:0)

首先,我定义向量和矩阵。

# Data definitions
a <- c(1:6)
b <- matrix(1:36, nrow = 6, ncol = 6)

接下来,我创建一个函数,该函数生成您的a值的列表。它默认为长度为2的零块。

# Define blocks of zeroes in vector 
define_block <- function(v, n = 2){
  # Check that v is a multiple of n
  if(length(v)%%n)warning("Vector not a multiple of block length")

  # Define blocks of zeroes
  lapply(1:(length(v)/n), function(x)replace(v, ((x-1)*n + 1):(x*n), 0))
}

在这里,我应用函数:

# Create lists of blocks
block_list <- define_block(a)

产生,

# [[1]]
# [1] 0 0 3 4 5 6
# 
# [[2]]
# [1] 1 2 0 0 5 6
# 
# [[3]]
# [1] 1 2 3 4 0 0

最后,我遍历block_list并执行您的计算,并使用do.callrbind将结果绑定在一起。

# Run through block list and bind result into a matrix
do.call(rbind, lapply(block_list, function(x)x%*%b))


#     [,1] [,2] [,3] [,4] [,5] [,6]
#[1,]   86  194  302  410  518  626
#[2,]   66  150  234  318  402  486
#[3,]   30   90  150  210  270  330