Die anderen Antworten zeigen Ihnen , wie Sie eine Liste von data.frames zu machen , wenn Sie bereits eine Reihe von data.frames, zum Beispiel d1, d2.... Mit Rahmen sequentiell benannt Daten ein Problem, und sie in einer Liste setzen a Gute Lösung, aber es wird empfohlen, zu vermeiden, dass eine Reihe von data.frames überhaupt nicht in einer Liste enthalten sind .
Die anderen Antworten enthalten viele Details zum Zuweisen von Datenrahmen zu Listenelementen, zum Zugriff darauf usw. Wir werden dies auch hier ein wenig behandeln, aber der Hauptpunkt ist, dass Sie nicht warten müssen, bis Sie ein paar a haben data.framesum sie einer Liste hinzuzufügen. Beginnen Sie mit der Liste.
Der Rest dieser Antwort behandelt einige häufige Fälle, in denen Sie möglicherweise versucht sind, sequentielle Variablen zu erstellen, und zeigt Ihnen, wie Sie direkt zu Listen gelangen. Wenn Sie mit Listen in R noch nicht vertraut sind, lesen Sie möglicherweise auch Was ist der Unterschied zwischen [[und [beim Zugriff auf Elemente einer Liste? .
Listen von Anfang an
Erschaffe niemals d1 d2 d3, ... überhaupt nicht dn. Erstellen Sie eine Liste dmit nElementen.
Einlesen mehrerer Dateien in eine Liste von Datenrahmen
Dies ist beim Einlesen von Dateien ziemlich einfach. Vielleicht haben Sie Dateien data1.csv, data2.csv, ...in einem Verzeichnis. Ihr Ziel ist eine Liste der aufgerufenen data.frames mydata. Als erstes benötigen Sie einen Vektor mit allen Dateinamen. Sie können dies mit Einfügen (z. B. my_files = paste0("data", 1:5, ".csv")) list.fileserstellen , aber es ist wahrscheinlich einfacher, alle entsprechenden Dateien abzurufen : my_files <- list.files(pattern = "\\.csv$"). Sie können reguläre Ausdrücke verwenden, um die Dateien abzugleichen. Weitere Informationen zu regulären Ausdrücken finden Sie in anderen Fragen, wenn Sie dort Hilfe benötigen. Auf diese Weise können Sie alle CSV-Dateien abrufen, auch wenn sie keinem netten Namensschema folgen. Oder Sie können ein schickeres Regex-Muster verwenden, wenn Sie bestimmte CSV-Dateien aus einer Reihe von Dateien auswählen müssen.
Zu diesem Zeitpunkt verwenden die meisten R-Anfänger eine forSchleife, und daran ist nichts auszusetzen. Sie funktioniert einwandfrei.
my_data <- list()
for (i in seq_along(my_files)) {
my_data[[i]] <- read.csv(file = my_files[i])
}
Ein eher R-ähnlicher Weg, dies zu tun, ist mit lapply, was eine Abkürzung für das Obige ist
my_data <- lapply(my_files, read.csv)
Ersetzen Sie natürlich read.csvgegebenenfalls andere Datenimportfunktionen . readr::read_csvoder data.table::freadwird schneller sein, oder Sie benötigen möglicherweise auch eine andere Funktion für einen anderen Dateityp.
In beiden Fällen ist es praktisch, die Listenelemente so zu benennen, dass sie mit den Dateien übereinstimmen
names(my_data) <- gsub("\\.csv$", "", my_files)
# or, if you prefer the consistent syntax of stringr
names(my_data) <- stringr::str_replace(my_files, pattern = ".csv", replacement = "")
Aufteilen eines Datenrahmens in eine Liste von Datenrahmen
Das ist super einfach, die Basisfunktion split()erledigt das für Sie. Sie können durch eine Spalte (oder Spalten) der Daten oder durch alles andere, was Sie möchten, teilen
mt_list = split(mtcars, f = mtcars$cyl)
# This gives a list of three data frames, one for each value of cyl
Dies ist auch eine gute Möglichkeit, einen Datenrahmen zur Kreuzvalidierung in Teile zu zerlegen. Vielleicht möchten Sie sich mtcarsin Trainings-, Test- und Validierungsstücke aufteilen .
groups = sample(c("train", "test", "validate"),
size = nrow(mtcars), replace = TRUE)
mt_split = split(mtcars, f = groups)
# and mt_split has appropriate names already!
Simulieren einer Liste von Datenrahmen
Vielleicht simulieren Sie Daten, ungefähr so:
my_sim_data = data.frame(x = rnorm(50), y = rnorm(50))
Aber wer macht nur eine Simulation? Sie möchten dies 100 Mal, 1000 Mal, mehr tun! Sie möchten jedoch nicht 10.000 Datenrahmen in Ihrem Arbeitsbereich. Verwenden Sie sie replicateund fügen Sie sie in eine Liste ein:
sim_list = replicate(n = 10,
expr = {data.frame(x = rnorm(50), y = rnorm(50))},
simplify = F)
Insbesondere in diesem Fall sollten Sie auch überlegen, ob Sie wirklich separate Datenrahmen benötigen oder ob ein einzelner Datenrahmen mit einer "Gruppen" -Spalte genauso gut funktioniert. Verwenden data.tableoder dplyres ist ziemlich einfach, Dinge "nach Gruppe" mit einem Datenrahmen zu tun.
Ich habe meine Daten nicht in eine Liste aufgenommen :( Ich werde es beim nächsten Mal tun, aber was kann ich jetzt tun?
Wenn es sich um ein seltsames Sortiment handelt (was ungewöhnlich ist), können Sie sie einfach zuweisen:
mylist <- list()
mylist[[1]] <- mtcars
mylist[[2]] <- data.frame(a = rnorm(50), b = runif(50))
...
Wenn Sie in einem Muster namens Datenrahmen haben, zum Beispiel df1, df2, df3und Sie diese in einer Liste möchten, können Sie getsie , wenn Sie einen regulären Ausdruck , die Namen übereinstimmen schreiben können. Etwas wie
df_list = mget(ls(pattern = "df[0-9]"))
# this would match any object with "df" followed by a digit in its name
# you can test what objects will be got by just running the
ls(pattern = "df[0-9]")
# part and adjusting the pattern until it gets the right objects.
Wird im Allgemeinen mgetverwendet, um mehrere Objekte abzurufen und in einer benannten Liste zurückzugeben. Sein Gegenstück getwird verwendet, um ein einzelnes Objekt abzurufen und zurückzugeben (nicht in einer Liste).
Kombinieren einer Liste von Datenrahmen zu einem einzelnen Datenrahmen
Eine häufige Aufgabe besteht darin, eine Liste von Datenrahmen zu einem großen Datenrahmen zu kombinieren. Wenn Sie sie übereinander stapeln möchten, würden Sie sie rbindfür ein Paar verwenden, aber für eine Liste von Datenrahmen gibt es drei gute Möglichkeiten:
# base option - slower but not extra dependencies
big_data = do.call(what = rbind, args = df_list)
# data table and dplyr have nice functions for this that
# - are much faster
# - add id columns to identify the source
# - fill in missing values if some data frames have more columns than others
# see their help pages for details
big_data = data.table::rbindlist(df_list)
big_data = dplyr::bind_rows(df_list)
(Ähnlich mit cbindoder dplyr::bind_colsfür Spalten.)
Um eine Liste von Datenrahmen zusammenzuführen (zu verbinden), können Sie diese Antworten sehen . Oft besteht die Idee darin, sie Reducemit merge(oder einer anderen Verbindungsfunktion) zu verwenden, um sie zusammenzubringen.
Warum die Daten in eine Liste aufnehmen?
Setzen Sie ähnliche Daten in Listen , weil Sie ähnliche Dinge zu jedem Datenrahmen tun wollen, und Funktionen wie lapply, sapply do.call, das purrrPaket und die alten plyr l*plyFunktionen machen es einfach , das zu tun. Beispiele für Leute, die leicht Dinge mit Listen tun, sind überall in SO.
Selbst wenn Sie eine Low-for-Schleife verwenden, ist es viel einfacher, die Elemente einer Liste zu durchlaufen, als Variablennamen mit zu erstellen pasteund auf die Objekte mit zuzugreifen get. Auch einfacher zu debuggen.
Denken Sie an Skalierbarkeit . Wenn Sie wirklich nur drei Variablen benötigen, es ist in Ordnung zu verwenden d1, d2, d3. Aber wenn sich herausstellt, dass Sie wirklich 6 brauchen, ist das viel mehr Tippen. Und das nächste Mal, wenn Sie 10 oder 20 brauchen, finden Sie sich selbst kopieren und Codezeilen einfügen, vielleicht finden mit / ersetzen Änderungen d14zu d15, und Sie denken , das ist nicht , wie die Programmierung sein sollte . Wenn Sie eine Liste verwenden, beträgt der Unterschied zwischen 3 Fällen, 30 Fällen und 300 Fällen höchstens eine Codezeile - keine Änderung, wenn Ihre Anzahl von Fällen automatisch erkannt wird, z. B. wie viele .csvDateien sich in Ihrer befinden Verzeichnis.
Sie können die Elemente einer Liste benennen, falls Sie für den Zugriff auf Ihre Datenrahmen etwas anderes als numerische Indizes verwenden möchten (und Sie können beide verwenden, dies ist keine XOR-Option).
Insgesamt führt die Verwendung von Listen dazu, dass Sie saubereren, besser lesbaren Code schreiben, was zu weniger Fehlern und weniger Verwirrung führt.
=nicht<-drinnen verwendendata.frame(). Durch die Verwendung<-erstellen Siey1undy2in Ihrer globalen Umgebung und Ihr Datenrahmen ist nicht das, was Sie wollen.