我正在寻找一种从数据表中选择行的有效方法,这样我就可以为特定列中的每个唯一值设置一个代表性行。
让我提出一个简单的例子:
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进行子集化。
答案 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