baxx
baxx

Reputation: 4705

Sort a list of vectors by a particular index

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

Answers (2)

akrun
akrun

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

ThomasIsCoding
ThomasIsCoding

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

Related Questions