【问题标题】:Randomly select number (without repetition) for each group in R为R中的每个组随机选择数字(不重复)
【发布时间】:2020-02-17 14:01:15
【问题描述】:

我有以下数据框,其中包含一个变量“组”和一个变量“每组的元素数”

group    elements
1        3
2        1
3        14
4        10
..       ..
..       ..
30       5

然后我有一堆从 1 到(比如说)30 的数字

当对“元素”求和时,我会得到 900。我想要获得的是从 1-30 中随机选择一个数字(从 0 到 30)并将其分配给每个组,直到我填充该组的元素数.每个应该总共出现 30 次。

因此,对于第 1 组,我想从 0 到 30 中随机选择 3 个数字 对于第 2 组,从 0 到 30 的 1 个数字等,直到我填满所有组。

决赛桌应该是这样的:

group     number(randomly selected)
1           7
1           20
1           7
2           4
3           21
3           20
...

关于如何实现这一点的任何建议?

【问题讨论】:

  • 为什么我们不能一次为所有组选择从 0 到 30 的 n 数字?
  • "当对 "numb" 求和时,我会得到 900" - numb 是什么 - 它没有定义

标签: r random dataset


【解决方案1】:

在基础 R 中,如果你有这样的 df...

df
  group elements
     1        3
     2        1
     3       14

那么你就可以这样做了……

data.frame(group = rep(df$group,                     #repeat group no...
                       df$elements),                 #elements times
           number = unlist(sapply(df$elements,       #for each elements...
                                  sample.int,        #...sample <elements> numbers
                                  n=30,              #from 1 to 30
                                  replace = FALSE))) #without duplicates

   group number
1      1     19
2      1     15
3      1     28
4      2     15
5      3     20
6      3     18
7      3     27
8      3     10
9      3     23
10     3     12
11     3     25
12     3     11
13     3     14
14     3     13
15     3     16
16     3     26
17     3     22
18     3      7

【讨论】:

  • 嗨,实际上我想要重复最多 30 个(每个数字应该出现 30 次),我有 30 个组,其元素总数为 900 (30 x 30)
  • 在这种情况下,您可以在上面执行number = sample(rep(1:30, 30)),这将产生一个长度为 900 的向量,这是 30 次 1:30 重复的随机随机播放(忽略 group)。
【解决方案2】:

试试看:

df <- read.table(text = "group    elements
1        3
2        1
3        14
4        10
30       5", header = TRUE)

# reproducibility
set.seed(1)
df_split2 <- do.call("rbind", 
                     (lapply(split(df, df$group),
                             function(m) cbind(m, 
                                               `number(randomly selected)` = 
                                                 sample(1:30, replace = TRUE, 
                                                        size = m$elements),
                                               row.names = NULL
                                        ))))

# remove element column name
df_split2$elements <- NULL
head(df_split2)
#>     group number(randomly selected)
#> 1.1     1                        25
#> 1.2     1                         4
#> 1.3     1                         7
#> 2       2                         1
#> 3.1     3                         2
#> 3.2     3                        29

split 函数根据group 列将df 拆分为块。然后,我们通过采样1:30 总共elements 时间来获取这些较小的数据帧并添加一列。然后我们在这个名单上do.callrbind 一起回来。

【讨论】:

  • 不确定是否要在结果中重复。您的问题表明您没有,但您的示例在第 1 组中有两个 7。要删除重复,您只需将调用中的 replace = TRUE 更改为 replace = FALSE 即可sample
  • 我的意思是每个重复数字不超过 30 次。每个数字应总共采样 30 次
【解决方案3】:

你必须生成一个重复 $group $element 次的新数据框,然后使用 sample 你可以生成确切数量的随机数:

data<-data.frame(group=c(1,2,3,4,5),
                 elements=c(2,5,2,1,3))

data.elements<-data.frame(group=rep(data$group,data$elements),
                          number=sample(1:30,sum(data$elements)))

结果:

group number
1      1      9
2      1      4
3      2     29
4      2     28
5      2     18
6      2      7
7      2     25
8      3     17
9      3     22
10     4      5
11     5      3
12     5      8
13     5     26

【讨论】:

    【解决方案4】:

    我解决如下:

    random_sample <- rep(1:30, each=30)
    random_sample <- sample(random_sample)
    

    然后我用这个变量和一个变量创建一个 df,其中每行包含一个组,该组由组本身中的元素数重复

    【讨论】:

      猜你喜欢
      • 2023-01-11
      • 1970-01-01
      • 2021-03-18
      • 1970-01-01
      • 2013-04-23
      • 2011-11-13
      • 2016-02-01
      • 1970-01-01
      相关资源
      最近更新 更多