duplicated()

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

François Bonnot
Messages : 537
Enregistré le : 10 Nov 2004, 15:19
Contact :

duplicated()

Messagepar François Bonnot » 11 Sep 2007, 11:59

Dans l'exemple suivant, la fonction duplicated() retourne les positions des lignes dupliquées, à partir de la seconde occurence de chaque ligne :

Code : Tout sélectionner

> (df <- data.frame(x=c("a","b","c","b","d","c"),y=c(1,2,3,2,4,3)))
  x y
1 a 1
2 b 2
3 c 3
4 b 2
5 d 4
6 c 3
> duplicated(df)
[1] FALSE FALSE FALSE  TRUE FALSE  TRUE
Comment faire pour écrire une fonction duplicated2() (simple et performante: penser aux très gros data frames) qui retournerait toutes les occurences des lignes dupliquées? Le résultat serait alors le suivant :

Code : Tout sélectionner

> duplicated2(df)
[1] FALSE TRUE  TRUE   TRUE FALSE  TRUE
Peut-être cette fonction existe-t-elle déjà?

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 11 Sep 2007, 16:05

je donne une idée comme elle me vient (j'ai pas regardé comment est codé la fonction duplicated() ), c à d dans les grandes lignes. Désolé mais je n'ai pas plus de temps que ça pour me lancer dans de la progra en dehors de mes besoins :oops: :?

On prend df et on accole (avec un paste par exemple) les éléments de chaque ligne.
On peut obtenir ainsi un facteur.
Avec un table sur ce nouveau facteur on a les éléments dupliqués (ceux dont la valeur du table est > à 1).
On peut à partir de la table obtenue, se servir de ces valeurs pour créer un nouveau facteur qui contient les nombres de répétitions pour chaque ligne (pour ça j'ai bien un code en tête mais c'est loin d'être optimal je pense). C'est à dire si le tableau a 100000 lignes, on génère le facteur à 100000 valeurs qui donne pour chaque ligne le nombre de fois où elle est répétée dans tout le tableau. Si on veut une réponse en logical, il suffit de modifier les levels de ce dernier facteur (toute valeur !=1 c'est TRUE sinon 'est FALSE).

Voilà en sachant bien que je cherche rarement à optimiser mes codes (quoique en ce moment j'en aurai besoin !!! :D). C'est peut être une piste pour ce que vous cherchez...ou pas ;)

Bon courage.

Nicolas.

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 11 Sep 2007, 16:11

Bonjour,

On peut envisager comme solution de passer par des chaînes de caractères (ce que fait duplicated.data.frame) et de les dénombrer :

Code : Tout sélectionner

duplicated2 <- function(x){
  auxi <- do.call("paste",c(x,sep="_"))
  y <- table(auxi)
  y <- y>1
  res <- y[match(auxi,names(y))]
  dimnames(res) <- NULL
  return(res)
}
(df <- data.frame(x=c("a","b","c","b","d","c"),y=c(1,2,3,2,4,3)))
duplicated2(df)
[1] FALSE  TRUE  TRUE  TRUE FALSE  TRUE


Maxime

François Bonnot
Messages : 537
Enregistré le : 10 Nov 2004, 15:19
Contact :

Messagepar François Bonnot » 11 Sep 2007, 16:13

Merci.
En fait j'ai trouvé la solution suivante, qui donne le résultat souhaité :

Code : Tout sélectionner

duplicated2 <- function(x){
  if (sum(dup <- duplicated(x))==0)
    return(dup)
  if (class(x) %in% c("data.frame","matrix"))
    duplicated(rbind(x[dup,],x))[-(1:sum(dup))]
  else duplicated(c(x[dup],x))[-(1:sum(dup))]
}


François

Nicolas Bergeron
Messages : 17
Enregistré le : 13 Déc 2007, 16:18

Re: duplicated()

Messagepar Nicolas Bergeron » 01 Avr 2008, 15:41

[quote="François Bonnot"]Dans l'exemple suivant, la fonction duplicated() retourne les positions des lignes dupliquées, à partir de la seconde occurence de chaque ligne :
[code]> (df <- data.frame(x=c("a","b","c","b","d","c"),y=c(1,2,3,2,4,3)))
x y
1 a 1
2 b 2
3 c 3
4 b 2
5 d 4
6 c 3
> duplicated(df)

Bonjour après une recherche dans les anciens messages, je voudrais avoir plus de précision concernant l'utilisation de la function duplicated().

[code]> (df <- data.frame(x=c("a","b","c","b","d","c"),y=c(1,2,3,2,4,3), z=c(1,2,3,4,5,6)))
x y z
1 a 1 1
2 b 2 2
3 c 3 3
4 b 2 4
5 d 4 5
6 c 3 6

Lorsque j'applique la fonction duplicated sur ce data.frame je n'ai aucun doublon et c'est normal. Je voudrais par ailleurs enlever les doublons seulement sur les variables x et y. Puis-je utiliser la fonction duplicated lorsque j'utilise seulement quelques variables et non toutes celles du data frame? J'ai tenter ceci:

df[duplicated(c(1,2)),]

Mais ça ne fonctionne pas! Avez-vous une solution afin de récupérer ces enregistrements. En résumé y-a-t-il un moyen détourné pour spécifier à la fonction duplicated d'utiliser seulement quelques variables?
NicB

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 01 Avr 2008, 15:45

Il suffit de la faire tourner uniquement sur les variables qui t'intéressent.

duplicated(df[,-3]) ou encore duplicated(df[,c("x","y")])

Maxime

Nicolas Bergeron
Messages : 17
Enregistré le : 13 Déc 2007, 16:18

Messagepar Nicolas Bergeron » 01 Avr 2008, 16:03

Logez Maxime a écrit :Il suffit de la faire tourner uniquement sur les variables qui t'intéressent.

duplicated(df[,-3]) ou encore duplicated(df[,c("x","y")])

Maxime


Bonjour Logez,

Merci pour ta rapidité de réponse.

En fait je voudrais extraire les enregistrements qui ne sont pas doublés et non seulement avoir les vecteurs logiques: F, F, F, T, F, T

Donc j'ai tenté ceci aussi:

df[,duplicated(-3)]

ou aussi ceci:

df[,duplicated(c("x","y"))]

Mais ça ne fonctionne pas. Une idée?
NicB

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 01 Avr 2008, 16:05

Le problème vient de la virgule dans les crochets. Ce sont les lignes que tu sélectionnes et pas les colonnes.

df[duplicated(-3),]

Maxime

Nicolas Bergeron
Messages : 17
Enregistré le : 13 Déc 2007, 16:18

Messagepar Nicolas Bergeron » 01 Avr 2008, 16:15

Logez Maxime a écrit :Le problème vient de la virgule dans les crochets. Ce sont les lignes que tu sélectionnes et pas les colonnes.

df[duplicated(-3),]

Maxime


Même avec ce que tu proposes ça ne fonctionne pas. Il n'y a aucun enregistrement?!?

> df[duplicated(-3),]
[1] x y z
<0 rows> (or 0-length row.names)

Est-ce que ça fonctionne cette commande sur ton ordi?

Merci!
NicB

jean lobry
Messages : 733
Enregistré le : 17 Jan 2008, 20:00
Contact :

Messagepar jean lobry » 01 Avr 2008, 16:30

Bonjour,

je propose la solution suivante :

Code : Tout sélectionner

duplicated2 <- function(x, ...) duplicated(x, ...) | duplicated(x, ..., fromLast=TRUE)


Amicalement,

Jean

Nicolas Péru
Messages : 1408
Enregistré le : 07 Aoû 2006, 08:13

Messagepar Nicolas Péru » 01 Avr 2008, 16:31

Parce que

Code : Tout sélectionner

duplicated(-3)
[1] FALSE


ça ne veux rien dire :)

Maxime t'indiquait ton erreur, je crois qu'il te disait de faire :

Code : Tout sélectionner

duplicated(df[,-3])


ce qui est très différent ;)

Nicolas Bergeron
Messages : 17
Enregistré le : 13 Déc 2007, 16:18

Messagepar Nicolas Bergeron » 01 Avr 2008, 17:01

Nicolas Péru a écrit :Parce que

Code : Tout sélectionner

duplicated(-3)
[1] FALSE


ça ne veux rien dire :)

Maxime t'indiquait ton erreur, je crois qu'il te disait de faire :

Code : Tout sélectionner

duplicated(df[,-3])


ce qui est très différent ;)


Bonjour Nicolas,

Voici le dataframe original:
> df
x y z
a 1 1
b 2 2
c 3 3
b 2 4
d 4 5
c 3 6

Si je fais celà:

> duplicated(df[,-3])
[1] FALSE FALSE FALSE TRUE FALSE TRUE

J'ai en retour un vecteur logique. Ce que je voudrais comme résultat serait plutôt ceci:

x y z
a 1 1
b 2 2
c 3 3
d 4 5

Je dois donc inclure le duplicated entre les crochets []. Mais ça ne fonctionne pas. Je veux enlever les doublons en tenant compte seulemnet des variables x et y (-z)

> df[duplicated(-3),]
[1] x y z
<0 rows> (or 0-length row.names)

J'ai tenter ceci avec uniq mais R détecte seulement un doublon

> df[unique(-3),]
x y z
1 a 1 1
2 b 2 2
4 b 2 4
5 d 4 5
6 c 3 6

javascript:emoticon(':cry:')

Merci pour votre aide avec "duplicated"

Merci de votre collaboration

Nicolas Bergeron
NicB

Logez Maxime
Messages : 3138
Enregistré le : 26 Sep 2006, 11:35

Messagepar Logez Maxime » 01 Avr 2008, 18:08

re,

j'ai tapé trop vite il faut faire df[!duplicated(df[,-3]),].

Maxime

Nicolas Bergeron
Messages : 17
Enregistré le : 13 Déc 2007, 16:18

Messagepar Nicolas Bergeron » 01 Avr 2008, 18:59

Logez Maxime a écrit :re,

j'ai tapé trop vite il faut faire df[!duplicated(df[,-3]),].

Maxime


Merci beaucoup Maxime!

Ça fonctionne
NicB

François Bonnot
Messages : 537
Enregistré le : 10 Nov 2004, 15:19
Contact :

Messagepar François Bonnot » 02 Avr 2008, 07:06

jean lobry a écrit :je propose la solution suivante :

Code : Tout sélectionner

duplicated2 <- function(x, ...) duplicated(x, ...) | duplicated(x, ..., fromLast=TRUE)



Bonjour,
Cela semble en effet être la meilleure solution à ma question de départ.
Merci.

FB


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité