Misha
Misha

Reputation: 3126

convert from list to dataframe in r

I need to dig out similar dataframes from a list and put them into a dataframe. I´ve created a toy example:

nn <- list()
h <- data.frame(a = c(5,6), j = c(8,1), g = c("d","o"))
rnz <- c("test1","test2")
o <- data.frame(a = c(1,2), j = c(6,4), g = c("r","u"))
rownames(h) <- rnz
rownames(o) <- rnz
i <- 1:4
nn$set1 <- list(num = i, df = h)
nn$set2 <- list(num = i / 2, df = o)

Now I´d like to extract the list into the following tidy format

       var a j
set1 test1 5 8
set1 test2 6 1
set2 test1 1 6
set2 test2 2 4

But - when I do

df <- lapply(nn, function(x) x$df[ , c(1,2)])
df2 <- lapply(df, function(x) tibble::rownames_to_column(x, "var"))

df3 <- do.call(rbind, lapply(df2, function(c) as.data.frame(c, row.names = NULL)))

I get:

         var a j
set1.1 test1 5 8
set1.2 test2 6 1
set2.1 test1 1 6
set2.2 test2 2 4

How can I remove remove the .1,.2 etc in the rowcolumn? Is there a neater way of doing this?

Upvotes: 1

Views: 3723

Answers (2)

akrun
akrun

Reputation: 886938

We can use rbindlist with the idcol argument

library(data.table)
rbindlist(lapply(nn, function(x) transform( x$df[1:2], 
         var = row.names(x$df))), idcol = "name")
#    name a j   var
#1: set1 5 8 test1
#2: set1 6 1 test2
#3: set2 1 6 test1
#4: set2 2 4 test2

Upvotes: 4

alistaire
alistaire

Reputation: 43334

dplyr::bind_rows has a .id parameter to coerce element names to a column. purrr::map_df wraps it, including the .id parameter, so you can convert directly from nn:

library(purrr)

       # extract data.frame elements
nn %>% map('df') %>% 
    # add rownames to each data.frame; coerce result to data.frame with element names as column
    map_df(tibble::rownames_to_column, 'var', .id = 'name')

##   name   var a j g
## 1 set1 test1 5 8 d
## 2 set1 test2 6 1 o
## 3 set2 test1 1 6 r
## 4 set2 test2 2 4 u

Upvotes: 8

Related Questions