Quindi ho un file di dati (separato da punto e virgola) che ha molti dettagli e righe incomplete (che portano Access e SQL a soffocare). È un set di dati a livello di contea suddiviso in segmenti, sottosegmenti e sottosegmenti (per un totale di ~ 200 fattori) per 40 anni. In breve, è enorme e non entrerà nella memoria se provo a leggerlo semplicemente.
Quindi la mia domanda è questa, dato che voglio tutte le contee, ma solo un anno (e solo il livello più alto di segmento ... che porta a circa 100.000 righe alla fine), quale sarebbe il modo migliore per ottenere questo rollup in R?
Attualmente sto cercando di eliminare anni irrilevanti con Python, aggirando il limite di dimensione del file leggendo e operando su una riga alla volta, ma preferirei una soluzione solo R (pacchetti CRAN OK). Esiste un modo simile per leggere nei file un pezzo alla volta in R?
Tutte le idee notevolmente sarebbero apprezzate.
Aggiornare:
- Vincoli
- Ha bisogno di usare la mia macchina, quindi nessuna istanza EC2
- Solo R possibile. La velocità e le risorse non sono un problema in questo caso ... a condizione che la mia macchina non esploda ...
- Come puoi vedere di seguito, i dati contengono tipi misti, su cui devo operare in seguito
- Dati
- I dati sono di 3,5 GB, con circa 8,5 milioni di righe e 17 colonne
- Un paio di migliaia di righe (~ 2k) non sono corretti, con una sola colonna invece di 17
- Questi sono del tutto irrilevanti e possono essere eliminati
- Ho solo bisogno di ~ 100.000 righe da questo file (vedi sotto)
Esempio di dati:
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]
Voglio tagliare alcune colonne e scegliere due dei 40 anni disponibili (2009-2010 dal 1980-2020), in modo che i dati possano rientrare in 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]
Risultati:
Dopo aver armeggiato con tutti i suggerimenti fatti, ho deciso che readLines, suggerito da JD e Marek, avrebbe funzionato meglio. Ho dato il controllo a Marek perché ha fornito un'implementazione di esempio.
Ho riprodotto una versione leggermente adattata dell'implementazione di Marek per la mia risposta finale qui, usando strsplit e cat per mantenere solo le colonne che voglio.
Va anche notato che questo è MOLTO meno efficiente di Python ... come in, Python chomps attraverso il file da 3,5 GB in 5 minuti mentre R impiega circa 60 ... ma se tutto ciò che hai è R, questo è il biglietto.
## 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)
Fallimenti per approccio:
- sqldf
- Questo è sicuramente ciò che userò per questo tipo di problema in futuro se i dati sono ben formati. Tuttavia, se non lo è, SQLite soffoca.
- Riduci mappa
- Ad essere onesti, i documenti mi hanno intimidito un po 'su questo, quindi non sono riuscito a provarlo. Sembrava che richiedesse che anche l'oggetto fosse nella memoria, il che avrebbe vanificato il punto se fosse così.
- bigmemory
- Questo approccio è chiaramente collegato ai dati, ma può gestire solo un tipo alla volta. Di conseguenza, tutti i miei vettori di caratteri cadevano quando inseriti in un big.table. Se ho bisogno di progettare set di dati di grandi dimensioni per il futuro, prenderei in considerazione l'utilizzo di numeri solo per mantenere attiva questa opzione.
- scansione
- La scansione sembrava avere problemi di tipo simili a quelli della grande memoria, ma con tutti i meccanismi di readLines. In breve, questa volta non si adattava al conto.
sed
e / oawk
creare una versione ridotta del CSV che puoi leggere direttamente. Poiché questa è più una soluzione alternativa che una risposta, la lascio come commento.