有没有办法在没有for循环的情况下计算数据表中的第4列(超时)?该列的每一行都使用第i-1行,因此在增加行数时需要花费大量时间。
library(data.table)
dt <- data.table(
id = 1:200,
timein = cumsum(runif(200,1,6)),
servtime = runif(200,3,4))
dt[,"timeout"] <- dt$timein # initialisation of timeout column
# update column timeout
for(i in 2:200) {
dt$timeout[i] <- max(dt$timein[i], dt$timeout[i-1]) + dt$servtime[i]
}
答案 0 :(得分:3)
我没有在基础R中看到一个简单的方法来使用矢量化运算符来加快速度,但是你可以使用Rcpp来加速操作:
library(Rcpp)
get.timeout <- cppFunction("
NumericVector getTimeout(NumericVector timein, NumericVector servtime) {
const int n = timein.size();
NumericVector timeout(n);
timeout[0] = timein[0];
for (int i=1; i < n; ++i) {
timeout[i] = fmax(timein[i], timeout[i-1]) + servtime[i];
}
return timeout;
}")
这比使用for循环的解决方案更快:
for.loop <- function(timein, servtime) {
timeout <- dt$timein
n <- length(timeout)
for(i in 2:n) {
timeout[i] <- max(timein[i], timeout[i-1]) + servtime[i]
}
return(timeout)
}
all.equal(for.loop(dt$timein, dt$servtime), get.timeout(dt$timein, dt$servtime))
# [1] TRUE
library(microbenchmark)
microbenchmark(for.loop(dt$timein, dt$servtime), get.timeout(dt$timein, dt$servtime))
# Unit: microseconds
# expr min lq mean median uq max neval
# for.loop(dt$timein, dt$servtime) 414.040 429.5315 438.68765 435.4000 445.1185 506.162 100
# get.timeout(dt$timein, dt$servtime) 22.432 23.9305 28.54934 27.9135 28.6670 97.259 100
对于较大的输入,优势可能会增加。