2016-04-17 2 views
3

Ceci est la suite de ce débordement de la pile précédente question:de nombreux fichiers .dat.gz sous-ensembles en utilisant fread et awk

Fastest way to read in 100,000 .dat.gz files

J'ai beaucoup de fichiers .dat.gz, mais la plupart des lignes dans cette les données ont des valeurs nulles que je veux éviter de mettre en mémoire.

Créer des données pour le cas de test:

# Make dir 
system("mkdir practice") 
require(data.table) 

# Function to create data 
create_write_data <- function(file.nm) { 
    dt <- data.table(Day=0:365) 
    dt[, (paste0("V", 1:17)) := lapply(1:17, function(x) rpois(n=366, 0.1))] 
    write.table(dt, paste0("./practice/",file.nm), row.names=FALSE, sep="\t", quote=FALSE) 
    system(paste0("gzip ./practice/", file.nm))  
} 

Et voici le code application:

# Apply function to create 10 fake zipped data.frames (550 kb on disk) 
tmp <- lapply(paste0("dt", 1:10,".dat"), function(x) create_write_data(x)) 

Ma solution (ne fonctionne pas)

La réponse liée Stack Overflow d'avant a donné ce grand répondre à la lecture de toutes les données à la fois:

tbl = fread('cat ./practice/*dat.gz | gunzip | grep -v "^Day"') 

Mais maintenant, je veux filtrer les données où les colonnes 14 et 15 sont à la fois 0, donc j'ai créé la canalisation suivante pour alimenter fread en utilisant une commande awk:

command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/ && $14 !=0 && $15 != 0'" 
fread(command) 

Cependant, ce ne filtre pas ma données du tout. Des idées sur la façon d'obtenir la commande awk pour travailler dans ce flux de travail?

+2

changer la 'grep' cmd-1 à être le awk cmd-2, comme' ... | awk -F, '/^Jour/&& $ 14! = 0 && $ 15! = 0' "'. (éliminant essentiellement cmd-2) Bonne chance – shellter

+0

Bonne suggestion! Il est logique de consolider cette étape. votre suggestion, mais l'étape de filtrage avec les variables 14 et 15 ne fonctionne toujours pas pour une raison quelconque –

+1

ok, mais mon but était d'éliminer cmd-2. Pourquoi avez-vous besoin? Si le cmd-1 travaillait avec le ' grep -v', il suffit de remplacer cela par le code awk modfied.À ce stade, je voudrais mettre en place un petit test pour confirmer que '$ 14 && $ 15' contiennent les valeurs que vous pensez qu'ils font.Bonne chance. – shellter

Répondre

0

Cette question a reçu une réponse dans les commentaires.

ok..it semble fonctionner avec les éléments suivants:
command <- "cat ./practice/*dat.gz | gunzip | awk -F, '!/^Day/' | awk '$14 != 0 || $15 != 0'"
Est-ce en prenant 2 passes les données? Il semble que cela pourrait ralentir les choses sur beaucoup de nombreux fichiers, mais cela semble fonctionner.

Non ce n'est pas 2 passages de données. C'est assez efficace. Mais il a manqué une autre optimisation mineure avant: vous pouvez simplifier encore à gunzip -c ./path/to/files*.dat.gz | awk ...