Reputation: 99
My general question concerns shuffling elements around in a list efficiently.
Say I have a list:
region <- list(c(1,3,2,6),c(5,8,9),c(10,4,7))
and two constants:
value <- 2
swapin <- 5
I want to do two things. I want to remove the element == value from the vector in the list, and then add it to the vector in which the first element of that vector == swapin
The result should look like:
region <- list(c(1,3,6),c(5,8,9,2),c(10,4,7))
For the first step, the only way I can think of doing it is doing something like this:
region <- lapply(1:length(region), function(x) region[[x]][region[[x]] != value])
but this seems inefficient. My actual data could involve a very large list, and this approach seems cumbersome. Is there an easy trick to avoiding the looping going on?
For the second step, I can create an updated vector like this:
updated <- c(unlist(region[sapply(region, `[`, 1)==swap]),best)
but I am stumped on how to replace the vector currently in the list, c(5,8,9), with the updated vector, c(5,8,9,2). Maybe I can just add the element some easier way?
Can anyone help, please?
Upvotes: 2
Views: 63
Reputation: 18681
Something like this will do the trick:
region <- list(c(1,3,2,6),c(5,8,9),c(10,4,7))
value <- 2
swapin <- 5
step1 = lapply(region, function(x) x[x != value])
step2 = lapply(step1, function(x){
if(x[1]==swapin){
return(c(x, value))
} else {
return(x)
}
})
Instead of looping through region
by feeding in it's element indices, you can just loop through region
itself. This is actually how lapply
is intended to be used - to apply a function to each element of a list. The second step replaces each element x
, with x
+ value
if the first element of x
matches with swapin
, or with x
itself if swapin
doesn't match.
Result:
> step2
[[1]]
[1] 1 3 6
[[2]]
[1] 5 8 9 2
[[3]]
[1] 10 4 7
You can also easily make it a convenience function for later use:
element_swap = function(list, value, swapin){
step1 = lapply(list, function(x) x[x != value])
step2 = lapply(step1, function(x){
if(x[1]==swapin){
return(c(x, value))
} else {
return(x)
}
})
return(step2)
}
Result:
> element_swap(region, 1, 10)
[[1]]
[1] 3 2 6
[[2]]
[1] 5 8 9
[[3]]
[1] 10 4 7 1
Upvotes: 1