R:从列表中随机选择项目

R: Randomly Selecting Items from a List

我正在使用 R 编程语言。我想创建一个问题:

在这个问题中,人员列表是随机排序的。此列表的顺序决定谁先“选择”。

根据名单的顺序,名单开头的人将被分配4个随机号码:

这是为所有人完成的随机数分配过程:Rand_1_1、Rand_1_2、Rand_1_3、Rand_1_4、Rand_2_1, Rand_2_2, Rand_2_3, Rand_2_4, Rand_3_1, Rand_3_2, Rand_3_3, Rand_3_4, Rand_4_1 , Rand_4_2, Rand_4_3, Rand_4_4

但是,有一个逻辑约束:

现在,我正在尝试在 R 中编写代码:

首先,我加载了库:

#load libraries

library(dplyr)
library(gtools)

其次,我创建的数据:

#create data

#variable 1: days of the year 

days <- 1:365

#variable 2 : food

food <- c("pizza", "apples", "tacos", "ice cream", "grapes", "olives", "sushi", "chocolate", "cake", "nachos", "pasta", "cookies", "popcorn", "soup")
food_data <- data.frame(food)
food_data$id <-  1:nrow(food_data)

# people 
people <- c("person 1", "person 2", "person 3" ,"person 4")

第三,我创建了人们选择的顺序:

# randomize order of people : this decides the order of who picks "days" and "food"

set.seed(123)

order_of_people = permute(people)

# in this example, "person 3" will pick first, "person 4" will pick second, "person 1" will pick third and "person 2" will pick last

order_of_people
[1] "person 3" "person 4" "person 1" "person 2"

我的问题: 我知道如何为每个人分配一个随机数,但我不知道如何分配随机数以符合逻辑约束。例如:

#choices for person 3 (according to the random seed, person 3 will pick 5 food items)

set.seed(120)

dim = dim(food_data)

#number of items selected by person 3

Rand_3_1 <- sample.int(dim[1], 1)

#which food items selected by person 3 (corresponding to the food_id : "3, 9, 6, 7, 4")
set.seed(120)

Rand_3_2 = c( sample.int(dim[1], 1), sample.int(dim[1], 1), sample.int(dim[1], 1),  sample.int(dim[1], 1), sample.int(dim[1], 1))

#which days selected by person 3 (according to this random seed, "65 to 87")

set.seed(120)

Rand_3_3 <- sample.int(365, 1)
Rand_3_4 <- sample.int(365, 1)

因此,我可以为每个人创建“selection frames”:

#Person 1
Rand_1_1 <- sample.int(dim[1], 1)

Rand_1_2 = c( #fill randomly with amount of items specified by Rand_1_1)

Rand_1_3 <- sample.int(365, 1)
Rand_1_4 <- sample.int(365, 1)

#Person 2
Rand_2_1 <- sample.int(dim[1], 1)

Rand_2_2 = c( #fill randomly with amount of items specified by Rand_2_1)

Rand_2_3 <- sample.int(365, 1)
Rand_2_4 <- sample.int(365, 1)


#Person 3
Rand_3_1 <- sample.int(dim[1], 1)

Rand_3_2 = c( #fill randomly with amount of items specified by Rand_3_1)

Rand_3_3 <- sample.int(365, 1)
Rand_3_4 <- sample.int(365, 1)

#Person 4
Rand_4_1 <- sample.int(dim[1], 1)

Rand_4_2 = c( #fill randomly with amount of items specified by Rand_4_1)

Rand_4_3 <- sample.int(365, 1)
Rand_4_4 <- sample.int(365, 1)

但我不知道如何做到这一点才能遵守逻辑约束。最后,我试图制作这样的东西:

#desired results
Person 1 : "apples, tacos" and "4-51"
Person 2: "cookies, nachos, cake, olives", and "56-180"
Person 3: "ice cream", and "200-214"
Person 4: "sushi, popcorn" and "350-365"

有人可以告诉我怎么做吗?

谢谢

这看起来很简单,除非我遗漏了什么,你有一份食物和日子的清单,所以每次你 运行 通过一个人并且只有 select 来自这些选项:

## initialize the inputs
set.seed(1)
foods <- letters[1:20]
nfoods <- sample(5, 4)
tmp <- list(unpicked = list(food = foods, days = 1:365))

## run it
tmp <- lapply(nfoods, function(x) tmp <<- f(tmp$unpicked$food, x, tmp$unpicked$days))

## summarize it
res <- sapply(seq_along(tmp), function(ii) {
  x <- tmp[[ii]]
  x <- sprintf('person %s: "%s" and "%s"', ii, toString(x$picked$food),
               paste0(x$picked$days, collapse = '-'))
  cat(x, sep = '\n')
  invisible(x)
})
# person 1: "b" and "270-299"
# person 2: "s, a, k, g" and "306-336"
# person 3: "m, t, h" and "42-89"
# person 4: "j, f, q, o, l" and "129-210"


f <- function(food, n, days) {
  # f(1:4, 3, 1:10)
  food1 <- sample(food, n)
  
  days1 <- split(days, cumsum(is.na(days)))
  days1 <- sample(Filter(function(x) length(x) > 2, days1), 1)[[1]]
  days1 <- sort(sample(sort(days1), 2))
  
  days[do.call('seq', as.list(days1))] <- NA
  
  list(
    picked = list(food = food1, days = days1),
    unpicked = list(food = setdiff(food, food1), days = days)
  )
}