R 根据id和data.table解决方案将观察结果分组到指定数量的组中

R 根据id和data.table解决方案将观察结果分组到指定数量的组中,r,data.table,R,Data.table,我有以下数据表: dt <- data.table(id = rep(1:5, 5), obs = rnorm(1, n = 25))[order(id)] dt id obs 1: 1 0.1470735 2: 1 1.6954685 3: 1 2.3947260 4: 1 2.1782338 5: 1 0.5168873 6: 2 -0.8879545 7: 2 1.9320034 8: 2 2.6269272 9: 2 1.521

我有以下数据表:

dt <- data.table(id = rep(1:5, 5), obs = rnorm(1, n = 25))[order(id)]
dt 

   id      obs
1:  1  0.1470735
2:  1  1.6954685
3:  1  2.3947260
4:  1  2.1782338
5:  1  0.5168873
6:  2 -0.8879545
7:  2  1.9320034
8:  2  2.6269272
9:  2  1.5212627
10: 2 -0.1581711
其中id 1和2分配给A组,id 3和4分配给B组,id 5分配给C组

我的实际数据集要大得多,不一定会均匀分组,但我不需要这些分组包含相同数量的ID。我确实需要控制组的一般大小(例如,我希望能够说每个组有5个ID,如果最后一个组只有3个ID就可以了)


有人能帮我一个优雅的数据表方法来完成这个吗

编辑:没有注意到您需要使用
数据表。我将把这个放在这里作为替代

我正在创建一个带有id和随机分配组的数据帧。这将与您的数据结合起来,通过
id
-

library(dplyr)
library(data.table)

dt <- data.table(id = rep(1:5, 5), obs = rnorm(1, n = 25))[order(id)]

max_per_group <- 5
n_ids <- length(unique(dt$id))

data.frame(id = unique(dt$id), grp = sample(rep(LETTERS, max_per_group), n_ids)) %>%
  left_join(dt, ., by = "id")

   id         obs grp
1   1  1.28879713   S
2   1  1.04471197   S
3   1  0.36470847   S
4   1  0.46741567   S
5   1  1.07749891   S
6   2  1.73640785   K
7   2  1.61144042   K
8   2  2.85196859   K
9   2  1.84848117   K
10  2  2.11395863   K
11  3  0.88623462   S
12  3  2.11706351   S
13  3  1.29225433   S
14  3  0.30458037   S
15  3 -1.72070005   S
16  4  2.24593162   U
17  4  2.10346287   U
18  4  2.28724412   U
19  4  0.02978044   U
20  4  0.56234660   U
21  5  2.92050008   F
22  5  1.08048974   F
23  5  0.58885261   F
24  5  1.53299092   F
25  5  1.47271123   F
库(dplyr)
库(数据表)

dt这与@Shree的答案相同,只使用
length.out
in
rep
而不使用dplyr

我确实需要控制组的一般大小(例如,我希望能够说每个组有5个ID,如果最后一个组只有3个ID就可以了)

您可以制作一个id表;在那里分配小组;如有必要,合并回:

# bigger, reproducible example
library(data.table)
max_per_group = 5
n_ids = 1e5+1
DT = data.table(id = rep(1:nid, each = max_per_group), obs = 1)

# make an id table
idDT = unique(DT[, "id"])

# randomly assign groups
idDT[, g := sample(rep(.I, each = 5, length.out = .N))]

# merge back if needed
DT[idDT, on=.(id), g := i.g]
您引用了“我的实际数据集”——但R允许您处理多个表。试图把每件事都集中在一个人身上几乎总是适得其反

# bigger, reproducible example
library(data.table)
max_per_group = 5
n_ids = 1e5+1
DT = data.table(id = rep(1:nid, each = max_per_group), obs = 1)

# make an id table
idDT = unique(DT[, "id"])

# randomly assign groups
idDT[, g := sample(rep(.I, each = 5, length.out = .N))]

# merge back if needed
DT[idDT, on=.(id), g := i.g]