我知道你問這個很長一段時間以前,但我認爲,當你擁有的行數變得非常大,我會與大家分享相比for
循環,這將得到更有效的解決方案。在少數行上,速度差異是可以忽略的(for循環甚至可能更快)。這僅依賴於子集和使用rowSums的,是非常簡單的:
## For reproducibility
set.seed(35471)
## Example data - bigger than the original to get and idea of difference in speed
x<-matrix(rnorm(60),20,3)
y<-matrix(rnorm(300),100,3)
# My function which uses grid.expand to get all combinations of row indices, then rowSums to operate on them
rs <- function(x , y){
rows <- expand.grid(1:nrow(x) , 1:nrow(y))
results <- matrix(rowSums(x[ rows[,1] , ] * y[ rows[,2] , ]) , nrow(x) , nrow(y))
return(results)
}
# Your orignal function
flp <- function(x ,y){
results<-matrix(NA,nrow(x),nrow(y))
for (i in 1:nrow(x)){
for (j in 1:nrow(y)){
r1<-x[i,]
r2<-y[j,]
results[i,j]<-sum(r1*r2) ## Example function
}
}
return(results)
}
## Benchmark timings:
library(microbenchmark)
microbenchmark(rs(x, y) , flp(x ,y) , times = 100L)
#Unit: microseconds
# expr min lq median uq max neval
# rs(x, y) 487.500 527.396 558.5425 620.486 679.98 100
# flp(x, y) 9253.385 9656.193 10008.0820 10430.663 11511.70 100
## And a subset of the results returned from each function to confirm they return the same thing!
flp(x,y)[1:3,1:3]
# [,1] [,2] [,3]
#[1,] -0.5528311 0.1095852 0.4461507
#[2,] -1.9495687 1.7814502 -0.3769874
#[3,] 1.8753978 -3.0908057 2.2341414
rs(x,y)[1:3,1:3]
# [,1] [,2] [,3]
#[1,] -0.5528311 0.1095852 0.4461507
#[2,] -1.9495687 1.7814502 -0.3769874
#[3,] 1.8753978 -3.0908057 2.2341414
所以你可以看到,通過使用rowSums
和子集,我們可以比for循環快20倍,當行組合的數量僅僅是如果你有更多的速度差異會更大。
HTH。
看起來不錯。雖然可能沒有比for循環更快,也可能更慢。 –
@DWin是對的。我嘗試了這種方法,我很驚訝的是,「外部」加「矢量化」方法至少與for循環一樣長(儘管我不知道在完成之前我切斷了多長時間)。最後,我發現我可以將我的功能分解成可以使用apply和matrix代數計算的部分,並且這與大約1天相比可以在幾秒鐘內計算出一些大的數據幀。但是,我擔心我不能用其他功能做到這一點。 – klar