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

如何在R中对超大规模计数型数据框抽样避免内存溢出?

解决超大规模加权抽样的内存问题

你的错误根源在于tidyr::uncount(count)这一步:把每个ID按count值展开成对应行数的行后,总数据量达到1013条,远远超过R能处理的向量最大长度(约2×109),直接触发内存溢出和向量超限错误。

根本不需要展开原始数据,直接基于ID的count值作为权重进行抽样即可,以下是两种高效可行的方案:

方案1:用dplyr的slice_sample直接加权抽样

这种方法直观易懂,适合快速实现:

target_size <- 1e12  # 替换成你的目标抽样规模:1e12/1e11等
total_count <- sum(df2$count)

df_random[[i]] <- df2 %>%
  mutate(ID = factor(ID)) %>%
  # 按count作为权重,有放回抽取target_size个样本
  slice_sample(n = target_size, replace = TRUE, weight_by = count) %>%
  # 统计每个ID的抽样次数
  count(ID, name = "value", .drop = FALSE)

方案2:用多项分布直接生成抽样次数(更高效)

当目标抽样规模极大时,直接生成每个ID的抽样次数比逐次抽样更快,核心是利用rmultinom函数基于多项分布计算结果:

target_size <- 1e12
total_count <- sum(df2$count)

df_random[[i]] <- df2 %>%
  mutate(
    ID = factor(ID),
    # 计算每个ID的抽样概率
    prob = count / total_count
  ) %>%
  # 生成每个ID的抽样次数
  mutate(value = rmultinom(n = 1, size = target_size, prob = prob)[, 1]) %>%
  select(ID, value) %>%
  # 确保所有ID都保留,即使抽样次数为0
  tidyr::complete(ID, fill = list(value = 0))

注意事项

  • 若需要无放回抽样:当抽样比例极低(比如1%以下),有放回抽样的结果和无放回几乎无差异;若抽样比例较高且必须无放回,可以用sample(df2$ID, size = target_size, replace = FALSE, prob = df2$count)后再统计频次,但这种方式在target_size极大时速度会比方案2慢。
  • 确保count列的数值类型正确:如果是整数型,转换为numeric后计算概率不会有精度问题。

内容的提问来源于stack exchange,提问作者mel099

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 16:12:46