简体   繁体   English

从数据帧列表中获取列名和数据帧名称到单个数据帧中

[英]Get column names and dataframe name from a list of dataframes into a single dataframe

I am looking for a way to make column names and dataframe names from a list of dataframes into a single dataframe.我正在寻找一种方法来将数据框列表中的列名和数据框名称转换为单个数据框。 They have unequal length of columns.它们的列长度不等。 What's the best way to do this?做到这一点的最佳方法是什么?

dlist <- list(mtcars[1:2], mtcars[1:3], mtcars[1:4])
names(dlist) <- c("mtcars1", "mtcars2", "mtcars3")

Tried:
dlist |> map(~colnames(.x))

Expected output:预期输出:

1 mtcars1 mpg   cyl   NA    NA   
2 mtcars2 mpg   cyl   disp  NA   
3 mtcars3 mpg   cyl   disp  hp  

You can try:你可以试试:

library(tidyverse)

dlist %>%
  map_df(~names(.x) %>%
           enframe(), .id = "id") %>%
  pivot_wider(names_from = name, id_cols = id)

# A tibble: 3 x 5
  id      `1`   `2`   `3`   `4`  
  <chr>   <chr> <chr> <chr> <chr>
1 mtcars1 mpg   cyl   NA    NA   
2 mtcars2 mpg   cyl   disp  NA   
3 mtcars3 mpg   cyl   disp  hp  

Or same idea in base:或在基地相同的想法:

reshape(stack(lapply(dlist, names)), idvar = "ind", timevar = "values", direction = "wide", v.names = "values")

      ind values.mpg values.cyl values.disp values.hp
1 mtcars1        mpg        cyl        <NA>      <NA>
3 mtcars2        mpg        cyl        disp      <NA>
6 mtcars3        mpg        cyl        disp        hp

Similar to the accepted solution but more compact thanks to unnest_wider :类似于公认的解决方案,但由于unnest_wider更紧凑:

library(tidyr)
library(tibble)
library(purrr)

dlist %>% 
  map(colnames) %>% 
  enframe %>% 
  unnest_wider(value, names_sep = "_")

#> # A tibble: 3 x 5
#>   name    value_1 value_2 value_3 value_4
#>   <chr>   <chr>   <chr>   <chr>   <chr>  
#> 1 mtcars1 mpg     cyl     NA      NA     
#> 2 mtcars2 mpg     cyl     disp    NA     
#> 3 mtcars3 mpg     cyl     disp    hp   

Maybe there is a better way but this is how I would do it:也许有更好的方法,但我会这样做:

library(purrr)

dlist %>%
  map(~ .x %>% 
        names() %>% 
        append(rep(NA_character_, dlist %>%
                     map(~ .x %>% names()) %>%
                     reduce(~ max(length(..1), length(..2))) - length(.x)))) %>%
  exec(rbind, !!!.) %>%
  as.data.frame()

         V1  V2   V3   V4
mtcars1 mpg cyl <NA> <NA>
mtcars2 mpg cyl disp <NA>
mtcars3 mpg cyl disp   hp

Or a bit more concise with map2 , similar to may dear friend's elegant solution:或者用map2更简洁一点,类似于可能亲爱的朋友的优雅解决方案:

dlist %>% 
  map2_dfr(names(dlist), ~ c(.y, names(.x)) %>% set_names(~ letters[seq_along(.x)])) %>%
  column_to_rownames("a")

          b   c    d    e
mtcars1 mpg cyl <NA> <NA>
mtcars2 mpg cyl disp <NA>
mtcars3 mpg cyl disp   hp

A base R solution is:基本的 R 解决方案是:

dlist |> lapply(names) |>
  (\(x){
    res <- t(sapply(x, `length<-`, max(lengths(x))))
    cbind(id = names(x), setNames(data.frame(res), 1:NCOL(res)))
  })()
#R>              id   1   2    3    4
#R> mtcars1 mtcars1 mpg cyl <NA> <NA>
#R> mtcars2 mtcars2 mpg cyl disp <NA>
#R> mtcars3 mtcars3 mpg cyl disp   hp

Since the row names and id are the same, then this might do:由于行名和id是相同的,那么这可能会:

dlist |> lapply(names) |>
  (\(x) sapply(x, `length<-`, max(lengths(x))))() |> 
  t() |> as.data.frame()
#R>          V1  V2   V3   V4
#R> mtcars1 mpg cyl <NA> <NA>
#R> mtcars2 mpg cyl disp <NA>
#R> mtcars3 mpg cyl disp   hp

or this one?还是这个?

library(tidyverse)
dlist <- list(mtcars[1:2], mtcars[1:3], mtcars[1:4])
names(dlist) <- c("mtcars1", "mtcars2", "mtcars3")


map_dfr(dlist, ~names(.x) %>% set_names(paste0('col', seq_along(.x))))

#> # A tibble: 3 x 4
#>   col1  col2  col3  col4 
#>   <chr> <chr> <chr> <chr>
#> 1 mpg   cyl   <NA>  <NA> 
#> 2 mpg   cyl   disp  <NA> 
#> 3 mpg   cyl   disp  hp

If you also want rownames back如果您还想要返回行名

imap_dfr(dlist, ~c(.y, names(.x)) %>% set_names('cc',paste0('col', seq_along(.x)))) %>%
  column_to_rownames('cc')

#>         col1 col2 col3 col4
#> mtcars1  mpg  cyl <NA> <NA>
#> mtcars2  mpg  cyl disp <NA>
#> mtcars3  mpg  cyl disp   hp

Created on 2021-07-02 by the reprex package (v2.0.0)reprex 包( v2.0.0 ) 于 2021 年 7 月 2 日创建

Another way would be:另一种方法是:

do.call('rbind',
        lapply(seq_len(length(dlist)), 
               function(i) c(names(dlist)[i], 
                             names(dlist[[i]]),
                             rep(NA, max(sapply(dlist, length)) - ncol(dlist[[i]]))
               )
        )
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将数据帧列表转换为具有 id 列的单个 dataframe - Convert a list of dataframes to a single dataframe with an id column 如何从数据框列表中创建 dataframe 但列名是数据框列表? - How to create a dataframe from a list of dataframes but have the column names be the list of dataframes? 从数据帧列中的嵌套数据帧列表创建数据帧中的列 - create columns in dataframe from nested list of dataframes in a dataframe column 在列表的数据框中设置一列等于 R 列表中的 dataframe 的名称 - Set a column in dataframes of a list equal to the name of the dataframe in the list in R 在数据框列表上使用数据框的名称 - use name of dataframe on a list of dataframes 使用 lapply 将单个数据框列转换为数据框列表中的数字 - Using lapply to convert a single dataframe column to numeric in a list of dataframes 使用 R 中每个 dataframe 中的相应列名填充数据帧列表中的列 - filling column in a list of dataframes with the corresponding column name from each dataframe in R 为数据框列表 R 中的每个 dataframe 中的每个列名添加前缀 - Adding a prefix to each column name in each dataframe in a list of dataframes R 使用其数据框名称重命名列表中的数据框列 - Rename column of dataframes inside a list with its dataframe name 如何将数据框分成R中有关列名的数据帧列表? - How to separate a dataframe into a list of dataframes regarding column name in R?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM