Reputation: 1015
I have a list that is structured as follows:
mylist <- list(list(list()),
list(list()), list(list()), list(list()),
list(structure(list(source = c("IDcode", "IDcode", "IDcode"
), db_id = c("id13653662", "id3396732", "id995182")), class = "data.frame", row.names = c(NA,
3L))), list(structure(list(source = c("IDcode", "IDcode"
), db_id = c("id1494969", "id869437")), class = "data.frame", row.names = 1:2)),
list(structure(list(source = c("IDcode", "IDcode"), db_id = c("id578674",
"id531006")), class = "data.frame", row.names = 1:2)), list(
structure(list(source = c("IDcode", "IDcode"), db_id = c("id578673",
"id531005")), class = "data.frame", row.names = 1:2)))
> mylist
[[1]]
[[1]][[1]]
list()
[[2]]
[[2]][[1]]
list()
[[3]]
[[3]][[1]]
list()
[[4]]
[[4]][[1]]
list()
[[5]]
[[5]][[1]]
source db_id
1 IDcode id13653662
2 IDcode id3396732
3 IDcode id995182
[[6]]
[[6]][[1]]
source db_id
1 IDcode id1494969
2 IDcode id869437
[[7]]
[[7]][[1]]
source db_id
1 IDcode id578674
2 IDcode id531006
[[8]]
[[8]][[1]]
source db_id
1 IDcode id578673
2 IDcode id531005
I want to convert this into a vector that be stored as a column in a dataframe. Ideally, the vector would have NA where there is an empty list (eg, [[1]]
to [[4]]
), and if there is a populated list, it would just enter the ID codes separated by ;
for example: id13653662; id3396732; id995182
.
In other words, I would like the resulting vector to look like this:
> mylist
[1] NA NA NA
[4] NA "id13653662; id3396732; id995182" "id1494969; id869437"
[7] "id578674; id531006" "id578673;id531005"
What is the best way to do this?
Upvotes: 1
Views: 52
Reputation: 2863
You mean something like
rbind(mylist[[5]][[1]],mylist[[6]][[1]], mylist[[7]][[1]], mylist[[8]][[1]])
source db_id
1 IDcode id13653662
2 IDcode id3396732
3 IDcode id995182
4 IDcode id1494969
5 IDcode id869437
6 IDcode id578674
7 IDcode id531006
8 IDcode id578673
9 IDcode id531005
OR
mySecFun <- function(mylist)
{
vec <- vector()
for (i in 1:length(mylist)) {
for (j in 1:length(mylist[[i]])) {
if(length(mylist[[i]][[j]]) == 0){
vec[i] <- NA
}
else{
vec[i] <- paste0(mylist[[i]][[j]]$db_id,collapse = ";")
}
}
}
vec
}
mySecFun(mylist)
And you can apply the same thing for other lists (mylist1,mylist2,...)
as
mySecFun(mylist1); mySecFun(mylist2)
Upvotes: 0
Reputation: 21
vec <- vector()
for (i in 1:length(mylist)) {
for (j in 1:length(mylist[[i]])) {
if(length(mylist[[i]][[j]]) == 0){
vec[i] <- NA
}
else{
vec[i] <- paste0(mylist[[i]][[j]]$db_id,collapse = ";")
}
}
}
Upvotes: 1
Reputation: 389325
Since we have a list inside every list we unlist
it one level and return the pasted output or NA
based on the length of each list.
sapply(unlist(mylist, recursive = FALSE), function(x)
if(length(x)) paste0(x$db_id, collapse = ";") else NA)
#[1] NA NA NA
#[4] NA "id13653662;id3396732;id995182" "id1494969;id869437"
#[7] "id578674;id531006" "id578673;id531005"
Upvotes: 2