1
votes

Remplir les NA avec les valeurs des cellules adjacentes dans R

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?


0 commentaires

3 Réponses :


5
votes

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


2 commentaires

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)%>%`



3
votes

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]


2 commentaires

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 .



2
votes

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)


0 commentaires