R函数可将观测值平均分为几组

时间:2019-09-06 19:03:30

标签: r grouping combinatorics

我有一个30 x 2数据帧(df),其中一列包含30个人的姓名,第二列包含其ID#。 我想在R中创建一个函数,该函数将30个个体随机且最均匀地分成几组,并且可以处理有无余数的除法。

为澄清起见,此函数将:

•以2个参数作为参数:df和代表组数的整数 •还给我原始的df,但又增加一列,列出每个人随机分配的组号 •如果人数(行)不能除以给定的整数,则剩余的行应在组之间尽可能平均地分配

例如: •如果我希望将30个人分成1组,则我的函数应返回df,并在新列“ group_no”中为每个人分配1(每个人都将分配到同一组)

•如果我想要4个群组,我想看到10个人被分配到2个群组,其余5个人被分配到另外2个群组。

•如果我要8个小组,那么该功能应给我6个小组(每4个人)和2个小组(每3个人),依此类推。

我已经写了一些代码,可以满足我的需要,但是我只是手动输入组,所以不只是随机性或正确性...我想将所有这些写在可以自动执行的函数中执行以下任务:

#My code so far
#For 1 group of 30 people

people=1:30
groups=1
df$group_no <- print(sample(groups))

#For 4 groups (2 groups of 10 people and 2 groups of 5 people)
groups=c(rep(1,5), rep(2,5), rep(3,10), rep(4,10))
df$group_no <- print(sample(groups))

#For 7 groups (3 groups of 6 people and 4 groups of 3 people)
groups=c(rep(1,6), rep(2,6), rep(3,6), rep(4,3), rep(5,3), rep(6,3), rep(7,3))
df$group_no <- print(sample(groups))

#For 8 groups (6 groups of 4 people and 2 groups of 3 people)
groups=c(rep(1,4), rep(2,4), rep(3,4), rep(4,4), rep(5,4), rep(6,4), rep(7,3), rep(8,3))
df$group_no <- print(sample(groups))


#For 10 groups of 3 people each
groups=c(rep(1,3), rep(2,3), rep(3,3), rep(4,3), rep(5,3), rep(6,3), rep(7,3), rep(8,3), rep(9,3), rep(10,3))
df$group_no <- print(sample(groups))


fct_grouping <- function(df, nr_groups) {
 ????? 
}

3 个答案:

答案 0 :(得分:2)

此功能使组大小尽可能接近,并使组分配随机化。


grouper <- function(df, n) {

  # create a random number for each row
  random <- sample(1:nrow(df), replace = FALSE, nrow(df))

  # divide the random number by the group size
  df$group_number <- ceiling(random / (nrow(df) / n))

  return(df)  
}

答案 1 :(得分:1)

以下代码应按照您的要求执行操作,并返回带有分组的向量。

fct_grouping <- function(df, nr_groups) {
    base_number <- floor(nrow(df) / nr_groups)
    rest <- nrow(df) - base_number * nr_groups
    groupings <- sort(c(rep(seq(nr_groups), base_number), if (rest==0) numeric() else seq(rest)))
    return(groupings)
}

答案 2 :(得分:1)

我确定您要寻找的内容应该可以在数学上用R编程,但是很难建模当人数的其余部分与人数不等于0时的情况,因为分配案例的选项不止1个(请考虑定义10个或更多的组数)。另外,您制作的示例不符合您所要求的条件(最相似的组大小)。 这是我能想到的最接近的东西:

df <- data.frame(people = c(1:30))

fct_grouping <- function(df, nr_groups) {

if (nrow(df) %% nr_groups == 0) {
print(cbind(df, sample(nr_groups)))

} else {
print("n is not a multiple of number of people")
}}

df2 <- fct_grouping(df, 5)

#         people sample(nr_groups)
# 1       1                 1
# 2       2                 3
# 3       3                 2
# 4       4                 5
# 5       5                 4
# 6       6                 1
# 7       7                 3
# 8       8                 2
# 9       9                 5
# 10     10                 4
# 11     11                 1
# 12     12                 3
# 13     13                 2
# 14     14                 5
# 15     15                 4
# 16     16                 1
# 17     17                 3
# 18     18                 2
# 19     19                 5
# 20     20                 4
# 21     21                 1
# 22     22                 3
# 23     23                 2
# 24     24                 5
# 25     25                 4
# 26     26                 1
# 27     27                 3
# 28     28                 2
# 29     29                 5
# 30     30                 4