Как я могу эффективно отсортировать символы каждой строки в векторе? Например, задан вектор строк:
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)))
Я написал функцию, которая будет разбивать каждую строку на вектор, сортировать вектор, а затем свернуть вывод:
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)
Однако вектор строк, к которым мне нужно применить это, очень длинный, а эта функция слишком медленная. У кого-нибудь есть предложения по улучшению производительности?
r
string
performance
sorting
Powege
источник
источник
letters
не всегда имеют длину три, как в вашем примере, не так ли?fixed = TRUE
вstrsplit()
может улучшить производительность , поскольку она не будет включать в себя использование регулярных выражений.Ответы:
Вы можете сократить время, минимизировав количество циклов, а затем сделайте это с помощью
parallel
пакета ... мой подход будет разбивать строки один раз, затем в цикле сортировать и вставлять:Бреется как 4 секунды, но все еще не так быстро ...
редактировать
Хорошо, добился успеха, используя
apply
.. стратегию здесь:1) извлекать буквы, а не разбивать границы 2) создавать матрицу с результатами 3) перебирать по строкам 4) сортировать 5) объединять
Вы избегаете многократных циклов и списков ... IGNORE:? Caveat
- если строки различной длины, вам нужно будет удалить все пустые или NA внутриapply
таких, какi[!is.na(i) && nchar(i) > 0]
Занимает у нас от 10,3 с до 3,98
источник
tmp <- strsplit(strings, split="") unlist(mclapply(tmp, function(i){ paste0(sort(i), collapse = "") }))
stringi
мой любимый пакет, безусловно, человек ...Повторная реализация с использованием
stringi
дает примерно 4-кратное ускорение. Я также отредактировалsort_cat
для использованияfixed = TRUE
вstrsplit
, что делает его немного быстрее. И спасибо Карлу за предложение по единой петле, которое ускоряет нас немного больше.Этот метод также может быть использован параллельно. Профилирование кода, чтобы увидеть, какие операции на самом деле занимают больше всего времени, было бы хорошим следующим шагом, если вы хотите пойти еще быстрее.
источник
Эта версия немного быстрее
Но я думаю, что это может быть оптимизировано
источник