La coupe d'un énorme (3.5 GO) fichier csv à lire dans la R
Donc j'ai un fichier de données (point-virgule de séparation) qui a beaucoup de détails et de lignes incomplètes (leader Access et SQL pour étouffer). C'est le comté de données au niveau de l'ensemble cassée dans les segments, les sous-segments et sous-sous-segments (pour un total de ~200 facteurs) pour 40 ans. En bref, c'est énorme, et il ne va pas tenir en mémoire si j'essaie simplement de le lire.
Donc ma question est, étant donné que je veux que tous les comtés, mais seulement une seule année (et seulement le plus haut niveau de segment... conduisant à environ 100 000 lignes à la fin), ce qui serait la meilleure façon de s'y prendre pour obtenir ce correctif cumulatif dans la R?
Actuellement, je suis en train de annulerait pas pertinent ans avec Python, obtenir autour de la taille limite par la lecture et l'exploitation sur une seule ligne à la fois, mais je préfère une R solution (CRAN paquets OK). Est-il une manière similaire à lire dans les fichiers d'un morceau à un moment dans la R?
Toutes les idées seraient grandement appréciés.
Mise à jour:
- Contraintes
- Doit utiliser mon de la machine, de sorte qu'aucune des instances EC2
- Que le R-seulement que possible. La vitesse et les ressources ne sont pas des préoccupations dans ce cas... à condition de ma machine n'explose pas...
- Comme vous pouvez le voir ci-dessous, les données contiennent les types mixtes, dont il a besoin pour fonctionner sur plus tard
- Données
- Les données est de 3,5 GO, avec environ 8,5 millions de lignes et de 17 colonnes
- Quelques milliers de lignes (~2k) sont mal formés, avec une seule colonne au lieu de 17
- Celles-ci sont totalement sans importance et peut être supprimée
- J'ai seulement besoin d'environ 100 000 lignes de ce fichier (Voir ci-dessous)
De données exemple:
County; State; Year; Quarter; Segment; Sub-Segment; Sub-Sub-Segment; GDP; ...
Ada County;NC;2009;4;FIRE;Financial;Banks;80.1; ...
Ada County;NC;2010;1;FIRE;Financial;Banks;82.5; ...
NC [Malformed row]
[8.5 Mill rows]
Je veux hacher quelques colonnes et de choisir deux des 40 années disponibles (2009-2010 de 1980-2020), de sorte que les données peuvent tenir dans R:
County; State; Year; Quarter; Segment; GDP; ...
Ada County;NC;2009;4;FIRE;80.1; ...
Ada County;NC;2010;1;FIRE;82.5; ...
[~200,000 rows]
Résultats:
Après bricoler avec toutes les suggestions faites, j'ai décidé que readLines, suggéré par JD et Marek, serait le mieux. J'ai donné Marek le vérifier parce qu'il a donné un exemple de mise en œuvre.
J'en ai reproduit un peu adapté la version de Marek mise en œuvre, pour ma dernière réponse ici, en utilisant strsplit et chat pour ne garder que les colonnes que je veux.
Il convient également de noter c'est BEAUCOUP moins efficace que le Python... comme dans, Python chomps de 3.5 GO de fichiers dans 5 minutes alors que la R prend environ 60... mais si tout ce que vous avez est R, alors c'est le billet.
## Open a connection separately to hold the cursor position
file.in <- file('bad_data.txt', 'rt')
file.out <- file('chopped_data.txt', 'wt')
line <- readLines(file.in, n=1)
line.split <- strsplit(line, ';')
# Stitching together only the columns we want
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
## Use a loop to read in the rest of the lines
line <- readLines(file.in, n=1)
while (length(line)) {
line.split <- strsplit(line, ';')
if (length(line.split[[1]]) > 1) {
if (line.split[[1]][3] == '2009') {
cat(line.split[[1]][1:5], line.split[[1]][8], sep = ';', file = file.out, fill = TRUE)
}
}
line<- readLines(file.in, n=1)
}
close(file.in)
close(file.out)
Échecs en Approche:
- sqldf
- C'est certainement ce que je vais utiliser pour ce type de problème dans l'avenir si les données sont bien formées. Toutefois, si elle ne l'est pas, alors SQLite étouffe.
- MapReduce
- Pour être honnête, les docs m'intimide sur ce un peu, donc je n'ai pas l'obtenir autour de l'essayer. Il a regardé comme il nécessaire que l'objet soit dans la mémoire, ce qui irait à l'encontre du point de si c'était le cas.
- bigmemory
- Cette approche proprement liées aux données, mais il ne peut gérer qu'un seul type à la fois. En conséquence, tous les mon personnage vecteurs a chuté lors de la mettre en une grande.table. Si j'en ai besoin pour la conception de grands ensembles de données pour l'avenir, cependant, je voudrais examiner uniquement à l'aide de chiffres, juste pour garder cette option en vie.
- analyse
- Scan semblait avoir les mêmes type de questions, comme une grande mémoire, mais avec toute la mécanique de readLines. En bref, il n'a tout simplement pas s'adapter à la facture de ce temps.
sed
et/ou awk
pour créer un coupé-bas version de la CSV que vous pouvez lire directement. Depuis c'est plus une solution de contournement que d'une réponse, je vais laisser un commentaire.Je suis d'accord avec Hank - vous devez utiliser le bon outil pour le travail, et si c'est simple de nettoyage des données/retrait hors de propos lignes/colonnes de la ligne de commande de flux des outils comme le tri/sed/awk sont grands et vont être moyen moins de ressources que R ou python - si vous donnez un échantillon de vos fichiers de format, on pourrait sans doute donner un exemple
Grand. Laissez-nous savoir ce que vous découvrez.
Aaron: je suis en général tous pour utiliser le bon outil pour le travail, mais étant donné que c'est sur une machine Windows à travailler et je suis en apprentissage R que je vais, j'ai pensé qu'il serait un bon exercice de renoncer à des pratiques exemplaires et d'essayer cela comme de la R-seulement si cela est possible.
Pour référence future, vérifier les données.tableau R package. Le
fread
fonction est beaucoup plus rapide que read.table
. Utilisez quelque chose comme x = fread(file_path_here, data.table=FALSE)
pour le charger comme un data.frame
objet.
OriginalL'auteur FTWynn | 2010-06-22
Vous devez vous connecter pour publier un commentaire.
Ma essayer avec
readLines
. Ce morceau de code créecsv
avec les années.OriginalL'auteur Marek
Oui. Le readChar() fonction va lire dans un bloc de caractères sans en supposant qu'ils sont null. Si vous voulez lire des données dans une ligne à la fois vous pouvez utiliser readLines(). Si vous lisez un bloc ou une ligne, faire une opération, puis écrire les données, vous pouvez éviter le problème de mémoire. Bien que si vous avez envie de tirer jusqu'à une mémoire grande instance Amazon EC2, vous pouvez obtenir jusqu'à 64 GO de RAM. Que doit contenir votre fichier plus beaucoup de place pour manipuler les données.
Si vous avez besoin de plus de vitesse, puis Shane recommandation de l'utilisation de la Carte de Réduire est un très bon produit. Toutefois, si vous allez l'itinéraire de l'utilisation d'une mémoire grande instance EC2, vous devriez regarder la multicœur package pour l'utilisation de toutes les carottes sur une machine.
Si vous vous trouvez vouloir lire de nombreux concerts de données délimitées dans R, vous devriez au moins la recherche de la sqldf package qui permet d'importer directement dans sqldf de R et puis de travailler sur les données de l'intérieur R. j'ai trouvé sqldf pour être l'un des moyens les plus rapides pour importer des concerts de données dans R, comme mentionné dans cette question précédente.
OriginalL'auteur JD Long
Je ne suis pas un expert, mais vous pourriez envisager d'essayer MapReduce, qui serait fondamentalement signifie "diviser et conquérir". R dispose de plusieurs options, notamment:
Sinon, R fournit plusieurs paquets à traiter avec de grandes données qui vont à l'extérieur de la mémoire (sur le disque). Vous pourriez probablement charger la totalité du jeu de données dans un
bigmemory
de l'objet et de faire de la réduction complètement à l'intérieur de R. Voir http://www.bigmemory.org/ pour un ensemble d'outils pour gérer cela.bigmemory
peut être plus facile pour vous d'essayer tout d'abord, dans ce cas.OriginalL'auteur Shane
La
ff
package est une manière transparente pour traiter de gros fichiers.Vous pouvez voir le package site web et/ou un présentation à ce sujet.
J'espère que cette aide
OriginalL'auteur Ali
Vous pourriez importer des données dans une base de données SQLite et ensuite utiliser RSQLite pour sélectionner des sous-ensembles.
OriginalL'auteur Marek
Il y a un tout nouveau pack appelé colbycol qui vous permet de lire uniquement les variables que vous voulez à partir d'énormes fichiers de texte:
http://colbycol.r-forge.r-project.org/
Il passe tous les arguments pour lire.de la table, de sorte que la combinaison devrait vous laisser sous-ensemble assez étroitement.
OriginalL'auteur Ari B. Friedman
Que sur l'utilisation de
readr
et laread_*_chunked
famille?Donc dans votre cas:
testfile.csv
Code
Cela s'applique
f
à chaque morceau, se souvenant de la col-des noms et en combinant les résultats filtrés à la fin. Voir?rappel
qui est la source de cet exemple.Il en résulte:
Vous pouvez même augmenter
chunk_size
mais dans cet exemple, il y a seulement 4 lignes.OriginalL'auteur Rentrop
Avez-vous consisered bigmemory ?
Découvrez cette et cette.
OriginalL'auteur George Dontas
Peut-être vous pouvez migrer vers MySQL ou PostgreSQL pour prévenir vous-même à partir de MS Access limites.
Il est assez facile de se connecter R de ces systèmes avec une DBI (disponible sur CRAN) de la base de données du connecteur.
OriginalL'auteur FloE
scan() possède à la fois une nlines argument et un saut de l'argument. Est-il une raison, vous pouvez l'utiliser pour lire dans un morceau de lignes de temps, vérifier la date pour voir si c'est approprié? Si le fichier d'entrée est commandée par date, vous pouvez stocker un index qui vous dit que votre saut et nlines devrait être qui permettrait d'accélérer le processus à l'avenir.
Je pense que vous avez mal compris sa proposition: lire votre fichier de morceau par morceau, et d'en extraire uniquement les lignes dont vous avez besoin à partir de chaque morceau. Les fichiers ne doivent pas être commandés.
OriginalL'auteur frankc
Ces jours-ci, 3,5 GO n'est tout simplement pas vraiment gros, je peux avoir accès à une machine avec 244GB RAM (r3.8xlarge) sur le cloud d'Amazon pour $2.80/heure. Combien d'heures faut-il vous de trouver comment résoudre le problème en utilisant de grands volumes de données type de solutions? De combien est la valeur de votre temps? Oui, il va vous prendre une heure ou deux pour comprendre comment l'utiliser AWS - mais vous pouvez apprendre les bases sur un niveau gratuit, télécharger les données et de lire le premier 10k lignes en R pour vérifier cela a fonctionné, et ensuite vous pouvez lancer une mémoire grande instance de celle-r3.8xlarge et de lire tout cela! Juste mon 2c.
OriginalL'auteur Sean
Maintenant, en 2017, je vous suggère d'aller pour la spark et la sparkR.
la syntaxe peut être écrit dans un simple plutôt dplyr-manière similaire
elle s'adapte assez bien à la mémoire de petite taille (petite, dans le sens de 2017)
Cependant, il peut être une expérience intimidante pour commencer...
OriginalL'auteur Ott Toomet
Je pencherais pour un DB et ensuite en faire des requêtes pour extraire les échantillons dont vous avez besoin via DBI
S'il vous plaît éviter l'importation d'un 3,5 GO de fichier csv dans SQLite. Ou au moins le double de vérifier que votre ÉNORME db s'inscrit dans SQLite limites, http://www.sqlite.org/limits.html
C'est un putain de gros DB que vous avez. Je pencherais pour MySQL si vous avez besoin de vitesse. Mais être prêts à attendre des heures et des heures pour l'importation à la fin. Sauf si vous avez non conventionnelles de matériel ou de vous écrire à partir de l'avenir...
Amazon EC2 pourrait être une bonne solution aussi pour l'instanciation d'un serveur exécutant de la R et MySQL.
mes deux humbles pièces d'un cent de la valeur.
OriginalL'auteur Liborio Francesco Cannici