从数据表中,每组随机选择一行

时间:2015-11-24 06:44:52

标签: r data.table subset random-sample

我正在寻找一种从数据表中选择行的有效方法,这样我就可以为特定列中的每个唯一值设置一个代表性行。

让我提出一个简单的例子:

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 )

我的目标是通过为z列中的每个字母a-h采样一行来对数据表dt进行子集化。

3 个答案:

答案 0 :(得分:8)

OP在示例中仅提供了一列。假设原始数据集中有多个列,我们按“z”,sample从每个行的行序列中划分1行,获取行索引(.I),使用行索引($V1)并使用它来对'dt'的行进行子集化。

dt[dt[ , .I[sample(.N,1)] , by = z]$V1]

答案 1 :(得分:2)

您可以使用dplyr

library(dplyr)

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

答案 2 :(得分:0)

我认为按行排列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")

下面是一个更大的data.table示例,其中包含3列分组。与@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