Frage

Ich habe zwei Datenrahmen df1 und df2 Das hat jeweils rund 10 Millionen Zeilen und 4 Säulen. Ich las sie mit Rodbc/sqlQuery ohne Probleme in R ein, aber wenn ich es versuche, versuche ich es rbind Ich bekomme das am meisten gefürchtete R -Fehlermeldungen: cannot allocate memory. Es muss effizientere Möglichkeiten geben, eine zu tun rbind Effizienter - hat jemand seine Lieblingstricks dazu, die er teilen möchte? Zum Beispiel fand ich dieses Beispiel im DOC für sqldf:

# rbind
a7r <- rbind(a5r, a6r)
a7s <- sqldf("select * from a5s union all select * from a6s")

Ist das der beste/empfohlene Weg, dies zu tun?

AKTUALISIERENIch habe es mit dem entscheidenden zum Laufen gebracht dbname = tempfile() Argument in der sqldf Rufen Sie oben an, wie JD Long in seiner Antwort darauf vorschlägt diese Frage

War es hilfreich?

Lösung

Anstatt sie am Anfang in R zu lesen und sie dann zu kombinieren, könnten Sie SQLite lesen lassen und kombinieren, bevor Sie sie an R senden, auf diese Weise werden die Dateien niemals individuell in R geladen.

# create two sample files
DF1 <- data.frame(A = 1:2, B = 2:3)
write.table(DF1, "data1.dat", sep = ",", quote = FALSE)
rm(DF1)

DF2 <- data.frame(A = 10:11, B = 12:13)
write.table(DF2, "data2.dat", sep = ",", quote = FALSE)
rm(DF2)

# now we do the real work
library(sqldf)

data1 <- file("data1.dat")
data2 <- file("data2.dat")

sqldf(c("select * from data1", 
 "insert into data1 select * from data2", 
 "select * from data1"), 
 dbname = tempfile())

Das gibt:

>  sqldf(c("select * from data1", "insert into data1 select * from data2", "select * from data1"), dbname = tempfile())
   A  B
1  1  2
2  2  3
3 10 12
4 11 13

Diese kürzere Version funktioniert auch, wenn die Zeilenbestellung unwichtig ist:

sqldf("select * from data1 union select * from data2", dbname = tempfile())

Siehe die SQLDF -Startseite http://sqldf.googlecode.com und ?sqldf Für mehr Information. Achten Sie besonders auf die Argumente des Dateiformates, da sie eng, aber nicht identisch sind mit read.table. Hier haben wir die Standardeinstellungen verwendet, also war es weniger ein Problem.

Andere Tipps

Beachten Sie die data.table R -Paket für effiziente Vorgänge bei Objekten mit über mehreren Millionen Datensätzen.

Version 1.8.2 dieses Pakets bietet die rbindlist Funktion, durch die Sie das erreichen können, was Sie sehr effizient wollen. Also statt von rbind(a5r, a6r) du kannst:

library(data.table)
rbindlist(list(a5r, a6r))

Versuchen Sie, a zu erstellen data.frame der gewünschten Größe, importieren Sie daher Ihre Daten mit Einweisungen.

dtf <- as.data.frame(matrix(NA, 10, 10))
dtf1 <- as.data.frame(matrix(1:50, 5, 10, byrow=TRUE))
dtf2 <- as.data.frame(matrix(51:100, 5, 10, byrow=TRUE))
dtf[1:5, ] <- dtf1
dtf[6:10, ] <- dtf2

Ich vermute, dass rbind Das Objekt wächst, ohne seine Dimensionen zu verbessern ... Ich bin mir nicht sicher sicher, dass dies nur eine Vermutung ist. Ich werde heute Abend "The R Inferno" oder "Datenmanipulation mit R" niederkämmen. Vielleicht merge Wird den Trick machen ...

BEARBEITEN

Und Sie sollten bedenken, dass Ihr System und/oder R (vielleicht) nicht mit etwas so Großem fertig werden können. Versuchen Sie es mit Revolutionr, vielleicht können Sie Zeit/Ressourcen verschaffen.

Für die Vollständigkeit in diesem Thread zum Thema Union: Ing große Dateien verwenden Sie Shell -Befehle in den Dateien, um sie zu kombinieren. In Windows, das den Befehl "Kopieren" mit "/B" -Flag ist. Beispiel:

system(command =
         paste0(
           c("cmd.exe /c COPY /Y"
             , '"file_1.csv" /B'
             , '+ "file_2.csv" /B'
             , '"resulting_file.csv" /B'
           ), collapse = " "
         )
)#system

Erfordert, dass Dateien keinen Kopfzeile haben und gleiche Trennzeichen usw. usw. Die Geschwindigkeit und Vielseitigkeit von Shell-Befehlen sind manchmal ein großer Vorteil. Vergessen Sie also nicht die Cli-Commands, wenn Sie Datenflows abbilden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top