我有88.000个观察结果,用1:
编码obs <- rep(1,88000)
另外,我有以下功能,其中进行随机实验。将值p与随机数进行比较;根据结果,x会改变(+ 1)或保持不变。
rexp <- function(x,p){
if(runif(1) <= p) return(x + 1)
return(x)
}
旁边&#34; obs&#34;和&#34; rexp&#34;一个空的数据帧&#34; dat&#34;给出了500行和0列。还有一个占位符&#34;结果&#34;:
dat <- data.frame(row.names = 1:500)
dat$result <- rep(',',500)
我使用以下循环来应用函数&#34; rexp&#34; (对于p = 0.03)向量矢量&#34; obs&#34;并保存&#34; obs&#34;的更改次数。由随机实验引起的结果&#34;结果&#34;在数据框&#34; dat&#34;:
for(i in 1:500){
x <- sapply(obs,rexp,0.03)
x <- table(x)
x <- x[names(x) == 2]
dat$result[i] <- x
}
现在问题:上面的for-Loop基本上可以工作,但是它的性能非常糟糕。执行需要很长时间,通常循环甚至会卡住。在上面的例子中,只使用了88,000个观测值,与880.000一样工作似乎几乎不可能。我不确定为什么表现如此糟糕。例如,在我的设备上,可以在不到一分钟的时间内完成相同的程序(即使有880.000次观察)。我知道for循环应该在r中被绕过,但我不知道如何执行该过程。如果有任何提示可以解释和改善所描述的循环的性能,我将不胜感激!
答案 0 :(得分:2)
我将如何操作:首先,使用rexp
的矢量化版本,如果您只想计算2
的数字而不使用表格,请不要使用表格。{0}使用可以使用整数的字符。
rexp <- function(x, p) {
x + (runif(length(x)) <= p)
}
replicate(500, {
sum(rexp(obs, 0.03) == 2)
})
对于大小为880
的输入:
microbenchmark::microbenchmark(
ME = {
replicate(500, {
sum(rexp(obs, 0.03) == 2)
})
},
OP = {
for(i in 1:500){
x <- sapply(obs,rexp,0.03)
x <- table(x)
x <- x[names(x) == 2]
dat$result[i] <- x
}
},
times = 10
)
Unit: milliseconds
expr min lq mean median uq max neval
ME 18.24666 18.31957 19.64568 20.05481 20.48095 21.69269 10
OP 1362.54543 1395.50414 1426.17977 1414.25281 1439.75136 1542.97861 10