【问题标题】:Using dplyr's do to perform bootstrap replications使用 dplyr 的 do 执行引导复制
【发布时间】:2014-11-05 18:04:21
【问题描述】:

我有兴趣使用 dplyr 构建引导复制(重复分析,其中每次首先对数据进行替换采样)。 Hadley Wickham here 提供了一些代码以有效地重复自举分析:

bootstrap <- function(df, m) {
  n <- nrow(df)

  attr(df, "indices") <- replicate(m, sample(n, replace = TRUE), 
    simplify = FALSE)
  attr(df, "drop") <- TRUE
  attr(df, "group_sizes") <- rep(n, m)
  attr(df, "biggest_group_size") <- n
  attr(df, "labels") <- data.frame(replicate = 1:m)
  attr(df, "vars") <- list(quote(boot)) # list(substitute(bootstrap(m)))
  class(df) <- c("grouped_df", "tbl_df", "tbl", "data.frame")

  df
}

library(dplyr)
mboot <- bootstrap(mtcars, 10)

# Works
mboot %.% summarise(mean(cyl))

虽然此函数适用于 summarise,但当 do 包含 data.frame 时,它​​不适用于 do。 (现在假设 data.frame 包含一些有用的东西,例如我们希望引导的分析结果)。

bootstrap(mtcars, 3) %>% do(data.frame(x=1:2))
# Error: index out of bounds

有回溯

11: stop(list(message = "index out of bounds", call = NULL, cppstack = NULL))
10: .Call("dplyr_grouped_df_impl", PACKAGE = "dplyr", data, symbols, 
        drop)
9: grouped_df_impl(data, unname(vars), drop)
8: grouped_df(cbind_list(labels, out), groups)
7: label_output_dataframe(labels, out, groups(.data))
6: do.grouped_df(`bootstrap(mtcars, 3)`, data.frame(x = 1:2))
5: do(`bootstrap(mtcars, 3)`, data.frame(x = 1:2))
4: eval(expr, envir, enclos)
3: eval(e, env)
2: withVisible(eval(e, env))
1: bootstrap(mtcars, 3) %>% do(data.frame(x = 1:2))

我能够通过执行两个do 步骤和一个 group by 来解决这个问题:

bootstrap(mtcars, 10) %>% do(d=data.frame(x=1:2)) %>% group_by(replicate) %>% do(.$d[[1]])

但这似乎需要很多额外的,有些笨拙的步骤(并且还会收到警告,Grouping rowwise data frame strips rowwise nature)。我也知道我可以先将数据复制到十次复制中,例如

data.frame(boot=1:10) %>% group_by(boot) %>% do(sample_n(mtcars, nrow(mtcars), replace=TRUE))

但如果数据或引导复制的数量很大,这在内存中的效率非常低。

有没有办法,也许通过改变bootstrap 设置函数,我可以用bootstrap(mtcars, 3) %&gt;% do(data.frame(x = 1:2)) 执行这些复制?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我认为这是bootstrap 函数中的一个小错误。 vars 属性应与labels 属性中data.frame 中的列名匹配。但是在函数中,vars属性被称为"boot",列名是replicate。所以,如果你做这个小改动:

    bootstrap <- function(df, m) {
      n <- nrow(df)
    
      attr(df, "indices") <- replicate(m, sample(n, replace = TRUE), 
                                       simplify = FALSE)
      attr(df, "drop") <- TRUE
      attr(df, "group_sizes") <- rep(n, m)
      attr(df, "biggest_group_size") <- n
      attr(df, "labels") <- data.frame(replicate = 1:m)
      attr(df, "vars") <- list(quote(replicate)) # Change
    #  attr(df, "vars") <- list(quote(boot)) # list(substitute(bootstrap(m)))
      class(df) <- c("grouped_df", "tbl_df", "tbl", "data.frame")
    
      df
    }
    

    然后它按预期工作:

    bootstrap(mtcars, 3) %>% do(data.frame(x=1:2))
    # Source: local data frame [6 x 2]
    # Groups: replicate
    
    #   replicate x
    # 1         1 1
    # 2         1 2
    # 3         2 1
    # 4         2 2
    # 5         3 1
    # 6         3 2
    

    【讨论】:

      猜你喜欢
      • 2016-07-15
      • 1970-01-01
      • 2020-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多