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
inrep
而不使用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]