web-dev-qa-db-fra.com

Recherche de TOUTES les lignes en double, y compris les "éléments avec des indices plus petits"

duplicated de R renvoie un vecteur indiquant si chaque élément d'un vecteur ou d'un bloc de données est un doublon d'un élément avec un indice plus petit. Donc, si les lignes 3, 4 et 5 d'un bloc de données à 5 lignes sont identiques, duplicated me donnera le vecteur

FALSE, FALSE, FALSE, TRUE, TRUE

Mais dans ce cas, je veux vraiment

FALSE, FALSE, TRUE, TRUE, TRUE

c'est-à-dire que je veux savoir si une ligne est dupliquée par une ligne avec un indice plus grand aussi.

95
Lauren Samuels

duplicated a un argument fromLast. La section "Exemple" de ?duplicated vous montre comment l'utiliser. Appelez simplement duplicated deux fois, une fois avec fromLast=FALSE et une fois avec fromLast=TRUE et prenez les lignes où soit TRUE.


Certains éditions tardives: Vous n'avez pas fourni d'exemple reproductible, voici donc une illustration aimablement fournie par @jbaums

vec <- c("a", "b", "c","c","c") 
vec[duplicated(vec) | duplicated(vec, fromLast=TRUE)]
## [1] "c" "c" "c"
108
Joshua Ulrich

Vous devez assembler l'ensemble des valeurs duplicated, appliquer unique, puis tester avec %in%. Comme toujours, un exemple de problème donnera vie à ce processus.

> vec <- c("a", "b", "c","c","c")
> vec[ duplicated(vec)]
[1] "c" "c"
> unique(vec[ duplicated(vec)])
[1] "c"
>  vec %in% unique(vec[ duplicated(vec)]) 
[1] FALSE FALSE  TRUE  TRUE  TRUE
33
42-

J'ai eu la même question , et si je ne me trompe pas, c'est aussi une réponse.

vec[col %in% vec[duplicated(vec$col),]$col]

Je ne sais pas lequel est le plus rapide, cependant, l'ensemble de données que j'utilise actuellement n'est pas assez grand pour faire des tests qui produisent des écarts de temps importants.

3
François M.

Les lignes dupliquées dans une trame de données peuvent être obtenues avec dplyr en faisant

df = bind_rows(iris, head(iris, 20)) # build some test data
df %>% group_by_all() %>% filter(n()>1) %>% ungroup()

Pour exclure certaines colonnes, group_by_at(vars(-var1, -var2)) pourrait être utilisé à la place pour regrouper les données.

Si les indices de ligne et pas seulement les données sont réellement nécessaires, vous pouvez les ajouter d'abord comme dans:

df %>% add_rownames %>% group_by_at(vars(-rowname)) %>% filter(n()>1) %>% pull(rowname)
2
Holger Brandl

Si vous êtes intéressé par les lignes qui sont dupliquées pour certaines colonnes, vous pouvez utiliser une approche plyr:

ddply(df, .(col1, col2), function(df) if(nrow(df) > 1) df else c())

Ajout d'une variable de comptage avec dplyr:

df %>% add_count(col1, col2) %>% filter(n > 1)  # data frame
df %>% add_count(col1, col2) %>% select(n) > 1  # logical vector

Pour les lignes en double (en tenant compte de toutes les colonnes):

df %>% group_by_all %>% add_tally %>% ungroup %>% filter(n > 1)
df %>% group_by_all %>% add_tally %>% ungroup %>% select(n) > 1

L'avantage de ces approches est que vous pouvez spécifier le nombre de doublons comme seuil.

0
qwr