[R-es] Familia *pply

Carlos Ortega cof en qualityexcellence.es
Sab Mar 21 17:11:06 CET 2015


Hola Fernando,

No, no sabía a priori si iba a ser más rápido o más lento.
Utilicé la estructura de Sys.time() que tenías construida en tu ejemplo
para medir los resultados.

Y como recomendación, hay muchos blogs que hablan de como programar de
forma eficiente R.
Pero si buscas un libro, acabo de leer este y me parece que lo trata muy
bien:

http://www.amazon.es/High-Performance-Programming-Aloysius-Lim/dp/1783989262/ref=sr_1_1?ie=UTF8&qid=1426953979&sr=8-1&keywords=R+high+performance+programming

Saludos,
Carlos Ortega
www.qualiytexcellence.es

El 21 de marzo de 2015, 14:11, Fernando Macedo <fermace en gmail.com> escribió:

>  Muchas gracias a ambos Carlos y Jorge por las respuestas. Pido disculpas
> en la demora de respuesta, pero estuvo complicada la semana.
>
> La pregunta era un ejercicio de ejemplo para poder entender mejor los
> usos, creo que me armaré una guía en markdown con ejemplos varios para ir
> consultando cuando me salgan dudas de como usarlos.
>
> En realidad no importaba tanto si mejorara demasiado los tiempos sino el
> cómo se podría implementar una solución en base a la familia; pero a
> propósito Carlos, sabias de antemano que no mejoraría los tiempos? si sí,
> como evalúas previamente si el uso de una función de la familia tendrá
> mejor desempeño que un for()?
> Si me pueden recomendar algún material de lectura más profundo sobre este
> tema sería de mucha ayuda.
>
> Muchísimas gracias!
>
> Abrazos!
>
> Fernando Macedo
>
> El 18/03/15 a las 22:03, Carlos Ortega escribió:
>
>  Hola,
>
>  Una forma de hacerlo es así (destaco en negrita los cambios).
>  De todas formas, ya te adelanto que no es un caso en el que aplicar, en
> este caso "mapply()", mejore los tiempos frente a la solución basada en un
> bucle.
>
> #-------------------------
> t1 <- Sys.time()
>
> *myfun <- function(x,y) { data[x,y] }*
>
> medias <- replicate(1000,{
>   sel <- sample(1:20,10)
>   pareja <- sample(sel,100,replace = T)
>   ta <- Sys.time()
>
>
> *#cambio    resnew <- mapply(myfun, pareja, col)  #cambio *
>   tb <- Sys.time()
>   media <- mean(resnew)
>   tt <- tb-ta
>   c(media,tt)
> })
>
> t2 <- Sys.time()
>
> diftime=(t2-t1)[[1]]
> diftime
>
> sum(medias[2,])/diftime
>
> #-------------------------
>
>
>
>  Saludos,
>  Carlos Ortega
>  www.qualiytexcellence.es
>
> El 19 de marzo de 2015, 1:14, Fernando Macedo <fermace en gmail.com>
> escribió:
>
>> Hola Jorge, muchas gracias por tu pronta respuesta, no me di cuenta que
>> el formateo podría causar problemas, envío de nuevo el código sin
>> formatos.
>> La idea básica es para un set de números de columnas (desordenados) y un
>> set de numeros de fila el loop lo que hace es ir a la fila y columna
>> correspondiente de data, tomar el valor y luego hacer la media sobre esos.
>>
>>
>>
>> data=matrix(rnorm(100*20),20,100)
>> col=sample(1:100,100)
>>
>> t1=Sys.time()
>> medias=replicate(1000,{
>>    sel=sample(1:20,10)
>>    pareja=sample(sel,100,replace = T)
>>    ta=Sys.time()
>>    recep=NULL
>>    for(i in 1:100){
>>      n=col[i]
>>      m=pareja[i]
>>      c=data[m,n]
>>      recep=c(recep,c)
>>    }
>>    tb=Sys.time()
>>    media=mean(recep)
>>    tt=tb-ta
>>    c(media,tt)
>> },simplify=T)
>>
>> t2=Sys.time()
>> diftime=(t2-t1)[[1]]
>>
>> sum(medias[2,])/diftime
>>
>>
>>
>> Fernando Macedo
>>
>> El 18/03/15 a las 21:06, Jorge I Velez escribió:
>> > Hola Fernando,
>> >
>> > No puedo ver las negritas, pero intuyo que lo que quieres es calcular
>> > la media por columnas?  Si es asi, hay dos maneras:
>> >
>> > 1. Usa colMeans(x), donde "x" es tu matriz de datos
>> > 2. Usa apply(x, 2, mean) donde "x" es tu matriz de datos
>> >
>> > Existe una tercera pero menos conocida posibilidad que es usando el
>> > paquete matrixStats.  Esta implementado en C en su mayoria y, de
>> > acuerdo con el autor, es mucho mas rapido que la familia *apply.  En
>> >
>> http://cran.r-project.org/web/packages/matrixStats/vignettes/matrixStats-methods.html
>> > puedes encontrar mas informacion.
>> >
>> > Saludos cordiales,
>> > Jorge.-
>> >
>> >
>> >
>> > 2015-03-19 11:01 GMT+11:00 Fernando Macedo <fermace en gmail.com
>> > <mailto:fermace en gmail.com>>:
>>  >
>> >     Buenas a todos. Desde hace un tiempo estoy tratando de aplicar las
>> >     funciones de la familia *pply en todo lo que puedo, pero todavía no
>> es
>> >     algo que me surja tan rápidamente o naturalmente al momento de los
>> >     loops
>> >     como usar for().
>> >     Conozco las ventajas de usar estas funciones y por eso mi intento de
>> >     hacerme de ellas.
>> >
>> >     Por ejemplo en este problema:
>> >
>> >         data=matrix(rnorm(100*20),20,100)
>> >         col=sample(1:100,100)
>> >
>> >         t1=Sys.time()
>> >
>> >         medias=replicate(1000,{
>> >            sel=sample(1:20,10)
>> >            pareja=sample(sel,100,replace = T)
>> >            ta=Sys.time()
>> >         *recep=NULL**
>> >         **  for(i in 1:100){**
>> >         **    n=col[i]**
>> >         **    m=pareja[i]**
>> >         **    c=data[m,n]**
>> >         **    recep=c(recep,c)**
>> >         **  }**
>> >         *  tb=Sys.time()
>> >            media=mean(recep)
>> >            tt=tb-ta
>> >            c(media,tt)
>> >         })
>> >
>> >         t2=Sys.time()
>> >
>> >         diftime=(t2-t1)[[1]]
>> >
>> >         sum(medias[2,])/diftime
>> >
>> >
>> >     la parte que está en negrita (si usé bien los Sys.time()) me
>> >     representa
>> >     (hice varias pruebas) aprox un 60% del tiempo total empleado.
>> >
>> >     Mi pregunta es, para este ejemplo ¿cómo plantearían una solución
>> >     usando
>> >     funciones *pply?
>> >     Y luego ver cuanto aumenta en el rendimiento del uso del tiempo.
>> >
>> >     De paso, la salida que obtengo es una matriz de 2 por 1000, cuando
>> >     sería
>> >     más interesante una matriz de 1000 por 2. Si se usa simplify = F
>> como
>> >     argumento de replicate() resulta en una lista. ¿Existe algún
>> argumento
>> >     que directamente obtenga una matriz de 1000 por 2? (Esto último
>> >     pensando
>> >     en de repente 100000 o 1000000 de repeticiones y salidas más
>> >     complejas).
>> >
>> >
>> >     Saludos!
>> >
>> >     --
>> >     Fernando Macedo
>> >
>> >
>> >             [[alternative HTML version deleted]]
>> >
>> >     _______________________________________________
>> >     R-help-es mailing list
>>  >     R-help-es en r-project.org <mailto:R-help-es en r-project.org>
>>  >     https://stat.ethz.ch/mailman/listinfo/r-help-es
>> >
>> >
>>
>>
>>         [[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