来自数据 table,随机 select 每组一行

from data table, randomly select one row per group

我正在寻找一种从数据 table 中提取 select 行的有效方法,这样我就可以为特定列中的每个唯一值创建一个代表行。

举个简单的例子:

require(data.table)

y = c('a','b','c','d','e','f','g','h')
x = sample(2:10,8,replace = TRUE)
z = rep(y,x)
dt = as.data.table( z )

my objective 是通过对 z 列中的每个字母 a-h 采样一行来对数据 table dt 进行子集化。

OP 在示例中仅提供了一个列。假设原始数据集中有多个列,我们从每组行的序列中按'z',sample1行分组,得到行索引(.I),提取列使用行索引 ($V1) 并使用它来对 'dt'.

的行进行子集化
dt[dt[ , .I[sample(.N,1)] , by = z]$V1]

你可以使用 dplyr

library(dplyr)

dt %>%
  group_by(z) %%
  sample_n(1)

我认为按行打乱 data.table 然后应用 unique(...,by) 也可以。组由 by 组成,之前的洗牌在每个组内滴落:

# shuffle the data.table row-wise
dt <- dt[sample(dim(dt)[1])]
# uniqueness by given column(s)
unique(dt, by = "z")

下面是按 3 列分组的更大 data.table 示例。与@akrun 的解决方案相比,似乎给出了相同的分组:

set.seed(2017)
dt <- data.table(c1 = sample(52*10^6), 
                 c2 = sample(LETTERS, replace = TRUE), 
                 c3 = sample(10^5, replace = TRUE), 
                 c4 = sample(10^3, replace = TRUE))
# the shuffling & uniqueness
system.time( test1 <- unique(dt[sample(dim(dt)[1])], by = c("c2","c3","c4")) )
# user  system elapsed 
# 13.87    0.49   14.33 

# @akrun' solution
system.time( test2 <- dt[dt[ , .I[sample(.N,1)] , by = c("c2","c3","c4")]$V1] )
# user  system elapsed 
# 11.89    0.10   12.01 

# Grouping is identical (so, all groups are being sampled in both cases)
identical(x=test1[,.(c2,c3)][order(c2,c3)], 
          y=test2[,.(c2,c3)][order(c2,c3)])
# [1] TRUE

对于每组抽样超过一行检查here