2
votes

Comment puis-je comparer les sous-valeurs d'une liste les unes aux autres en utilisant une boucle for?

Actuellement, j'ai une liste telle que celle illustrée ci-dessous. Je voudrais développer un forloop qui parcourt chaque élément de la liste et compare les personnages de cette liste. Il n'y a jamais plus de deux caractères dans un élément.

all = [[a, z]], [[a, a]], [[e, r]], [[p, p]] .... (autres éléments similaires)]

Également écrit comme suit:

[[2]]
 [1] "a" "a"

 [[4]] 
 [1] "p" p"

Je voudrais parcourir chaque élément de la liste et tester si les éléments sont identiques. Je voudrais imprimer le nombre d'articles qui correspondent. Par exemple, dans cette liste, je voudrais:

[[1]]
[1] "a" "z"

[[2]]
[1] "a" "a"

[[3]] 
[1] "e" "r"

[[4]] 
[1] "p" p"

Puisque "a" correspond à "a" et "p" correspond à "p". Je voudrais que la boucle for renvoie une valeur de 2, en comptant le nombre de correspondances.

Des suggestions?


2 commentaires

en voici une de plus: sum (sapply (lst, dupliqué))


merci je l'ai ajouté à mon benchmark


3 Réponses :


2
votes

Nous pouvons utiliser Filter pour filtrer les éléments de la liste en créant une condition logique qui vérifie la longueur de unique éléments dans chaque élément list comme 1

lst1 <- list(c('a', 'z'), c('a', 'a'), c('e', 'r'), c('p', 'p'))

Ou une autre option est

sum(sapply(lst1, function(x) do.call(identical, as.list(x))))

données

out <- Filter(function(x) length(unique(x))==1, lst1)
out
#[[1]]
#[1] "a" "a"

#[[2]]
#[1] "p" "p"

length(out)
#[1] 2


0 commentaires

3
votes

Utilisation de sapply avec uniqueN

lst1[sapply(lst1,data.table::uniqueN)==1]
[[1]]
[1] "a" "a"

[[2]]
[1] "p" "p"


4 commentaires

Bienvenue du côté R, gourou de Python Pandas!


@Parfait Merci mec, je ferai de mon mieux pour améliorer mes compétences R :-)


il fonctionne aussi avec dplyr :: n_distinct au lieu de data.table :: uniqueN et est deux fois plus rapide avec dplyr sur mon ordinateur.


@Moody_Mudskipper c'est génial, merci pour l'info :-)



1
votes

Voici 3 autres méthodes:

lst2 <- rep(lst1,1000)

microbenchmark::microbenchmark(
  mm1 = sum((x<-unlist(lst2))[c(T,F)]==x[c(F,T)]),
  mm2 = sum(sapply(lst2,function(x) x[1] == x[2])),
  mm3 = sum(lengths(sapply(lst2,unique))==1),
  akrun = length(Filter(function(x) length(unique(x))==1, lst2)),
  WB  = length(lst2[sapply(lst2,data.table::uniqueN)==1]),
  WB2 = length(lst2[sapply(lst2,dplyr::n_distinct)==1]),
  dd  = sum(sapply(lst2, duplicated)),
  dd2 = sum(sapply(lst2, function(x) duplicated(x)[2]))
)

# Unit: microseconds
#  expr       min        lq      mean    median        uq        max neval    cld
# mm1     146.104   156.972   284.218   160.292   164.368   9357.887   100 a     
# mm2    4141.922  4493.899  5211.921  5043.449  5550.736   8576.352   100  b    
# mm3   15911.727 17504.531 19123.916 19108.955 20324.424  26267.587   100    de 
# akrun 17991.895 19451.122 21222.071 20960.609 22765.172  29885.165   100     e 
# WB    31602.789 36288.222 39258.331 37895.967 39659.628 134526.556   100      f
# WB2   14003.624 15026.653 16783.403 15391.911 16116.695 119739.284   100   c   
# dd    14493.253 15950.668 17077.778 16792.124 17932.125  21876.323   100   cd  
# dd2   16532.970 17768.060 19172.640 18722.867 20769.075  24318.128   100    de 

Et un benchmark:

sum((x<-unlist(lst1))[c(T,F)]==x[c(F,T)])
#[1] 2
sum(sapply(lst1,function(x) x[1] == x[2]))
#[1] 2
sum(lengths(sapply(lst1,unique))==1)
#[1] 2


0 commentaires