【问题标题】:R bootstrap statistics by group for big data大数据组的 R 引导统计
【发布时间】:2013-09-25 14:51:48
【问题描述】:

我想引导一个包含组的数据集。一个简单的场景是引导简单的方法:

data <- as.data.table(list(x1 = runif(200), x2 = runif(200), group = runif(200)>0.5))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2)), by = "group"]}
boot(data, stat, R = 10)

这给了我错误incorrect number of subscripts on matrix,因为by = "group" 部分。我设法使用子集来解决它,但不喜欢这个解决方案。有没有更简单的方法来完成这种任务?

特别是,我想在stat(x, i, groupvar) 之类的统计函数中引入一个附加参数,并将其传递给boot(data, stat(groupvar = group), R = 100) 之类的引导函数?

【问题讨论】:

  • 您要进行分层重采样吗? boot 中有一个 strata 参数。
  • 不,我只想为每个组设置单独的统计值。如果我理解正确,strata 参数可确保您的统计数据不会使用一组数据来计算,不是吗?分层的结果值将是一维的,相反,我想要 n 个结果统计数据,其中 n 是组数

标签: r data.table data-manipulation statistics-bootstrap


【解决方案1】:

使用

 boot       * 1.3-18  2016-02-23 CRAN (R 3.2.3)                        
 data.table * 1.9.7   2015-10-05 Github (Rdatatable/data.table@d607425)

我使用 OP 的代码和@eddi 提供的答案收到错误:

data <- as.data.table(list(x1 = runif(200), x2 = runif(200), group = runif(200)>0.5))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2)), by = "group"]}
data[, list(list(boot(.SD, stat, R = 10))), by = group]$V1

产生错误信息:

Error in eval(expr, envir, enclos) : object 'group' not found 

通过从函数stat 中删除by=group 来修复错误:

set.seed(1000)
data <- as.data.table(list(x1 = runif(200), x2 = runif(200), group = runif(200)>0.5))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2))]}
data[, list(list(boot(.SD, stat, R = 10))), by = group]$V1

这会产生以下引导统计结果:

[[1]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
     original       bias    std. error
t1* 0.5158232  0.004930451  0.01576641
t2* 0.5240713 -0.001851889  0.02851483

[[2]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
     original        bias    std. error
t1* 0.5142383 -0.0072475030  0.02568692
t2* 0.5291694 -0.0001509404  0.02378447

下面,我修改了示例数据集以突出显示哪个 Bootstrap Statistic 与哪个组列组合:

考虑第 1 组,其中 x1 的平均值为 10,x2 的平均值为 10000;第 2 组,x1 的平均值为 2000,x2 的平均值为 8000:

data2 <- as.data.table(list(x1 = c(runif(100, 9,11),runif(100, 1999,2001)), x2 = c(runif(100, 9999,10001),runif(100, 7999,8001)), group = rep(c(1,2), each=100)))
stat <- function(x, i) {x[i, c(m1 = mean(x1), m2 = mean(x2))]}
data2[, list(list(boot(.SD, stat, R = 10))), by = group]$V1

这给出了:

[[1]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
      original       bias    std. error
t1*   10.00907  0.007115938  0.04349184
t2* 9999.90176 -0.019569568  0.06160653

[[2]]

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = .SD, statistic = stat, R = 10)


Bootstrap Statistics :
    original       bias    std. error
t1* 1999.965  0.031694179  0.06561209
t2* 8000.110 -0.006569872  0.03992401

【讨论】:

    【解决方案2】:

    应该这样做:

    data[, list(list(boot(.SD, stat, R = 10))), by = group]$V1
    

    【讨论】:

    • 做得很好。我试图用data.tableby 参数来做到这一点,但无法弄清楚。想解释一下为什么需要list(list(
    • @AriB.Friedman 你需要内部的list 告诉data.table 你在列中存储了一个list(外部的list);也许data[, list(newcol = list(boot(... 会更清楚
    • @eddi 我发现您的答案需要从 OP 提供的 stat 函数中删除 by = group...有关更多详细信息,请参阅我的答案。
    【解决方案3】:

    在您进入按组部分之前,您的代码中存在很多问题。

    你的意思是这样的吗?

    data <- as.data.frame(list(x1 = runif(200), x2 = runif(200), group = factor(sample(letters[1:2]))))
    stat <- function(x, i)  c(m1 = mean(x$x1[i]), m2 = mean(x$x2[i]))
    
    > stat(x,1:10)
           m1        m2 
    0.4465738 0.5522221 
    

    然后你可以从那里担心doing it by group however you choose to

    例如:

    library(plyr)
    dlply( data, .(group), function( dat ) boot(dat, stat, R=10) )
    

    对于更大的数据集,请尝试data.table

    by( seq(nrow(data)), data$group, function(idx) myboot(data[idx,]))
    

    我选择了by() 而不是data.table,by= 参数,因为您希望输出是一个列表。可能有一些我不知道的功能,但我找不到它(请参阅编辑历史记录以了解它导致的问题)。

    子集仍然是通过data.table[]方法完成的,所以应该很快。

    【讨论】:

    • 谢谢,这就是我想要的。但是您发布的链接建议使用 data.table 包来对大型数据集进行子集化和分组(在我的情况下 - 80 万行,220 个组)。我仍然很难为您的解决方案应用 data.table 子集
    • @RInatM 你没有提到大数据 ;-)。我会看看我能做什么,虽然我不是 data.table 专家。
    • @AriB.Friedman data[idx,](其中idx 是行号)使用data.table 并不比使用data.frame 快。
    • @MatthewDowle 使用 .SD 是否像 eddi 的回答那样更快?
    • data[.I] 将为每个组创建新的内存(如splitby 这样做),因此会否定data.table 分组的好处。 .SD 预先分配给最大的组一次,然后为每个组重复使用。如果data的所有列都用完了,那么推荐.SD,并且尽可能快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-21
    • 1970-01-01
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 2019-02-14
    相关资源
    最近更新 更多