Skip to content
Prev 10558 / 15379 Next

[R-es] Porcentajes por grupos

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!!