web-dev-qa-db-fra.com

Recherche d'éléments qui ne se chevauchent pas entre deux vecteurs

J'essaie d'identifier des éléments qui ne sont pas inclus dans l'autre vecteur. Par exemple, dans deux vecteurs, j'ai

list.a <- c("James", "Mary", "Jack", "Sonia", "Michelle", "Vincent")

list.b <- c("James", "Sonia", "Vincent")

y a-t-il un moyen de vérifier quelles personnes ne se chevauchent pas? Dans l'exemple, je voudrais obtenir le résultat vectoriel contenant Mary, Jack et Michelle.

Toutes les suggestions aideront!

10
song0089

Oui, il y a un moyen:

setdiff(list.a, list.b)
# [1] "Mary"     "Jack"     "Michelle"
23
Julius Vainora

Réponse étendue basée sur les commentaires de Hadley et de moi-même: voici comment autoriser les doublons.

Final Edit: Je ne recommande à personne d’utiliser cette option, car le résultat risque de ne pas être conforme à vos attentes. S'il existe une valeur répétée dans x qui ne figure pas dans y, cette valeur sera répétée dans la sortie. Mais si, par exemple, il y a quatre 9 dans x et un 9 dans y, tous les 9s seront supprimés. On pourrait s’attendre à en conserver trois; cela prend du code plus compliqué.

mysetdiff<-function (x, y, multiple=FALSE) 
{
    x <- as.vector(x)
    y <- as.vector(y)
    if (length(x) || length(y)) {
        if (!multiple) {
             unique( x[match(x, y, 0L) == 0L])  
              }else  x[match(x, y, 0L) == 0L] 
        } else x
}

Rgames> x
[1]  8  9  6 10  9
Rgames> y
[1] 5 3 8 8 1
Rgames> setdiff(x,y)
[1]  9  6 10
Rgames> mysetdiff(x,y)
[1]  9  6 10
Rgames> mysetdiff(x,y,mult=T)
[1]  9  6 10  9
Rgames> mysetdiff(y,x,mult=T)
[1] 5 3 1
Rgames> setdiff(y,x)
[1] 5 3 1
2
Carl Witthoft

Je pense qu’il faut mentionner que la réponse retenue n’est que partiellement correcte. La commande setdiff(list.a, list.b) recherche les éléments ne se chevauchant pas uniquement si ces éléments sont contenus dans l'objet utilisé comme premier argument !. 

Si vous n'êtes pas au courant de ce problème et que vous avez setdiff(list.b, list.a) à la place, les résultats seront character(0) dans ce cas, ce qui vous mènerait à la conclusion qu'il n'y a pas d'éléments ne se chevauchant pas.

En utilisant un exemple légèrement étendu à titre d’illustration, une solution rapide évidente consiste à:

list.a <- c("James", "Mary", "Jack", "Sonia", "Michelle", "Vincent")
list.b <- c("James", "Sonia", "Vincent", "Iris")

c(setdiff(list.b, list.a), setdiff(list.a, list.b))
# [1] "Iris"     "Mary"     "Jack"     "Michelle" 
2
Manuel R

Un one-liner sympa qui s’applique aux doublons:

anti_join(data_frame(c(1,1,2,2)), data_frame(c(1,1)))

Cela renvoie le bloc de données {2,2}. Ceci ne s'applique cependant pas au cas de 1,2 sur 1,1,2,2, car il le trouve deux fois

0
Noale