Cette question peut sembler similaire à d'autres questions sur ce forum et avant de la signaler comme duplicata, veuillez vous assurer que la duplication fonctionne dans mon cas.
J'ai un dataframe ( df1 ), comme suit:
> df1 %>% arrange(c1, c2) %>% fill(c3) %>% fill(c3, .direction = "up") c1 c2 c3 -------------- ER017 1 18 ER017 2 18 ER017 3 20 ER017 4 20 ER017 5 20 ER018 1 20 ER018 2 20 ER018 3 150 ER018 4 200
Je voudrais remplacer NA dans c3 de telle sorte que la valeur soit de la cellule précédente basée sur les valeurs de c1 et c2. Par exemple, pour ER017; c2 = 1, c3 = 18, donc pour ER017; c2 = 2, c3 serait 18 mais pour ER017; c2 = 4, c3 serait 20 car la valeur est modifiée pour ER017 et c2 = 3, qui est la cellule précédente. De même, pour ER018, c2 = 1 et c2 = 2, c3 devrait avoir 150 comme pour c2 = 3 correspond à c3 = 150.
Voici le résultat souhaité:
> library(zoo) > library(dplyr) > df1 %>% arrange(c1,c2) %>% group_by(c1,c2) %>% mutate(c3 = na.locf0(c3)) %>% ungroup c1 c2 c3 ------------------- ER017 1 18 ER017 2 18 ER017 3 20 ER017 4 20 ER017 5 20 ER018 1 20 ER018 2 20 ER018 3 150 ER018 4 200
J'ai essayé les extraits de code suivants mais le résultat obtenu n'est pas correct.
c1 c2 c3 ----------------------- ER017 1 18 ER017 2 18 ER017 3 20 ER017 4 20 ER017 5 20 ER018 1 150 ER018 2 150 ER018 3 150 ER018 4 200
> df1 <- data.frame(c1=c('ER017','ER017','ER017','ER017','ER017','ER018','ER018','ER018','ER018'),c2=c(1,4,3,2,5,3,1,2,4),c3=c(18,NA,20,NA,NA,150,NA,NA,200))
> df1
c1 c2 c3
-----------------------
ER017 1 18
ER017 4 NA
ER017 3 20
ER017 2 NA
ER017 5 NA
ER018 3 150
ER018 1 NA
ER018 2 NA
ER018 4 200
Aucune de ces solutions ne fonctionne dans mon cas comme pour ER018, c2 = 1 et 2, c3 devrait être 150 mais d'une manière ou d'une autre la valeur 20 est reportée de ER017 à ER018 . Quelqu'un peut-il aider à obtenir la sortie souhaitée comme mentionné ci-dessus?
3 Réponses :
Vous devez définir .direction = "downup" dans fill () pour remplir les valeurs manquantes d'abord vers le bas, puis vers le haut.
df1 %>% group_by(c1) %>% arrange(c2, .by_group = T) %>% fill(c3, .direction = "downup") %>% ungroup() # # A tibble: 9 x 3 # c1 c2 c3 # <fct> <dbl> <dbl> # 1 ER017 1 18 # 2 ER017 2 18 # 3 ER017 3 20 # 4 ER017 4 20 # 5 ER017 5 20 # 6 ER018 1 150 # 7 ER018 2 150 # 8 ER018 3 150 # 9 ER018 4 200
Quand j'essaye le code ci-dessus, j'obtiens une erreur: Erreur dans l'ordre (c2, .by_group = T): les longueurs d'argument diffèrent
C'était un problème de mon côté ... chargé des bibliothèques supplémentaires qui ont créé un problème avec la fonction arrange () . Résolu le problème en utilisant `dplyr :: arrange (c2, .by_group = T)%>%`
Similaire en utilisant la solution à Darren mais en utilisant nafill de data.table
library(data.table) setDT(df1) df1[order(c2), nafill(nafill(c3, type = 'locf'), type = 'nocb'), by = c1]
En utilisant votre code, j'obtiens le message d'erreur: Erreur dans nafill (nafill (c3, type = "locf"), type = "nocb"): impossible de trouver la fonction "nafill"
Je suppose que vous n'avez pas le package data.table , ou que vous avez une ancienne version du package. Je suggère d'essayer d'installer le package en utilisant install.packages ("data.table") ou update.packages () (s'il est déjà installé). Enfin, j'exécute R3.6.3 et R4.0.0 et peut-être que la fonction a été introduite dans le package après une certaine version de R .
Solution de base R:
data.frame(do.call("rbind", lapply(split(df1, df1$c1), function(x){
x <- x[order(x$c2),]
x$c3[1] <- ifelse(is.na(x$c3[1]), x$c3[which(!(is.na(x$c3)))[1]], x$c3[1])
x$c3 <- na.omit(x$c3)[cumsum(!(is.na(x$c3)))]
return(x)
}
)
), row.names = NULL)