2017-10-12 2 views
2

Enfin, je viens à un problème que le traitement des données très lent et l'ajout de lignes de data.frames. J'utilise lapply et dplyr combinaison pour le traitement des données. OTH, le processus devient très lent car j'ai 20000 lignes dans chaque trame de données multiplié par 100 fichiers dans le répertoire.Comment traiter et combiner data.frames dans une liste avec plus rapidement

Actuellement c'est un col de bouteille énorme pour moi même après lapply finitions de processus je n'ai pas assez de mémoire au processus bind_rows.

Voici ma méthode de traitement de données,

d'abord une liste des fichiers

files <- list.files("file_directory",pattern = "w.*.csv",recursive=T,full.names = TRUE) 

transformons cette liste de fichiers

library(tidyr) 
    library(dplyr) 

data<- lapply(files,function(x){ 
    tmp <- read.table(file=x, sep=',', header = T,fill=F,skip=0, stringsAsFactors = F,row.names=NULL)%>% 

     select(A,B, C)%>% 
     unite(BC,BC,sep='_')%>% 

     mutate(D=C*A)%>% 
     group_by(BC)%>% 
     mutate(KK=median(C,na.rm=TRUE))%>% 
     select(BC,KK,D) 
    }) 

data <- bind_rows(data) 

Je reçois une erreur qui dit,

“Error: cannot allocate vector of size ... Mb” ... depends on how much left in my ram. I have 8 Gb ram but seems still struggling;(

J'ai aussi essayé do.call mais rien n'a changé! Qui est ma fonction ou approche amicale pour ce problème? J'utilise R version 3.4.2 et dplyr 0.7.4.

+2

Essayez d'utiliser les fonctions data.table (fread, mise à jour par référence, etc). Je suggère également de lire les fichiers sans manipulation de furrther, puis rbind avec un id et puis exécutez l'analyse une seule fois, regroupés par "BC" et votre nouvel ID de fichier. –

+0

@ r2evans Merci pour les commentaires. Que voulez-vous dire par «ne jamais l'utiliser», je suppose que l'opérateur '%>%' passe tous les fichiers de la liste après avoir lu la fonction 'select'? – Alexander

+0

Vous avez une erreur? Attention? Quelle indication avez-vous que quelque chose ne va pas? Vous devez fournir plus d'informations. Alexander, désolé, le premier '%>%' était un peu hors de l'écran vers la droite quand je l'ai commenté. (Vous devez également inclure tous les paquets utilisés, probablement au moins 'dplyr' et' tidyr'.) – r2evans

Répondre

4

Je ne peux pas tester cette réponse car il n'y a pas de données reproductibles, mais je suppose que cela pourrait être quelque chose comme ce qui suit, en utilisant data.table:

library(data.table) 

data <- setNames(lapply(files, function(x) { 
    fread(x, select = c("A", "B", "C")) 
}), basename(files)) 

data <- rbindlist(data, use.names = TRUE, fill = TRUE, id = "file_id") 
data[, BC := paste(B, C, sep = "_")] 
data[, D := C * A] 
data[, KK := median(C, na.rm = TRUE), by = .(BC, file_id)] 
data[, setdiff(names(data), c("BC", "KK", "D")) := NULL] 
+0

Parfait pour moi pour commencer ! Vraiment apprécié! – Alexander

2

En utilisant ldply du paquet plyr éliminerait la nécessité de lier la liste après le traitement car il sortira un data.frame

library(tidyr) 
library(dplyr) 
library(plyr) 

files <- list.files("file_directory", pattern = "w.*.csv", recursive = TRUE, full.names = TRUE) 

data<- ldply(files, function(x){ 
    read.table(file=x, sep=',', header = TRUE, fill = FALSE, skip = 0, stringsAsFactors = FALSE, row.names = NULL) %>% 
    select(A, B, C) %>% 
    unite(BC, BC, sep='_') %>% 
    mutate(D = C * A) %>% 
    group_by(BC) %>% 
    mutate(KK = median(C, na.rm = TRUE)) %>% 
    select(BC, KK, D) 
}) 
+0

Merci l'homme. Je vais comparer les vitesses et faire un retour des résultats ici dès que possible! – Alexander

+1

Si les fichiers sont volumineux, typiquement 'data.table' fonctionnera plus vite, mais' ldply' a une option '.parallel' qui offre une augmentation de vitesse d'environ 50% lors de la lecture d'un grand nombre de fichiers. – manotheshark

+0

merci l'homme! Je garderai ça à l'esprit! – Alexander