【发布时间】:2014-01-21 22:59:53
【问题描述】:
所以我想弄清楚是否有更好的方法可以将多个条件语句添加到R 的 if 子句中,以加快处理速度。下面是我编写的一些代码,它们在简单的情况下在大型数据集上运行得非常快,而在不太简单的情况下运行得不是那么快。任何建议都非常感谢!此外,tic-toc 函数位于问题的最底部,以防您想自己运行它并查看该函数的运行速度。
此外,为了直观地了解代码在做什么,第一块只是简单地确定是否有任何一对 x 和 y 的值大于其他所有 x 和 y。
第二段代码做同样的事情,但是,它添加了任何 x 值实际上彼此相等的条件,然后检查哪个具有最低的 y 值。同样,如果任何一个 y 值彼此相等,则检查哪个具有最低的 x 值。
所以,在简单的情况下运行代码我有以下内容:
tic()
x = runif(10000)
y = runif(10000)
front = 1:length(x)
for(i in 1:length(x)){
for(n in 1:length(x)){
if((x[i]>x[n] & y[i]>y[n])){
front[i] = NA
break
}
}
}
toc()
如您所见,我只评估x[i]>x[n] & y[i]>y[n] 的单一条件
目录() 过去 1.28
上面的代码运行时间为 1.28 秒。 现在,当我有三个要检查的条件时运行代码,我有以下内容:
tic()
x = runif(10000)
y = runif(10000)
front = 1:length(x)
for(i in 1:length(x)){
for(n in 1:length(x)){
if((x[i]>x[n] & y[i]>y[n]) | (x[i]==x[n] & y[i]!=min(y[which(x==x[i])])) | (y[i]==y[n] & x[i]!=min(x[which(y==y[i])]))){
front[i] = NA
break
}
}
}
toc()
如您所见,我现在必须检查 if 语句中的三个条件,即,
(x[i]>x[n] & y[i]>y[n]) | (x[i]==x[n] & y[i]!=min(y[which(x==x[i])])) | (y[i]==y[n] & x[i]!=min(x[which(y==y[i])]))
但是,这会导致 R 中的计算负担巨大,并使代码变得更慢。
> toc()
elapsed
74.47
我们看到运行新修改的代码现在显着减慢到 74.47 秒。现在,我正在寻找可以加快我的代码速度的替代函数调用,或者只是以“更好”的方式重写它,以使代码不那么慢。
如果需要,这里是 tic-toc 函数的代码:
tic <- function(gcFirst = TRUE, type=c("elapsed", "user.self", "sys.self"))
{
type <- match.arg(type)
assign(".type", type, envir=baseenv())
if(gcFirst) gc(FALSE)
tic <- proc.time()[type]
assign(".tic", tic, envir=baseenv())
invisible(tic)
}
toc <- function()
{
type <- get(".type", envir=baseenv())
toc <- proc.time()[type]
tic <- get(".tic", envir=baseenv())
print(toc - tic)
invisible(toc)
}
为 sashkello 编辑
所以我的代码现在看起来像这样:
library(mvtnorm)
#Here are the variables I will be working with
> x
[1] 0.53137100 0.75357474 0.87904120 0.29727488 0.00000000 0.00000000
[7] 0.00000000 0.00000000 0.00000000 0.04059217
> y
[1] 4.873500 3.896917 1.258215 5.776484 12.475491 5.273784 13.803158
[8] 4.472204 2.629839 6.689242
> front
[1] NA NA 3 NA NA NA NA NA 9 NA
> all.preds
[1] 0.596905183 0.027696850 1.005666896 0.007688514 3.900000000
x = x[!is.na(front)]
y = y[!is.na(front)]
mu = c(all.preds[1],all.preds[3])
sigma = matrix(c(all.preds[2],0,0,all.preds[4]),nrow=2)
z = rmvnorm(10000,mu,sigma)
z[,1] = sapply(z[,1],function(x){max(x,0)})
points(z,col="black",pch=19,cex=.01)
temp = 1:nrow(z)
for(i in 1:length(temp)){
cond1 = z[i,2]!=min(z[which(z[,1]==z[i,1]),2])
cond2 = z[i,1]!=min(z[which(z[,2]==z[i,2]),1])
for(n in 1:length(x)){
if((z[i,1]>x[n] & z[i,2]>y[n]) | (z[i,1]==x[n] & cond1) | (z[i,2]==y[n] & cond2)){
temp[i] = NA
break
}
}
}
prop = sum(!is.na(temp))/length(temp)
而 cond1 和 cond2 语句仍然需要很长的时间。有什么建议吗?
【问题讨论】:
-
我认为您可以将
cond1和cond2的计算排除在循环之外,并使用outer一次计算所有cond1[i]/cond2[i]。 -
@Roland,你能扩展一下这个想法,和/或提供一个示例代码的 sn-p 吗?
标签: r performance if-statement