131

Given the following matrix lets assume I want to find the maximum value in column two:

mat <- matrix(c(1:3,7:9,4:6), byrow = T, nc = 3)
mat
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    7    8    9
[3,]    4    5    6

I know max(mat[,2]) will return 8. How can I return the row index, in this case row two?

Rich Scriven
  • 97,041
  • 11
  • 181
  • 245
Jared
  • 39,513
  • 29
  • 110
  • 145

5 Answers5

186

See ?which.max

> which.max( matrix[,2] )
[1] 2
Danko Durbić
  • 7,077
  • 5
  • 34
  • 39
29

See ?order. You just need the last index (or first, in decreasing order), so this should do the trick:

order(matrix[,2],decreasing=T)[1]
yoyoyoyosef
  • 7,000
  • 8
  • 40
  • 39
  • 6
    +1 I like this answer because it allows me to easily look at the top few, rather than just the max. I've found it useful for looking up the dates of near maximal values from another column. – djhocking Jul 31 '12 at 18:06
  • 7
    But keep in mind that this is slower than which.max, because you need to sort the whole column :) – bartektartanus Jul 13 '14 at 09:03
  • @bartektartanus And how do you suppose which.max figures out the max? :p – Nick Ulle Nov 29 '14 at 23:30
  • 10
    Without sorting, of course. Finding out the max needs O(n), sorting requires more time :) – bartektartanus Nov 30 '14 at 19:07
  • I got confused between rank and order. `order` returns the index each element has, but sorted by the elements' value. `rank` returns the index each element **would have**, if the list were sorted first. Thus `order` returns current index values; and be used as an "indexer" in pandas terms. – Nate Anderson Oct 28 '15 at 06:15
3

How about the following, where y is the name of your matrix and you are looking for the maximum in the entire matrix:

row(y)[y==max(y)]

if you want to extract the row:

y[row(y)[y==max(y)],] # this returns unsorted rows.

To return sorted rows use:

y[sort(row(y)[y==max(y)]),]

The advantage of this approach is that you can change the conditional inside to anything you need. Also, using col(y) and location of the hanging comma you can also extract columns.

y[,col(y)[y==max(y)]]

To find just the row for the max in a particular column, say column 2 you could use:

seq(along=y[,2])[y[,2]==max(y[,2])]

again the conditional is flexible to look for different requirements.

See Phil Spector's excellent "An introduction to S and S-Plus" Chapter 5 for additional ideas.

Sumedh
  • 4,835
  • 2
  • 17
  • 32
QFanatic
  • 31
  • 2
1

A different way using dplyr:

mat <- matrix(c(1:3,7:9,4:6), byrow = T, nc = 3)
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    7    8    9
[3,]    4    5    6

mat %>% as_tibble() %>% filter( V2 == max(V2) )

# A tibble: 1 x 3
     V1    V2    V3
  <int> <int> <int>
1     7     8     9
rubengavidia0x
  • 501
  • 1
  • 5
  • 18
0

There is a function max.col(). For every row it finds which column has the maximum value:

max.col(mat)
[1] 3 3 3

To find the maximum row for each column instead, simply transpose the matrix:

max.col(t(mat))
[1] 2 2 2
Karolis Koncevičius
  • 9,417
  • 9
  • 56
  • 89