# [R] Trying to avoid a loop -- which.max & max.col

Martin Maechler maechler at stat.math.ethz.ch
Wed Jan 24 09:01:20 CET 2001

```>>>>> "TL" == Thomas Lumley <thomas at biostat.washington.edu> writes:

TL> On Tue, 23 Jan 2001, Michael Roberts wrote:
>>  Wow.  That was a quick reply. Thanks...  but see below.
>>
>> Michael J. Roberts Resource Economics Division, PMT USDA-ERS
>> 202-694-5557
>>
>> >>> Thomas Lumley <thomas at biostat.washington.edu> 01/23 5:51 PM >>>
>> On Tue, 23 Jan 2001, Michael Roberts wrote:
>>
>> > Hello:
>> >
>> > Although I could write a loop to do the following, I would like
>> to avoid this as it would be expensive.  Does anyone know if there
>> is an R function that would make this faster?
>> >
>> > Given a 3 dimensional array, say Z with dimensions {n,l,k}, I
>> would like to create a matrix Y with dimensions {n,l}, each
>> element of which contains the position {k} with the largest
>> element that dimension.
>> >
>>
>> apply(z,c(1,2),max)
>>
>> This is close, but not exactly what I am looking for.  I don't want
>> the maximum value, but the position of the maximum value.  Is there
>> something like an "argmax" I could put in for max?

TL> apply(z,1:2, function(x) which(x==max(x)))

and exactly because the above is not quite efficient,
which.max   (and which.min)
~~~~~~~~~        ~~~~~~~~~
functions to R (1.1.0).
I.e.
apply(z,1:2, which.max)

Note further that we have the (original MASS) function

max.col

to work for matrices which again is more efficient than
apply(mat, 1, which.max)
{and not quite equivalent:
max.col breaks ties at random, which.max always gives the first max}.

Now, you can reshape your rank-3 array {n,l,k} into a matrix {n*l, k}
use  max.col() on that matrix and reshape the {n * l} vector to the desired
{n, l} matrix:

x <- rnorm(50000)

ar <- array(x, dim = c(25,40,50))
system.time(m1 <- apply(ar, 1:2, which.max))

system.time({
mat <- ar
dim(mat) <- c(25*40, 50)
m2 <- matrix(max.col(mat), 25, 40)
})

all(m1 == m2) # these two are identical

## On my Linux machine, the
## max.col() version uses 0.03 sec  compared to 0.10 for the apply() solution
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._

```