用于分层/多级数据的bootstrap重采样

时间:2012-10-19 21:59:34

标签: r resampling

我正在尝试在多级/分层数据集上进行引导程序重采样。 观察结果是(独特的)患者聚集在医院内。

我的策略是依次对每家医院内的患者进行取样,这将确保所有医院都在样本中代表,并且重复时所有样本的大小都相同。这是方法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。任何进一步的帮助将不胜感激

1 个答案:

答案 0 :(得分:2)

加速自举的常用技巧是立即为每个医院绘制整个样本(所有重复样本),然后将它们分配给重复。这样你每个医院只能运行一次ss1<-。您可以通过不为每家医院进行子集化来改进。另一个巨大的胜利可能来自预先分配而不是rbindMore 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(行号或行名),然后在循环外选择。