# [R] Second largest element from each matrix row

William Dunlap wdunlap at tibco.com
Tue Apr 26 18:11:17 CEST 2011

```A different approach is to use order() to sort
first by row number and then break the ties by
value.  It is quick when there are lots of short
rows.

> f1 <- function (x)
+    apply(x, 1, function(row) sort(row, decreasing = TRUE)[2])
> f2 <- function (x)
+     -apply(-x, 1, function(row) sort.int(row, partial = 2)[2])
> f3 <- function (x)
+ {
+     # order by row number then by value
+     y <- t(x)
+     array(y[order(col(y), y)], dim(y))[nrow(y) - 1, ]
+ }
> f4 <- function (x)
+     apply(x, 1, function(row) max(row[-which.max(row)]))
> x <- matrix(runif(1e5*6), nrow=1e5)
> library(rbenchmark)
> benchmark(r1 <- f1(x), r2 <- f2(x), r3 <- f3(x), r4 <- f4(x),
+     replications=5, columns=c("test","replications","elapsed"),
order="elapsed")
test replications elapsed
3 r3 <- f3(x)            5    1.08
4 r4 <- f4(x)            5   12.59
2 r2 <- f2(x)            5   23.19
1 r1 <- f1(x)            5   59.54
> identical(r1,r2) && identical(r1, r3) && identical(r1, r4)
[1] TRUE

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com

> -----Original Message-----
> From: r-help-bounces at r-project.org
> [mailto:r-help-bounces at r-project.org] On Behalf Of peter dalgaard
> Sent: Tuesday, April 26, 2011 8:13 AM
> To: David Winsemius
> Cc: r-help at r-project.org
> Subject: Re: [R] Second largest element from each matrix row
>
>
> On Apr 26, 2011, at 14:36 , David Winsemius wrote:
>
> >
> > On Apr 26, 2011, at 8:01 AM, Lars Bishop wrote:
> >
> >> Hi,
> >>
> >> I need to extract the second largest element from each row of a
> >> matrix. Below is my solution, but I think there should be
> a more efficient
> >> way to accomplish the same, or not?
> >>
> >>
> >> set.seed(1)
> >> a <- matrix(rnorm(9), 3 ,3)
> >> sec.large <- as.vector(apply(a, 1, order, decreasing=T)[2,])
> >> ans <- sapply(1:length(sec.large), function(i) a[i, sec.large[i]])
> >> ans
> >
> > There are probably many but this one is reasonably compact,
> >
> > > ans2 <- apply(a, 1, function(i) sort(i)[ dim(a)[2]-1])
> > > ans2
> >
> > Refreshing my mail client proves I was right about many
> solutions, but this is the first (so far) to use the dim attribute.
>
> Anything with sort() or order() will have complexity
> O(n*log(n)) or worse (n is the number of columns), whereas
> finding the k-th largest element has complexity O(k*n).
>
> For moderate n, this may be unimportant, but you could
> potentially find a speedup using
>
> sort.int(i, decreasing=TRUE, partial=2)[2]
>
> or
>
> max(i[-which.max(i)])
>
> --
> Peter Dalgaard
> Center for Statistics, Copenhagen Business School
> Solbjerg Plads 3, 2000 Frederiksberg, Denmark
> Phone: (+45)38153501
> Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help