24

I have a simple matrix like:

> 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

I would like to get this result:

      [,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

The exact reverse of the matrix. How can I get it? Thanks

Dail
  • 4,622
  • 16
  • 74
  • 109
  • 20
    From the example you used, it's not clear whether you want the columns or the rows reversed. Just for the record, Dirk's solution reverses the order of the rows, while mine reverses the order of columns. – Josh O'Brien Feb 03 '12 at 22:10
  • 2
    Came to say exactly this. I ended up using Josh's solution myself, as I was looking to reverse columns. Perhaps you can edit this so you have a matrix more like matrix(1:20, nrow = 10) – Evan Senter Aug 06 '13 at 19:42
  • If you apply either of Josh or Dirk's solutions to an array with singleton dimensions, R will collapse them. You can wrap the calls like so: `array(reversing.thing, dim = dim(thing))` to keep it from happening. – bright-star Nov 07 '13 at 19:02

3 Answers3

35
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
MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
Per
  • 577
  • 4
  • 7
  • This is the fastest of the solutions listed here. `a[dim(a)[1]:1, ]` is (marginally) faster still, if less readable. – Martin Smith Mar 08 '22 at 11:48
30

Try rev with apply:

> 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
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • 2
    Why not two times rotate? http://stackoverflow.com/a/16497058/54964 such as `rotate = function(mat) t(mat[nrow(mat):1,,drop=FALSE])` from docs archive. – Léo Léopold Hertz 준영 Nov 25 '16 at 21:31
  • 1
    It's much slower than the `a[, ncol(a):1]` approach, but has the advantage that it can be done inline to declare `b`: `b = apply(matrix(c(1:10, 10:1), 10, 2), 2, rev)` – MichaelChirico Jan 31 '17 at 02:51
  • @dirk-eddelbuettel Thx a lot. This is a very nice and perfect replacer of `matlab::flipud`. In the usage of that function, people may face many errors, but in your solution, that is very neat and perfect, no errors appears. One such error for flipud is `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`. Once more, many thanks Dirk. Really, your solution is life-saver for many cases. – Erdogan CEVHER Apr 08 '17 at 10:09
12

Here's one way:

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
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • 1
    This also works for any higher number of dimensions in an array, thankfully--just add more commas and replace `ncol()` with `dim()[n]`. – bright-star Nov 06 '13 at 21:28
  • 3
    why not just `ncol(a):1`? – MichaelChirico Aug 05 '15 at 19:48
  • @MichaelChirico While I’m no R expert, your solution seems to work and to be more elegant to me, so I’d say add that as an answer! – doncherry Oct 28 '16 at 08:24
  • @doncherry thanks, but it's the same as Per's solution (on rows instead of columns) – MichaelChirico Jan 31 '17 at 02:48
  • @MichaelChirico Actually, your solution and Per's solution do completely different things (though with the example data given here, the result is the same). Your answer and mine reflect the matrix using a vertical line of symmetry, while Per's reflects it across a horizontal line of symmetry. (There's no telling for sure which the OP wanted, though given that they accepted Dirk's answer, it looks like they wanted what he and Per gave them, rather than what you and I did.) – Josh O'Brien Jan 31 '17 at 03:09
  • Yes, I meant the logic/syntax is the same -- it's not hard to translate Per's approach to go column-wise depending on what's needed – MichaelChirico Jan 31 '17 at 03:16
  • @MichaelChirico Sure. I didn't mean to sound pedantic/lecturing. I just remember this question having been unclear at the time, and was really clarifying (as much for me as anyone else) the difference! – Josh O'Brien Jan 31 '17 at 03:24
  • no offense taken at all, it's good to keep a record in case anyone else loses the thread of thinking in the future :) – MichaelChirico Jan 31 '17 at 03:24