加速R中的循环

时间:2014-04-22 10:25:28

标签: r for-loop kernel-density

我使用以下函数来估计某些数据的内核密度

KDens = function(x,h,N) {
         fx = matrix(0,N,1)
         Kx = AK(x,h,N)
         for (i in 1:N) {
         fx[i] = sum(Kx[i,], na.rm=T)/N
         }
         return(fx) }

我知道这不是关于加速循环的第一个问题。我在网站上查看过,我发现有时使用某些apply函数会更快,但如果你设法正确设置循环,情况并非总是这样。

在上面的代码中,每个“不需要的东西”都被排除在循环之外,因为 - 如果我理解正确的话 - 建议加速计算。但是,我在上面的KDens函数和默认情况下在R中实现的density函数进行了比较。好吧,density需要1或2秒,而KDens在我的机器上需要~30秒。

trywiththis <- rnorm(4800)
x = trywiththis
N = length(trywiththis)
h = 1.059*sd(trywiththis , na.rm=T)*(N^(-0.2))

编辑:我提供的信息不完整

kerf = function(x){ return(dnorm(x)) }
ker = function(x,x0,h){
       temp = kerf((x-x0)/h)/h
       return(temp)
       }

AK = function(x,h,N) {
      K = array(0,c(N,N))                 
         for (i in 1:N) {
         for (j in 1:N) {
         K[i,j] = ker(x[i],x[j],h) 
       }}
       return(K) }

假设我想加快KDens功能,我怎么能这样做?

1 个答案:

答案 0 :(得分:4)

试试这个......对于原始的4800长度数据集,需要2.5秒。

KDens2 = function(x,h,N) {
Kx <- outer( x , x , FUN = function(x,y) dnorm( ( x-y ) / h ) / h )
fx <- as.matrix( rowSums( Kx ) / N , ncol = 1 )
return( fx )
}

测试

set.seed(1)
trywiththis <- rnorm(480)
x = trywiththis
N = length(trywiththis)
h = 1.059*sd(trywiththis , na.rm=T)*(N^(-0.2))

#Produce same result? (posibly not identical because of 'dnorm' function)
all.equal( KDens(x,h,N) , KDens2(x,h,N) )
[1] TRUE

#Rough timing on N=480 length data...
system.time( KDens2(x,h,N) )
#   user  system elapsed 
#   0.01    0.00    0.02 

system.time( KDens(x,h,N) )
#   user  system elapsed 
#    2.7     0.0     2.7 

N=4800 ...

system.time( KDens2(x,h,N) )
   user  system elapsed 
   2.33    0.19    2.51