Есть ли простой и быстрый способ получить частоту каждого целого числа, которое встречается в векторе целых чисел в R?Каков самый быстрый способ получить частоты целых чисел в векторе?
Вот мои попытки до сих пор:
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
и вот результаты:
[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
Как вы можете видеть table
невероятно медленно и hist
кажется самым быстрым. Но hist
(как я его использую) работает над произвольно заданными точками останова, тогда как я просто хочу целые числа. Разве нет возможности использовать эту гибкость для повышения производительности?
В C, for(i=0;i<1000000;i++)h[x[i]]++;
будет стремительно быстрым.
Inline может быть немного больным для работы. В Windows вам нужен пакет [rtools] (http://cran.r-project.org/bin/windows/Rtools/), но я не уверен в Ubuntu. Я проверил ваши тесты с помощью своего кода, и он с комфортом выиграл, в 4 раза быстрее, чем решение в виде таблиц. – Joe