R 中 apply/reverse 函数的奇怪行为
Strange behavior of apply/ reverse function in R
我有一个简单的矩阵:
mat = rbind(c(1:3),c(4:6),c(7:9))
mat
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# [3,] 7 8 9
我现在想逐行反转矩阵。那就是我要获得:
revMat
# [,1] [,2] [,3]
# [1,] 3 2 1
# [2,] 6 5 4
# [3,] 9 8 7
为此我尝试了
apply(mat, 1, rev)
结果是:
# [,1] [,2] [,3]
# [1,] 3 6 9
# [2,] 2 5 8
# [3,] 1 4 7
我觉得这很奇怪。这就像行被反转,然后最终矩阵被转置。我不明白为什么。例如,如果我简单地尝试
apply(mat, 2, rev)
它给了我每列的预期反转
# [,1] [,2] [,3]
# [1,] 7 8 9
# [2,] 4 5 6
# [3,] 1 2 3
因此要获得最终结果我必须执行
t(apply(t(bg), 2, rev))
因此获得所需的矩阵对我来说不是问题,但我不理解应用/反向行为中的 "anomaly"。谁能给我解释一下?
编辑:为了区分清楚,我已经知道如何进行反转了。我想知道为什么会这样。如何从许多早期的问题中清楚地看到,包括
How to reverse a matrix in R?
如果您查看 apply()
的帮助,这正是您所期望的行为:
Value
If each call to FUN returns a vector of length n, then apply returns
an array of dimension c(n, dim(X)[MARGIN]) if n > 1.
一个不错的选择是使用索引:
mat[,ncol(mat):1]
apply
始终将结果放在第一个维度中。有关详细信息,请参阅 ?apply
。假设这个输入:
mat <- matrix(1:9, 3, byrow = TRUE)
这里有一些替代方案:
1) 转置
t(apply(mat, 1, rev))
2) 避免应用索引
mat[, 3:1]
3) iapply 此处发布了一个幂等应用:
https://stat.ethz.ch/pipermail/r-help/2006-January/086064.html
使用我们有:
iapply(mat, 1, rev)
在 reshape 包的 0.8.0 版中也有一个幂等应用 iapply
(但在最新版本的 reshape 中没有):https://cran.r-project.org/src/contrib/Archive/reshape/
4) zoo包中的rollapply rollapply
可以使用:
library(zoo)
rollapply(mat, 1, rev, by.column = FALSE)
5) tapply 这里的 tapply
表达式 returns 一个列表,让我们有机会以我们想要的方式把它放在一起——在这个使用 rbind
的案例:
do.call("rbind", tapply(mat, row(mat), rev))
6) 乘以一个反向对角矩阵 因为rev
是一个线性算子所以它可以用一个矩阵来表示:
mat %*% apply(diag(3), 1, rev)
或
mat %*% (row(mat) + col(mat) == 3+1)
我有一个简单的矩阵:
mat = rbind(c(1:3),c(4:6),c(7:9))
mat
# [,1] [,2] [,3]
# [1,] 1 2 3
# [2,] 4 5 6
# [3,] 7 8 9
我现在想逐行反转矩阵。那就是我要获得:
revMat
# [,1] [,2] [,3]
# [1,] 3 2 1
# [2,] 6 5 4
# [3,] 9 8 7
为此我尝试了
apply(mat, 1, rev)
结果是:
# [,1] [,2] [,3]
# [1,] 3 6 9
# [2,] 2 5 8
# [3,] 1 4 7
我觉得这很奇怪。这就像行被反转,然后最终矩阵被转置。我不明白为什么。例如,如果我简单地尝试
apply(mat, 2, rev)
它给了我每列的预期反转
# [,1] [,2] [,3]
# [1,] 7 8 9
# [2,] 4 5 6
# [3,] 1 2 3
因此要获得最终结果我必须执行
t(apply(t(bg), 2, rev))
因此获得所需的矩阵对我来说不是问题,但我不理解应用/反向行为中的 "anomaly"。谁能给我解释一下?
编辑:为了区分清楚,我已经知道如何进行反转了。我想知道为什么会这样。如何从许多早期的问题中清楚地看到,包括
How to reverse a matrix in R?
如果您查看 apply()
的帮助,这正是您所期望的行为:
Value
If each call to FUN returns a vector of length n, then apply returns an array of dimension c(n, dim(X)[MARGIN]) if n > 1.
一个不错的选择是使用索引:
mat[,ncol(mat):1]
apply
始终将结果放在第一个维度中。有关详细信息,请参阅 ?apply
。假设这个输入:
mat <- matrix(1:9, 3, byrow = TRUE)
这里有一些替代方案:
1) 转置
t(apply(mat, 1, rev))
2) 避免应用索引
mat[, 3:1]
3) iapply 此处发布了一个幂等应用: https://stat.ethz.ch/pipermail/r-help/2006-January/086064.html 使用我们有:
iapply(mat, 1, rev)
在 reshape 包的 0.8.0 版中也有一个幂等应用 iapply
(但在最新版本的 reshape 中没有):https://cran.r-project.org/src/contrib/Archive/reshape/
4) zoo包中的rollapply rollapply
可以使用:
library(zoo)
rollapply(mat, 1, rev, by.column = FALSE)
5) tapply 这里的 tapply
表达式 returns 一个列表,让我们有机会以我们想要的方式把它放在一起——在这个使用 rbind
的案例:
do.call("rbind", tapply(mat, row(mat), rev))
6) 乘以一个反向对角矩阵 因为rev
是一个线性算子所以它可以用一个矩阵来表示:
mat %*% apply(diag(3), 1, rev)
或
mat %*% (row(mat) + col(mat) == 3+1)