datasheet cheatsheet r sum dplyr na

cheatsheet - dplyr:: mutate(asignar na.rm=TRUE)



sum by group in r (3)

Tengo un data.frame que tiene 100 variables. Quiero obtener la suma de tres variables solo usando mutate (no summarise ).

Si hay NA en cualquiera de las 3 variables, aún quiero obtener la sum . Para hacer esto usando mutate , reemplacé todos los valores de NA con 0 usando ifelse luego obtuve la sum .

library(dplyr) df %>% mutate(mod_var1 = ifelse(is.na(var1), 0, var1), mod_var2 = ifelse(is.na(var2), 0, var2), mod_var3 = ifelse(is.na(var3), 0, var3), sum = (mod_var1+mod_var2+mod_var3))

¿Hay alguna forma mejor (más corta) de hacer esto?

DATOS

df <- read.table(text = c(" var1 var2 var3 4 5 NA 2 NA 3 1 2 4 NA 3 5 3 NA 2 1 1 5"), header =T)


Donde mejor = tidyr :

df %>% mutate(rn = row_number()) %>% gather(var, varNum, var1:var3) %>% group_by(rn) %>% mutate(sum = sum(varNum, na.rm = TRUE)) %>% spread(var, varNum)

En caso de que su conjunto de datos esté a punto de crecer ...


Podemos usar Reduce con +

df %>% mutate_each(funs(replace(., is.na(.), 0)), var1:var3) %>% mutate(Sum = Reduce(`+`, .)) # var1 var2 var3 Sum #1 4 5 0 9 #2 2 0 3 5 #3 1 2 4 7 #4 0 3 5 8 #5 3 0 2 5 #6 1 1 5 7

O con rowSums

df %>% mutate(Sum = rowSums(.[names(.)[1:3]], na.rm = TRUE)) # var1 var2 var3 Sum #1 4 5 NA 9 #2 2 NA 3 5 #3 1 2 4 7 #4 NA 3 5 8 #5 3 NA 2 5 #6 1 1 5 7

Puntos de referencia

set.seed(24) df1 <- as.data.frame(matrix(sample(c(NA, 1:5), 1e6 *3, replace=TRUE), dimnames = list(NULL, paste0("var", 1:3)), ncol=3)) system.time({ df1 %>% rowwise() %>% mutate(Sum = sum(c(var1, var2, var3), na.rm = TRUE)) }) # user system elapsed # 21.50 0.03 21.66 system.time({ df1 %>% mutate(rn = row_number()) %>% gather(var, varNum, var1:var3) %>% group_by(rn) %>% mutate(sum = sum(varNum, na.rm = TRUE)) %>% spread(var, varNum)}) # user system elapsed # 5.96 0.39 6.37 system.time({ replace(df1, is.na(df1), 0) %>% mutate(sum = var1 + var2 + var3) }) # user system elapsed # 0.17 0.01 0.19 system.time({ df1 %>% mutate_each(funs(replace(., is.na(.), 0)), var1:var3) %>% mutate(Sum = Reduce(`+`, .)) }) # user system elapsed # 0.10 0.02 0.11 system.time({ df1 %>% mutate(Sum = rowSums(.[names(.)[1:3]], na.rm = TRUE)) }) # user system elapsed # 0.04 0.00 0.03


rowwise() es mi función de rowwise() . Es como group_by() pero trata cada fila como un grupo individual.

df %>% rowwise() %>% mutate(Sum = sum(c(var1, var2, var3), na.rm = TRUE))