Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

which.min by row without apply

Tags:

r

min

apply

I was sure something of the sort would exist (along the lines of rowSums, etc), but I couldn't find anything. Basically, do this:

apply(mx, 1, which.min)

without using apply so that we can avoid the overhead of calling which.min nrow(mx) times, which could be a large number.

like image 883
BrodieG Avatar asked Jan 08 '15 19:01

BrodieG


1 Answers

Thanks to @user20650 for the answer:

set.seed(1)
mx <- matrix(runif(1e7), ncol=5)

With apply:

system.time(which.min.mx <- apply(mx, 1, which.min))
# user  system elapsed 
#  4.7     0.0     4.7 

with max.col:

system.time(mx.mins.2 <- max.col(-mx, ties="first"))
# user  system elapsed 
# 0.12    0.00    0.13 
all.equal(which.min.mx, mx.mins.2)
# [1] TRUE

Old answer: This is the best I came up with. Hopefully somebody has something better like a built in row.which.min or some such. Data:

Using pmin, ==, %%, and some vector recycling:

system.time({
  row.min <- do.call(pmin, as.data.frame(mx))
  mx.mins <- which(t(mx == row.min)) %% ncol(mx)
  mx.mins[!mx.mins] <- ncol(mx)
})
# user  system elapsed 
# 0.51    0.00    0.51 
all.equal(which.min.mx, mx.mins)
# [1] TRUE

Not to mention this kind of falls flat on its face if there is more than one minimum value in a row.

like image 80
BrodieG Avatar answered Oct 18 '22 01:10

BrodieG