根据样本均值按组进行条件抽样

Conditional sampling by group based on sample mean

我正在尝试使用 R 制作一系列不同的琐事测验。我有一个大型数据集 (quiz_df),其中包含许多分为类别和困难的问题,如下所示:

           ID      Category      Difficulty
1           1      Sports            3         
2           2      Science           7        
3           3      Low culture       4         
4           4      High culture      2         
5           5      Geography         8       
6           6      Lifestyle         3   
7           7      Society           3         
8           8      History           5       
9           9      Sports            2
10         10      Science           8         
...       ...      ...             ...    
1000     1000      Science           3    

现在我想从8类中每类随机抽取3道题,使得平均难度为4(或者总和为4*24 = 96)。

library(dplyr)
set.seed(100)

quiz1 <- quiz_df %>% group_by(Category) %>% sample_n(3)

这会创建一个随机测验集,每个类别有 3 个问题,但不考虑难度。我知道 sample_n:

中的权重选项
library(dplyr)
set.seed(100)

quiz1 <- quiz_df %>% group_by(Category) %>% sample_n(3, weight = Diffculty)

但这并不能解决问题。理想情况下,我想添加一个选项,例如:sum = 96, or mean = 4.

有人有线索吗?

这是一个brute-force解决方案:

library(dplyr)

# Generating sample data.
set.seed(1986)

n = 1000
quiz_df = data.frame(id = 1:n, 
                     Category = sample(c("Sports", "Science", "Society"), size = n, replace = TRUE), 
                     Difficulty = sample(1:10, size = n , replace = TRUE))


# Solution: resample until condition is met.
repeat {
  temp.draw = quiz_df %>% group_by(Category) %>% slice_sample(n = 3) # From documentation, sample_n() is outdated!
  temp.mean = mean(temp.draw$Difficulty)
  
  if (temp.mean == 4) # Check if the draw satisfies your condition.
  {
    final.draw = temp.draw
    break
  }
}

final.draw
mean(final.draw$Difficulty)

首先,由于您是 SO 的新手,让我告诉您,您应该始终在您的问题中包含一些示例数据 - 不仅仅是结构,而是我们可以在我们的机器上 运行 的东西。无论如何,这次我只是模拟了一些数据,仅包括 Category 的三个实例。我的解决方案 运行 不到两秒,但是对于整个数据集,代码可能需要更多时间。

我们的想法是重新采样,直到我们得到 24 个问题,每个类别三个问题,其平均值 Difficulty 等于 4。显然,这不是一个优雅的解决方案,但它可能是第一步。

我将再次尝试寻找更好的解决方案。我想问题是抽签不是独立的,我会深入研究。

Ps,从文档中我看到 sample_n() 已被 slice_sample() 取代,所以我建议您依赖后者。