Comment puis-je trier efficacement les caractères de chaque chaîne d'un vecteur? Par exemple, étant donné un vecteur de chaînes:
set.seed(1)
strings <- c(do.call(paste0, replicate(4, sample(LETTERS, 10000, TRUE), FALSE)),
do.call(paste0, replicate(3, sample(LETTERS, 10000, TRUE), FALSE)),
do.call(paste0, replicate(2, sample(LETTERS, 10000, TRUE), FALSE)))
J'ai écrit une fonction qui divisera chaque chaîne en un vecteur, triera le vecteur, puis réduira la sortie:
sort_cat <- function(strings){
tmp <- strsplit(strings, split="")
tmp <- lapply(tmp, sort)
tmp <- lapply(tmp, paste0, collapse = "")
tmp <- unlist(tmp)
return(tmp)
}
sorted_strings <- sort_cat(strings)
Cependant, le vecteur de chaînes auquel je dois l'appliquer est très long et cette fonction est trop lente. Quelqu'un a-t-il des suggestions pour améliorer les performances?
r
string
performance
sorting
Powege
la source
la source
letters
ne sont pas toujours de longueur trois comme dans votre exemple, n'est-ce pas?fixed = TRUE
dansstrsplit()
peut améliorer les performances car il ne comportera pas l'utilisation de regex.Réponses:
Vous pouvez réduire le temps en minimisant le nombre de boucles à coup sûr, et le faire en utilisant le
parallel
package ... mon approche serait de fractionner les chaînes une fois, puis de trier et coller les boucles:Se rase en 4 secondes, mais ce n'est toujours pas si rapide ...
Éditer
Ok, je l'ai bien compris en utilisant
apply
.. la stratégie ici:1) extraire des lettres plutôt que de séparer les limites 2) créer une matrice avec les résultats 3) parcourir les lignes 4) trier 5) joindre
Vous évitez les boucles multiples et la suppression de la liste .... IGNORE:? Mise en
garde est que si les chaînes de différentes longueurs, vous devrez supprimer tout vide ou NA dans leapply
tel quei[!is.na(i) && nchar(i) > 0]
Cela nous prend de 10,3 secondes à 3,98
la source
tmp <- strsplit(strings, split="") unlist(mclapply(tmp, function(i){ paste0(sort(i), collapse = "") }))
stringi
est de loin mon paquet préféré ...La réimplémentation à l'aide
stringi
donne une accélération d'environ 4x. J'ai également éditésort_cat
pour l'utiliserfixed = TRUE
dans lestrsplit
, ce qui le rend un peu plus rapide. Et merci à Carl pour la suggestion de boucle unique, qui nous accélère un peu plus.Cette méthode pourrait également être utilisée en parallèle. Le profilage du code pour voir quelles opérations prennent réellement le plus de temps serait une bonne étape suivante si vous voulez aller encore plus vite.
la source
Cette version est légèrement plus rapide
Mais je pense que ça pourrait être optimisé
la source