在boot::boot()中使用dplyr进行自助抽样时遇group_by_错误求助
解决Bootstrap抽样比例时的
group_by_错误问题 错误原因分析
你遇到的no applicable method for 'group_by_' applied to an object of class "character"错误,核心原因是数据框自动降维:当boot包执行抽样时,如果某次抽样仅选中单行数据,d[i,]会默认把单列数据框转换为字符向量(R的原生行为),而dplyr::count()需要处理数据框对象,因此触发了方法不匹配的报错。
修正后的函数代码
只需要在抽样步骤添加drop=FALSE参数,强制保持结果为数据框格式,避免降维即可解决问题:
library(dplyr) library(boot) notes_bootstrap <- function(d, i){ # 强制保持数据框结构,防止单行抽样时降维为向量 sampler <- d[i,, drop = FALSE] # 计算各分类的占比 proportion_table <- sampler %>% count(notes) %>% mutate(proportion = n / sum(n)) %>% ungroup() # 补全所有可能的分类,将未出现的分类比例设为0 global_set <- d %>% distinct(notes) final_table <- proportion_table %>% right_join(global_set, by = "notes") %>% mutate(proportion = if_else(is.na(proportion), 0, proportion)) %>% select(notes, proportion) # 转换为boot包要求的命名向量格式 output <- setNames(final_table$proportion, final_table$notes) return(output) } # 测试运行 foo <- structure(list(notes = c("a", "b", "c", "c", "b", "c", "b", "c", "a", "a", "c", "b", "d", "e", "f", "f", "g", "a", "b", "c", "c")), class = "data.frame", row.names = c(NA, -21L)) bootstrap_analysis <- boot(foo, notes_bootstrap, R = 100)
更高效的替代方案
如果追求代码简洁和运行效率,可以用table()函数替代dplyr的多步操作,避免频繁的数据框转换:
notes_bootstrap_fast <- function(d, i){ sampler <- d[i,, drop = FALSE] # 用factor强制指定所有可能的分类水平,table会自动补全未出现分类的频数为0 freq_table <- table(factor(sampler$notes, levels = unique(d$notes))) # 直接计算比例并返回向量 return(as.vector(freq_table / sum(freq_table))) } # 快速运行抽样 bootstrap_analysis_fast <- boot(foo, notes_bootstrap_fast, R = 100)
这个方案利用factor的水平特性,让table()自动补全缺失分类的计数,代码更简洁,运行速度也比dplyr流程更快。
查看置信区间结果
抽样完成后,你可以用boot.ci()提取任意分类的置信区间,比如查看分类"a"的结果:
boot.ci(bootstrap_analysis, index = which(names(bootstrap_analysis$t0) == "a"))
内容的提问来源于stack exchange,提问作者davidjohnbaker
相关产品推荐
相关产品推荐

