我需要循环遍历对角线+1(即对角线右侧的一列),并将该值写入数据框中的一列:
如何使用函数来完成这个操作,而不是仅列出值的所有位置?
write.csv(data.frame(matrix[1,2], matrix[2,3], matrix[3,4])
如何使用函数来完成这个操作,而不是仅列出值的所有位置?
row()
和col()
函数。它们分别返回矩阵中每个元素所属的行或列。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
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
m[row(m) == col(m) + 1
> m[row(m) == col(m) + 1]
[1] 2 8 14 20
m[row(m) == col(m) -1]
> m[row(m) == col(m) -1]
[1] 6 12 18 24
通过增加添加到列索引的值,可以提取高阶超级和次对角线。
本质上您已经拥有了这个,但是
write.csv(data.frame(m[row(m) == col(m) + 1), file = "subdiag.csv")
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)]
}
我们正在使用以下内容:
> diags(m)
[1] 2 8 14 20
> diags(m, type = "super")
[1] 6 12 18 24
> diags(m, offset = 2)
[1] 3 9 15
m <- matrix(1:25, ncol = 5)
可以使用以下方式访问偏对角线:
offd <- cbind(1:4,2:5)
m[offd]
## [1] 6 12 18 24
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
diag
中的代码:y <- c(x)[1 + 0L:(m - 1L) * (dim(x)[1L] + 1)]
。 - IRTFM取子矩阵,然后取其对角线。
使用 mnel 的 m
:
diag(m[, -1])
[1] 6 12 18 24
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
diag(m[,-1])
可能更好。 - Josh O'Briendiag
有这样的功能。 - IRTFM
row
和col
需要构建两个与输入矩阵相同大小的完整逻辑矩阵。而这种方法只需构建两个向量并提取即可。 - IRTFMnrow(m)
的向量与两个长度为prod(nrow(m), ncol(m))
的向量。因此,就内存效率而言,@mnel的解决方案毫无疑问是更胜一筹的。 - Gavin Simpson