如何在R中反转矩阵?

25

我有一个简单的矩阵,如下所示:

> a = matrix(c(c(1:10),c(10:1)), ncol=2)
> a
      [,1] [,2]
 [1,]    1   10
 [2,]    2    9
 [3,]    3    8
 [4,]    4    7
 [5,]    5    6
 [6,]    6    5
 [7,]    7    4
 [8,]    8    3
 [9,]    9    2
[10,]   10    1

我想要获得这个结果:

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

矩阵的精确反转。我该如何得到它? 谢谢


20
从您所用的例子中,不清楚您是想要颠倒列还是行。只是为了记录,Dirk的解决方案颠倒了行的顺序,而我的解决方案颠倒了列的顺序。 - Josh O'Brien
2
来到这里就是为了说这个。我最终使用了Josh的解决方案,因为我想要翻转列。也许你可以编辑一下,这样你就可以得到一个更像matrix(1:20, nrow = 10)的矩阵了。 - Evan Senter
如果你将Josh或Dirk的解决方案应用于具有单例维度的数组,R会将它们合并。你可以像这样包装调用:array(reversing.thing, dim = dim(thing))以防止发生这种情况。 - bright-star
3个回答

36
a[nrow(a):1,]
#       [,1] [,2]
#  [1,]   10    1
#  [2,]    9    2
#  [3,]    8    3
#  [4,]    7    4
#  [5,]    6    5
#  [6,]    5    6
#  [7,]    4    7
#  [8,]    3    8
#  [9,]    2    9
# [10,]    1   10

这是列出的解决方案中最快的。如果可读性较差,a[dim(a)[1]:1, ]仍然(略微)更快。 - Martin Smith

30

使用 apply 来尝试 rev 函数:

> a <- matrix(c(1:10,10:1), ncol=2)
> a
      [,1] [,2]
 [1,]    1   10
 [2,]    2    9
 [3,]    3    8
 [4,]    4    7
 [5,]    5    6
 [6,]    6    5
 [7,]    7    4
 [8,]    8    3
 [9,]    9    2
[10,]   10    1
> b <- apply(a, 2, rev)
> b
      [,1] [,2]
 [1,]   10    1
 [2,]    9    2
 [3,]    8    3
 [4,]    7    4
 [5,]    6    5
 [6,]    5    6
 [7,]    4    7
 [8,]    3    8
 [9,]    2    9
[10,]    1   10

2
为什么不旋转两次?例如从文档存档中 rotate = function(mat) t(mat[nrow(mat):1,,drop=FALSE])。https://dev59.com/mWQn5IYBdhLWcg3w5aay#16497058 - Léo Léopold Hertz 준영
1
它比 a[, ncol(a):1] 方法慢得多,但其优点在于它可以内联完成来声明 b: b = apply(matrix(c(1:10, 10:1), 10, 2), 2, rev) - MichaelChirico
@dirk-eddelbuettel 非常感谢。这是一个非常好的和完美的 matlab::flipud 替代品。在使用该函数时,人们可能会遇到许多错误,但在您的解决方案中,非常整洁和完美,没有出现任何错误。其中一个 flipud 的错误是 error in evaluating the argument 'object' in selecting a method for function 'flipud': Error in .findInheritedMethods(classes, fdef, mtable) : trying to get slot "group" from an object (class "nonstandardGenericFunction") that is not an S4 object。再次感谢 Dirk。真的,您的解决方案对许多情况都是救命稻草。 - Erdogan CEVHER

12

这是一种方法:

a[, rev(seq_len(ncol(a)))]
      [,1] [,2]
 [1,]   10    1
 [2,]    9    2
 [3,]    8    3
 [4,]    7    4
 [5,]    6    5
 [6,]    5    6
 [7,]    4    7
 [8,]    3    8
 [9,]    2    9
[10,]    1   10

1
这对于数组中任何更高维度的数字也适用,值得庆幸的是--只需添加更多逗号并将 ncol() 替换为 dim()[n] - bright-star
3
为什么不直接写成 ncol(a):1 - MichaelChirico
@doncherry 谢谢,但这与 Per 的解决方案相同(在行而非列上)。 - MichaelChirico
是的,我的意思是逻辑/语法是相同的 - 将Per的方法根据需要转换为按列进行并不困难。 - MichaelChirico
@MichaelChirico 当然可以。我并不是要显得学究或教训人。我只是记得当时这个问题很不清楚,所以我想澄清一下(对我和其他人都有帮助),弄清楚其中的区别! - Josh O'Brien
显示剩余3条评论

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