2014-12-02 2 views
0

Я хочу выбрать подмножество n случайных записей из фреймворка данных, но я хочу уникальные значения на основе столбца. Так, например, из набора данныхВыберите подмножество уникальных случайных записей в R

X1 X2 
1 4 
1 5 
1 6 
2 44 
2 55 
3 444 
3 555 
3 666 
3 777 

Отсюда при п = 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 будет содержать около 50 миллионов записей, и я, возможно, захочу пробовать 1 миллион из них. (например, уникальные точки данных 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 
4

Вы можете использовать функцию stratified из моего пакета "splitstackshape", как это:

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 

Кроме того, вы можете использовать sample_n из "dplyr":

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 также даст вам другие колокола и свистки из коробки, такие как динамическое подмножество, выборки, пропорциональные размеру групп, и так далее :-))

+0

А, кажется, я добавил свою идею, когда вы обновили свой ответ! – jazzurro

3

Это сотрудничество uld будет другим способом, используя dplyr.

group_by(df, X1) %>% 
sample_n(1) 

# X1 X2 
#1 1 5 
#2 2 55 
#3 3 777 
Смежные вопросы