首页 > 解决方案 > 如何在 R 中的(多个)子组中对行进行采样而不进行替换

问题描述

我有一个随机/抽样问题,我无法理解。假设我想在一个实验中创建一个随机顺序来呈现刺激,其中包含两个变量,颜色和项目,每个变量都有三个级别。

library(dplyr)
set.seed(42)

participant_id <- 1:12
colour <- c("blue", "green", "red")
item <- c("apple", "banana", "pear")

我希望每个参与者在列表中以随机顺序看到颜色和项目的随机配对,但永远不会看到任何单独的值超过一次。

我可以接近下面的代码 - 每个参与者以随机顺序看到每种颜色一次 - 但无法思考如何确保与每种颜色配对的项目也不会重复出现。

# dataframe of all possible combinations
all_permutations <- crossing(participant_id, colour, item) 

my_list <- all_permutations %>%
  group_by(participant_id, colour) %>%
  # randomly sample one row of item, per colour and participant  
  sample_n(1) %>% 
  group_by(participant_id) %>% 
  # randomly re-order within grouping
  sample_frac()

head(my_list, 15) 

# A tibble: 15 x 3
# Groups:   participant_id [5]
   participant_id colour item  
            <int> <chr>  <chr> 
 1              1 blue   pear  
 2              1 red    apple 
 3              1 green  pear  
 4              2 green  banana
 5              2 blue   pear  
 6              2 red    banana
 7              3 blue   pear  
 8              3 green  apple 
 9              3 red    banana
10              4 red    pear  
11              4 green  banana
12              4 blue   pear  
13              5 red    banana
14              5 green  apple 
15              5 blue   pear  

任何建议都感激不尽!提前致谢。

标签: rrandomdplyrpermutation

解决方案


这是一个基本的 R 解决方案。如果你想对一个向量的所有元素只采样一次,那么sample(vec)它就会返回一个vec.

set.seed(42)
res <-lapply(participant_id, function(p){
  data.frame(participant_id = rep(p, length(item)),
             colour = sample(colour), item = sample(item))
})
res <- do.call(rbind, res)
res

推荐阅读