2014-09-11 43 views
10

Tôi quan tâm đến việc sử dụng dplyr để xây dựng bản sao bootstrap (phân tích lặp lại nơi dữ liệu được lấy mẫu lần đầu tiên thay thế mỗi lần). Hadley Wickham here cung cấp một số mã cho lặp đi lặp lại các phân tích bootstrapped một cách hiệu quả:Sử dụng dplyr làm để thực hiện sao chép bootstrap

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)) 

Trong khi chức năng này hoạt động tốt cho summarise, nó không hoạt động cho do khi do chứa một data.frame. (Hãy tưởng tượng bây giờ rằng data.frame chứa một cái gì đó hữu ích như các kết quả của phân tích mà chúng tôi muốn khởi động).

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

với traceback

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)) 

tôi đã có thể làm việc này bằng cách thực hiện hai do bước và một nhóm bởi:

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

nhưng điều này dường như đòi hỏi nhiều thêm , và hơi vụng về, các bước (và cũng nhận được cảnh báo, Grouping rowwise data frame strips rowwise nature). Tôi cũng biết rằng tôi có thể sao chép các dữ liệu thành mười lần lặp đầu tiên với một cái gì đó giống như

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

nhưng nếu dữ liệu hoặc số bootstrap tái tạo là lớn này là cực kỳ hiệu quả trong bộ nhớ.

Có cách nào, có lẽ bằng cách thay đổi chức năng thiết lập bootstrap, để tôi có thể thực hiện các lần sao chép này với bootstrap(mtcars, 3) %>% do(data.frame(x = 1:2))?

Trả lời

6

Tôi nghĩ rằng đó là một lỗi nhỏ trong hàm bootstrap. Thuộc tính vars phải khớp với tên cột trong số data.frame trong thuộc tính labels. Nhưng trong hàm, thuộc tính vars được gọi là "boot" và tên cột là replicate. Vì vậy, nếu bạn thực hiện thay đổi nhỏ này:

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 
} 

Sau đó, nó hoạt động như mong đợi:

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 
Các vấn đề liên quan