循环通过矩阵的对角线+ 1

his*_*eim 3 r matrix

我需要循环对角线+ 1(即对角线右侧的值1列)并将值写入数据帧中的列:

write.csv(data.frame(matrix[1,2], matrix[2,3], matrix[3,4])
Run Code Online (Sandbox Code Playgroud)

如何使用函数执行此操作,而不是仅列出值的所有位置?

Rei*_*son 9

这样做没有编程工作了指数的头刮的一个快速方法是使用经常被忽视row()col()功能.它们分别为矩阵的每个元素返回该元素所属的行或列.

对角线是元素的行索引等于列索引的位置.第一个子对角线是行索引等于列索引加1的位置,而第一个超对角线是行索引等于列索引减去1的位置.

这里有些例子:

m <- matrix(1:25, ncol = 5)
m

> m
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    6   11   16   21
[2,]    2    7   12   17   22
[3,]    3    8   13   18   23
[4,]    4    9   14   19   24
[5,]    5   10   15   20   25
Run Code Online (Sandbox Code Playgroud)

对角线

m[row(m) == col(m)]
diag(m)

> m[row(m) == col(m)]
[1]  1  7 13 19 25
> diag(m) ## just to show this is correct
[1]  1  7 13 19 25
Run Code Online (Sandbox Code Playgroud)

第一个对角线

m[row(m) == col(m) + 1

> m[row(m) == col(m) + 1]
[1]  2  8 14 20
Run Code Online (Sandbox Code Playgroud)

第一个超对角线

m[row(m) == col(m) -1]

> m[row(m) == col(m) -1]
[1]  6 12 18 24
Run Code Online (Sandbox Code Playgroud)

可以通过增加添加到列索引的值来提取高阶超级和子对角线.

创建数据框并写出

基本上你已经有了这个,但是

write.csv(data.frame(m[row(m) == col(m) + 1), file = "subdiag.csv")
Run Code Online (Sandbox Code Playgroud)

sub或superdiagonals的一般功能

diags <- function(m, type = c("sub", "super"), offset = 1) {
  type <- match.arg(type)
  FUN <-
  if(isTRUE(all.equal(type, "sub")))
    `+`
  else
    `-`
  m[row(m) == FUN(col(m), offset)] 
}
Run Code Online (Sandbox Code Playgroud)

在使用中我们有:

> diags(m)
[1]  2  8 14 20
> diags(m, type = "super")
[1]  6 12 18 24
> diags(m, offset = 2)
[1]  3  9 15
Run Code Online (Sandbox Code Playgroud)


mne*_*nel 7

您可以使用矩阵进行索引.

例如

m <- matrix(1:25, ncol = 5)
Run Code Online (Sandbox Code Playgroud)

可以使用关闭对角线访问

offd <- cbind(1:4,2:5)


m[offd]

## [1]  6 12 18 24
Run Code Online (Sandbox Code Playgroud)

您可以创建一个执行此操作的函数

offdiag <- function(m, offset){
  i <- seq_len(nrow(m)-offset)
  j <- i + offset
  m[cbind(i,j)]

}


offdiag(m, 1)
## [1]  6 12 18 24
offdiag(m, 2)
[1] 11 17 23
offdiag(m, 3)
## [1] 16 22
offdiag(m, 4)
## [1] 21
Run Code Online (Sandbox Code Playgroud)


Mat*_*erg 6

取子矩阵,然后是对角线.

使用mnel的m:

diag(m[, -1])
[1]  6 12 18 24
Run Code Online (Sandbox Code Playgroud)

作为具有可变偏移的函数(但在这种形式下,它不比mnel的解决方案更清晰):

offdiag <- function(m, offset) {
  s <- seq(offset)
  diag(m[,-s, drop=FALSE])
}

offdiag(m, 1)
## [1]  6 12 18 24
offdiag(m, 2)
## [1] 11 17 23
offdiag(m, 3)
## [1] 16 22
offdiag(m, 4)
## [1] 21
Run Code Online (Sandbox Code Playgroud)