Je cherche un moyen plus agréable de le faire dans R. J'ai une possibilité mais il semble qu'il devrait y avoir un moyen intelligent/plus lisible.
Je souhaite supprimer les doublons dans une/plusieurs colonnes uniquement si une condition est remplie dans une autre colonne (ou colonnes).
Dans mon exemple simplifié, je souhaite supprimer les doublons dans la colonne X
uniquement si la colonne Y
est NA
, mais conserver NA
en Y sans X dupliqué.
testDF<- data.frame(X= c(1:4,4:8,8:12), Y = 1:14)
testDF$Y[c(4,6,10)]<- NA
Ma solution actuelle est :
testDF[!(testDF$X %in% testDF$X[which(duplicated(testDF$X))] & is.na(testDF$Y)),]
ou alors
library(dplyr)
testDF %>%
dplyr::filter(!(testDF$X%in% testDF$X[which(duplicated(testDF$X))] & is.na(testDF$Y)))
qui semblent tous les deux désordonnés et déroutants, et dans une application réelle où je vais regarder plus de deux colonnes, cela pourrait devenir impraticable.
J'espérais quelque chose de plus du genre :
testDF %>% dplyr::filter(!(duplicated(X) & is.na(Y)))
mais il duplicated()
n'identifie que la deuxième instance d'une duplication, donc si Y
's NA
est conforme à la première des valeurs X dupliquées, il ne sera pas filtré.
Vous recherchez de préférence une solution de base ou de rangement car aucun des autres scripts n'utilise data.table
Vous pouvez également simplement postuler duplicated
dans les deux sens :
testDF %>%
filter(!is.na(Y) | (!duplicated(X) & !duplicated(X, fromLast = TRUE) ))
(fortement influencé par ceci : recherchez les éléments dupliqués avec dplyr - je laisserai les autres décider s'il est suffisamment proche pour être un doublon)
Pour rendre votre code encore plus lisible, vous pouvez même le mettre dans une fonction (peut-être avec un meilleur nom de fonction que le mien) :
all_duplicates <- function(x) {
duplicated(x) | duplicated(x, fromLast = TRUE)
}
testDF %>%
filter(!is.na(Y) | !all_duplicates(X) )
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots