用行来替换矩阵的一定范围为0

4
我希望能够替换矩阵中每行的部分内容为0,但保留指定范围内的内容。每行需要保留的指定范围不同。我可以使用嵌套的for循环来实现此操作。
然而,我认为可能有一种简单的方法,也许可以使用apply语句来实现。
以下是一个使用嵌套for循环解决方案的示例。
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个回答

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

2
避免一些循环和操作的完全相同的方法是:n = last.position - first.position + 1; ij = cbind(rep(seq_len(nrow(my.matrix)), n), sequence(n) + rep(first.position, n) - 1); new.matrix = matrix(0, nrow = nrow(my.matrix), ncol = ncol(my.matrix)); new.matrix[ij] = my.matrix[ij] - alexis_laz
1
@alexis_laz,做得好。或者可以这样做:m <- t(my.matrix); k <- (seq_along(first.position)-1)*ncol(m); m[-unlist(mapply(seq,first.position+k,last.position+k))] <- 0; result <- t(m) - Marat Talipov

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

试试这个:

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相同的TRUE/FALSE矩阵,然后我们将其赋值为零。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接