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

使用R或tidyverse调整数据框比例匹配已知参数的实现

用For循环调整数据分布匹配目标比例

完全可以用for循环实现数据裁剪,让最终样本的性别、教育水平分布匹配指定比例。下面是具体实现步骤和代码:

1. 修正测试数据(避免原代码的行数不匹配问题)

原测试数据的sex和schooling行数不一致,先调整为可正常使用的随机数据:

set.seed(123) # 设置随机种子,保证结果可重复
df2 <- data.frame(
  sex = sample(c("m","f"), size = 300, replace = TRUE),
  schooling = sample(c("elementary","highschool","college"), size = 300, replace = TRUE)
)

# 查看当前数据的分布比例
prop.table(table(df2$sex))
prop.table(table(df2$schooling))

2. 定义目标分布比例

# 性别目标比例:女性(f)70%,男性(m)30%
target_sex <- c("f" = 0.7, "m" = 0.3)
# 教育水平目标比例:小学50%,高中30%,大学20%
target_school <- c("elementary" = 0.5, "highschool" = 0.3, "college" = 0.2)

3. 计算可保留的最大样本量

为了保证每个分组都能抽取到目标数量的样本,先计算当前数据能支持的最大最终样本量:

# 按性别计算最大可支撑样本量
max_n_sex <- min(
  sum(df2$sex == "f") / target_sex["f"],
  sum(df2$sex == "m") / target_sex["m"]
)

# 按教育水平计算最大可支撑样本量
max_n_school <- min(
  sum(df2$schooling == "elementary") / target_school["elementary"],
  sum(df2$schooling == "highschool") / target_school["highschool"],
  sum(df2$schooling == "college") / target_school["college"]
)

# 取两者的较小值作为最终样本量(向下取整)
final_n <- floor(min(max_n_sex, max_n_school))

4. For循环实现分组抽样

通过循环遍历每个性别-教育水平的交叉分组,抽取对应数量的样本:

# 生成所有交叉分组的目标数量表
target_counts <- expand.grid(sex = names(target_sex), schooling = names(target_school))
target_counts$proportion <- target_sex[target_counts$sex] * target_school[target_counts$schooling]
target_counts$target_n <- floor(final_n * target_counts$proportion)

# 初始化空数据框存储调整后的数据
adjusted_df <- data.frame()

# 循环抽取每个分组的样本
for(i in 1:nrow(target_counts)){
  # 筛选当前分组的原始数据
  current_group <- df2[df2$sex == target_counts$sex[i] & df2$schooling == target_counts$schooling[i], ]
  
  # 抽取目标数量的样本(如果现有样本足够)
  if(nrow(current_group) >= target_counts$target_n[i]){
    sampled_rows <- sample(nrow(current_group), size = target_counts$target_n[i], replace = FALSE)
    adjusted_df <- rbind(adjusted_df, current_group[sampled_rows, ])
  } else {
    # 若现有样本不足,则全部保留(理论上不会出现,因为已提前计算final_n)
    adjusted_df <- rbind(adjusted_df, current_group)
  }
}

5. 验证调整后的分布

运行以下代码查看最终数据的比例是否符合要求:

prop.table(table(adjusted_df$sex))
prop.table(table(adjusted_df$schooling))

关键说明

  • 采用交叉分组抽样的方式,能同时保证性别和教育水平的分布都匹配目标比例,避免单一维度调整后破坏另一维度的比例
  • 设置set.seed()可以让抽样结果可重复,方便后续验证

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:42:50