基于data.table按组随机生成0/1并维持比例,重复计算行期望值
解决方案
1. 按组生成与status比例一致的随机0/1列
你原来的代码用sample(c(1,0), .N, replace=TRUE)无法保证组内0/1比例和status一致,因为replace=TRUE会允许重复抽样,导致每组的1和0数量可能偏离原比例。正确的做法是:先根据每组status的1和0数量生成对应长度的向量,再随机打乱这个向量。
代码实现:
library(data.table) # 示例数据 district <- c(1,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3) village <- c(1,2,3,4,1,2,3,4,5,1,2,3,4,5,6,7) status <- c(1,0,1,0, 1,1,1,0,0,1,1,1,1,0,0,0) datei <- data.table(district, village, status) # 生成与status组内比例一致的随机列 datei[, random_status := sample(c(rep(1, sum(status)), rep(0, .N - sum(status))), .N), by = district]
解释:
sum(status)获取当前组内1的数量,.N - sum(status)获取0的数量rep(1, sum(status))和rep(0, .N - sum(status))生成和原组比例完全一致的向量sample(..., .N)随机打乱这个向量,保证每个元素位置随机但比例不变
2. 重复1000次随机化并计算每行期望值
我们可以通过循环生成1000次随机结果,再对每行的所有结果取均值得到期望值:
set.seed(123) # 设置随机种子,保证结果可复现 n_iterations <- 1000 # 生成1000次随机化结果的列表 random_list <- lapply(1:n_iterations, function(x) { datei[, sample(c(rep(1, sum(status)), rep(0, .N - sum(status))), .N), by = district]$V1 }) # 将列表转换为矩阵(每行对应原数据的一行,每列对应一次迭代) random_matrix <- do.call(cbind, random_list) # 计算每行的均值作为期望值 datei[, exp_status := rowMeans(random_matrix)] # 查看结果 datei
最终输出的exp_status列就是每行在1000次随机化后的期望值,理论上会接近该组1的比例(比如district1的期望值接近0.5,district2接近0.6,district3接近4/7≈0.571)。
内容的提问来源于stack exchange,提问作者Alfa
相关产品推荐
相关产品推荐

