Reputation: 15
I am new to R and after some research I couldn't find a solution to my problem.
I am trying to split a nested list based on the index of the character (if an index is even, it is stored in 'even', if an index is odd, it is stored in 'odd'). I have managed to solve this problem using a for loop, but do not wish to proceed with this approach as the data I am trying to parse is quite large.
Without a nested list, the following statements work (as it is a simple list of characters). The split I am using is splitting the elements of the parent list instead of the nested list.
odd <- x[(2*(1:(length(x)/2))-1)]
even <- x[2*(1:(length(x)/2))]
This is a code snippet of an example I generated to better explain the problem
test <- vector(mode = "list",length = 0)
new <- "a b c d e f g h i g k"
new <- strsplit(new, split = " ")
new1 <- "l m n o p q"
new1 <- strsplit(new1, split = " ")
new2 <- "q s t u v w x"
new2 <- strsplit(new2, split = " ")
new3 <- "y z"
new3 <- strsplit(new3, split = " ")
test <- c(test, new,new1,new2,new3)
odd <- test[(2*(1:(length(test)/2))-1)]
even <- test[2*(1:(length(test)/2))]
The Desired result is as follows:
>odd
[[1]]
[1] "a" "c" "e" "g" "i" "k"
[[2]]
[1] "l" "n" "p"
[[3]]
[1] "q" "t" "v" "x"
[[4]]
[1] "y"
>even
[[1]]
[1] "b" "d" "f" "h" "j"
[[2]]
[1] "m" "o" "q"
[[3]]
[1] "s" "u" "w"
[[4]]
[1] "z"
The obtained result using the code shown above:
>odd
[[1]]
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k"
[[2]]
[1] "q" "s" "t" "u" "v" "w" "x"
>even
[[1]]
[1] "l" "m" "n" "o" "p" "q"
[[2]]
[1] "y" "z"
Would really appreciate it if anyone can help me out with the problem.
Upvotes: 0
Views: 311
Reputation: 43344
One option is to split
each element and then use purrr::transpose
to rearrange your list into an even and odd list:
test <- list(c("a", "b", "c", "d", "e", "f", "g", "h", "i", "g", "k"),
c("l", "m", "n", "o", "p", "q"),
c("q", "s", "t", "u", "v", "w", "x"),
c("y", "z"))
library(purrr)
test_split <- test %>%
map(~split(.x, rep_along(.x, c('odd', 'even')))) %>%
# just `map(split, c('odd', 'even'))` will work, but warns about recycling
transpose()
str(test_split)
#> List of 2
#> $ even:List of 4
#> ..$ : chr [1:5] "b" "d" "f" "h" ...
#> ..$ : chr [1:3] "m" "o" "q"
#> ..$ : chr [1:3] "s" "u" "w"
#> ..$ : chr "z"
#> $ odd :List of 4
#> ..$ : chr [1:6] "a" "c" "e" "g" ...
#> ..$ : chr [1:3] "l" "n" "p"
#> ..$ : chr [1:4] "q" "t" "v" "x"
#> ..$ : chr "y"
Upvotes: 1
Reputation: 269714
Use the fact that short logical vectors recycle:
odd <- lapply(test, "[", c(TRUE, FALSE))
even <- lapply(test, "[", c(FALSE, TRUE))
Upvotes: 2