2016-07-22 9 views
1

Ich bin ziemlich neu zu arbeiten mit Listen in R und habe eine kurze Frage, die auch mit purrr inspiziert. Unten sind als Beispiel zu kleine Beispieldatenrahmen.Wie purrr mit dplyr zu verwenden, um Listenelemente zu filtern und Listen in Excel zu exportieren

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) 

Bonus, wenn Sie können, umfassen, wie auf einmal Listenelemente anstelle umbenennen der Verwendung der zwei Zeilen unter:

names(Data1)[1:3] <- c("Client","Animals","Living") 
names(Data2)[1:3] <- c("Client","Animals","Living") 

Also das nächste, wenn ich jeden Datenrahmen von Animals filtern möchten und dann jeweils exportieren in eine Excel-Tabelle unten durch die beiden Zeilen von Code verwendet:

Data1 %>% filter(Animals=="Cat") %>% write.csv(.,file="Data1.csv") 
Data2 %>% filter(Animals=="Cat") %>% write.csv(.,file="Data2.csv") 

, jedoch effizienter zu sein, die ich beiden Datenrahmen in einebeitreten 10 und verwenden Sie purrr, um jeweils gleichzeitig zu filtern.

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

Für den obigen Code, werde ich mehr ~filter Linien für jedes Tier, verwenden Sie also nicht sicher, ob eine effizientere Art und Weise gibt es, die viele verschiedene Zeilen Code zu schreiben vermeiden, während immer noch purrr und dplyr mit?

Auch, wie verwende ich write.csv mit purrr. Ich kann die Liste entweder in eine Tabelle exportieren, aber ich bin mir nicht sicher, wie ich die Liste aufteilen soll, damit sie korrekt exportiert wird. Außerdem kann ich jedes Listenelement in separate Tabellen exportieren. Es wäre schön, für beide Situationen eine Lösung zu finden.

+0

Ist das Endergebnis eine separate CSV-Datei für jede Art von Tier aus jedem Datensatz? In Ihrer realen Situation sind Ihre Datensätze so ähnlich (d. H. Sie enthalten die gleichen Variablen)? – aosmith

Antwort

2

Wenn ich Ihre Frage richtig verstanden habe, wollen Sie für jede der Animals sowohl der Datenrahmen eine separate Datei schreiben:

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)) 

Wir werfen zunächst sowohl die Datenrahmen in DataList, benennen Sie dann die Spalten für beide Datenrahmen mit der ersten map, dann split sowohl die Datenrahmen von Animals und schließlich flatten die verschachtelte Liste.

Ich wünschte, ich könnte dies tun, ohne die Kette zu brechen, aber ich konnte keinen anderen Weg finden.

Von hier aus benennen wir zuerst die Elemente der Liste um, dann verwenden Sie lapply, um alle Elemente in der Liste zu durchlaufen und wenden Sie write.csv auf jedem von ihnen an. zum Schreiben von Excel-Dateien aus R

2

Hier ist eine Möglichkeit, an denen die Bindung der beiden Datensätze zusammen vor dem erneuten Spaltung Sie können ebenso leicht write.csv mit eine der Funktionen ersetzen -

Sie erwähnten 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)) 

Die erste map Linie zeigt, wie die Spalten aller Datensätze in einer Liste auf einmal über setNames umbenennen.

DataList %>% 
    map(~setNames(.x, c("Client","Animals","Living"))) 

Ich habe dann die Namen der Datensätze in der Liste über setNames. Beim Stapeln der Datensätze in einem einzigen Daten.Rahmen über dplyrs bind_rows, diese Namen werden als neue Spalte hinzugefügt, id.

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

Der letzte Schritt ist die kombinierte data.frame durch idAnimal und vor dem Schreiben jedes geteilten in eine separate CSV-Datei zu trennen. Informationen werden aus dem Dataset herausgezogen, um die einzelnen Dateien nach Dataset und Tier zu benennen (dies war der Grund, die Elemente von DataList zu benennen). Ich habe die id Variable über select vor dem Schreiben der Dateien entfernt, da es für Ihre Bedürfnisse nicht relevant sein kann.

split(list(.$id, .$Animals), drop = TRUE) %>% 
map(~select(.x, -id) %>% 
      write.csv(file = paste0(unique(.x$id), unique(.x$Animals), ".csv"), 
           row.names = FALSE)) 

Dies alles kann, ohne dass diese in einen einzigen data.frame zu setzen getan werden, aber ich hatte Probleme mit den Dateien am Ende zu benennen.

Verwandte Themen