用0替换矩阵的范围

时间:2016-05-10 21:17:14

标签: r matrix

我希望将matrix的每一行的部分替换为0。保留指定范围内的部分。要保留的指定范围因行而异。我可以使用嵌套的for-loops来完成此任务。

但是,我认为必须有一种简单的方法,可能使用apply语句。

以下是嵌套for-loop解决方案的示例。

my.matrix <- matrix(c( -5, -4, -3, -2, -1,
                       -2, -1,  0,  1,  2,
                        0,  1,  2,  3,  4,
                       -3, -2, -1,  0,  1), nrow = 4, byrow = TRUE)

# range to retain specified by the following two vectors
first.position <- c(2, 3, 2,  1)
last.position  <- c(4, 5, 5,  1)

# desired result
desired.result <- matrix(c(  0, -4, -3, -2,  0,
                             0,  0,  0,  1,  2,
                             0,  1,  2,  3,  4,
                            -3,  0,  0,  0,  0), nrow = nrow(my.matrix), byrow = TRUE)

new.matrix <- matrix(0, nrow = nrow(my.matrix), ncol = ncol(my.matrix))

# solution using loops
for(i in 1:nrow(my.matrix)) {
     for(j in 1:ncol(my.matrix)) {

          if(j >= first.position[i] & j <= last.position[i]) new.matrix[i,j] = my.matrix[i,j]

     }
}

all.equal(new.matrix, desired.result)
# [1] TRUE

3 个答案:

答案 0 :(得分:2)

例如,

# Produce a matrix with indices where my.matrix elements should be kept
L <- mapply(seq,first.position,last.position)
L2 <- sapply(1:length(L),function(i) cbind(i,L[[i]]))
z <- do.call(rbind,L2)

# create a helper matrix m2 and fill it with zeroes
m2 <- my.matrix*0
# set the protected elements to 1 and multiple element-wise with the original matrix
m2[z] <- 1
result <- m2*my.matrix

#     [,1] [,2] [,3] [,4] [,5]
#[1,]    0   -4   -3   -2    0
#[2,]    0    0    0    1    2
#[3,]    0    1    2    3    4
#[4,]   -3    0    0    0    0

答案 1 :(得分:2)

将嵌套循环减少到单个循环的另一个选项:

new.matrix <- my.matrix
index <- Map(`:`, first.position, last.position)
for(i in 1:nrow(my.matrix)) {
    new.matrix[i,-index[[i]]] <- 0
}
new.matrix
     [,1] [,2] [,3] [,4] [,5]
[1,]    0   -4   -3   -2    0
[2,]    0    0    0    1    2
[3,]    0    1    2    3    4
[4,]   -3    0    0    0    0
> identical(new.matrix, desired.result)
[1] TRUE

答案 2 :(得分:2)

试试这个:

my.matrix[
  t(sapply(1:nrow(my.matrix), function(i)
    !(1:ncol(my.matrix) %in% first.position[i]:last.position[i])
  ))] <- 0

sapply位使用与my.matrix相同的nrow和ncol创建TRUE / FALSE矩阵,然后我们将其赋值为零。