在多个条件下分配随机数

问题描述 投票:0回答:1

我的学生提交了小组项目。现在他们应该对其他学生的作品提供反馈。每个学生应该对另外两个学生项目提供反馈。我想随机分配这些项目。必须满足两个条件:

  1. 学生不应该对自己的项目提供反馈。
  2. 学生不应该对同一个项目提供两次反馈。
#Example Data
group <- c(1,1,1,2,2,3,3,3,4,4)
name <- c("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")
feedback1 <- c(1,1,1,2,2,3,3,3,4,4)
feedback2 <- c(1,1,1,2,2,3,3,3,4,4)
df <- data.frame(group, name, feedback1, feedback2)

正如您所看到的,小组的规模不一样(有些小组有 2 名成员,有些有 3 名)。我创建了一个循环来检查某人是否要向自己提供反馈。如果是,则从所有组数中随机选择一个数,直到选择一个合适的数。然后,将从组号码中删除所选号码的一次出现,并检查下一个学生。

# Fill feedback1
for (i in 1:nrow(df)) {
  while (df$feedback1[i] == df$group[i]) {
    df$feedback1[i] <- sample(group, 1)
  }
  group <- group[-match(df$feedback1[i], group)]
}

到目前为止,这有效:


   group name feedback1 feedback2
1      1    a         2         1
2      1    b         3         1
3      1    c         3         1
4      2    d         1         2
5      2    e         1         2
6      3    f         4         3
7      3    g         4         3
8      3    h         2         3
9      4    i         1         4
10     4    j         3         4

如果我添加第二个条件(“学生不应向同一组提供反馈”),循环将无法工作:

# Fill feedback2
group <- c(1,1,1,2,2,3,3,3,4,4)

for (i in 1:nrow(df)) {
  while (df$feedback2[i] == df$group[i] & df$feedback1[i] == df$feedback2[i] ) {
    df$feedback2[i] <- sample(group, 1)
  }
  group <- group[-match(df$feedback2[i], group)]
}

我没有收到错误消息,但 df$feedback2 对所有学生都保持不变:

 group name feedback1 feedback2
1      1    a         2         1
2      1    b         3         1
3      1    c         3         1
4      2    d         1         2
5      2    e         1         2
6      3    f         4         3
7      3    g         4         3
8      3    h         2         3
9      4    i         1         4
10     4    j         3         4
  1. 我的第二个反馈循环中的错误是什么?
  2. (一般来说)解决问题的更好方法是什么?

致以诚挚的问候

r random while-loop conditional-statements
1个回答
0
投票

实际上对于这种情况,循环并不是 R'ly 风格的解决方案。我将提供以下 tidyverse 解决方案(请注意,在评估脚本之前您不需要分配反馈列):

library(tidyverse)

possibleGroups <- df$group %>% unique()
df %>% 
  rowwise() %>% 
  mutate(fb = sample(possibleGroups[possibleGroups != group], size = 2) %>% `names<-`(paste(c("feedback"), 1:2)) %>%  list()
) %>% 
  unnest_wider(fb)

这导致:

# A tibble: 10 × 4
   group name  `feedback 1` `feedback 2`
   <dbl> <chr>        <dbl>        <dbl>
 1     1 a                2            4
 2     1 b                4            2
 3     1 c                3            4
 4     2 d                3            4
 5     2 e                1            3
 6     3 f                1            4
 7     3 g                1            4
 8     3 h                4            1
 9     4 i                3            1
10     4 j                2            3

如果我需要提供其工作原理的任何详细信息,请告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.