我有以下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.5212627
10: 2 -0.1581711
总共有5个不同的ID(数字1至5),每个ID有5个观察值(obs)。我想根据ID将ID随机分组为X个ID组,并用分组创建一个新列。对于此示例,假设我要以这样一个data.table结尾:
id obs group
1: 1 0.1470735 A
2: 1 1.6954685 A
3: 1 2.3947260 A
4: 1 2.1782338 A
5: 1 0.5168873 A
6: 2 -0.8879545 A
7: 2 1.9320034 A
8: 2 2.6269272 A
9: 2 1.5212627 A
10: 2 -0.1581711 A
其中将ID 1和2分配给A组,将ID 3和4分配给B组,将ID 5分配给C组。
我的实际数据集要大得多,不一定会均匀分组,但是我不需要分组包含相同数量的ID。我确实需要控制组的总体大小(例如,我希望每个组可以说5个ID,如果最后一个组只有3个ID可以)。
有人可以用一种优雅的data.table方法来帮助我吗?
答案 0 :(得分:2)
这与@Shree的答案相同,只是在length.out
中使用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允许您处理多个表。试图将所有事情合而为一几乎总是适得其反。
答案 1 :(得分:1)
编辑:没注意到您需要data.table
使用它。我将把它留在这里作为替代。
我正在创建具有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