将不均匀列表分解为数据帧以在 ggplot2 中使用

Break apart uneven list into dataframes to use in ggplot2

我有一个巨大的列表,其中包含我从 运行 一个 for 循环输出的各种小标题。此列表中的小标题是使用 count()group_by_() 的结果,并按类别 a 显示在各种设施工作和不工作的人数,但每个元素列表具有可变数量的行和名称不同的一列。

这是我的(20 多个元素)列表中的三个元素:

library(plyr)    
library(tidyverse)

(Hospital1 <- tibble(a = c("In.City", "In.City", "Likely Move", "Likely Move", "Possibly Move", "Unlikely Move", "Unlikely Move", NA), 
                     Something.Hospital1 = c("Hospital1", NA, "Hospital1", NA, NA, "Hospital1", NA, NA), 
                     n= c(sample(1:100, 8, replace = TRUE))))
(Hospital2 <- tibble(a = c("In.City", "In.City", "Likely Move", "Likely Move", "Possibly Move", "Unlikely Move", NA),
                     Something.Hospital2 = c("Hospital2", NA, "Hospital2", NA, NA, NA, NA), 
                     n= c(sample(1:100, 7, replace = TRUE))))
(Hospital3 <- tibble(a = c("In.City", "Likely Move", "Unlikely Move", "Possibly Move", NA),
                     Something.Hospital3 = as.character(c(NA, NA, NA, NA, NA)), 
                     n= c(sample(1:100, 5, replace = TRUE))))

#What my data actually looks like
(example.list <- list(Hospital1, Hospital2, Hospital3))

不在每个列表元素第二列中 NA 旁边的第 3 列中 n 的值最重要。到目前为止,我真的很难将它们变成 ggplot2 可以使用它们的形式。因为我正在使用大约 20 个列表元素,所以我觉得我需要在代码中使用列表结构,并且能够在需要时进行迭代或创建函数。我试过:

1) 使用 cbind(example.list[[1:3]])bind_cols([[1:3]]),将它们绑定到一个小标题中,但由于行数不同(与单个括号相同),两者都失败了。

2) 单独绘制这些元素的图形,但 ggplot2 无法列出列表。

3) 使用 list2env(example.list[1:3], envir = .GlobalEnv) 将它们拆分为单独的数据帧,但这给了我错误

names(x) must be a character vector of the same length as x

4) 做一个 for 循环 left_join() 但要这样做,我需要一个键,我可以使用类似于 cumsum() 的东西形成它,但用于字符单元格。那必须看起来像这样

              a Something.Hospital1     n match.key
          <chr>               <chr> <int> <dbl>
1       In.City           Hospital1    40     1
2       In.City                <NA>    25     2
3   Likely Move           Hospital1    17     1
4   Likely Move                <NA>    56     2
5 Possibly Move           Hospital1    59     1

5) 我尝试使用 ddply(output[[10]], .(crosstab, n), nrow),但 V1 对这样的合并没有帮助。

       crosstab   n V1
1     In.Camden  14  1
2     In.Camden 139  1
3   Likely Move   4  1
4   Likely Move 171  1

在我看来,我希望我的数据看起来像这样,并列出所有可能性。然后我可以使用 tidyr() 将其转换为 ggplot 形式

             a Something.Hospital1    n1 Something.Hospital2    n2 Something.Hospital3    n3
          <chr>               <chr> <int>               <chr> <int>               <chr> <int>
1       In.City           Hospital1    39           Hospital2    24           Hospital3    13
2       In.City                <NA>    86                <NA>    82                <NA>    85
3   Likely Move           Hospital1    77           Hospital2    16           Hospital3    17
4   Likely Move                <NA>     4                <NA>    78                <NA>    49
5 Possibly Move           Hospital1   100           Hospital2    79           Hospital3    95
6 Possibly Move                <NA>    49                <NA>    31                <NA>    62
7 Unlikely Move           Hospital1    82           Hospital2     3           Hospital3    96
8 Unlikely Move                <NA>    27                <NA>    30                <NA>    39
9          <NA>                <NA>    55                <NA>    96                <NA>    47

我根本不了解 lapply 和相关内容,所以如果您提出建议,请清楚说明如何使用它们。我更喜欢 dplyr,因为这是我最了解的。

非常感谢您的帮助

您可以将每个 tibble 中的列重命名为相同的东西,这将为绑定行和获取长格式数据集打开大门,而无需稍后重新整形。

您可以使用 lapplypurrr::map 遍历列表,重命名每个列表元素中的列。我将使用 map_dfrmap_df 在较旧的 purrr 版本中),因为它会在遍历列表后使用 bind_rows 将数据集绑定在一起。 map_dfr 有一个 .id 参数,因此我们可以添加一列来区分数据集。这在这里可能有用,但可以跳过。

您可以通过 rename_atdplyr 更改列名称。因为您想重命名单个列,所以我将使用 paste0.

将它们全部命名为新名称

这是循环遍历 example.list 的每个元素并将包含单词 "Hospital" 的所有列重命名为 "Something.Hospital" 的代码。

map_dfr(example.list, ~rename_at(.x, vars( contains( "Hospital") ), 
                                 funs( paste0("Something.Hospital") ) ), 
        .id = "group" )

# A tibble: 20 x 4
   group             a Something.Hospital     n
   <chr>         <chr>              <chr> <int>
 1     1       In.City          Hospital1    31
 2     1       In.City               <NA>    81
 3     1   Likely Move          Hospital1    71
 4     1   Likely Move               <NA>    87
 5     1 Possibly Move               <NA>     6
 6     1 Unlikely Move          Hospital1    16
 7     1 Unlikely Move               <NA>    16
 8     1          <NA>               <NA>    92
 9     2       In.City          Hospital2    98
...