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

R语言无重复分组抽样求助:避免样本内PId重复的解决方案

解决分组抽样中样本内PId不重复的问题

问题背景

需从384行的dataframe中随机抽取24个样本,每个样本包含16条数据,且必须覆盖4个分组因子(Type、Valence、LT、Gender,各2个水平)的所有组合。要求单个样本内的PId不能重复,但原有分组抽样方法会出现同一PId在样本内重复的情况。

核心思路

每个PId对应固定的Gender,且覆盖了Type、Valence、LT的全部8种组合。因此每个样本的16条数据(对应16种因子组合)需从16个不同的PId中抽取(8个M、8个F),每个PId仅贡献其Gender下某一种Type+Valence+LT组合的条目。


方法一:组合匹配式抽样(高效稳定)

直接为每个因子组合分配不重复的PId,避免重复抽样的冗余操作:

library(tidyverse)

# 预处理:按Gender和PId聚合每个被试的所有组合条目
pid_combinations <- df2 %>%
  group_by(Gender, PId) %>%
  nest() %>%
  ungroup()

# 生成所有需要覆盖的因子组合模板
combination_template <- expand_grid(
  Type = c("E", "S"),
  Valence = c("P", "N"),
  LT = c("L", "T"),
  Gender = c("M", "F")
)

set.seed(123) # 保证结果可复现
samples <- map_dfr(seq_len(24), function(sample_num) {
  # 分Gender处理:为每个Gender的8种组合分配8个不重复的PId
  sample_data <- map_dfr(c("M", "F"), function(gender) {
    # 筛选当前Gender的所有PId
    available_pids <- pid_combinations %>% filter(Gender == gender) %>% pull(PId)
    # 随机抽取8个不重复的PId
    selected_pids <- sample(available_pids, size = 8, replace = FALSE)
    # 为选中的PId随机分配对应的Type+Valence+LT组合
    assigned_pairs <- combination_template %>%
      filter(Gender == gender) %>%
      slice_sample(n = 8) %>%
      mutate(PId = selected_pids)
    # 从原数据中匹配对应条目
    df2 %>% inner_join(assigned_pairs, by = c("Gender", "PId", "Type", "Valence", "LT"))
  })
  # 添加样本编号
  sample_data %>% mutate(sample_no = sample_num)
})

# 验证:每个样本的PId是否全部唯一
samples %>%
  group_by(sample_no) %>%
  summarise(unique_pid_count = n_distinct(PId)) %>%
  pull(unique_pid_count) %>%
  all(. == 16) # 返回TRUE则验证通过

方法二:循环抽样直到满足条件(直观易理解)

通过循环重复抽样,直到单个样本内的PId无重复,适合样本量较小的场景:

set.seed(123)
N <- 24
df3 <- tibble()

for (i in 1:N) {
  repeat {
    # 按因子组合随机抽取16条数据
    candidate_sample <- df2 %>%
      group_by(Type, Valence, LT, Gender) %>%
      slice_sample(n = 1) %>%
      ungroup()
    # 检查样本内PId是否重复
    if (n_distinct(candidate_sample$PId) == 16) break
  }
  # 合并样本并添加编号
  df3 <- df3 %>% bind_rows(candidate_sample %>% mutate(sample_no = i))
}

# 验证结果
df3 %>% group_by(sample_no) %>% summarise(n_distinct(PId)) %>% pull() %>% all(. ==16)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 02:35:16