如何将列名作为第一行绑定到列表中的每个 data.frame

how to bind the col names as first row to each data.frame in a list

我有一个列表列表,每个子列表也有多个dfs。我想将名称(df)绑定到 df。我该怎么做?

数据:

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

我的代码不起作用:

q2<-imap(q1, ~ map(.x, ~
 .x %>%
 map(~ bind_rows(names(.x), .x) )))

我的预期结果是这样的:

试一试。

library(purrr)
library(dplyr)

# First map the bind_rows function to each sub-list of your list of two
q2 <- imap(q1, ~ map(.x, 
  .f = function(x) {
    name_df <- tibble(a = names(x), b = names(x)) %>%
      pivot_wider(names_from = a, values_from = b)
    data <- bind_rows(name_df, x)
  }))
q2
#> $Demographics
#> $Demographics$`101-01-101`
#> # A tibble: 2 x 3
#>   SubjectID  BRTHDTC    SEX   
#>   <chr>      <chr>      <chr> 
#> 1 SubjectID  BRTHDTC    SEX   
#> 2 101-01-101 1953-07-07 Female
#> 
#> $Demographics$`101-02-102`
#> # A tibble: 2 x 3
#>   SubjectID  BRTHDTC    SEX   
#>   <chr>      <chr>      <chr> 
#> 1 SubjectID  BRTHDTC    SEX   
#> 2 101-02-102 1963-07-02 Female
#> 
#> $Demographics$`101-03-103`
#> # A tibble: 2 x 3
#>   SubjectID  BRTHDTC    SEX  
#>   <chr>      <chr>      <chr>
#> 1 SubjectID  BRTHDTC    SEX  
#> 2 101-03-103 1940-09-11 Male 
#> 
#> $Demographics$`101-04-104`
#> # A tibble: 2 x 3
#>   SubjectID  BRTHDTC    SEX  
#>   <chr>      <chr>      <chr>
#> 1 SubjectID  BRTHDTC    SEX  
#> 2 101-04-104 1955-12-31 Male 
#> 
#> $Demographics$`104-05-201`
#> # A tibble: 2 x 3
#>   SubjectID  BRTHDTC    SEX   
#>   <chr>      <chr>      <chr> 
#> 1 SubjectID  BRTHDTC    SEX   
#> 2 104-05-201 1950-12-04 Female
#> 
#> 
#> $DiseaseStatus
#> $DiseaseStatus$`101-01-101`
#> # A tibble: 2 x 3
#>   SubjectID  DSDT       DSDT_P
#>   <chr>      <chr>      <chr> 
#> 1 SubjectID  DSDT       DSDT_P
#> 2 101-01-101 2016-03-14 <NA>  
#> 
#> $DiseaseStatus$`101-02-102`
#> # A tibble: 2 x 3
#>   SubjectID  DSDT       DSDT_P
#>   <chr>      <chr>      <chr> 
#> 1 SubjectID  DSDT       DSDT_P
#> 2 101-02-102 2017-04-04 <NA>  
#> 
#> $DiseaseStatus$`101-03-103`
#> # A tibble: 2 x 3
#>   SubjectID  DSDT  DSDT_P     
#>   <chr>      <chr> <chr>      
#> 1 SubjectID  DSDT  DSDT_P     
#> 2 101-03-103 <NA>  UN-UNK-2015
#> 
#> $DiseaseStatus$`101-04-104`
#> # A tibble: 2 x 3
#>   SubjectID  DSDT       DSDT_P
#>   <chr>      <chr>      <chr> 
#> 1 SubjectID  DSDT       DSDT_P
#> 2 101-04-104 2016-05-02 <NA>  
#> 
#> $DiseaseStatus$`104-05-201`
#> # A tibble: 2 x 3
#>   SubjectID  DSDT       DSDT_P
#>   <chr>      <chr>      <chr> 
#> 1 SubjectID  DSDT       DSDT_P
#> 2 104-05-201 2018-07-06 <NA>

reprex package (v2.0.0)

于 2021-05-27 创建

进一步解释为什么您的代码不起作用:

  • imap 将您的地图应用于每个列表
  • map 适用于每个列表中每个 df 的每一列 - 并且导致错误作为代码 map bind_rows 函数记录每一列(向量)

如果将 bind_rows 替换为 print,您的代码将执行以下操作。它打印出每个列表中每个 df 中每一列的每条记录。

q2<-imap(q1, ~ map(.x, ~
    .x %>%
    map(~ print(.x))))
#> [1] "101-01-101"
#> [1] "1953-07-07"
#> [1] "Female"
#> [1] "101-02-102"
#> [1] "1963-07-02"
#> [1] "Female"
#> [1] "101-03-103"
#> [1] "1940-09-11"
#> [1] "Male"
#> [1] "101-04-104"
#> [1] "1955-12-31"
#> [1] "Male"
#> [1] "104-05-201"
#> [1] "1950-12-04"
#> [1] "Female"
#> [1] "101-01-101"
#> [1] "2016-03-14"
#> [1] NA
#> [1] "101-02-102"
#> [1] "2017-04-04"
#> [1] NA
#> [1] "101-03-103"
#> [1] NA
#> [1] "UN-UNK-2015"
#> [1] "101-04-104"
#> [1] "2016-05-02"
#> [1] NA
#> [1] "104-05-201"
#> [1] "2018-07-06"
#> [1] NA

reprex package (v2.0.0)

于 2021-05-27 创建

基础 R 使用 lapply -

lapply(q1, function(x) lapply(x, function(y) rbind(names(y), y)))

#$Demographics
#$Demographics$`101-01-101`
# A tibble: 2 x 3
#  SubjectID  BRTHDTC    SEX   
#  <chr>      <chr>      <chr> 
#1 SubjectID  BRTHDTC    SEX   
#2 101-01-101 1953-07-07 Female

#$Demographics$`101-02-102`
# A tibble: 2 x 3
#  SubjectID  BRTHDTC    SEX   
#  <chr>      <chr>      <chr> 
#1 SubjectID  BRTHDTC    SEX   
#2 101-02-102 1963-07-02 Female
#...
#...

您的尝试很接近,但需要做一些改动 -

  • 你不需要 3 map
  • bind_rows 需要一个数据帧或 tibble 来组合。 names(.x) 是一个字符向量,所以我们可以使用 rbind.
library(purrr)
map(q1, function(x) map(x, ~rbind(names(.x), .x)))