我正在尝试在多级/分层数据集上进行引导程序重采样。 观察结果是(独特的)患者聚集在医院内。
我的策略是依次对每家医院内的患者进行取样,这将确保所有医院都在样本中代表,并且重复时所有样本的大小都相同。这是方法2 here。
我的代码是这样的:
hv <- na.omit(unique(dt$hospital))
samp.out <- NULL
for (hosp in hv ) {
ss1 <- dt[dt$hospital==hosp & !is.na(dt$hospital),]
ss2 <- ss1[sample(1:nrow(ss1),nrow(ss1), replace=T),]
samp.out <- rbind(samp.out,ss2)
}
这似乎有效(但如果有人能看到任何问题,我将不胜感激)。
问题在于它很慢,所以我想知道是否有办法加快速度。
更新
我试图实现Ari B. Friedman的答案,但没有成功 - 所以我稍微修改了它,目的是构建一个矢量,然后索引原始数据帧。这是我的新代码:
# this is a vector that will hold unique IDs
v.samp <- rep(NA, nrow(dt))
#entry to fill next
i <- 1
for (hosp in hv ) {
ss1 <- dt[dt$hospital==hosp & !is.na(dt$hospital),]
# column 1 contains a unique ID
ss2 <- ss1[sample(1:nrow(ss1),nrow(ss1), replace=T),1]
N.fill <- length(ss2)
v.samp[ seq(i,i+N.fill-1) ] <- ss2
# update entry to fill next
i <- i + N.fill
}
samp.out <- dt[dt$unid %in% v.samp,]
这很快!但是,它无法正常工作,因为它只选择最后一行中v.samp
的唯一ID,但是采样是替换的,因此v.samp
中有重复的ID。任何进一步的帮助将不胜感激
答案 0 :(得分:2)
加速自举的常用技巧是立即为每个医院绘制整个样本(所有重复样本),然后将它们分配给重复。这样你每个医院只能运行一次ss1<-
。您可以通过不为每家医院进行子集化来改进。另一个巨大的胜利可能来自预先分配而不是rbind
。 More suggestions on speed improvements.
要重新分配,请计算您需要的条目数量(称之为N.out
)。然后,在循环之前,添加:
samp.out <- rep(NA, N.out)
并将您的rbind
行替换为:
samp.out[ seq(i,i+N.iter) ] <- ss2
i
是您对尚未填充的第一个条目的计算,i+N.iter
是您在本轮中填写数据的最后一个条目。
有关详细信息和技巧,请参阅R Inferno。
<强>更新强>
你有两种方法,你正在混合它们。您可以使v.samp成为一个data.frame,只是实时对其中的所有行进行采样,或者您可以对ID进行采样,然后使用循环外部的ID向量选择一个data.frame。后者的关键是myDF[c(1,1,5,2,3),]
将为您提供一个data.frame,它重复第一行 - 正是您想要的,以及该功能的设计目标。确保v.samp
是一个可以从data.frame中选择的ID(行号或行名),然后在循环外选择。