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.
Si vos critères sont assez simples, vous pouvez probablement vous en sortir avec l'aide de 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