Ann A.
Ann A.

Reputation: 61

R arrange list of vectors

Say I have a list of vectors like this:

list.of.vec <- data.frame(id = c(1,2,3,4)) %>% 
  mutate(a = list(list(c(1,2,3), c(2,3,4)), list(c(2,4,5), c(1,3,4)), list(c(1,2,3), c(4,3,4)), list(c(3,2,3), c(2,3,4))))

how can I arrange a such that in each pair of vectors, the one with the bigger first values goes first? E.g., if there was a list c(1,2,3), c(2,3,4), it should become c(2,3,4), c(1,2,3). And if first values are equal then it looks at the next value.

Upvotes: 2

Views: 101

Answers (3)

akrun
akrun

Reputation: 887951

We can use rrapply

library(rrapply)
library(purrr)
library(dplyr)
list.of.vec <- list.of.vec %>%
     mutate(a = map(a, ~ .x[order(-rrapply(.x, f = function(x) x[1], 
          how = 'unlist'))]))

-output

> list.of.vec
  id                a
1  1 2, 3, 4, 1, 2, 3
2  2 2, 4, 5, 1, 3, 4
3  3 4, 3, 4, 1, 2, 3
4  4 3, 2, 3, 2, 3, 4

> list.of.vec$a
[[1]]
[[1]][[1]]
[1] 2 3 4

[[1]][[2]]
[1] 1 2 3


[[2]]
[[2]][[1]]
[1] 2 4 5

[[2]][[2]]
[1] 1 3 4


[[3]]
[[3]][[1]]
[1] 4 3 4

[[3]][[2]]
[1] 1 2 3


[[4]]
[[4]][[1]]
[1] 3 2 3

[[4]][[2]]
[1] 2 3 4

Upvotes: 2

ThomasIsCoding
ThomasIsCoding

Reputation: 102880

We can try

lapply(
  a,
  function(x) {
    x[order(-sapply(x, `[`, 1))]
  }
)

which gives

[[1]]
[[1]][[1]]
[1] 2 3 4

[[1]][[2]]
[1] 1 2 3


[[2]]
[[2]][[1]]
[1] 2 4 5

[[2]][[2]]
[1] 1 3 4


[[3]]
[[3]][[1]]
[1] 4 3 4

[[3]][[2]]
[1] 1 2 3


[[4]]
[[4]][[1]]
[1] 3 2 3

[[4]][[2]]
[1] 2 3 4

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 389325

You can use -

list.of.vec$a <- lapply(list.of.vec$a, function(x) {
  inds <- match(TRUE, x[[1]] != x[[2]])
  if(x[[1]][inds] > x[[2]][inds]) x else rev(x)
})

list.of.vec$a

#[[1]]
#[[1]][[1]]
#[1] 2 3 4

#[[1]][[2]]
#[1] 1 2 3


#[[2]]
#[[2]][[1]]
#[1] 2 4 5

#[[2]][[2]]
#[1] 1 3 4


#[[3]]
#[[3]][[1]]
#[1] 4 3 4

#[[3]][[2]]
#[1] 1 2 3


#[[4]]
#[[4]][[1]]
#[1] 3 2 3

#[[4]][[2]]
#[1] 2 3 4

inds would return the index for each list that we need to compare, an index where the value is different in both the vectors. If the first index has a higher value we return the list as it is without any change or else we return the reversed list.

Upvotes: 2

Related Questions