2016-07-22 41 views
1

我对R中的列表使用相当新,并有一个快速问题,也使用purrr involes。下面的示例数据帧太小。如何使用purrr与dplyr过滤列表元素和导出列表到Excel

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线每一个动物,所以不知道是否有这将避免而仍然使用purrrdplyr编写很多代码不同行更有效的方法?

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

+0

最终结果是你想为每个数据集中的每种动物分别使用csv文件吗?在你的真实情况下,你的数据集是否类似(即它们包含相同的变量)? – aosmith

回答

2

如果我正确理解你的问题,你想要写一个单独的文件为每两个数据帧的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

2

写入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,这些名称被添加为一个新的列,id

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

的最后一步是写入每个分割到一个单独的csv文件之前通过idAnimal组合data.frame分裂。信息从数据集中提取出来,用数据集和动物命名单个文件(这就是命名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中,但我在最后命名文件时遇到了麻烦。