在R中生成随机数

4
在R语言中如何生成150个随机数,且至少使用1到100之间的每个数字一次?
library(tidyverse)
set.seed(123)
df <- tibble(Random_number = sample(x = 1:100,
                                    size = 150,
                                    replace = TRUE)) %>% 
  arrange(Random_number)

例如,数字1、2、3等从未出现过。 我知道这个脚本不足以使数字1到100至少出现一次,正如我所期望的那样,但我不知道如何实际编写脚本。

你错过了一个非常重要的点,那就是“随机”可以有很多含义。这让早期的iPod用户感到困惑,因为他们不理解它。正如答案所建议的那样,你将“已知集合的随机顺序”与“带替换的随机选择”结合在了一起。 - Carl Witthoft
4个回答

6
你可以将程序分为两部分:一部分是确保 1:100,另一部分是从 1:100 中抽取额外的 50 个样本,例如:
sample(c(1:100, sample(1:100, 50, replace = TRUE)))

你说得对,我们不需要对1到100进行“采样”。从你的逻辑中学到了很多!+1!! - benson23
抱歉回复晚了。我按照你的建议使用了代码,得到了预期的结果。非常感谢你。 将随机数生成操作分为两部分很简单。(我缺乏想象力) - NOZOMI

4

这里有一个函数,它会至少一次地对从1到n的所有数字进行抽样。最终的sample会对一个向量进行随机排列,该向量:

  1. 如果n大于或等于size,则只是数n。这是因为sample(n)将随机排列序列1:n
  2. 如果size大于n,则是序列1:n加上size-n个数在1:n中。
fun <- function(n, size, replace = TRUE) {
  x <- if(n >= size) n else c(seq.int(n), sample(n, size - n, replace = replace))
  sample(x)
}

set.seed(2023)
table(fun(100, 150))
#> 
#>   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19  20 
#>   1   1   2   2   2   1   1   1   2   1   1   1   1   1   1   1   2   1   2   1 
#>  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36  37  38  39  40 
#>   1   1   1   2   1   2   1   1   2   2   1   2   2   2   1   2   2   2   2   2 
#>  41  42  43  44  45  46  47  48  49  50  51  52  53  54  55  56  57  58  59  60 
#>   2   2   1   2   2   2   2   2   2   1   1   2   1   1   1   2   2   1   1   2 
#>  61  62  63  64  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80 
#>   1   1   2   2   2   1   1   2   1   2   1   2   1   1   2   2   1   2   2   2 
#>  81  82  83  84  85  86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 
#>   2   1   2   1   1   2   1   1   1   2   2   1   2   1   2   2   1   2   1   1

使用 reprex v2.0.2 于2023-04-08创建


1
我会添加一个 replace 参数,可能默认为 TRUE。否则,当 size > 2n 时,函数将失败。 - zephryl
我敢打赌,由于if-else语句的存在,这个程序会比其他答案运行得更慢...我要去测试一下了! - Carl Witthoft
感谢您的出色回答。我认为将其定义为一个函数会非常有用,因为在模拟研究中很可能需要生成多次随机数。 - NOZOMI

4
我们可以对数字进行三次抽样来实现您的目标。第一次从1到100中有放回地随机抽取50个数字。第二次随机排列1到100的顺序。第三次将以上两个输出进行抽样以随机化150个数字。
请注意,上述后两个抽样使用默认的无放回抽样方法。
library(dplyr)

set.seed(123)

df <- tibble(Random_number = sample(c(sample(1:100, 50, replace = T), sample(1:100))))

table 结果显示,数字 1 到 100 至少被抽取了一次。

table(df$Random_number)

  1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17 
  1   2   1   1   1   1   1   2   1   1   2   2   3   1   1   2   1 
 18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34 
  1   2   3   2   2   1   1   1   2   1   1   1   3   2   1   3   1 
 35  36  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51 
  2   2   1   1   2   2   2   3   1   1   1   1   2   1   1   3   1 
 52  53  54  55  56  57  58  59  60  61  62  63  64  65  66  67  68 
  1   1   1   1   1   1   1   1   1   1   1   2   1   1   1   2   1 
 69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85 
  2   1   1   1   1   3   1   2   2   1   1   1   4   3   2   2   1 
 86  87  88  89  90  91  92  93  94  95  96  97  98  99 100 
  1   1   1   2   1   1   1   2   4   1   3   1   2   1   1 

1
非常感谢您的出色回答。 我所缺乏的是灵活性。 此外,还感谢您修改了用于问题的代码! - NOZOMI

3

好吧,我错了(请参见Rui的回答评论)。尽可能避免使用sample可以使事情运行得更快。

Rgames> n = 1e4
Rgames> size = 1.5e4
Rgames> microbenchmark(rifelse(n,size), rtrisamp(n,size), rbisamp(n,size))
Unit: microseconds
              expr      min        lq      mean    median        uq       max neval cld
  rifelse(n, size)  849.655  968.8905  982.1622  975.5885  996.2145  1089.916   100 a  
 rtrisamp(n, size) 2261.861 2365.4385 2587.5585 2374.7670 2390.5145 13360.855   100   c
  rbisamp(n, size) 1400.847 1576.1280 1684.7027 1584.5185 1592.8440 11510.640   100  b

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接