R 如何通过避免循环来优化代码?
我对一个需要花费大量时间运行的代码有一些问题。有人能帮我一下吗?提前谢谢R 如何通过避免循环来优化代码?,r,optimization,R,Optimization,我对一个需要花费大量时间运行的代码有一些问题。有人能帮我一下吗?提前谢谢 all_dist=c() ddim=dim(b)[1] ddimi=ddim-1 for (k in 1:dim(b)[2]){ for (i in seq(1,ddimi,1)){ for (j in seq(i+1,ddim,1)){ ze=(b[i,k])-(b[j,k])*(b[i,k])-(b[j,k]) all_dist=c(all_dist,ze) }
all_dist=c()
ddim=dim(b)[1]
ddimi=ddim-1
for (k in 1:dim(b)[2]){
for (i in seq(1,ddimi,1)){
for (j in seq(i+1,ddim,1)){
ze=(b[i,k])-(b[j,k])*(b[i,k])-(b[j,k])
all_dist=c(all_dist,ze)
}}}
请注意:
str(b)
数值[1:5,1:30007]-0.000292-0.001384-0.001412-0.002603-0.002848
...
-属性(*,“dimnames”)=2..$:NULL..$:chr[1:30007]“V1”“V2”“V3”“V4”的列表
或者,您可以使用索引向量替换内部两个for循环,并生成一个apply循环,而不是k-for循环:
system.time({
I <- seq(1,ddimi,1)
J <- unlist(lapply(I+1, function(x) seq(x,ddim,1)))
I <- I[rep(seq_along(I), rep((ddim-1):1,length.out=length(I)))]
tt <- as.vector(apply(b, 2, function(x) {x[I] - x[J] * x[I] - x[J]}))
})
# User System verstrichen
# 0.085 0.000 0.085
identical(all_dist, tt)
#[1] TRUE
system.time({
我
或者,您可以使用索引向量替换内部两个for循环,并生成一个apply循环,而不是k-for循环:
system.time({
I <- seq(1,ddimi,1)
J <- unlist(lapply(I+1, function(x) seq(x,ddim,1)))
I <- I[rep(seq_along(I), rep((ddim-1):1,length.out=length(I)))]
tt <- as.vector(apply(b, 2, function(x) {x[I] - x[J] * x[I] - x[J]}))
})
# User System verstrichen
# 0.085 0.000 0.085
identical(all_dist, tt)
#[1] TRUE
system.time({
IFor循环和使用c()
增加向量会减慢速度。最好尝试利用向量化,并使用*apply(或map)尽可能多地使用函数。这里有一些方法可以同时使用sapply
对列进行迭代,创建组合并计算这些组合的乘积和差异:
matFor循环和使用c()增加向量会减慢速度。最好尝试利用向量化,并使用*apply(或map)尽可能多地使用函数。这里有一些方法可以同时使用sapply
对列进行迭代,创建组合并计算这些组合的乘积和差异:
mat如果您的代码正常工作,则最好在上询问此问题如果您的代码正常工作,则最好在上询问此问题
system.time({
I <- seq(1,ddimi,1)
J <- unlist(lapply(I+1, function(x) seq(x,ddim,1)))
I <- I[rep(seq_along(I), rep((ddim-1):1,length.out=length(I)))]
tt <- as.vector(apply(b, 2, function(x) {x[I] - x[J] * x[I] - x[J]}))
})
# User System verstrichen
# 0.085 0.000 0.085
identical(all_dist, tt)
#[1] TRUE
system.time({
mat <- as.vector(sapply(as.data.frame(b), function(x) {y <- combn(x, 2); y[1,] - y[2,] * y[1,] - y[2,]}))
})
# User System verstrichen
# 1.083 0.000 1.082
identical(all_dist, mat)
#[1] TRUE