valores reemplazar perdidos filas faltantes eliminar elementos datos agrupar r dplyr

perdidos - reemplazar NA en una cadena dplyr



reemplazar na en r (1)

El problema principal que tienes es que la mean devuelve un doble, mientras que la columna G_batting es un número entero. Así que envolver la media en as.integer funcionaría, o tendrías que convertir toda la columna en numeric , supongo.

Dicho esto, aquí hay un par de alternativas de datos. No data.table cuál es más rápido.

library(data.table) # using ifelse dt = data.table(a = 1:2, b = c(1,2,NA,NA,3,4,5,6,7,8)) dt[, b := ifelse(is.na(b), mean(b, na.rm = T), b), by = a] # using a temporary column dt = data.table(a = 1:2, b = c(1,2,NA,NA,3,4,5,6,7,8)) dt[, b.mean := mean(b, na.rm = T), by = a][is.na(b), b := b.mean][, b.mean := NULL]

Y esto es lo que me gustaría hacer idealmente ( hay un FR sobre esto):

# again, atm this is pure fantasy and will not work dt[, b[is.na(b)] := mean(b, na.rm = T), by = a]

La versión dplyr de ifelse es (como en OP):

dt %>% group_by(a) %>% mutate(b = ifelse(is.na(b), mean(b, na.rm = T), b))

No estoy seguro de cómo implementar la segunda idea de data.table en una sola línea en dplyr . Tampoco estoy seguro de cómo puede evitar que dplyr codificar / ordenar los datos (además de crear una columna de índice).

La pregunta ha sido editada desde el original .

Después de leer esta interesante discussion me preguntaba cómo reemplazar las NA en una columna usando dplyr en, por ejemplo, los datos de bateo de Lahman:

Source: local data frame [96,600 x 3] Groups: teamID yearID teamID G_batting 1 2004 SFN 11 2 2006 CHN 43 3 2007 CHA 2 4 2008 BOS 5 5 2009 SEA 3 6 2010 SEA 4 7 2012 NYA NA

Lo siguiente no funciona como esperaba

library(dplyr) library(Lahman) df <- Batting[ c("yearID", "teamID", "G_batting") ] df <- group_by(df, teamID ) df$G_batting[is.na(df$G_batting)] <- mean(df$G_batting, na.rm = TRUE)

Fuente: marco de datos local [20 x 3] Grupos: ID de año, ID de equipo

yearID teamID G_batting 1 2004 SFN 11.00000 2 2006 CHN 43.00000 3 2007 CHA 2.00000 4 2008 BOS 5.00000 5 2009 SEA 3.00000 6 2010 SEA 4.00000 7 2012 NYA **49.07894** > mean(Batting$G_battin, na.rm = TRUE) [1] **49.07894**

De hecho, imputa la media general y no la media del grupo. ¿Cómo harías esto en una cadena dplyr? Usar la transform de la base R tampoco funciona, ya que imputa la media general y no la media del grupo. También este enfoque convierte los datos a un dat regular. un cuadro. ¿Hay una mejor manera de hacer esto?

df %.% group_by( yearID ) %.% transform(G_batting = ifelse(is.na(G_batting), mean(G_batting, na.rm = TRUE), G_batting) )

Editar: Reemplazar la transform con mutate da el siguiente error

Error in mutate_impl(.data, named_dots(...), environment()) : INTEGER() can only be applied to a ''integer'', not a ''double''

Editar: Agregar as.integer parece resolver el error y produce el resultado esperado. Ver también la respuesta de @ eddi.

df %.% group_by( teamID ) %.% mutate(G_batting = ifelse(is.na(G_batting), as.integer(mean(G_batting, na.rm = TRUE)), G_batting)) Source: local data frame [96,600 x 3] Groups: teamID yearID teamID G_batting 1 2004 SFN 11 2 2006 CHN 43 3 2007 CHA 2 4 2008 BOS 5 5 2009 SEA 3 6 2010 SEA 4 7 2012 NYA 47 > mean_NYA <- mean(filter(df, teamID == "NYA")$G_batting, na.rm = TRUE) > as.integer(mean_NYA) [1] 47

Editar: Siguiendo con el comentario de @ Romain, instalé dplyr desde github:

> head(df,10) yearID teamID G_batting 1 2004 SFN 11 2 2006 CHN 43 3 2007 CHA 2 4 2008 BOS 5 5 2009 SEA 3 6 2010 SEA 4 7 2012 NYA NA 8 1954 ML1 122 9 1955 ML1 153 10 1956 ML1 153 > df %.% + group_by(teamID) %.% + mutate(G_batting = ifelse(is.na(G_batting), mean(G_batting, na.rm = TRUE), G_batting)) Source: local data frame [96,600 x 3] Groups: teamID yearID teamID G_batting 1 2004 SFN 0 2 2006 CHN 0 3 2007 CHA 0 4 2008 BOS 0 5 2009 SEA 0 6 2010 SEA 1074266112 7 2012 NYA 90693125 8 1954 ML1 122 9 1955 ML1 153 10 1956 ML1 153 .. ... ... ...

Así que no obtuve el error (bien) pero obtuve un resultado (aparentemente) extraño.