Reputation: 29
I have a list (l):
[1] 0 0 0 1 1 1 2 2 2
[2] 0 0 0 1 1 1 2 2 2
[3] 0 0 0 1 1 1 2 2 2
and now I want to sort it like this first:
[1] 0 1 2 0 1 2 0 1 2
[2] 0 1 2 0 1 2 0 1 2
[3] 0 1 2 0 1 2 0 1 2
and then:
[1] 0 1 2
[2] 0 1 2
[3] 0 1 2
[4] 0 1 2
[5] 0 1 2
[6] 0 1 2
[7] 0 1 2
[8] 0 1 2
[9] 0 1 2
How can I do this? I have no idea :/ Please help me
Upvotes: 0
Views: 66
Reputation: 887851
We loop through the list
of vector
s with lapply
, create a sequence with ave
to order
the vector
l1 <- lapply(l, function(x) x[order(ave(x, x, FUN = seq_along))])
l1
#[[1]]
#[1] 0 1 2 0 1 2 0 1 2
#[[2]]
#[1] 0 1 2 0 1 2 0 1 2
#[[3]]
#[1] 0 1 2 0 1 2 0 1 2
Then, we find where the 0 is to split the vector into sub vectors
unname(do.call(c, lapply(l1, function(x) split(x, cumsum(!x)))))
#[[1]]
#[1] 0 1 2
#[[2]]
#[1] 0 1 2
#[[3]]
#[1] 0 1 2
#[[4]]
#[1] 0 1 2
#[[5]]
#[1] 0 1 2
#[[6]]
#[1] 0 1 2
#[[7]]
#[1] 0 1 2
#[[8]]
#[1] 0 1 2
#[[9]]
#[1] 0 1 2
Also, if the end result is the goal, this can be done in a single step
unname(split(c(aperm(array(unlist(l), c(3, 3, 3)), c(2, 1, 3))), as.numeric(gl(27, 3, 27))))
#[[1]]
#[1] 0 1 2
#[[2]]
#[1] 0 1 2
#[[3]]
#[1] 0 1 2
#[[4]]
#[1] 0 1 2
#[[5]]
#[1] 0 1 2
#[[6]]
#[1] 0 1 2
#[[7]]
#[1] 0 1 2
#[[8]]
#[1] 0 1 2
#[[9]]
#[1] 0 1 2
l <- replicate(3, rep(0:2, each = 3), simplify = FALSE)
Upvotes: 1
Reputation: 1877
You can use lapply
and unique
to repeat each unique elements multiple times. Here I just show it on two elements, the length of the list does not matter:
my_list <- list(c(0, 0, 0, 1, 1, 1, 2, 2, 2), c(0, 0, 0, 1, 1, 1, 2, 2, 2))
The first sorted list:
## Replicate each unique element in a list
new.list.1 <- function(list) {
unique_elements <- unique(list)
rep(unique_elements, length(list)/length(unique_elements))
}
## Apply the function
lapply(my_list, new.list.1)
#[[1]]
#[1] 0 1 2 0 1 2 0 1 2
#
#[[2]]
#[1] 0 1 2 0 1 2 0 1 2
And the second one on the same principle
## Replicate each unique in multiple lists
new.list.2 <- function(list) {
unique_elements <- unique(list)
rep(list(unique_elements), length(list)/length(unique_elements))
}
## Apply the function and unlist the nested level
unlist(lapply(my_list, new.list.2), recursive = FALSE)
#[[1]]
#[1] 0 1 2
#
#[[2]]
#[1] 0 1 2
#
#[[3]]
#[1] 0 1 2
#
#[[4]]
#[1] 0 1 2
#
#[[5]]
#[1] 0 1 2
#
#[[6]]
#[1] 0 1 2
Upvotes: 0