icedcoffee
icedcoffee

Reputation: 1015

How to take specific elements out of a list and return a vector

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

Answers (3)

Seyma Kalay
Seyma Kalay

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

Nitesh Saurabh
Nitesh Saurabh

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

Ronak Shah
Ronak Shah

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

Related Questions