如何通过减去给定矩阵中的列来创建新矩阵?

时间:2020-12-19 09:30:34

标签: r matrix

mat_sub <- function(x){
nc <- ncol(x)
  for (i in 1:nc){
    s <- x[,i]-x[,i-1]
 } 
 Z <- cbind(x,s)
 Z}

请帮助理解我哪里做错了。

2 个答案:

答案 0 :(得分:1)

您每次都在循环中重写 s。此外,您以 1 开始循环,在这种情况下没有 i-1,即第 0 列。

你可以试试:

mat_sub <- function(x){
  nc <- ncol(x)
  x[, 2:nc] - x[, 1:(nc-1)]
}

举个例子:

set.seed(123)
mat <- matrix(sample(16), 4)
mat

#     [,1] [,2] [,3] [,4]
#[1,]   15   10    4   11
#[2,]   16    2   12   13
#[3,]    3    6    7    8
#[4,]   14    5    1    9

mat_sub(mat)
#     [,1] [,2] [,3]
#[1,]   -5   -6    7
#[2,]  -14   10    1
#[3,]    3    1    1
#[4,]   -9   -4    8

答案 1 :(得分:1)

如评论中所述,您需要在第二列开始 for 循环,否则 i - 1 为零且无法进行子集化。另一个问题是 s,它在每次迭代中都会被覆盖。您想预先定义一个二维 array(即矩阵),将原始矩阵的维度减去一列,在每次迭代中填充。

您可能希望将代码更正为:

mat_sub <- function(x) {
  nc <- ncol(x)
  s <- array(NA, dim(x))[, -nc]
  for (i in 2:nc) {
    s[, i - 1] <- x[, i] - x[, i - 1]
  } 
  Z <- cbind(x, s)
  Z
}

m <- matrix(1:12, 3, 4)
mat_sub(m)
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,]    1    4    7   10    3    3    3
# [2,]    2    5    8   11    3    3    3
# [3,]    3    6    9   12    3    3    3

或者,在 R 中,您可以简单地进行矢量化计算,包括矩阵相减。

cbind(m, m[, -1] - m[, -ncol(m)])
#      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
# [1,]    1    4    7   10    3    3    3
# [2,]    2    5    8   11    3    3    3
# [3,]    3    6    9   12    3    3    3