在R中将矩阵顺时针旋转90度

59

我在R中有一个矩阵,如下所示:

|1|2|3|
|1|2|3|
|1|2|3|

有没有一种简单的方法将整个矩阵顺时针旋转90度以获得这些结果?

|1|1|1|
|2|2|2|
|3|3|3|

再次旋转90度:

|3|2|1|
|3|2|1|
|3|2|1|

?


1
这被称为矩阵转置。尝试使用函数“t”。 - Roman Luštrik
2
是的,但t能够360度工作吗?还是只能向右90度? - Johannes
5个回答

112

t 不会旋转条目,它是沿着对角线翻转:

x <- matrix(1:9, 3)
x
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

t(x)
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6
## [3,]    7    8    9

R矩阵顺时针旋转90度:

在转置之前,您还需要颠倒列:

rotate <- function(x) t(apply(x, 2, rev))
rotate(x)
##      [,1] [,2] [,3]
## [1,]    3    2    1
## [2,]    6    5    4
## [3,]    9    8    7

rotate(rotate(x))
##      [,1] [,2] [,3]
## [1,]    9    6    3
## [2,]    8    5    2
## [3,]    7    4    1

rotate(rotate(rotate(x)))
##      [,1] [,2] [,3]
## [1,]    7    8    9
## [2,]    4    5    6
## [3,]    1    2    3

rotate(rotate(rotate(rotate(x))))
##      [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

R矩阵逆时针旋转90度:

在进行反转之前先进行转置,相当于逆时针旋转:

foo = matrix(1:9, 3)
foo
## [,1] [,2] [,3]
## [1,]    1    4    7
## [2,]    2    5    8
## [3,]    3    6    9

foo <- apply(t(foo),2,rev)
foo

## [,1] [,2] [,3]
## [1,]    7    8    9
## [2,]    4    5    6
## [3,]    1    2    3

14
申请可能不是最佳选择;来自 R-help 档案:rotate = function(mat) t(mat[nrow(mat):1,,drop=FALSE]) - baptiste
1
除了两次重复操作外,是否有逆时针旋转的公式?对于大矩阵来说,这是一个相当密集的过程。 - geotheory
1
@geotheory 只需要逆转操作的顺序即可:apply(t(x), 2, rev) - Matthew Lundberg
谢谢。或者显然可以使用apply(x, 1, rev),但我不理解一个重新排序的函数如何可能改变矩阵的维度(尽管在这种情况下没有改变)?!如果你不知道我会发布一个问题。 - geotheory
1
已发布:https://dev59.com/ZHzaa4cB1Zd3GeqPPmln - geotheory
显示剩余2条评论

31
m <- matrix(rep(1:3,each=3),3)

     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    1    2    3
[3,]    1    2    3

t(m[nrow(m):1,])

     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2
[3,]    3    3    3

m[nrow(m):1,ncol(m):1]

     [,1] [,2] [,3]
[1,]    3    2    1
[2,]    3    2    1
[3,]    3    2    1

t(m)[ncol(m):1,]

     [,1] [,2] [,3]
[1,]    3    3    3
[2,]    2    2    2
[3,]    1    1    1

10

旋转矩阵180°的简单方法如下:

m <- matrix(1:8,ncol=4)
#      [,1] [,2] [,3] [,4]
# [1,]    1    3    5    7
# [2,]    2    4    6    8


rot <- function(x) "[<-"(x, , rev(x))

rot(m)
#      [,1] [,2] [,3] [,4]
# [1,]    8    6    4    2
# [2,]    7    5    3    1

rot(rot(m))
#      [,1] [,2] [,3] [,4]
# [1,]    1    3    5    7
# [2,]    2    4    6    8

1
这个函数的一个好处是,如果你使用Matrix类,它可以保持稀疏性。然而,你的代码在R 3.2.1中不起作用了吗?它抱怨缺少value参数。相反,这个变化可以工作:rotate <- function(x) {x[] <- rev(x); x} - Ken Williams
我应该提到,即使这样可以保留稀疏性,但它确实需要暂时实例化一个非稀疏向量,其大小是矩阵维度的乘积。 - Ken Williams
@KenWilliams 我无法重现这个问题。在我的机器上,使用 R 3.2.1 仍然可以正常工作。 - Sven Hohenstein
1
哦 - 看起来只有当“m”是一个“Matrix”对象时才会失败。当“m”是普通的“matrix”时,它确实可以正常工作。 - Ken Williams
@SvenHohenstein,您能否解释一下"[<-"这部分的含义? - pogibas
2
@PoGibas 函数[<-用于索引替换。在代码x[i] <- y中,对象x将被更改。如果您使用"[<-"(x, i, y),则修改后的对象将被返回,而x不会被更改。 - Sven Hohenstein

3

用R语言实现矩阵的90度和-90度旋转

#first reverse, then transpose, it's the same as rotate 90 degrees
rotate_clockwise         <- function(x) { t(     apply(x, 2, rev))}
#first transpose, then reverse, it's the same as rotate -90 degrees:
rotate_counter_clockwise <- function(x) { apply(     t(x),2, rev)}

#or if you want a library to help make things easier to read:
#install.packages("pracma")
library(pracma)
rotate_one_eighty <- function(x) { rot90(x, 2) }
rotate_two_seventy <- function(x) { rot90(x, -1) }

foo = matrix(1:9, 3)
foo

foo = rotate_clockwise(foo)
foo

foo = rotate_counter_clockwise(foo)
foo

foo = rotate_one_eighty(foo)
foo

输出:

     [,1] [,2] [,3]
[1,]    1    4    7          #original matrix
[2,]    2    5    8
[3,]    3    6    9
     [,1] [,2] [,3]
[1,]    3    2    1
[2,]    6    5    4          #rotated 90 degrees
[3,]    9    8    7
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8          #rotated -90 degrees
[3,]    3    6    9
     [,1] [,2] [,3]
[1,]    9    6    3
[2,]    8    5    2          #rotated 180 degrees
[3,]    7    4    1

注意,将矩阵顺时针旋转,然后逆时针旋转会将数字返回到原始位置,而旋转180度就像旋转90度两次。


0

或者根据Eric Leschinski的方法将它们合并到一个函数中:

rotate  <- function(x, clockwise=T) {
  if (clockwise) { t( apply(x, 2, rev))
  } else {apply( t(x),2, rev)} 
}

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