是否可以将不等大小的样本传递给R中的函数启动

时间:2013-08-15 15:11:45

标签: r

我目前正在R编写关于自举的教程。我确定了boot包中的函数boot。我得到了Efron / Tibshirani(1993)的“引导程序”一书,并且只复制了一些例子。

在这些示例中,他们经常根据不同的样本计算统计数据。例如,他们有一个例子,他们有16只老鼠的样本。这些小鼠中的7只接受了旨在延长试验手术后存活时间的治疗。其余9只小鼠未接受治疗。对于每只小鼠,收集它存活的天数(数值如下)。

现在,我想使用自举方法来确定平均值的差异是否显着。但是,如果我正确理解boot的帮助页面,我不能只将两个不同样本大小的样本传递给函数。我的解决方法如下:

#Load package boot
library(boot)
#Read in the survival time in days for each mouse
treatment <- c(94, 197, 16, 38, 99, 141, 23)
control   <- c(52, 104, 146, 10, 51, 30, 40, 27, 46)
#Call boot twice(!)
b1 <- boot(data = treatment,
           statistic = function(x, i) {mean(x[i])},
           R = 10000)
b2 <- boot(data = control,
           statistic = function(x, i) {mean(x[i])},
           R = 10000)
#Compute difference of mean manually
mean_diff <- b1$t -b2$t

在我看来,这个解决方案有点像黑客。我感兴趣的统计信息现在保存在向量mean_diff中,但我不再获得boot包的所有强大功能。我无法在boot.ci等上致电mean_diff

所以我的问题基本上是,如果我的hack是使用boot中的R包进行引导的唯一方法,以及比较两个不同样本的统计数据。或者还有另一种方式吗?

我考虑过将一个data.frame传递给16行,并添加一列“Group”:

df <- data.frame(survival=c(treatment, control), 
                 group=c(rep(1, length(treatment)), rep(2, length(control))))
head(df)
  survival group
1       94     1
2      197     1
3       16     1
4       38     1
5       99     1
6      141     1

然而,现在我必须告诉boot它必须从前7行中取7个观察值并从最后9行中取9个观察值并将它们视为单独的样本。我不知道该怎么做。

3 个答案:

答案 0 :(得分:1)

我从未真正弄清楚启动的巨大优势是什么,因为手动编写引导程序非常容易。您可以使用replicate尝试以下示例:

myboot1 <- function(){
    booty <- tapply(df$survival,df$group,FUN=function(x) sample(x,length(x),TRUE))
    sapply(booty,mean)
}
out1 <- replicate(1000,myboot1())

通过这种方式,您可以非常轻松地获得大量有用的统计数据:

rowMeans(out1) # group means
diff(rowMeans(out1)) # difference
mean(out1[1,]-out1[2,]) # another way of getting difference
apply(out1,1,quantile,c(0.025,0.975)) # treatment-group CIs
quantile(out1[1,]-out1[2,],c(0.025,0.975)) # CI for the difference

答案 1 :(得分:1)

这是?boot.return中的一个示例:

diff.means <- function(d, f)
{    n <- nrow(d)
     gp1 <- 1:table(as.numeric(d$series))[1]
     m1 <- sum(d[gp1,1] * f[gp1])/sum(f[gp1])
     m2 <- sum(d[-gp1,1] * f[-gp1])/sum(f[-gp1])
     ss1 <- sum(d[gp1,1]^2 * f[gp1]) - (m1 *  m1 * sum(f[gp1]))
     ss2 <- sum(d[-gp1,1]^2 * f[-gp1]) - (m2 *  m2 * sum(f[-gp1]))
     c(m1 - m2, (ss1 + ss2)/(sum(f) - 2))
}
grav1 <- gravity[as.numeric(gravity[,2]) >= 7,]
boot(grav1, diff.means, R = 999, stype = "f", strata = grav1[,2])

可以参考Davison和Hinkley的第3.2节。

答案 2 :(得分:0)

再想一想,我意识到我实际上可以将托马斯的回答与boot结合起来。这是一个解决方案:

b <- boot(data=df, 
           statistic = function(x, i) {
             booty <- tapply(x$survival,x$group,FUN=function(x) sample(x,length(x),TRUE))
             diff(sapply(booty,mean))*-1
           },
           R=10000)

技巧是你为参数statistic提供的函数必须接受索引的参数i,但你在函数中完全忽略了这个参数。相反,你自己做采样。当然,这不是最有效的(因为boot也必须进行抽样),但我想在大多数情况下这不应该是一个大问题。