Nói chung, bạn nên cố gắng sử dụng chức năng vectơ để bắt đầu. Sử dụng strsplit
sẽ thường xuyên yêu cầu một số loại lặp lại sau đó (sẽ chậm hơn), vì vậy hãy cố gắng tránh nó nếu có thể. Trong ví dụ của bạn, bạn nên sử dụng nchar
thay vì:
> nchar(words)
[1] 1 5 5 3
Tổng quát hơn, tận dụng lợi thế của một thực tế rằng strsplit
trả về một danh sách và sử dụng lapply
:
> as.numeric(lapply(strsplit(words,""), length))
[1] 1 5 5 3
Hoặc người nào khác sử dụng một chức năng l*ply
gia đình từ plyr
. Ví dụ:
> laply(strsplit(words,""), length)
[1] 1 5 5 3
Edit:
Trong danh dự của Bloomsday, tôi quyết định để kiểm tra việc thực hiện các phương pháp sử dụng Joyce của Ulysses:
joyce <- readLines("http://www.gutenberg.org/files/4300/4300-8.txt")
joyce <- unlist(strsplit(joyce, " "))
Bây giờ tôi có tất cả các từ , chúng tôi có thể đếm số lượng:
> # 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
Chức năng vectơ hóa và lapply
nhanh hơn đáng kể so với phiên bản sapply
gốc. Tất cả các giải pháp trả về cùng một câu trả lời (như được thấy bởi đầu ra tóm tắt).
Dường như phiên bản mới nhất của plyr
nhanh hơn (đây là phiên bản cũ hơn một chút).
Cảm ơn Shane, nhưng tôi không nhận được kết quả tương tự từ những gì tôi đang làm. Nó thực hiện một chương trình chữ số kiểm tra Verhoeff. Tôi đã sửa đổi chức năng của mình để tương thích với việc triển khai ở trên, nhưng với đầu vào của một vectơ dài 100.000, tôi nhận được danh sách 8 phần tử từ phần tử đầu tiên và vectơ của 8 phần tử từ phần tử thứ hai (8 là độ dài có khả năng của các phần tử vectơ). – James
@ James: Sau đó, tôi sẽ tưởng tượng rằng phải có một cái gì đó khác đang xảy ra với chức năng của bạn. Như bạn có thể thấy ở trên, tôi đã thử nghiệm điều này trên một vectơ với hơn 270k bản ghi và có cùng kết quả từ mỗi bản ghi. Bạn có thể thử cung cấp thêm mã của bạn hoặc người khác cung cấp một số dữ liệu của bạn. – Shane
Ngẫu nhiên, tôi chỉ cài đặt phiên bản plyr 0.1.9 trong R 2.11.1 và có thời gian tương tự như ở trên. – Shane