[R-es] Mi script R es muy lento

Carlos Ortega cof en qualityexcellence.es
Lun Jun 1 10:45:44 CEST 2015


Hola,

En el segundo link puedes ver más detalles de lo que han llegado a probar
con data.table y los tiempos de respuesta:

1. Speed

Quite a few benchmarks (though mostly on grouping operations) have been
added to the question already showing data.table gets *faster* than dplyr
as the number of groups and/or rows to group by increase, including benchmarks
by Matt
<https://github.com/Rdatatable/data.table/wiki/Benchmarks-%3A-Grouping> on
grouping from *10 million to 2 billion rows* (100GB in RAM) on *100 - 10
million groups* and varying grouping columns, which also compares pandas.
Y el "benchmarks by Matt" (Matt es uno de los autores del paquete) detalla
las pruebas de comparación con "dplyr" y con "pandas" (Python) y los costes
en el EC2 de Amazon:

https://github.com/Rdatatable/data.table/wiki/Benchmarks-%3A-Grouping

Saludos,
Carlos Ortega
www.qualityexcellence.es

El 1 de junio de 2015, 9:15, MªLuz Morales <mlzmrls en gmail.com> escribió:

> Hola Carlos,
> bueno la verdad es que mi pregunta era algo general, cuando no has usado
> data.table no parece muy intuitivo pasar de la forma de programar a la que
> estás más acostumbrado (bucles, notación matricial...) a esa otra. Aun no
> tengo un cálculo complejo concreto pero lo tendré que hacer... solo quería
> saber si se puede, y parece que sí, asi que será cuestión de empaparse un
> poco de data.tables
>
> Tendré que usar en un futuro próximo grandes cantidades de datos, GB...con
> plataforma como hadoop para  Big data, para ello data.table tb parece
> funcionar verdad?
>
> Gracias por los enlaces con las comparativas, son muy útiles
>
> Un saludo
> MªLuz
>
> Universidad Europea de Madrid
>
> El 30 de mayo de 2015, 0:45, Carlos Ortega <cof en qualityexcellence.es>
> escribió:
>
>> 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
>>
>
>


-- 
Saludos,
Carlos Ortega
www.qualityexcellence.es

	[[alternative HTML version deleted]]



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