2

我对使用 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")

但是,为了提高效率,我可以将两个数据帧加入 alistpurrr同时过滤每个数据帧。

DataList <- list(Data1,Data2)
DataList %>% map(~filter(.,Animals=="Cat"))

对于上面的代码,我将为~filter每个动物使用多行,所以不确定是否有更有效的方法可以避免在仍然使用purrrand的同时编写许多不同的代码行dplyr

另外,我如何使用write.csvwith purrr。我可以将列表导出到一个电子表格中,但我不确定如何分解列表以便正确导出。此外,我可以将每个列表元素导出到单独的电子表格中。很高兴看到这两种情况的解决方案。

4

2 回答 2

4

如果我正确理解您的问题,您想为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数据splitAnimals,最后flatten是嵌套列表。

我希望我可以在不破坏链条的情况下做到这一点,但我找不到其他方法。

从这里开始,我们首先重命名列表的元素,然后使用lapply循环遍历列表中的所有元素并应用于write.csv每个元素。

你提到Excel- 你可以很容易地替换write.csv为任何用于编写 excel 文件的函数R

于 2016-07-22T17:29:49.877 回答
3

这是一种选择,涉及在重新拆分之前将两个数据集绑定在一起。

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 将数据集堆叠到一个单独的 data.frame 中时bind_rows,这些名称将作为新列添加id

setNames(c("Data1", "Data2")) %>%
bind_rows(.id = "id")

最后一步是在将每个拆分写入单独的 csv 文件之前拆分组合id的data.frame 。Animal从数据集中提取信息以按数据集和动物命名单个文件(这就是命名 元素的原因DataList)。我在编写文件之前删除了id变量 via select,因为它可能与您的需求无关。

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 的情况下完成,但我在最后命名文件时遇到了麻烦。

于 2016-07-22T17:49:54.880 回答