首页 > 解决方案 > 随机化 R 数据表中组的顺序,同时保留组的内部顺序

问题描述

在 R 中,我有以下示例数据表:

library(data.table)
x <- data.table(Group = c("d1", "d1", "d1", "d1", "d2", "d3", "d3", "d4", "d5", "d5", "d5", "d6", "d7", "d7", "d7", "d7", "d7"))
x[, InternalOrder := seq(.N), by = Group]

看起来像这样:

# Input:
#
    Group InternalOrder
 1:    d1             1
 2:    d1             2
 3:    d1             3
 4:    d1             4
 5:    d2             1
 6:    d3             1
 7:    d3             2
 8:    d4             1
 9:    d5             1
10:    d5             2
11:    d5             3
12:    d6             1
13:    d7             1
14:    d7             2
15:    d7             3
16:    d7             4
17:    d7             5

我的目标是随机化数据表 x 中组的顺序,同时保留每个组的内部顺序。

我已经制定了解决方案

groupsizes <- x[, .N, by = Group]$N  # Get number of elements (= rows) for each group
set.seed(10)
x[, RandomGroupID := rep(sample(c(1:length(unique(x$Group))), replace = F), groupsizes)]  # Make new column with random ID for each group
setorder(x, RandomGroupID, InternalOrder)  # Re-order data by random group ID and internal order

给出所需的输出:

# Output (as desired):

    Group InternalOrder RandomGroupID
 1:    d5             1             1
 2:    d5             2             1
 3:    d5             3             1
 4:    d2             1             2
 5:    d3             1             3
 6:    d3             2             3
 7:    d1             1             4
 8:    d1             2             4
 9:    d1             3             4
10:    d1             4             4
11:    d4             1             5
12:    d7             1             6
13:    d7             2             6
14:    d7             3             6
15:    d7             4             6
16:    d7             5             6
17:    d6             1             7

由于我正在尝试提高我的数据表技能,我想知道是否有一个更好、更惯用的解决方案,它不需要创建向量的中间步骤,groupsizes而是使用典型的数据表语法分配一个新列by论据与.GRP.I或类似的组合。我想到了类似的东西x[, RandomGroupIDAlternative := rep(sample(c(1:length(unique(x$Group))), replace = F), .GRP), by = Group],显然不能提供所需的输出。

我期待您的评论,并期待看到这个问题的替代解决方案。

标签: rdata.table

解决方案


这可以通过加入一个随机的组列表来习惯性地完成。

x[sample(unique(Group)), on = "Group"][, RandomGroupID := .GRP, by = Group][]

推荐阅读