how to create a tibble from a list with named vectors

Advertisements

I am trying to make an edge df from a dataset that I have for a network I’m building:

    > head(x)
# A tibble: 6 × 8
     visitID entry_date          propertyID prop_grp_ID   entry_type edgeID   
       <dbl> <dttm>                   <dbl>       <dbl>      <fct>      <chr>    
1 1157349647 2022-04-01 00:00:00  251317243  1915318832  X14        231224220
2 1215457284 2022-04-01 00:00:00  165589924  1915318832  X14        231224220
3  986527720 2022-04-01 00:00:00  659308365  1915318832  X14        231224220
4  986527720 2022-04-01 00:00:00  659308365  1915318832  X14        231224220
5 1106040433 2022-04-01 00:00:00 1659425840  1915318832  X14        231224220
6 1106040433 2022-04-01 00:00:00 1659425840  1915318832  X14        231224220

# create an empty list to add to
edge_list <- vector("list", nrow(x)-1)

# loop through each row number and add the from and to property ids to edge list
for (k in 1 : (nrow(x)-1)) {
    # check to see if the property IDs in adjacent rows are the same or not. 
    if (x[[k, 3]] != x[[k+1, 3]]) {
        # create a named vector inside each list element
        edge_list[[k]] = c(from = x[[k,3]], to = x[[k+1,3]])  # if they aren't the same, then add the propertyID to the list
    } else {
        edge_list[[k]] = c(from = NA, to = NA)  # if they are the same, then put NA, these will be dropped later.
    }
}

And this is what it looks like:

    > head(edge_list)
[[1]]
     from        to 
251317243 165589924 

[[2]]
     from        to 
165589924 659308365 

[[3]]
from   to 
  NA   NA 

[[4]]
      from         to 
 659308365 1659425840 

[[5]]
from   to 
  NA   NA 

[[6]]
      from         to 
1659425840 1834267060

I am trying to turn it into a tibble that will look like this so I can feed it into the network packages:

from             to
251317243      165589924 
165589924      659308365 
NA             NA 
659308365      1659425840 
NA             NA
1659425840     1834267060

I’ve found posts How to convert list of list into a tibble (dataframe), Convert named list of lists to dataframe using tidy approach, Named list to data frame, Named List To/From Data.Frame, How to keep the name of vector as a column in the tibble but not quite what I’m looking for since the list isn’t named, but the vector inside the list is, and that’s what I need for the column names.

I’ve tried:

 test <- enframe(unlist(edge_list))
 test <- test |> 
     pivot_wider(names_from = name, values_from = value)

and got

 # A tibble: 1 × 2
 from        to         
 <list>      <list>     
     1 <dbl [693]> <dbl [693]>

and warnings that there are duplicates, which I’m expecting.

I’ve tried versions of this:

 tbl_colnames <- c("from", "to")
 
 edge_df <- tibble(
     from = numeric(),
     to = numeric(),
     .name_repair = tbl_colnames
 )

I’ve found posts an using map(), which I don’t really understand what they are doing. I’ve also tried starting with a dataframe instead of a list, but couldn’t figure out how to make an empty tibble with named columns and 693 rows. (I was taught not to ‘grow’ vectors so I assumed you shouldn’t grow tibbles either)

Is there a straight forward way of doing this?
Thanks.

>Solution :

Sample data:

edge_list <- list(c(from=1,to=2), c(from=3,to=4), c(from=NA, to=NA))

dplyr

library(dplyr)
bind_rows(edge_list)
# # A tibble: 3 × 2
#    from    to
#   <dbl> <dbl>
# 1     1     2
# 2     3     4
# 3    NA    NA

base R

# R-4 or newer
do.call(rbind.data.frame, edge_list) |>
  setNames(names(edge_list[[1]]))
#   from to
# 1    1  2
# 2    3  4
# 3   NA NA

or

do.call(rbind.data.frame, lapply(edge_list, as.list))
#   from to
# 1    1  2
# 2    3  4
# 3   NA NA

(Base R isn’t getting the names from a named vector, but a named list works.)

Leave a ReplyCancel reply