Como posso classificar eficientemente os caracteres de cada string em um vetor? Por exemplo, dado um vetor de strings:
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)))
Eu escrevi uma função que irá dividir cada seqüência de caracteres em um vetor, classificar o vetor e recolher a saída:
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)
No entanto, o vetor de strings ao qual preciso aplicar isso é muito longo e essa função é muito lenta. Alguém tem alguma sugestão de como melhorar o desempenho?
r
string
performance
sorting
Powege
fonte
fonte
letters
não são sempre de comprimento três como no seu exemplo, são eles?fixed = TRUE
destrsplit()
pode melhorar o desempenho, pois não irá envolver o uso de regex.Respostas:
Você pode reduzir o tempo minimizando o número de loops, com certeza, e ainda usando o
parallel
pacote ... minha abordagem seria dividir seqüências de caracteres uma vez e, em seguida, classificar e colar o loop:Raspa-se como 4 segundos, mas ainda não é tão rápido ...
Editar
Ok, consegui resolver o problema usando
apply
.. estratégia aqui:1) extrair letras em vez de dividir limites 2) criar uma matriz com os resultados 3) iterar por linhas 4) Classificar 5) Unir
Você evita vários loops e cancelamentos de lista. ... IGNORE:? Ressalva
é que, se as cordas tiverem comprimentos diferentes, será necessário remover qualquer NA vazia ou NAapply
, comoi[!is.na(i) && nchar(i) > 0]
Leva-nos de 10,3 segundos para 3,98
fonte
tmp <- strsplit(strings, split="") unlist(mclapply(tmp, function(i){ paste0(sort(i), collapse = "") }))
stringi
é meu pacote favorito pelo homem agora ...A reimplementação usando
stringi
fornece uma aceleração de aproximadamente 4x. Também editeisort_cat
para usarfixed = TRUE
nostrsplit
, o que o torna um pouco mais rápido. E obrigado a Carl pela sugestão de loop único, que nos acelera um pouco mais.Este método também pode ser usado em paralelo. Criar um perfil do código para ver quais operações realmente demoram mais seria um bom próximo passo, se você quiser ir ainda mais rápido.
fonte
Esta versão é um pouco mais rápida
Mas acho que pode ser otimizado
fonte