cbind a list of dataframe and to a vector of list

Gabriel Source

let say I have a nested list with data.frame called list_df_A which have the following structure:

$ :'data.frame':      1 obs. of 3 variables:
  ..$ a             :chr a1
  ..$ b             :chr b1
  ..$ c             :chr c1

$ :'data.frame':      3 obs. of 3 variables:
  ..$ a             :chr [1:3] a21 a22 a23
  ..$ b             :chr [1:3] b21 b22 b23
  ..$ c             :chr [1:3] c21 c22 c23

$ :'data.frame':      1 obs. of 3 variables:
  ..$ a             :chr a3
  ..$ b             :chr b3
  ..$ c             :chr c3

so if I rbind them into a data.table/data.frame:

list_df_A <- rbindlist(list_df_A)

list_df_A will then look like this:

      a     b     c
1:   a1    a2    a3
2:  a21   b21   c21
3:  a22   b22   c22
4:  a23   b23   c23
5:   a3    b3    c3

Now, I have another list. This list is actually the root of a json file. Let me call this list list_root which have the following structure:

chr [1:3] "type1" "type2" "type3"

if I make it as data.table/data.frame:

list_root <- as.data.table(list_root)

I get this table

       V1
1:  type1
2:  type2
3:  type3

The question now comes: I know that type2 in list_root has 3 records in list_df_A. This is because each "type" refers to one dataframe in list_df_A

How do you tell R when it cbind the two data.table together, it will show something like this?

           V1       a     b     c
     1: type1      a1    a2    a3
     2: type2     a21   a21   a21
     3: type2     b22   b22   b22
     4: type2     c23   c23   c23
     5: type3      a3    b3    c3

In a sense, row 2,3,4 belongs to type2?

rdataframecbind

Answers

answered 6 months ago Felipe Alvarenga #1

Prior to rbindlist you can supply each data frame with an outside vector of ids using mapply

my_list <- mapply(`[<-`, my_list, 'colname', value = list_root , SIMPLIFY = FALSE)

And then, just rbind all of them.

answered 6 months ago Gabriel #2

My answer to this is:

We use the .id as key to merge two dataframe/datatable together.

for list_root, we first turn it into datatable format, then add a column with ".id" so we have a key:

list_root <- as.data.table(list_root)[, .id := seq(1, nrow(list_root),1)]

Next I can use rbindlist on list_df_A:

list_df_A <- rbindlist(list_df_A, use.names=TRUE, fill=TRUE, idcol=TRUE)

Now both have an common key ".id" we can then perform merge:

new_dt <- merge(list_root, list_df_A, on=".id")

And we get the required result:

       V1       a     b     c    .id
 1: type1      a1    a2    a3      1
 2: type2     a21   a21   a21      2
 3: type2     b22   b22   b22      2
 4: type2     c23   c23   c23      2
 5: type3      a3    b3    c3      3

answered 6 months ago joran #3

You set the names of your list and then use the idcol argument as follows:

names(list_df_A) <- list_root
rbindlist(list_df_A,idcol = "id")

comments powered by Disqus