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

时间:2018-10-17 00:53:07

标签: r data.table

我有以下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方法来帮助我吗?

2 个答案:

答案 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