代码之家  ›  专栏  ›  技术社区  ›  Miao Cai

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

  •  0
  • Miao Cai  · 技术社区  · 7 年前

    假设我们有一个值池,我想从这个池中随机抽取一些值,这样这些值的总和就在两个阈值之间。我想在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 回复  |  直到 7 年前
        1
  •  1
  •   Jon Spring    7 年前

    这里有一种方法,我洗牌输入并检查洗牌输出的累积和,以寻找一个可接受的和。

    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"