Intenté buscar varias publicaciones en SO, pero no estoy seguro de qué estoy haciendo mal aquí, e imagino que la solución es bastante simple. Estoy tratando de agrupar un marco de datos por una variable y calcular la media de varias variables dentro de ese grupo.

Esto es lo que estoy intentando:

head(airquality)
target_vars = c("Ozone","Temp","Solar.R")
airquality %>% group_by(Month) %>% select(target_vars) %>% summarise(rowSums(.))

Pero recibo el error de que mis longitudes no coinciden. He intentado variaciones usando mutate para crear la columna o summarise_all, pero ninguno de estos parece funcionar. Necesito las sumas de filas dentro del grupo, y luego calcular la media dentro del grupo (sí, no tiene sentido aquí).

Además, quiero usar select porque estoy tratando de hacer esto sobre ciertas variables.

Estoy segura de que esto podría ser un duplicado, pero no puedo encontrar la correcta.

EDITAR PARA CLARIDAD Lo siento, mi pregunta original no estaba clara. Imagine que la variable de agrupación es el mes calendario, y tenemos v1, v2 y v3. Me gustaría saber, dentro de month, cuál fue el promedio de las sumas de v1, v2 y v3. Entonces, si tenemos 12 meses, el resultado sería un marco de datos de 12x1. Aquí hay un ejemplo si solo tuviéramos 1 mes:

Month v1 v2 v3 Sum 
1      1  1  0   2
1      1  1  1   3
1      1  0  0   3

Entonces el resultado sería:

Month  Average
1           8/3
0
vashts85 23 oct. 2017 a las 17:40

3 respuestas

La mejor respuesta

Puedes probar:

library(tidyverse)
airquality %>% 
  select(Month, target_vars) %>% 
  gather(key, value, -Month) %>% 
  group_by(Month) %>%
  summarise(n=length(unique(key)),
            Sum=sum(value, na.rm = T)) %>% 
  mutate(Average=Sum/n)
# A tibble: 5 x 4
  Month     n   Sum  Average
  <int> <int> <int>    <dbl>
1     5     3  7541 2513.667
2     6     3  8343 2781.000
3     7     3 10849 3616.333
4     8     3  8974 2991.333
5     9     3  8242 2747.333

La idea es convertir los datos de ancho a largo usando tidyr::gather(), luego agrupar por Month y calcular la suma y el promedio.

2
Roman 24 oct. 2017 a las 07:38

Esto parece entregar lo que quieres. Es una R. normal La función sapply mantiene los meses separados por "nombre". La función sum aplicada a cada marco de datos no mantendrá las sumas de columnas separadas. (Corrección # 2: usado solo target_vars):

sapply( split( airquality[target_vars], airquality$Month), sum, na.rm=TRUE)
    5     6     7     8     9 
 7541  8343 10849  8974  8242 

Si quisieras el número de resultados variables, entonces dividirías por el número de variables:

sapply( split( airquality[target_vars], airquality$Month), sum, na.rm=TRUE)/
                                                           (length(target_vars))
       5        6        7        8        9 
2513.667 2781.000 3616.333 2991.333 2747.333 
2
IRTFM 26 oct. 2017 a las 15:55

Quizás esto es lo que estás buscando

library(dplyr)
library(purrr)
library(tidyr)   # forgot this in original post
airquality %>%
  group_by(Month) %>% 
  nest(Ozone, Temp, Solar.R, .key=newcol) %>%
  mutate(newcol = map_dbl(newcol, ~mean(rowSums(.x, na.rm=TRUE))))

# A tibble: 5 x 2
  # Month   newcol
  # <int>    <dbl>
# 1     5 243.2581
# 2     6 278.1000
# 3     7 349.9677
# 4     8 289.4839
# 5     9 274.7333  

Nunca me he encontrado con una situación en la que todas las respuestas no estén de acuerdo. Aquí hay alguna validación (al menos creo) para el quinto mes

airquality %>%
  filter(Month == 5) %>%
  select(Ozone, Temp, Solar.R) %>%
  mutate(newcol = rowSums(., na.rm=TRUE)) %>%
  summarise(sum5 = sum(newcol), mean5 = mean(newcol))

#   sum5    mean5
# 1 7541 243.2581
1
CPak 26 oct. 2017 a las 01:02