Question

Je df1 et df2 deux données-cadres qui ont chacun environ 10 millions de lignes et 4 colonnes. Je les lis en utilisant R rodbc / sqlquery sans problème, mais lorsque je tente de les rbind, je reçois que la plus redoutée des messages d'erreur R: cannot allocate memory. Il y a eu à être des moyens plus efficaces pour faire un rbind plus efficacement - quelqu'un a leurs trucs préférés sur ce qu'ils veulent partager? Par exemple, je trouve cet exemple dans le doc pour sqldf:

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

Est-ce la meilleure / méthode recommandée pour le faire?

UPDATE Je l'ai au travail en utilisant l'argument dbname = tempfile() crucial dans l'appel sqldf ci-dessus, JD long suggère dans sa réponse à cette question

Était-ce utile?

La solution

Au lieu de les lire en R au début, puis en les combinant, vous pourriez avoir SQLite les lire et de les combiner avant de les envoyer à R. De cette façon, les fichiers ne sont jamais chargés individuellement dans R.

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

Cela donne:

>  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

Cette version plus courte fonctionne également si l'ordre des lignes est sans importance:

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

Voir la page d'accueil de sqldf http://sqldf.googlecode.com et ?sqldf pour plus d'informations. Portez une attention particulière aux arguments de format de fichier, car ils sont proches mais pas identiques à read.table. Ici, nous avons utilisé les paramètres par défaut de sorte qu'il était moins un problème.

Autres conseils

Notez que le package de R data.table pour des opérations efficaces sur les objets avec plus de plusieurs millions d'enregistrements.

Version 1.8.2 que les offres de package la fonction rbindlist à travers lequel vous pouvez réaliser ce que vous voulez de façon très efficace. Ainsi, au lieu de rbind(a5r, a6r) vous pouvez:

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

Essayez de créer une data.frame de taille souhaitée, importer donc vos données en utilisant les indices.

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

Je suppose que rbind pousse objet sans pré-allocation de ses dimensions ... Je suis, ce n'est pas positivement sûr qu'une supposition. Je peigne vers le bas « La R Inferno » ou « Manipulation de données avec R » ce soir. Peut-être merge fera l'affaire ...

EDIT

Et vous devriez nu à l'esprit que (peut-être) votre système et / ou R ne peuvent pas faire face à quelque chose de ce grand. Essayez RevolutionR, peut-être vous parvenez à épargner un certain temps / ressources.

Pour être complet dans ce fil sur le thème de l'union: ing gros fichiers, essayez d'utiliser des commandes shell sur les fichiers pour les combiner. Dans Windows qui commande « COPIE » avec le drapeau « / B ». Exemple:

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

Exige que les fichiers ont sans en-tête, et même delimiter etc etc. La vitesse et la polyvalence des commandes shell est parfois un grand avantage, donc ne pas oublier CLI-commandes lors de la cartographie des flux de données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top