Marc in the box
Marc in the box

Reputation: 11995

How to order a list of vectors based on the order of values contained within [in R]

I have the following object:

L <- list(4, 7, c(3, 1), c(1, 2), c(5, 6))
> L
[[1]]
[1] 4

[[2]]
[1] 7

[[3]]
[1] 3 1

[[4]]
[1] 1 2

[[5]]
[1] 5 6

which I would like to reorder based on the appearance of each value, such that those vectors containing 1 come first, and the vector 1,2 comes before 1,3. My desired result would be:

[[1]]
[1] 1 2

[[2]]
[1] 3 1

[[3]]
[1] 4

[[4]]
[1] 5 6

[[5]]
[1] 7

Thanks in advance for your help!

Edit:

Here is a more complicated case:

L <- list(7, c(9, 20), c(2, 3), c(10, 17), c(1, 12, 14), c(1, 3, 5, 
12), c(8, 9, 18, 19), c(6, 11, 15, 16, 17), c(4, 6, 11, 13, 15, 
16))

Upvotes: 0

Views: 90

Answers (3)

jlhoward
jlhoward

Reputation: 59355

L[order(sapply(L,function(x)paste0(sort(x),collapse=".")))]
# [[1]]
# [1] 1 2
#
# [[2]]
# [1] 3 1
# 
# [[3]]
# [1] 4
# 
# [[4]]
# [1] 5 6
#
# [[5]]
# [1] 7

This will work for integers of up to n digits:

L <- list(4, 7, c(3, 1), c(20, 10), c(5, 6))
library(stringr)
n <- 5
L[order(sapply(L,function(x)paste0(str_pad(sort(x),n,pad="0"),collapse=".")))]

Upvotes: 2

MrFlick
MrFlick

Reputation: 206242

This is a bit more involved, but I believe it will work

ml<-max(sapply(L, length))
reord<-do.call(order, data.frame(
    do.call(rbind, 
        lapply(L, function(x) c(sort(x), rep.int(0, ml-length(x))))
    )
))
L[reord]

Upvotes: 1

Ramnath
Ramnath

Reputation: 55695

L[sort(sapply(L, '[[', 1), index.return = T)$ix]

Upvotes: 2

Related Questions