Có cách nào đơn giản và nhanh chóng để có được tần suất của mỗi số nguyên xảy ra trong một vectơ các số nguyên trong R?Cách nhanh nhất để thu được tần số của các số nguyên trong một vector là gì?
Dưới đây là những nỗ lực của tôi cho đến nay:
x <- floor(runif(1000000)*1000)
print('*** using TABLE:')
system.time(as.data.frame(table(x)))
print('*** using HIST:')
system.time(hist(x,breaks=min(x):(max(x)+1),plot=FALSE,right=FALSE))
print('*** using SORT')
system.time({cdf<-cbind(sort(x),seq_along(x)); cdf<-cdf[!duplicated(cdf[,1]),2]; c(cdf[-1],length(x)+1)-cdf})
print('*** using ECDF')
system.time({i<-min(x):max(x); cdf<-ecdf(x)(i)*length(x); cdf-c(0,cdf[-length(i)])})
print('*** counting in loop')
system.time({h<-rep(0,max(x)+1);for(i in seq_along(x)){h[x[i]]<-h[x[i]]+1}; h})
#print('*** vectorized summation') #This uses too much memory if x is large
#system.time(colSums(matrix(rbind(min(x):max(x))[rep(1,length(x)),]==x,ncol=max(x)-min(x)+1)))
#Note: There are some fail cases in some of the above methods that need patching if, for example, there is a chance that some integer bins are unoccupied
và đây là kết quả:
[1] "*** using TABLE:"
user system elapsed
1.26 0.03 1.29
[1] "*** using HIST:"
user system elapsed
0.11 0.00 0.10
[1] "*** using SORT"
user system elapsed
0.22 0.02 0.23
[1] "*** using ECDF"
user system elapsed
0.17 0.00 0.17
[1] "*** counting in loop"
user system elapsed
3.12 0.00 3.12
Như bạn thấy table
là ridiculously chậm và hist
có vẻ là nhanh nhất. Nhưng hist
(như tôi đang sử dụng nó) đang làm việc trên các điểm ngắt tùy ý-specifiable, trong khi tôi chỉ đơn giản muốn bin số nguyên. Không có cách nào để giao dịch tính linh hoạt đó cho hiệu suất tốt hơn?
Trong C, for(i=0;i<1000000;i++)h[x[i]]++;
sẽ nhanh chóng bị phồng rộp.
nội tuyến có thể hơi khó khăn để làm việc. Trên Windows, bạn cần [rtools package] (http://cran.r-project.org/bin/windows/Rtools/), nhưng tôi không chắc về Ubuntu. Tôi chạy thử nghiệm của bạn với mã của tôi và nó thoải mái thắng, 4 lần nhanh hơn so với các giải pháp tabulate. – Joe