[R-es] Mi script R es muy lento

Carlos Ortega cof en qualityexcellence.es
Sab Mayo 30 00:45:37 CEST 2015


Hola Mª Luz,

¿A qué tipo de cálculos complejos te refieres?.

Con data.table puedes definir operaciones (con la complejidad que quieras)
para un conjunto de filas, agrupándolas por columnas y más... Su sintaxis
es muy compacta pero a poco que la utilizas acabas encontrando la forma de
hacer las cosas sin muchos pasos intermedios. Pero puedes hacerlo menos
compacto y quizás más comprensible.

Y sobre la eficiencia de data.table comparándolo con otras alternativas
aquí viene una comparativa:
http://stackoverflow.com/questions/4322219/whats-the-fastest-way-to-merge-join-data-frames-in-r

Aunque desde la aparición de dplyr, la duda aparece sobre si es más
conveniente data.table o dplyr.
Aquí hay otro hilo que los compara, teniendo en cuenta diferentes atributos:

http://stackoverflow.com/questions/21435339/data-table-vs-dplyr-can-one-do-something-well-the-other-cant-or-does-poorly/27718317#27718317

¿Qué volúmen de datos quieres procesar?
Y...¿quieres algo más rápido que menos de un segundo?...

Saludos,
Carlos Ortega
www.qualityexcellence.es



El 29 de mayo de 2015, 15:50, MªLuz Morales <mlzmrls en gmail.com> escribió:

> Hola, quiero compartir con vosotros mi problema y la solución que me han
> planteado. Mi programa carga Outcomes.csv y Set-A.csv  (descargados de
> http://garrickadenbuie.com/blog/2013/04/11/visualize-physionet-data-with-r/
> ,
> apartado Getting Started --> the code and the data set) de unos 50MB entre
> los dos. Mi código era:
>
>
> #  Transforma csv a data frame
> seta <- read.csv('Set-A.csv');
> outcomes <- read.csv('Outcomes-A.csv');
>
> ids <- as.character(unique(outcomes$RecordID));
> ## Número de RecordsID distintos
> Length_ids <- length(ids); #número de RecordsID distintos
> ListaABP <- list('RecordID'=-1,'SAPS.I'=-1, 'SOFA'=-1, 'Survival'=-1,
> 'In.hospital_death'=-1, 'NISysABP_Min'=-1,'NISysABP_Max'=-1,
> 'NISysABP_Mean'=-1, 'NIDiasABP_Min'=-1,'NIDiasABP_Max'=-1,
> 'NIDiasABP_Mean'=-1,'NIMAP_Min'=-1,'NIMAP_Max'=-1, 'NIMAP_Mean'=-1);
> for (i in 1:Length_ids){#NumRecordID){   # Para cada paciente...
>
>   ListaABP$RecordID[i] <- outcomes$RecordID[i];
>   ListaABP$SAPS.I[i] <- outcomes$SAPS.I[i];
>   ListaABP$SOFA[i] <- outcomes$SOFA[i];
>   ListaABP$Survival[i] <- outcomes$Survival[i];
>   ListaABP$In.hospital_death[i] <- outcomes$In.hospital_death[i];
>
>   # Parameter == 'NISysBP'
>   #seta_NISysABP <- seta[seta$RecordID == ids[i] & seta$Parameter ==
> 'NISysABP' , c('RecordID','Value')] ;
>   seta_NISysABP <- seta[seta$RecordID == ids[i] & seta$Parameter ==
> 'NISysABP' , 'Value'] ; #Creo que esto ya no sería un dataframe, por lo que
> en la siguiente línea puede dar error
>   ListaABP$NISysABP_Min[i] <- min(seta_NISysABP);
>   ListaABP$NISysABP_Max[i] <- max(seta_NISysABP);
>   ListaABP$NISysABP_Mean[i] <- mean(seta_NISysABP);
>
>   # Parameter == 'NIDiasABP'
>   #seta_NIDiasABP <- seta[seta$RecordID == ids[i] & seta$Parameter ==
> 'NIDiasABP' , c('Time','Value')] ; #En este caso la forma de hacer el min
> sería ...min(seta_NIDiasABP$Value);
>   seta_NIDiasABP <- seta[seta$RecordID == ids[i] & seta$Parameter ==
> 'NIDiasABP' , 'Value'] ;
>   ListaABP$NIDiasABP_Min[i] <- min(seta_NIDiasABP);
>   ListaABP$NIDiasABP_Max[i] <- max(seta_NIDiasABP);
>   ListaABP$NIDiasABP_Mean[i] <- mean(seta_NIDiasABP);
>
>   # Parameter == 'NIMAP'
>   #seta_NIMAP <- seta[seta$RecordID == ids[i] & seta$Parameter == 'NIMAP' ,
> c('Time','Value')] ;
>   seta_NIMAP <- seta[seta$RecordID == ids[i] & seta$Parameter == 'NIMAP' ,
> 'Value'] ;
>   ListaABP$NIMAP_Min[i] <- min(seta_NIMAP);
>   ListaABP$NIMAP_Max[i] <- max(seta_NIMAP);
>   ListaABP$NIMAP_Mean[i] <- mean(seta_NIMAP);
>
> }#for i
>
> Tabla <- data.frame(ListaABP);
> #+++++++++++++++++++++++++++++++++++++++++++++++++
>
> Este código tardaba 3 horas en ejecutarse. La solución que me han propuesto
> es usar data.table en lugar de data.frame y ahora tarda 1 segundo
> aproximadamente en ejecutarse y es este:
>
> #-------------
> library(data.table)
> datSet <- fread("Set-A.csv")
> resOut <- datSet[, .(ValMax=max(Value), ValMin=min(Value),
> ValAvg=mean(Value)), by=c("RecordID","Parameter")]
> resOut$RecordID <- as.factor(resOut$RecordID)
> setkey(resOut, RecordID)
> head(datSet)
> datOutcome <- fread("Outcomes-A.csv")
> datOutcome$RecordID <- as.factor(datOutcome$RecordID)
> setkey(datOutcome, RecordID)
> head(datOutcome)
> #resEnd <- merge(resOut, datOutcome, by="RecordID", all=TRUE,
> allow.cartesian=FALSE)
> resEnd <- resOut[datOutcome]
> head(resEnd)
> setkey(resEnd, Parameter)
> #Ejemplo para conseguir uno o varios parametros.
> myRes <- resEnd[c("NISysABP","NIDiasABP","NIMAP")]
> head(myRes)
> #--------------
>
> Tengo una pregunta, data.table es lo más eficiente para procesar grandes
> cantidades de datos?, es fácil de manejar si quieres realizar cálculos
> complejos además de reorganizar tablas...??
>
> Gracias
> Un saludo
>
>         [[alternative HTML version deleted]]
>
> _______________________________________________
> R-help-es mailing list
> R-help-es en r-project.org
> https://stat.ethz.ch/mailman/listinfo/r-help-es
>



-- 
Saludos,
Carlos Ortega
www.qualityexcellence.es

	[[alternative HTML version deleted]]



Más información sobre la lista de distribución R-help-es