在 R 替代方案中使用嵌套循环
Using a nested loop in R alternative
我在 R 中有以下代码,我试图加快速度,因为我知道 R 中的循环速度较慢。有没有一种方法可以在不使用嵌套循环的情况下执行此 R。
# initialize 2 vectors of length 10,000
totalNum <- rep(0,10000)
totalAmt <- rep(0,10000)
values <- sample(200:5000,150000, replace = TRUE)
chances <- # similar to f in length and contains values between 0 and 1
# loop over length of a vector
for (i in 1:150000){
# value between 200-5000
value <- values[i]
# value of number between 0 and 1
chance <- chances[i]
# loop over vectors created
for (j in 1:10000){
# run test
dice <- runif(1)
if (dice < chance){
totalnum[j] <- totalNum[j] + 1
totalAmt[j] <- totalAmt[j] + value
}
}
}
我一直在尝试使用 lapply 或 mapply,但它似乎不适用于这种情况。
lapply
和 mapply
只是隐藏循环,比 for
循环略有改进。要获得显着改进,您需要使用函数的矢量化形式。
内部循环很容易用矢量化形式替换:
#generate all of the rolls
dice<-runif(10000)
#identify the affected index
dicelesschance<-which(dice<chance)
#update the values
totalNum[dicelesschance]<-totalNum[dicelesschance] + 1
totalAmt[dicelesschance]<-totalAmt[dicelesschance] + value
这应该对性能有显着改善。
size = 150000
值和机会向量
library('data.table')
df1 <- data.table(totalNum = rep(0,10000),
totalAmt = rep(0,10000))
values <- sample(200:5000,150000, replace = TRUE)
chances <- runif(n=150000, min=1e-12, max=.9999999999)
invisible( mapply( function(value, chance){
df1[runif(10000) < chance, `:=` (totalNum = totalNum + 1, totalAmt = totalAmt + value)]
return(0)
}, value = values, chance = chances) )
在我的系统上,此代码使用 system.time()
函数在以下时间完成。
# user system elapsed
# 252.83 43.93 298.68
我在 R 中有以下代码,我试图加快速度,因为我知道 R 中的循环速度较慢。有没有一种方法可以在不使用嵌套循环的情况下执行此 R。
# initialize 2 vectors of length 10,000
totalNum <- rep(0,10000)
totalAmt <- rep(0,10000)
values <- sample(200:5000,150000, replace = TRUE)
chances <- # similar to f in length and contains values between 0 and 1
# loop over length of a vector
for (i in 1:150000){
# value between 200-5000
value <- values[i]
# value of number between 0 and 1
chance <- chances[i]
# loop over vectors created
for (j in 1:10000){
# run test
dice <- runif(1)
if (dice < chance){
totalnum[j] <- totalNum[j] + 1
totalAmt[j] <- totalAmt[j] + value
}
}
}
我一直在尝试使用 lapply 或 mapply,但它似乎不适用于这种情况。
lapply
和 mapply
只是隐藏循环,比 for
循环略有改进。要获得显着改进,您需要使用函数的矢量化形式。
内部循环很容易用矢量化形式替换:
#generate all of the rolls
dice<-runif(10000)
#identify the affected index
dicelesschance<-which(dice<chance)
#update the values
totalNum[dicelesschance]<-totalNum[dicelesschance] + 1
totalAmt[dicelesschance]<-totalAmt[dicelesschance] + value
这应该对性能有显着改善。
size = 150000
值和机会向量
library('data.table')
df1 <- data.table(totalNum = rep(0,10000),
totalAmt = rep(0,10000))
values <- sample(200:5000,150000, replace = TRUE)
chances <- runif(n=150000, min=1e-12, max=.9999999999)
invisible( mapply( function(value, chance){
df1[runif(10000) < chance, `:=` (totalNum = totalNum + 1, totalAmt = totalAmt + value)]
return(0)
}, value = values, chance = chances) )
在我的系统上,此代码使用 system.time()
函数在以下时间完成。
# user system elapsed
# 252.83 43.93 298.68