You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 14:57:56