J'ai donc un fichier de données (séparé par des points-virgules) qui contient beaucoup de détails et des lignes incomplètes (amenant Access et SQL à s'étouffer). Il s'agit d'un ensemble de données au niveau du comté divisé en segments, sous-segments et sous-sous-segments (pour un total d'environ 200 facteurs) pendant 40 ans. Bref, c'est énorme, et ça ne rentrera pas dans la mémoire si j'essaie simplement de le lire.
Donc ma question est la suivante, étant donné que je veux tous les comtés, mais seulement une seule année (et juste le plus haut niveau de segment ... conduisant à environ 100000 lignes à la fin), quelle serait la meilleure façon de procéder pour obtenir ce rollup en R?
Actuellement, j'essaie de couper les années non pertinentes avec Python, de contourner la limite de taille du fichier en lisant et en opérant sur une ligne à la fois, mais je préférerais une solution R-only (packages CRAN OK). Existe-t-il une manière similaire de lire dans les fichiers un morceau à la fois dans R?
Toutes les idées seraient grandement appréciées.
Mise à jour:
- Contraintes
- Doit utiliser ma machine, donc pas d'instance EC2
- Aussi R-seulement que possible. La vitesse et les ressources ne sont pas concernées dans ce cas ... à condition que ma machine n'explose pas ...
- Comme vous pouvez le voir ci-dessous, les données contiennent des types mixtes, sur lesquels je devrai opérer plus tard
- Les données
- Les données sont de 3,5 Go, avec environ 8,5 millions de lignes et 17 colonnes
- Quelques milliers de lignes (~ 2k) sont mal formées, avec une seule colonne au lieu de 17
- Ceux-ci sont totalement sans importance et peuvent être supprimés
- Je n'ai besoin que d'environ 100000 lignes de ce fichier (voir ci-dessous)
Exemple de données:
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 découper certaines colonnes et choisir deux des 40 années disponibles (2009-2010 de 1980-2020), afin que les données puissent 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 avoir bricolé toutes les suggestions faites, j'ai décidé que readLines, suggéré par JD et Marek, fonctionnerait le mieux. J'ai donné le chèque à Marek parce qu'il a donné un exemple d'implémentation.
J'ai reproduit une version légèrement adaptée de l'implémentation de Marek pour ma réponse finale ici, en utilisant strsplit et cat pour ne garder que les colonnes que je veux.
Il convient également de noter que c'est BEAUCOUP moins efficace que Python ... comme dans, Python parcourt le fichier de 3,5 Go en 5 minutes tandis que R en prend environ 60 ... mais si tout ce que vous avez est R, c'est le ticket.
## 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 par approche:
- sqldf
- C'est certainement ce que j'utiliserai pour ce type de problème à l'avenir si les données sont bien formées. Cependant, si ce n'est pas le cas, SQLite s'étouffe.
- MapReduce
- Pour être honnête, les documents m'ont un peu intimidé sur celui-ci, donc je n'ai pas essayé. Il semblait qu'il fallait que l'objet soit également en mémoire, ce qui irait à l'encontre du point si tel était le cas.
- grande mémoire
- Cette approche est clairement liée aux données, mais elle ne peut gérer qu'un seul type à la fois. En conséquence, tous mes vecteurs de caractères ont chuté lorsqu'ils sont placés dans une grande table. Si j'ai besoin de concevoir de grands ensembles de données pour l'avenir, j'envisagerais d'utiliser uniquement des nombres juste pour garder cette option en vie.
- analyse
- Scan semblait avoir des problèmes de type similaires à ceux de la grande mémoire, mais avec tous les mécanismes de readLines. En bref, cela ne correspondait tout simplement pas à la facture cette fois.
sed
et / ouawk
en créant une version réduite du CSV que vous pouvez lire directement. Puisqu'il s'agit plus d'une solution de contournement qu'une réponse, je vais le laisser en commentaire.