通常情况下,你应该尝试使用向量化函数来开始处理。如果可能的话,尽量避免使用strsplit
,因为它通常需要之后进行某种形式的迭代(这会更慢)。在你的例子中,你应该使用nchar
代替:
> nchar(words)
[1] 1 5 5 3
更一般地,利用strsplit
返回列表的事实,并使用lapply
:
> as.numeric(lapply(strsplit(words,""), length))
[1] 1 5 5 3
或者使用来自plyr
的l*ply
家族函数。例如:
> laply(strsplit(words,""), length)
[1] 1 5 5 3
编辑:
为了纪念布卢姆之日,我决定使用乔伊斯的《尤利西斯》来测试这些方法的性能:
joyce <- readLines("http://www.gutenberg.org/files/4300/4300-8.txt")
joyce <- unlist(strsplit(joyce, " "))
现在我已经有了所有的单词,我们可以进行计数:
>
> 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
>
> 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
>
> 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
>
> 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
>
> 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
更快(这是使用稍旧版本的情况)。