我想从数据框中选择n个随机记录的子集,但我想要基于列的唯一值。例如,来自数据集
X1 X2
1 4
1 5
1 6
2 44
2 55
3 444
3 555
3 666
3 777
从这个n = 3,我不想要像:
X1 X2
3 777
3 555
2 55
其中两个记录来自同一种子X1 = 3 但我想要这样的东西:
X1 X2
1 5
2 44
3 555
我该怎么做?
我尝试了以下内容:
df <- data.frame(matrix(c(1,1,1,2,2,3,3,3,3,4,4,4,5,5,5,5,5,4,5,6,44,55,444,555,666,777,4444,5555,6666,10,20,30,40,50),nrow=17,ncol=2))
df.colnames = c("x1","x2")
df[sample(nrow(df),3),]
但它似乎没有给我我想要的东西。如何调整样本以获得我想要的内容?或者我应该使用不同的功能进行子集化
编辑请注意,我的df将会有大约5000万条记录,我可能想要抽取100万条记录。 (如1米独特的数据点)。哪种方法效率最高?
答案 0 :(得分:4)
您可以使用我的&#34; splitstackshape&#34;中的stratified
功能。包,像这样:
library(splitstackshape)
set.seed(1) ## so you can reproduce this
stratified(df, "X1", 1)
# X1 X2
# 1: 1 4
# 2: 2 44
# 3: 3 666
或者,您可以使用&#34; dplyr&#34;中的sample_n
:
library(dplyr)
set.seed(1) ## again, just to reproduce this
df %>% group_by(X1) %>% sample_n(1)
# Source: local data frame [3 x 2]
# Groups: X1
#
# X1 X2
# 1 1 4
# 2 2 44
# 3 3 666
关于您的注释,以下是我的系统上20M行的一些快速计时:
set.seed(1)
df <- data.frame(X1 = sample(1000000, 20000000, TRUE),
X2 = rnorm(20000000))
dim(df)
# [1] 20000000 2
system.time(df %>% group_by(X1) %>% sample_n(1))
# user system elapsed
# 39.687 0.365 40.583
system.time(as.data.table(df)[, list(X2=sample(X2,1)), by=X1])
# user system elapsed
# 10.792 0.156 11.033
system.time(stratified(df, "X1", 1))
# user system elapsed
# 12.351 0.455 12.895
(当然,stratified
还会为您提供开箱即用的其他花哨功能,例如动态子集,取样与组的大小成比例,等等:-))
答案 1 :(得分:3)
尝试
set.seed(1)
aggregate(X2~X1, df, sample, 1)
# X1 X2
#1 1 4
#2 2 44
#3 3 666
或使用data.table
set.seed(1)
setDT(df)[, list(X2=sample(X2,1)), by=X1]
# X1 X2
#1: 1 4
#2: 2 44
#3: 3 666
答案 2 :(得分:3)
这可能是使用dplyr
的另一种方式。
group_by(df, X1) %>%
sample_n(1)
# X1 X2
#1 1 5
#2 2 55
#3 3 777