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.frames
um 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 d
mit n
Elementen.
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.files
erstellen , 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 for
Schleife, 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.csv
gegebenenfalls andere Datenimportfunktionen . readr::read_csv
oder data.table::fread
wird 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 mtcars
in 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 replicate
und 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.table
oder dplyr
es 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
, df3
und Sie diese in einer Liste möchten, können Sie get
sie , 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 mget
verwendet, um mehrere Objekte abzurufen und in einer benannten Liste zurückzugeben. Sein Gegenstück get
wird 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 rbind
fü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 cbind
oder dplyr::bind_cols
für Spalten.)
Um eine Liste von Datenrahmen zusammenzuführen (zu verbinden), können Sie diese Antworten sehen . Oft besteht die Idee darin, sie Reduce
mit 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 purrr
Paket und die alten plyr
l*ply
Funktionen 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 paste
und 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 d14
zu 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 .csv
Dateien 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 Siey1
undy2
in Ihrer globalen Umgebung und Ihr Datenrahmen ist nicht das, was Sie wollen.