Hola. Necesito calcular los porcentajes de un valor dado (valores) como porcentaje de la suma de ese mismo valor pero agrupando por una tercera columna (en este caso, podría ser Mes-Año). El resultado sería el que se ve en la var: "EnR" Necesito además que ese resultado quede pegado en mi data.frame. Año Mes AñoMes Factor Valores enR 2015 1 2015-1 a 105 0.25 2015 1 2015-1 b 104 0.24 2015 1 2015-1 c 109 0.25 2015 1 2015-1 d 110 0.26 2015 2 2015-2 a 115 0.17 2015 2 2015-2 b 116 0.17 2015 2 2015-2 c 118 0.17 2015 2 2015-2 d 220 0.32 2015 2 2015-2 e 110 0.16 2015 3 2015-3 a 99 0.24 2015 3 2015-3 b 98 0.24 2015 3 2015-3 c 105 0.26 2015 3 2015-3 d 109 0.27 2016 1 2016-1 a 98 0.26 2016 1 2016-1 b 78 0.21 2016 1 2016-1 c 100 0.27 2016 1 2016-1 d 101 0.27 2016 2 2016-2 a 110 0.19 2016 2 2016-2 b 112 0.20 2016 2 2016-2 c 115 0.20 2016 2 2016-2 d 118 0.21 2016 2 2016-2 e 119 0.21 Imagino una forma "larga" de hacerlo, que sería aprox: c <- datos[ , .(SumPorGrupo=sum(Valores)), by= .(MesAño)] datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == datos$MesAño)] Pero como era de esperarse, no funciona :( Entonces, podría resolverlo usando SQL: datos$enRv <- sqldf("SELECT Valores/SumPorGrupo AS EnR FROM datosINNER JOIN c ON datos.MesAño = c.MesAño") Y ahí sí. Pero me parece que debe haber una función que lo haga directamente sobre el data.frame, ¿no? Luego, quisiera una forma "extendida", donde el resultado sea para las clases que definen dos variables (en el ejemplo, datos$Mes y datos$Año por separado). Para mi, si funcionara iría por: c <- datos[ , .SumPorGrupo=(sum(Valores)), by= .(Año, Mes)] datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == c(datos$Año, datos$mes)] De manera similar, ¿es posible usar cumsum(datos$Valores) también por grupos? Espero que se entiendan las consultas. Adjunto el ejemplo. Muchas gracias!! -- Mauricio ------------ próxima parte ------------ Se ha borrado un adjunto en formato HTML... URL: <https://stat.ethz.ch/pipermail/r-help-es/attachments/20160817/7c0aa1ab/attachment.html> ------------ próxima parte ------------ A non-text attachment was scrubbed... Name: datos.csv Type: text/csv Size: 602 bytes Desc: no disponible URL: <https://stat.ethz.ch/pipermail/r-help-es/attachments/20160817/7c0aa1ab/attachment.bin>
No tengo tiempo de mirar tu código ahora, pero para esas cosas dplyr suele funcinoar muy bien. https://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html 2016-08-17 16:31 GMT+02:00 Mauricio Monsalvo <m.monsalvo en gmail.com>:> Hola. > Necesito calcular los porcentajes de un valor dado (valores) como > porcentaje de la suma de ese mismo valor pero agrupando por una tercera > columna (en este caso, podría ser Mes-Año). El resultado sería el que se ve > en la var: "EnR" > Necesito además que ese resultado quede pegado en mi data.frame. > Año Mes AñoMes Factor Valores enR > 2015 1 2015-1 a 105 0.25 > 2015 1 2015-1 b 104 0.24 > 2015 1 2015-1 c 109 0.25 > 2015 1 2015-1 d 110 0.26 > 2015 2 2015-2 a 115 0.17 > 2015 2 2015-2 b 116 0.17 > 2015 2 2015-2 c 118 0.17 > 2015 2 2015-2 d 220 0.32 > 2015 2 2015-2 e 110 0.16 > 2015 3 2015-3 a 99 0.24 > 2015 3 2015-3 b 98 0.24 > 2015 3 2015-3 c 105 0.26 > 2015 3 2015-3 d 109 0.27 > 2016 1 2016-1 a 98 0.26 > 2016 1 2016-1 b 78 0.21 > 2016 1 2016-1 c 100 0.27 > 2016 1 2016-1 d 101 0.27 > 2016 2 2016-2 a 110 0.19 > 2016 2 2016-2 b 112 0.20 > 2016 2 2016-2 c 115 0.20 > 2016 2 2016-2 d 118 0.21 > 2016 2 2016-2 e 119 0.21 > Imagino una forma "larga" de hacerlo, que sería aprox: > c <- datos[ , .(SumPorGrupo=sum(Valores)), by= .(MesAño)] > datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == datos$MesAño)] > Pero como era de esperarse, no funciona :( > Entonces, podría resolverlo usando SQL: > datos$enRv <- sqldf("SELECT Valores/SumPorGrupo AS EnR FROM datosINNER > JOIN c ON datos.MesAño = c.MesAño") > Y ahí sí. Pero me parece que debe haber una función que lo haga > directamente sobre el data.frame, ¿no? > > Luego, quisiera una forma "extendida", donde el resultado sea para las > clases que definen dos variables (en el ejemplo, datos$Mes y datos$Año por > separado). > Para mi, si funcionara iría por: > c <- datos[ , .SumPorGrupo=(sum(Valores)), by= .(Año, Mes)] > datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == c(datos$Año, > datos$mes)] > > De manera similar, ¿es posible usar cumsum(datos$Valores) también por > grupos? > > Espero que se entiendan las consultas. > Adjunto el ejemplo. > Muchas gracias!! > -- > Mauricio > > _______________________________________________ > R-help-es mailing list > R-help-es en r-project.org > https://stat.ethz.ch/mailman/listinfo/r-help-es >[[alternative HTML version deleted]]
Para calculos sobre data.frame agrupando por niveles de una variable la libreria data.table va muy bien: > install.packages(data.table) > library(data.table) x ejemplo, con tu data.frame podrias calcular: tmp <- read.csv("datos.csv", header=TRUE) tmp <- as.data.table(tmp) tmp[, mean(Valores), by=Mes] Mes V1 1: 1 100.625 2: 2 125.300 3: 3 102.750 o por año tmp[, mean(Valores), by=Agno] Agno V1 1: 2015 116.7692 2: 2016 105.6667 la expresion mean(Valores) la puedes cambiar por el calculo que tu necesitas hacer. al leer el archivo tuve problemas con la Ñ, asi es que la cambie. Saludos, eric. On 08/17/2016 11:31 AM, Mauricio Monsalvo wrote:> Hola. > Necesito calcular los porcentajes de un valor dado (valores) como > porcentaje de la suma de ese mismo valor pero agrupando por una tercera > columna (en este caso, podría ser Mes-Año). El resultado sería el que se > ve en la var: "EnR" > Necesito además que ese resultado quede pegado en mi data.frame. > AñoMesAñoMesFactorValoresenR > 201512015-1a1050.25 > 201512015-1b1040.24 > 201512015-1c1090.25 > 201512015-1d1100.26 > 201522015-2a1150.17 > 201522015-2b1160.17 > 201522015-2c1180.17 > 201522015-2d2200.32 > 201522015-2e1100.16 > 201532015-3a990.24 > 201532015-3b980.24 > 201532015-3c1050.26 > 201532015-3d1090.27 > 201612016-1a980.26 > 201612016-1b780.21 > 201612016-1c1000.27 > 201612016-1d1010.27 > 201622016-2a1100.19 > 201622016-2b1120.20 > 201622016-2c1150.20 > 201622016-2d1180.21 > 201622016-2e1190.21 > Imagino una forma "larga" de hacerlo, que sería aprox: > c <- datos[ , .(SumPorGrupo=sum(Valores)), by= .(MesAño)] > datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == datos$MesAño)] > Pero como era de esperarse, no funciona :( > Entonces, podría resolverlo usando SQL: > datos$enRv <- sqldf("SELECT Valores/SumPorGrupo AS EnR FROM datosINNER > JOIN c ON datos.MesAño = c.MesAño") > Y ahí sí. Pero me parece que debe haber una función que lo haga > directamente sobre el data.frame, ¿no? > > Luego, quisiera una forma "extendida", donde el resultado sea para las > clases que definen dos variables (en el ejemplo, datos$Mes y datos$Año > por separado). > Para mi, si funcionara iría por: > c <- datos[ , .SumPorGrupo=(sum(Valores)), by= .(Año, Mes)] > datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == c(datos$Año, > datos$mes)] > > De manera similar, ¿es posible usar cumsum(datos$Valores) también por > grupos? > > Espero que se entiendan las consultas. > Adjunto el ejemplo. > Muchas gracias!! > -- > Mauricio > > > _______________________________________________ > R-help-es mailing list > R-help-es en r-project.org > https://stat.ethz.ch/mailman/listinfo/r-help-es >-- Forest Engineer Master in Environmental and Natural Resource Economics Ph.D. student in Sciences of Natural Resources at La Frontera University Member in AguaDeTemu2030, citizen movement for Temuco with green city standards for living Nota: Las tildes se han omitido para asegurar compatibilidad con algunos lectores de correo.
Hola Eric. Muchas gracias por tu respuesta. Intenté hacer lo mismo sobre una variable agregada a datos, de modo: datos$p_Valores <- datos[, Valores/sum(Valores), by=MesAño] pero no funciona, porque pega un data.table en una única variable: In `[<-.data.table`(x, j = name, value = value) : Supplied 2 items to be assigned to 5849 items of column 'pValores' (recycled leaving remainder of 1 items). El cálculo es correcto, pero si: head(datos) #Solo copio y pego la columna de interés: pValores 1: 2011-1,2011-1,2011-1,2011-1,2011-1,2011-1, 2: 0.17677003,0.08411600,0.06379952,0.05113864,0.04911275,0.04214248, 3: 2011-1,2011-1,2011-1,2011-1,2011-1,2011-1, 4: 0.17677003,0.08411600,0.06379952,0.05113864,0.04911275,0.04214248, 5: 2011-1,2011-1,2011-1,2011-1,2011-1,2011-1, 6: 0.17677003,0.08411600,0.06379952,0.05113864,0.04911275,0.04214248, Luego, puedo crear un objeto, tal como vos hacés, y luego darle pegar la segunda variable, que es la que contiene mis datos de interés. Pero sigue siendo una forma larga... debo crear, estimar y pegar (y siempre me da "miedo" pegar).- Por eso consultaba por una función que lo hiciera. Saludos!! El 17 de agosto de 2016, 14:47, eric <ericconchamunoz en gmail.com> escribió:> Para calculos sobre data.frame agrupando por niveles de una variable la > libreria data.table va muy bien: > > > install.packages(data.table) > > library(data.table) > > x ejemplo, con tu data.frame podrias calcular: > > tmp <- read.csv("datos.csv", header=TRUE) > tmp <- as.data.table(tmp) > tmp[, mean(Valores), by=Mes] > > Mes V1 > 1: 1 100.625 > 2: 2 125.300 > 3: 3 102.750 > > > o por año > > tmp[, mean(Valores), by=Agno] > Agno V1 > 1: 2015 116.7692 > 2: 2016 105.6667 > > > la expresion mean(Valores) la puedes cambiar por el calculo que tu > necesitas hacer. > > al leer el archivo tuve problemas con la Ñ, asi es que la cambie. > > Saludos, > > eric. > > > > > > > On 08/17/2016 11:31 AM, Mauricio Monsalvo wrote: > >> Hola. >> Necesito calcular los porcentajes de un valor dado (valores) como >> porcentaje de la suma de ese mismo valor pero agrupando por una tercera >> columna (en este caso, podría ser Mes-Año). El resultado sería el que se >> ve en la var: "EnR" >> Necesito además que ese resultado quede pegado en mi data.frame. >> AñoMesAñoMesFactorValoresenR >> 201512015-1a1050.25 >> 201512015-1b1040.24 >> 201512015-1c1090.25 >> 201512015-1d1100.26 >> 201522015-2a1150.17 >> 201522015-2b1160.17 >> 201522015-2c1180.17 >> 201522015-2d2200.32 >> 201522015-2e1100.16 >> 201532015-3a990.24 >> 201532015-3b980.24 >> 201532015-3c1050.26 >> 201532015-3d1090.27 >> 201612016-1a980.26 >> 201612016-1b780.21 >> 201612016-1c1000.27 >> 201612016-1d1010.27 >> 201622016-2a1100.19 >> 201622016-2b1120.20 >> 201622016-2c1150.20 >> 201622016-2d1180.21 >> 201622016-2e1190.21 >> Imagino una forma "larga" de hacerlo, que sería aprox: >> c <- datos[ , .(SumPorGrupo=sum(Valores)), by= .(MesAño)] >> datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == datos$MesAño)] >> Pero como era de esperarse, no funciona :( >> Entonces, podría resolverlo usando SQL: >> datos$enRv <- sqldf("SELECT Valores/SumPorGrupo AS EnR FROM datosINNER >> JOIN c ON datos.MesAño = c.MesAño") >> Y ahí sí. Pero me parece que debe haber una función que lo haga >> directamente sobre el data.frame, ¿no? >> >> Luego, quisiera una forma "extendida", donde el resultado sea para las >> clases que definen dos variables (en el ejemplo, datos$Mes y datos$Año >> por separado). >> Para mi, si funcionara iría por: >> c <- datos[ , .SumPorGrupo=(sum(Valores)), by= .(Año, Mes)] >> datos$enRv <- datos$Valores/c$SumPorGrupo[which(c == c(datos$Año, >> datos$mes)] >> >> De manera similar, ¿es posible usar cumsum(datos$Valores) también por >> grupos? >> >> Espero que se entiendan las consultas. >> Adjunto el ejemplo. >> Muchas gracias!! >> -- >> Mauricio >> >> >> _______________________________________________ >> R-help-es mailing list >> R-help-es en r-project.org >> https://stat.ethz.ch/mailman/listinfo/r-help-es >> >> > -- > Forest Engineer > Master in Environmental and Natural Resource Economics > Ph.D. student in Sciences of Natural Resources at La Frontera University > Member in AguaDeTemu2030, citizen movement for Temuco with green city > standards for living > > Nota: Las tildes se han omitido para asegurar compatibilidad con algunos > lectores de correo. >-- Mauricio [[alternative HTML version deleted]]