我一直在用rbinom为r中的循环运行 Bootstrap ,但是它们运行的时间太长了。
我想对一个包含1,500,000行的数据集执行引导。
我想对行和进行重新采样,对于每个重新采样的行
1.将两个概率("prob1"和"prob2")归为0和1("prob1_ber"和"prob2_ber")
1.添加新列"配对",其中包含步骤1的合并结果
- rbinom将列"paired"和"positive"的唯一组合分为0和1('prob_final')
1.计算"配对FPR"和"配对TPR"
下面是我的代码:
library(boot)
#making example data
set.seed(1)
d2 <- data.frame(prob1=runif(n=1500000, min=1e-50, max=.9999999999),
prob2=runif(n=1500000, min=1e-44, max=.9999999989),
Positive=sample(c(0,1), replace=TRUE, size=1500000))
#making bootstrap function
function_1 <- function(data, i){
d2<-data[i,]
d2$prob1_ber <- rbinom(nrow(d2), 1, d2$prob1) #bernoulli 1 or 0
d2$prob2_ber <- rbinom(nrow(d2), 1, d2$prob2) #bernoulli 1 or 0
d2$paired <- ifelse(d2$prob1_ber == 1 & d2$prob2_ber == 1, '11',
ifelse(d2$prob1_ber == 0 & d2$prob2_ber ==0, '00',
ifelse(d2$prob1_ber == 1 & d2$prob2_ber ==0, '10',
ifelse(d2$prob1_ber == 0 & d2$prob2_ber ==1, '01', NA))))
d2$prob_final <- ifelse(d2$paired == '00',d2$prob1_ber, NA) #if both negative then negative
for (i in which(d2$paired =='11' & d2$Positive==1)) {
d2$prob_final[i] <- rbinom(1,1,0.9)
}
for (i in which(d2$paired =='11' & d2$Positive==0)) {
d2$prob_final[i] <- rbinom(1,1,0.5)
}
for (i in which(d2$paired =='01' & d2$Positive==1)) {
d2$prob_final[i] <- rbinom(1,1,0.8)
}
for (i in which(d2$paired =='01' & d2$Positive==0)) {
d2$prob_final[i] <- rbinom(1,1,0.1)
}
for (i in which(d2$paired =='10' & d2$Positive==1)) {
d2$prob_final[i] <- rbinom(1,1,0.7)
}
for (i in which(d2$paired =='10' & d2$Positive==0)) {
d2$prob_final[i] <- rbinom(1,1,0.2)
}
pair_FPR <- sum(d2[which(d2$Positive==0),]$prob_final) / nrow(d2[which(d2$Positive==0),])*100
pair_TPR <- sum(d2[which(d2$Positive==1),]$prob_final) / nrow(d2[which(d2$Positive==1),])*100
return(c(pair_FPR, pair_TPR))
}
set.seed(1)
boot_out <- boot(d2, function_1, 1000)
print(boot_out)
这个 Bootstrap 运行时间太长(n = 1000)。有没有办法让它更快?
非常感谢!
1条答案
按热度按时间fnx2tebb1#
有一个很好的理由说“如果你正在使用R,并且考虑使用
for
循环,可能有一个更好的方法来做它”,我认为这是一个很好的例子。你没有给出你的总体目标的上下文或描述,我也没有花时间去理解你的代码。我也很困惑为什么你在某些地方利用了R的矢量化,而在其他地方却没有。
另外,我认为使用
boot
库是一个转移注意力的问题。重要的是函数function_1
的底层性能。最后,我认为没有必要生成150,000,000个观测值--甚至1,500,000个--来调查底层性能。因此,我尝试改进您的功能:
我的测试数据是
注意
function_1(d2, i)
的结果与function_2(d2, i)
的结果不同,这是因为随机数产生的 * 顺序 *。(function_2
从第1行到第n行按顺序工作,function_1 works through rows in groups defined by
对and
为正。)然而,我相信这两个函数的分布性质是相同的。因此,为了比较性能...
执行时间平均相对减少100 *(27.7 - 8.9)/ 27.7 = 67.8%。相对性能可能很大程度上取决于
N
,但我预计N
的好处会增加,因为矢量化相对于循环的好处会随着N
的增加而增加。请记住,使用tidyverse,虽然给出的代码通常易于阅读和维护,但通常不会给予最快的执行时间。
data.table
和base R通常上级。我让别人来改进我的努力。我相信这是可以做到的。