¿Cómo puedo ordenar eficientemente los caracteres de cada cadena en un vector? Por ejemplo, dado un vector de cadenas:
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)))
He escrito una función que dividirá cada cadena en un vector, clasificará el vector y luego colapsará la salida:
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)
Sin embargo, el vector de cadenas al que necesito aplicar esto es muy largo y esta función es demasiado lenta. ¿Alguien tiene alguna sugerencia sobre cómo mejorar el rendimiento?
r
string
performance
sorting
Powege
fuente
fuente
letters
no siempre son de la longitud de tres como en su ejemplo, ¿verdad?fixed = TRUE
destrsplit()
puede mejorar el rendimiento, ya que no implica el uso de expresiones regulares.Respuestas:
Puede reducir el tiempo minimizando la cantidad de bucles con seguridad, y hacerlo aún más utilizando el
parallel
paquete ... mi enfoque sería dividir cadenas una vez, luego en el bucle ordenar y pegar:Se afeita como 4 segundos, pero aún no es tan rápido ...
Editar
Bien, lo conseguí usando la
apply
estrategia aquí:1) extraer letras en lugar de dividir límites 2) crear una matriz con los resultados 3) iterar por filas 4) Ordenar 5) Unir
A evitar múltiples bucles y unlisting .... IGNORE:
? Salvedad es si cadenas diferentes longitudes, tendrá que eliminar cualquier vacío o NA dentro de laapply
tales comoi[!is.na(i) && nchar(i) > 0]
Nos lleva de 10.3 segundos a 3.98
fuente
tmp <- strsplit(strings, split="") unlist(mclapply(tmp, function(i){ paste0(sort(i), collapse = "") }))
stringi
es mi paquete favorito de lejos hombre ...La reimplementación usando
stringi
proporciona una aceleración de aproximadamente 4x. También editésort_cat
para usarfixed = TRUE
en elstrsplit
, lo que lo hace un poco más rápido. Y gracias a Carl por la sugerencia de bucle único, que nos acelera un poco más.Este método también podría usarse en paralelo. Perfilar el código para ver qué operaciones realmente toman más tiempo sería un buen próximo paso si desea ir aún más rápido.
fuente
Esta versión es un poco más rápida.
Pero creo que podría estar optimizado.
fuente