如何将 purrr 与 dplyr 一起使用来过滤列表元素并将列表导出到 Excel
How to use purrr with dplyr to filter list elements and export lists into Excel
我对在 R 中使用列表还很陌生,有一个快速问题也涉及使用 purrr
。下面以太小的样本数据框为例。
Client1 <- c("John","Chris","Yutaro","Dean","Andy")
Animals <- c("Cat","Cat","Dog","Rat","Bird")
Living <- c("House","Condo","Condo","Apartment","House")
Data1 <- data.frame(Client1,Animals,Living)
Client1 <- c("John","Chris","Yutaro","Dean","Andy")
Animals2 <- c("Cat","Dog","Dog","Rat","Cat")
Living2 <- c("House","Apartment","Apartment","Family","Apartment")
Data2 <- data.frame(Client1,Animals2,Living2)
如果您可以包括如何立即重命名列表元素而不是使用下面的两行,则奖励:
names(Data1)[1:3] <- c("Client","Animals","Living")
names(Data2)[1:3] <- c("Client","Animals","Living")
接下来,如果我想按 Animals
过滤每个数据框,然后使用以下两行代码将每个数据框导出到 Excel 电子表格中:
Data1 %>% filter(Animals=="Cat") %>% write.csv(.,file="Data1.csv")
Data2 %>% filter(Animals=="Cat") %>% write.csv(.,file="Data2.csv")
但是,为了提高效率,我可以将两个数据帧连接到一个 list
中,并使用 purrr
同时过滤每个数据帧。
DataList <- list(Data1,Data2)
DataList %>% map(~filter(.,Animals=="Cat"))
对于上面的代码,我将为每只动物使用多行 ~filter
行,所以不确定是否有更有效的方法可以避免在仍然使用 purrr
的同时编写许多不同的代码行dplyr
?
此外,如何将 write.csv
与 purrr
一起使用。我可以将列表导出到一个电子表格中,但我不确定如何分解列表以使其正确导出。此外,我可以将每个列表元素导出到单独的电子表格中。很高兴看到针对这两种情况的解决方案。
如果我正确理解你的问题,你想为两个数据框的每个 Animals
编写一个单独的文件:
DataList <- list(Data1, Data2)
library(purrr)
a <- DataList %>% map(., function(x) {
colnames(x) <- c("Client","Animals","Living")
x
}) %>% map(., function(x) {
split(x, x$Animals)
}) %>% flatten(.)
names(a) <- paste0("Data", (1:length(a)))
lapply(1:length(a), function(x) write.csv(a[[x]],
file = paste0(names(a[x]), ".csv"),
row.names = FALSE))
我们首先转储 DataList
中的两个数据框,然后用第一个 map
重命名两个数据框的列,然后 split
两个数据框用 Animals
,最后是 flatten
嵌套列表。
我希望我能在不破坏链条的情况下做到这一点,但我找不到其他方法。
从这里开始,我们首先重命名列表的元素,然后使用lapply
遍历列表中的所有元素并对每个元素应用write.csv
。
您提到了 Excel
- 您可以轻松地将 write.csv
替换为用于从 R
写入 excel 文件的任何函数
这是一个选项,涉及在重新拆分之前将两个数据集绑定在一起。
library(purrr)
library(dplyr)
DataList %>%
map(~setNames(.x, c("Client","Animals","Living"))) %>%
setNames(c("Data1", "Data2")) %>%
bind_rows(.id = "id") %>%
split(list(.$id, .$Animals), drop = TRUE) %>%
map(~select(.x, -id) %>%
write.csv(file = paste0(unique(.x$id), unique(.x$Animals), ".csv"),
row.names = FALSE))
第一行 map
显示如何通过 setNames
.
一次重命名列表中所有数据集的列
DataList %>%
map(~setNames(.x, c("Client","Animals","Living")))
然后我通过 setNames
在列表中设置数据集的名称。通过 dplyr 的 bind_rows
将数据集堆叠在一起形成一个 data.frame 时,这些名称将添加为新列 id
。
setNames(c("Data1", "Data2")) %>%
bind_rows(.id = "id")
最后一步是将组合的 data.frame 拆分为 id
和 Animal
,然后再将每个拆分写入单独的 csv 文件。从数据集中提取信息以按数据集和动物命名各个文件(这是命名 DataList
的元素的原因)。在写入文件之前,我通过 select
删除了 id
变量,因为它可能与您的需求无关。
split(list(.$id, .$Animals), drop = TRUE) %>%
map(~select(.x, -id) %>%
write.csv(file = paste0(unique(.x$id), unique(.x$Animals), ".csv"),
row.names = FALSE))
无需将它们放入一个文件中即可完成所有这些操作 data.frame,但我在最后命名文件时遇到了麻烦。
我对在 R 中使用列表还很陌生,有一个快速问题也涉及使用 purrr
。下面以太小的样本数据框为例。
Client1 <- c("John","Chris","Yutaro","Dean","Andy")
Animals <- c("Cat","Cat","Dog","Rat","Bird")
Living <- c("House","Condo","Condo","Apartment","House")
Data1 <- data.frame(Client1,Animals,Living)
Client1 <- c("John","Chris","Yutaro","Dean","Andy")
Animals2 <- c("Cat","Dog","Dog","Rat","Cat")
Living2 <- c("House","Apartment","Apartment","Family","Apartment")
Data2 <- data.frame(Client1,Animals2,Living2)
如果您可以包括如何立即重命名列表元素而不是使用下面的两行,则奖励:
names(Data1)[1:3] <- c("Client","Animals","Living")
names(Data2)[1:3] <- c("Client","Animals","Living")
接下来,如果我想按 Animals
过滤每个数据框,然后使用以下两行代码将每个数据框导出到 Excel 电子表格中:
Data1 %>% filter(Animals=="Cat") %>% write.csv(.,file="Data1.csv")
Data2 %>% filter(Animals=="Cat") %>% write.csv(.,file="Data2.csv")
但是,为了提高效率,我可以将两个数据帧连接到一个 list
中,并使用 purrr
同时过滤每个数据帧。
DataList <- list(Data1,Data2)
DataList %>% map(~filter(.,Animals=="Cat"))
对于上面的代码,我将为每只动物使用多行 ~filter
行,所以不确定是否有更有效的方法可以避免在仍然使用 purrr
的同时编写许多不同的代码行dplyr
?
此外,如何将 write.csv
与 purrr
一起使用。我可以将列表导出到一个电子表格中,但我不确定如何分解列表以使其正确导出。此外,我可以将每个列表元素导出到单独的电子表格中。很高兴看到针对这两种情况的解决方案。
如果我正确理解你的问题,你想为两个数据框的每个 Animals
编写一个单独的文件:
DataList <- list(Data1, Data2)
library(purrr)
a <- DataList %>% map(., function(x) {
colnames(x) <- c("Client","Animals","Living")
x
}) %>% map(., function(x) {
split(x, x$Animals)
}) %>% flatten(.)
names(a) <- paste0("Data", (1:length(a)))
lapply(1:length(a), function(x) write.csv(a[[x]],
file = paste0(names(a[x]), ".csv"),
row.names = FALSE))
我们首先转储 DataList
中的两个数据框,然后用第一个 map
重命名两个数据框的列,然后 split
两个数据框用 Animals
,最后是 flatten
嵌套列表。
我希望我能在不破坏链条的情况下做到这一点,但我找不到其他方法。
从这里开始,我们首先重命名列表的元素,然后使用lapply
遍历列表中的所有元素并对每个元素应用write.csv
。
您提到了 Excel
- 您可以轻松地将 write.csv
替换为用于从 R
这是一个选项,涉及在重新拆分之前将两个数据集绑定在一起。
library(purrr)
library(dplyr)
DataList %>%
map(~setNames(.x, c("Client","Animals","Living"))) %>%
setNames(c("Data1", "Data2")) %>%
bind_rows(.id = "id") %>%
split(list(.$id, .$Animals), drop = TRUE) %>%
map(~select(.x, -id) %>%
write.csv(file = paste0(unique(.x$id), unique(.x$Animals), ".csv"),
row.names = FALSE))
第一行 map
显示如何通过 setNames
.
DataList %>%
map(~setNames(.x, c("Client","Animals","Living")))
然后我通过 setNames
在列表中设置数据集的名称。通过 dplyr 的 bind_rows
将数据集堆叠在一起形成一个 data.frame 时,这些名称将添加为新列 id
。
setNames(c("Data1", "Data2")) %>%
bind_rows(.id = "id")
最后一步是将组合的 data.frame 拆分为 id
和 Animal
,然后再将每个拆分写入单独的 csv 文件。从数据集中提取信息以按数据集和动物命名各个文件(这是命名 DataList
的元素的原因)。在写入文件之前,我通过 select
删除了 id
变量,因为它可能与您的需求无关。
split(list(.$id, .$Animals), drop = TRUE) %>%
map(~select(.x, -id) %>%
write.csv(file = paste0(unique(.x$id), unique(.x$Animals), ".csv"),
row.names = FALSE))
无需将它们放入一个文件中即可完成所有这些操作 data.frame,但我在最后命名文件时遇到了麻烦。