从池中随机采样值,以使总和小于R中的阈值

时间:2018-09-24 20:16:54

标签: r simulation

比方说,我们有一个值池,我想从该池中抽样随机数的值,以便这些值的总和介于两个阈值之间。我想在R中设计一个函数来实现该功能。

pool = data.frame(ID = letters, value = sample(1:5, size = 26, replace = T))
> print(pool)
   ID  value
1  a     1
2  b     4
3  c     4
4  d     2
5  e     2
6  f     4
7  g     5
8  h     5
9  i     4
10 j     3
11 k     3
12 l     5
13 m     3
14 n     2
15 o     3
16 p     4
17 q     1
18 r     1
19 s     5
20 t     1
21 u     2
22 v     4
23 w     5
24 x     2
25 y     4
26 z     1

我想随机采样任何数量的ID,以使这些ID的值之和在两个阈值之间,比如8到10(包括两个边界)。预期结果应如下所示:

  • c(“ a”,“ b”,“ c”)
  • c(“ f”,“ g”)
  • c(“ a”,“ d”,“ e”,“ j”,“ k”)

我认为以前没有问过这个问题。有人知道吗?

1 个答案:

答案 0 :(得分:1)

这是一种我对输入进行混洗并检查经过混洗的输出的累积总和以寻找可接受的总和的方法。

如果该初始序列的一个子集恰好起作用,它将输出该序列(在此表示中,最大阈值下的最长序列)。如果它不起作用,它将重新组合并再次查找,直至达到最大迭代次数。

set.seed(42)
library(dplyr)
sample_in_range <- function(src_tbl, min_sum = 8, max_sum = 10, max_iter = 100) {
  for(i in 1:max_iter) {
    output <- src_tbl %>% 
      sample_n(nrow(src_tbl)) %>%
      mutate(ID = as.character(ID),
             cuml = cumsum(value)) %>%
      filter(cuml <= max_sum)
    if(max(output$cuml) >= min_sum) return(output)
  }
}

output <- sample_in_range(pool)
output
  ID value cuml
1  k     3    3
2  w     2    5
3  z     4    9
4  t     1   10

output %>% pull(ID)
[1] "k" "w" "z" "t"