我对使用dplyr构建bootstrap复制感兴趣(重复分析,其中每次首次采样替换数据)。 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
步骤和一个分组来解决这个问题:
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) %>% do(data.frame(x = 1:2))
执行这些重复?
答案 0 :(得分:6)
我认为这是bootstrap
函数中的一个小错误。 vars
属性应与data.frame
属性中labels
中的列名称匹配。但在函数中,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