Reputation: 4705
Given the following list :
l = list(
c('first', 5),
c('second',3),
c('third',2)
)
Which is
> l
[[1]]
[1] "first" "5"
[[2]]
[1] "second" "3"
[[3]]
[1] "third" "2"
How best to sort the elements of the list based on the second elements within the elements. By this I mean that I have
c('first', 5),
c('second',3),
c('third',2)
And would like to have the ordering based on 5,3,2
, giving
c('third',2)
c('second',3),
c('first', 5),
One approach would be :
x=as.double(sapply(l, function(x) x[2]))
l[order(x)]
I'm not sure if there's a better approach though.
Upvotes: 1
Views: 339
Reputation: 887118
An option is to extract the 2nd element with [
, convert to numeric
, order
and use the index for ordering the list
'l'
l[order(as.numeric(sapply(l, `[`, 2)))]
Or unlist
, then extract the 2nd element with a recycling logical index, convert to numreic
and order
l[order(as.numeric(unlist(l)[c(FALSE, TRUE)]))]
Or using a faster approach with vapply
l[order(as.numeric(vapply(l, `[`, 2, FUN.VALUE = character(1))))]
Or with map
and pluck
library(dplyr)
library(purrr)
map_chr(l, pluck, 2) %>%
as.integer %>%
order %>%
l[.]
Upvotes: 4
Reputation: 101343
Maybe data frame can help you somewhat, i.e.
l[order(as.numeric(data.frame(l)[2,]))]
which gives
> l[order(as.numeric(data.frame(l)[2,]))]
[[1]]
[1] "third" "2"
[[2]]
[1] "second" "3"
[[3]]
[1] "first" "5"
Upvotes: 0