mutate funcion datos arrange agrupar r dplyr missing-data zoo

funcion - mutate en r



Reemplace NA con el valor anterior o siguiente, por grupo, usando dplyr (4)

Tengo un marco de datos que se organiza por orden descendente de la fecha.

ps1 = data.frame(userID = c(21,21,21,22,22,22,23,23,23), color = c(NA,''blue'',''red'',''blue'',NA,NA,''red'',NA,''gold''), age = c(''3yrs'',''2yrs'',NA,NA,''3yrs'',NA,NA,''4yrs'',NA), gender = c(''F'',NA,''M'',NA,NA,''F'',''F'',NA,''F'') )

Deseo imputar (reemplazar) los valores de NA con valores anteriores y agrupados por ID de usuario En caso de que la primera fila de una ID de usuario tenga NA, reemplace con el siguiente conjunto de valores para ese grupo de ID de usuario.

Estoy tratando de usar los paquetes dplyr y zoo algo como esto ... pero no funciona

cleanedFUG <- filteredUserGroup %>% group_by(UserID) %>% mutate(Age1 = na.locf(Age), Color1 = na.locf(Color), Gender1 = na.locf(Gender) )

Necesito un resultado df como este:

userID color age gender 1 21 blue 3yrs F 2 21 blue 2yrs F 3 21 red 2yrs M 4 22 blue 3yrs F 5 22 blue 3yrs F 6 22 blue 3yrs F 7 23 red 4yrs F 8 23 red 4yrs F 9 23 gold 4yrs F


El uso de zoo::na.locf directamente en todo el data.frame llenaría la NA independientemente de los grupos de ID de usuario. El agrupamiento del paquete dplyr desafortunadamente no tiene efecto en la función na.locf , por eso fui con una división:

library(dplyr); library(zoo) ps1 %>% split(ps1$userID) %>% lapply(function(x) {na.locf(na.locf(x), fromLast=T)}) %>% do.call(rbind, .) #### userID color age gender #### 21.1 21 blue 3yrs F #### 21.2 21 blue 2yrs F #### 21.3 21 red 2yrs M #### 22.4 22 blue 3yrs F #### 22.5 22 blue 3yrs F #### 22.6 22 blue 3yrs F #### 23.7 23 red 4yrs F #### 23.8 23 red 4yrs F #### 23.9 23 gold 4yrs F

Lo que hace es que primero divide los datos en 3 cuadros de datos, luego aplico una primera pasada de imputación (hacia abajo), luego hacia arriba con la función anónima en lapply , y finalmente uso rbind para volver a unir los cuadros de datos. Tienes la salida esperada.


Escribí esta función y es definitivamente más rápido que el relleno y probablemente más rápido que na.locf:

fill_NA <- function(x) { which.na <- c(which(!is.na(x)), length(x) + 1) values <- na.omit(x) if (which.na[1] != 1) { which.na <- c(1, which.na) values <- c(values[1], values) } diffs <- diff(which.na) return(rep(values, times = diffs)) }


Usando el método @agenis con na.locf() combinado con purrr , podrías hacer:

library(purrr) library(zoo) ps1 %>% slice_rows("userID") %>% by_slice(function(x) { na.locf(na.locf(x), fromLast=T) }, .collate = "rows")


require(tidyverse) #fill is part of tidyr ps1 %>% group_by(userID) %>% fill(color, age, gender) %>% #default direction down fill(color, age, gender, .direction = "up")

Lo que te da:

Source: local data frame [9 x 4] Groups: userID [3] userID color age gender <dbl> <fctr> <fctr> <fctr> 1 21 blue 3yrs F 2 21 blue 2yrs F 3 21 red 2yrs M 4 22 blue 3yrs F 5 22 blue 3yrs F 6 22 blue 3yrs F 7 23 red 4yrs F 8 23 red 4yrs F 9 23 gold 4yrs F