从具有不同列名的表列表制作数据框

时间:2019-04-14 03:44:53

标签: r tidyverse

我有一长串表,需要将它们转换成数据框。问题在于不同的表具有不同的列名。所有名称的范围从1到5,但是例如某些表仅具有第2列,另一些表具有第4和5列,而另一些则具有5列。

数据的示例是:

> head(bffrsTbls)
[[1]]

   2    5 
 711 1781 

[[2]]

   2    5 
1168 1530 

[[3]]

   1    2    3    5 
 390  471  904 1237 

我已经尝试过bffrsTbls %>% purrr::map_df(., dplyr::bind_rows),但是结果数据框中的值并不对应于每个表的列名。

我正在寻找的结果是一个这样的数据帧,其中val1到val5列对应于每个表的第1到5列,另外一列显示了列表元素的编号,其中该特定数据列来自:

ListElmnt   val1   val2   val3   val4   val5
1           NA     711    NA     NA     1781
2           NA     1168   NA     NA     1530
3           390    471    904    NA     1237

1 个答案:

答案 0 :(得分:1)

我们可以通过将list遍历tibble并将其更改为单个数据来将list元素转换为map

library(tidyverse)
map_dfr(bffrsTbls, ~ .x %>%
                     as.list %>%
                     as_tibble)

如果我们还需要所有组合,请将enframe元素list设为2列标题,并将spread的输出数据集更改为“宽”格式

bffrsTbls %>%
  map_df(enframe, .id = 'ListElmnt') %>% 
  mutate(name = factor(paste0('val', name), levels = paste0("val", 1:5))) %>% 
  spread(name, value, drop = FALSE)
# A tibble: 3 x 6
#  ListElmnt  val1  val2  val3  val4  val5
#  <chr>     <dbl> <dbl> <dbl> <dbl> <dbl>
#1 1            NA   711    NA    NA  1781
#2 2            NA  1168    NA    NA  1530
#3 3           390   471   904    NA  1237

或使用base R

xtabs(values ~ ListElmnt + ind, do.call(rbind, Map(cbind, 
      lapply(bffrsTbls, stack), ListElmnt = seq_along(bffrsTbls))))

数据

bffrsTbls <- list(structure(c(`2` = 711, `5` = 1781), .Dim = 2L, .Dimnames = list(
c("2", "5")), class = "table"), structure(c(`2` = 1168, `5` = 1530
 ), .Dim = 2L, .Dimnames = list(c("2", "5")), class = "table"), 
   structure(c(`1` = 390, `2` = 471, `3` = 904, `5` = 1237), .Dim = 4L,
   .Dimnames = list(
    c("1", "2", "3", "5")), class = "table"))