我有一个由研究和实验获得的数据组成的数据集。实验嵌套在研究中。我想对数据集进行子采样,以便每个研究只代表一个实验。我想重复此过程10,000次,每次随机绘制1个实验,然后计算值的一些摘要统计。这是一个示例数据集:
df=data.frame(study=c(1,1,2,2,2,3,4,4),expt=c(1,2,1,2,3,1,1,2),value=runif(8))
我写了以下函数来完成上述操作,但这是永远的。有没有人有任何简化此代码的建议?谢谢!
subsample=function(x,A) {
subsample.list=sapply(1:A,function(m) {
idx=ddply(x,c("study"),function(i) sample(1:nrow(i),1)) #Sample one experiment from each study
x[paste(x$study,x$expt,sep="-") %in% paste(idx$study,idx$V1,sep="-"),"value"] } ) #Match the study-experiment combinations and retrieve values
means.list=ldply(subsample.list,mean) #Calculate the mean of 'values' for each iteration
c(quantile(means.list$V1,0.025),mean(means.list$V1),upper=quantile(means.list$V1,0.975)) } #Calculate overall means and 95% CIs
答案 0 :(得分:1)
你可以通过这种方式进行更多的矢量化(甚至使用plyr),并且速度更快:
function=yoursummary(x)c(quantile(x,0.025),mean(x),upper=quantile(x,0.975))
subsampleX=function(x,M)
yoursummary(
aaply(
daply(.drop_o=F,df,.(study),
function(x)sample(x$value,M,replace=T)
),1,mean
)
)
这里的诀窍是预先进行所有采样。如果我们想要抽样M次,为什么不在你有权访问研究的情况下做所有这些。
> system.time(subsample(df,20000))
user system elapsed
123.23 0.06 124.74
> system.time(subsampleX(df,20000))
user system elapsed
0.24 0.00 0.25
这大约快了500倍。
答案 1 :(得分:1)
这是一个基本R解决方案,由于速度原因,它避免了ddply:
df=data.frame(study=c(1,1,2,2,2,3,4,4),expt=c(1,2,1,2,3,1,1,2),value=runif(8))
sample.experiments <- function(df) {
r <- rle(df$study)
samp <- sapply( r$lengths , function(x) sample(seq(x),1) )
start.idx <- c(0,cumsum(r$lengths)[1:(length(r$lengths)-1)] )
df[samp + start.idx,]
}
> sample.experiments(df)
study expt value
1 1 1 0.6113196
4 2 2 0.5026527
6 3 1 0.2803080
7 4 1 0.9824377
<强>基准强>
> m <- microbenchmark(
+ ddply(df,.(study),function(i) i[sample(1:nrow(i),1),]) ,
+ sample.experiments(df)
+ )
> m
Unit: microseconds
expr min lq median uq max
1 ddply(df, .(study), function(i) i[sample(1:nrow(i), 1), ]) 3808.652 3883.632 3936.805 4022.725 6530.506
2 sample.experiments(df) 337.327 350.734 357.644 365.915 580.097