On 2011-04-26 09:11, William Dunlap wrote:
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.
Bill,
That's what Dmitris did, too; his solution falls between
f3 and f4. Unless speed were paramount, I would choose
Peter D's (f4) for its simplicity and transparency.
I kind of figured that you'd do your magic and pull
out a speed demon.
Peter Ehlers
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-boun...@r-project.org
[mailto:r-help-boun...@r-project.org] On Behalf Of peter dalgaard
Sent: Tuesday, April 26, 2011 8:13 AM
To: David Winsemius
Cc: r-help@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,
one-step, and readable:
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....@cbs.dk Priv: pda...@gmail.com
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide
http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
______________________________________________
R-help@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.