How to bind a df to a list of df

Viewed 66

I have a list of df lst1 and a df for variable name and label Label. How can I bind Label with each df in lst. I understand that all cols in lst will be charters and won't be able to used again for analysis. But that is what I want. How should I do that?

lst<-list(Demographics = structure(list(SubjectID = c("101-01-101", 
"101-02-102", "101-03-103", "101-04-104", "104-05-201"), BRTHDTC = c("1953-07-07", 
"1963-07-02", "1940-09-11", "1955-12-31", "1950-12-04"), SEX = c("Female", 
"Female", "Male", "Male", "Female")), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame")), DiseaseStatus = structure(list(SubjectID = c("101-01-101", 
"101-02-102", "101-03-103", "101-04-104", "104-05-201"), DSDT = c("2016-03-14", 
"2017-04-04", NA, "2016-05-02", "2018-07-06"), DSDT_P = c(NA, 
NA, "UN-UNK-2015", NA, NA)), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame")), Visits = structure(list(SubjectID = c("101-01-101", 
"101-02-102", "101-03-103", "101-04-104", "104-05-201"), Visit = c("Screening: -28 Days to Day 1", 
"Screening: -28 Days to Day 1", "Screening: -28 Days to Day 1", 
"Screening: -28 Days to Day 1", "Screening: -28 Days to Day 1"
), VISND = c(NA_character_, NA_character_, NA_character_, NA_character_, 
NA_character_)), row.names = c(NA, -5L), class = c("tbl_df", 
"tbl", "data.frame")))

Label<-structure(list(Var = c("SubjectID", "BRTHDTC", "SEX", "DSDT", 
"DSDT_P", "Visit", "VISND"), label = c("Subject ID", "Birthday", 
"Gender", "DS Date", "DS Date Prob", "Date of Visit", "ND Visit"
)), row.names = c(NA, -7L), class = c("tbl_df", "tbl", "data.frame"

The expected df in lst will look like this:

enter image description here

2 Answers

For these sort of problems where you need to map names to names, I like to use named vectors (with the function setNames()) the way you would use dictionaries in python. Then you can use it to extract the vector of labels that you want to prepend to each data.frame.


var2label = setNames(Label$label, nm = Label$Var)

new_df_list = lapply(lst, function(L){

 col_names = names(L)
 col_labels = var2label[col_names]
 
 df = rbind(col_labels, data.frame(L))

 return(df)

})

Output of the first data.frame

> new_df_list[[1]]
   SubjectID    BRTHDTC    SEX
1 Subject ID   Birthday Gender
2 101-01-101 1953-07-07 Female
3 101-02-102 1963-07-02 Female
4 101-03-103 1940-09-11   Male
5 101-04-104 1955-12-31   Male
6 104-05-201 1950-12-04 Female

We could use tidyverse

library(purrr)
library(dplyr)
library(tibble)
out <- map(lst, ~ bind_rows(as.list(deframe(Label)[names(.x)]), .x))

-output

out
$Demographics
# A tibble: 6 x 3
  SubjectID  BRTHDTC    SEX   
  <chr>      <chr>      <chr> 
1 Subject ID Birthday   Gender
2 101-01-101 1953-07-07 Female
3 101-02-102 1963-07-02 Female
4 101-03-103 1940-09-11 Male  
5 101-04-104 1955-12-31 Male  
6 104-05-201 1950-12-04 Female

$DiseaseStatus
# A tibble: 6 x 3
  SubjectID  DSDT       DSDT_P      
  <chr>      <chr>      <chr>       
1 Subject ID DS Date    DS Date Prob
2 101-01-101 2016-03-14 <NA>        
3 101-02-102 2017-04-04 <NA>        
4 101-03-103 <NA>       UN-UNK-2015 
5 101-04-104 2016-05-02 <NA>        
6 104-05-201 2018-07-06 <NA>        

$Visits
# A tibble: 6 x 3
  SubjectID  Visit                        VISND   
  <chr>      <chr>                        <chr>   
1 Subject ID Date of Visit                ND Visit
2 101-01-101 Screening: -28 Days to Day 1 <NA>    
3 101-02-102 Screening: -28 Days to Day 1 <NA>    
4 101-03-103 Screening: -28 Days to Day 1 <NA>    
5 101-04-104 Screening: -28 Days to Day 1 <NA>    
6 104-05-201 Screening: -28 Days to Day 1 <NA>   

If we want the other way

map(lst, ~ {
    nm1 <- deframe(Label)[names(.x)]
    bind_rows(as.list(setNames(names(nm1), nm1)), setNames(.x, nm1)) })

-output

$Demographics
# A tibble: 6 x 3
  `Subject ID` Birthday   Gender
  <chr>        <chr>      <chr> 
1 SubjectID    BRTHDTC    SEX   
2 101-01-101   1953-07-07 Female
3 101-02-102   1963-07-02 Female
4 101-03-103   1940-09-11 Male  
5 101-04-104   1955-12-31 Male  
6 104-05-201   1950-12-04 Female

$DiseaseStatus
# A tibble: 6 x 3
  `Subject ID` `DS Date`  `DS Date Prob`
  <chr>        <chr>      <chr>         
1 SubjectID    DSDT       DSDT_P        
2 101-01-101   2016-03-14 <NA>          
3 101-02-102   2017-04-04 <NA>          
4 101-03-103   <NA>       UN-UNK-2015   
5 101-04-104   2016-05-02 <NA>          
6 104-05-201   2018-07-06 <NA>          

$Visits
# A tibble: 6 x 3
  `Subject ID` `Date of Visit`              `ND Visit`
  <chr>        <chr>                        <chr>     
1 SubjectID    Visit                        VISND     
2 101-01-101   Screening: -28 Days to Day 1 <NA>      
3 101-02-102   Screening: -28 Days to Day 1 <NA>      
4 101-03-103   Screening: -28 Days to Day 1 <NA>      
5 101-04-104   Screening: -28 Days to Day 1 <NA>      
6 104-05-201   Screening: -28 Days to Day 1 <NA>     
Related