如何用data.table高效实现千次随机计算并生成带迭代标识的扩展行
R data.table 无循环重复模拟计算实现方案
以下两种实现方案均无显式循环,依托data.table原生向量化运算实现高效计算,同时保留全部模拟结果与模拟序号标识:
方案1:全量复制后统一计算
适合中小规模原始数据集,逻辑直观易理解:
library(data.table) # 原始数据集 dt <- data.table(Group=c(rep("A",3),rep("B",3)), Year=rep(2020:2022,2), N=c(300,350,400,123,175,156), Count=c(25,30,35,3,6,8), Pop=c(1234,1543,1754,2500,2600,2400)) n_sim <- 1000 # 模拟次数 dt_result <- dt[rep(1:.N, n_sim)] # 将原数据集每一行重复1000次 dt_result[, sim_id := rep(1:n_sim, each = nrow(dt))] # 新增模拟序号列 dt_result[, c("rate", "value") := { rate <- rpois(.N, lambda = Count)/Pop * 100000 value <- N * rate / 100000 .(rate, value) }]
方案2:分组生成模拟值(更优,适合大型数据集)
依托data.table的分组运算能力,逐行生成对应1000次的模拟结果,无需提前全量复制原始数据,内存占用更低、运算速度更快:
library(data.table) dt <- data.table(Group=c(rep("A",3),rep("B",3)), Year=rep(2020:2022,2), N=c(300,350,400,123,175,156), Count=c(25,30,35,3,6,8), Pop=c(1234,1543,1754,2500,2600,2400)) n_sim <- 1000 dt_result <- dt[, { rpois_val <- rpois(n_sim, lambda = Count) .( sim_id = 1:n_sim, rate = rpois_val / Pop * 100000, value = N * rpois_val / 100000 ) }, by = .(Group, Year, N, Count, Pop)]
结果说明
两种方案输出的结果格式完全一致:
- 包含所有原始字段(Group、Year、N、Count、Pop)
sim_id列取值1~1000,对应每次模拟的序号- 包含对应每次模拟生成的
rate和value字段
内容的提问来源于stack exchange,提问作者jsirgo
相关产品推荐
相关产品推荐

