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 <http://www.qualiytexcellence.es> > > El 19 de marzo de 2015, 1:14, Fernando Macedo <fermace en gmail.com > <mailto: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> > > <mailto: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> > <mailto: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 <mailto:R-help-es en r-project.org> > https://stat.ethz.ch/mailman/listinfo/r-help-es > > > > > -- > Saludos, > Carlos Ortega > www.qualityexcellence.es <http://www.qualityexcellence.es>[[alternative HTML version deleted]]
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]]
Muchas gracias! Algunos blogs sigo aunque no con la frecuencia que me gustaría. El libro me viene bien pues es en lo que me estoy metiendo, con datos de grandes dimensiones. Saludos!!! Fernando Macedo El 21/03/15 a las 13:11, Carlos Ortega escribió:> 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 <http://www.qualiytexcellence.es> > > El 21 de marzo de 2015, 14:11, Fernando Macedo <fermace en gmail.com > <mailto: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 <http://www.qualiytexcellence.es> >> >> El 19 de marzo de 2015, 1:14, Fernando Macedo <fermace en gmail.com >> <mailto: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> >> > <mailto: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> >> <mailto: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 <mailto:R-help-es en r-project.org> >> https://stat.ethz.ch/mailman/listinfo/r-help-es >> >> >> >> >> -- >> Saludos, >> Carlos Ortega >> www.qualityexcellence.es <http://www.qualityexcellence.es> > > > > > -- > Saludos, > Carlos Ortega > www.qualityexcellence.es <http://www.qualityexcellence.es>[[alternative HTML version deleted]]