В общем, вы должны попытаться использовать векторизованную функцию для начала. При использовании strsplit
часто потребуется некоторая итерация (которая будет медленнее), поэтому старайтесь избегать ее, если это возможно. В вашем примере, вы должны использовать nchar
вместо:
> nchar(words)
[1] 1 5 5 3
В более общем плане, воспользоваться тем, что strsplit
возвращает список и использовать lapply
:
> as.numeric(lapply(strsplit(words,""), length))
[1] 1 5 5 3
Или использовать функцию l*ply
семьи из plyr
, Например:
> laply(strsplit(words,""), length)
[1] 1 5 5 3
Edit:
В честь Bloomsday, я решил проверить эффективность этих подходов с использованием Джойса Улисс:
joyce <- readLines("http://www.gutenberg.org/files/4300/4300-8.txt")
joyce <- unlist(strsplit(joyce, " "))
Теперь у меня есть все слова , мы можем делать все от нас зависящее:
> # original version
> system.time(print(summary(sapply(joyce, function (x) length(strsplit(x,"")[[1]])))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
2.65 0.03 2.73
> # vectorized function
> system.time(print(summary(nchar(joyce))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
0.05 0.00 0.04
> # with lapply
> system.time(print(summary(as.numeric(lapply(strsplit(joyce,""), length)))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
0.8 0.0 0.8
> # with laply (from plyr)
> system.time(print(summary(laply(strsplit(joyce,""), length))))
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.000 3.000 4.000 4.666 6.000 69.000
user system elapsed
17.20 0.05 17.30
> # with ldply (from plyr)
> system.time(print(summary(ldply(strsplit(joyce,""), length))))
V1
Min. : 0.000
1st Qu.: 3.000
Median : 4.000
Mean : 4.666
3rd Qu.: 6.000
Max. :69.000
user system elapsed
7.97 0.00 8.03
Векторная функция и lapply
значительно быстрее оригинальной версии sapply
. Все решения возвращают один и тот же ответ (как видно из итогового вывода).
По-видимому, последняя версия plyr
работает быстрее (это немного устаревшая версия).
Спасибо Шейн, но я не получаю одинаковых результатов от того, что я делаю. Его реализация схемы контрольных цифр Verhoeff. Я изменил мою функцию, чтобы быть совместимой с вышеупомянутыми реализациями, но с вводом вектора длиной 100 000, я получаю список из 8 элементов из первого и вектор из 8 элементов из второго (8 - это наиболее вероятная длина векторных элементов). – James
@James: Тогда я бы предположил, что с вашей функцией должно быть что-то еще. Как вы можете видеть выше, я просто проверил это на векторе с более чем 270 тыс. Записей и получил одинаковые результаты от каждого. Вы можете попытаться предоставить больше своего кода или предоставить некоторые свои данные. – Shane
Кстати, я только что установил версию 0.1.9 в R.2.11.1 и имел аналогичные тайминги, как указано выше. – Shane