将不均匀列表分解为数据帧以在 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 中的列重命名为相同的东西,这将为绑定行和获取长格式数据集打开大门,而无需稍后重新整形。
您可以使用 lapply
或 purrr::map
遍历列表,重命名每个列表元素中的列。我将使用 map_dfr
(map_df
在较旧的 purrr 版本中),因为它会在遍历列表后使用 bind_rows
将数据集绑定在一起。 map_dfr
有一个 .id
参数,因此我们可以添加一列来区分数据集。这在这里可能有用,但可以跳过。
您可以通过 rename_at
从 dplyr 更改列名称。因为您想重命名单个列,所以我将使用 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
...
我有一个巨大的列表,其中包含我从 运行 一个 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 中的列重命名为相同的东西,这将为绑定行和获取长格式数据集打开大门,而无需稍后重新整形。
您可以使用 lapply
或 purrr::map
遍历列表,重命名每个列表元素中的列。我将使用 map_dfr
(map_df
在较旧的 purrr 版本中),因为它会在遍历列表后使用 bind_rows
将数据集绑定在一起。 map_dfr
有一个 .id
参数,因此我们可以添加一列来区分数据集。这在这里可能有用,但可以跳过。
您可以通过 rename_at
从 dplyr 更改列名称。因为您想重命名单个列,所以我将使用 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
...