2017-07-26 5 views
2

J'ai un list de charactervector s:supprimer des éléments dupliqués de la liste

my.list <- list(e1 = c("a","b","c","k"),e2 = c("b","d","e"),e3 = c("t","d","g","a","f")) 

Je suis à la recherche d'un function que pour tout character qui apparaît plus d'une fois dans vector s du list (en chaque vector un character ne peut apparaître qu'une fois), ne gardera que la première apparition.

La liste des résultats pour cet exemple serait donc:

res.list <- list(e1 = c("a","b","c","k"),e2 = c("d","e"),e3 = c("t","g","f")) 

Notez qu'il est possible qu'une vector entière dans le list est éliminé de sorte que le nombre d'éléments dans le list résultant ne doit pas nécessairement être égal à l'entrée list.

Répondre

5

Nous pouvons unlist le list, obtenir un list logique à l'aide duplicated et extraire les éléments « my.list » en fonction de l'indice logique

un <- unlist(my.list) 
res <- Map(`[`, my.list, relist(!duplicated(un), skeleton = my.list)) 
identical(res, res.list) 
#[1] TRUE 
2

Voici une alternative en utilisant mapply avec setdiff et Reduce.

# make a copy of my.list 
res.list <- my.list 
# take set difference between contents of list elements and accumulated elements 
res.list[-1] <- mapply("setdiff", res.list[-1], 
            head(Reduce(c, my.list, accumulate=TRUE), -1)) 

Garder le premier élément de la liste, on calcule sur les éléments suivants et une liste du vecteur cumulatif des éléments produits par Reduce avec c et l'argument accumulate=TRUE. head(..., -1) supprime l'élément de liste final contenant tous les éléments afin que les longueurs s'alignent.

Ce retour

res.list 
$e1 
[1] "a" "b" "c" "k" 

$e2 
[1] "d" "e" 

$e3 
[1] "t" "g" "f" 

Notez que dans Reduce, nous pourrions remplacer c avec function(x, y) unique(c(x, y)) et accomplir la même sortie finale.