2016-11-16 7 views
1

Вот пример данныхКак выбрать отдельные (случайные) строки, которые можно сгруппировать по значениям столбца?

p <- structure(list(name = structure(1:5, .Label = c("Alice", "Bob", 
"Charlie", "Dennis", "Earl"), class = "factor"), cohort = structure(c(3L, 
3L, 2L, 2L, 1L), .Label = c("X", "Y", "Z"), class = "factor"), 
    group = structure(c(1L, 1L, 2L, 2L, 1L), .Label = c("A", 
    "B"), class = "factor"), var = c(1L, 2L, 1L, 3L, 4L)), .Names = c("name", 
"cohort", "group", "var"), class = "data.frame", row.names = c(NA, 
-5L)) 

, который выглядит как

 name cohort group var 
1 Alice  Z  A 1 
2  Bob  Z  A 2 
3 Charlie  Y  B 1 
4 Dennis  Y  B 3 
5 Earl  X  A 4 

и мне нужно что-то вроде следующего, на основе cohort колонке. Мне нужно пробовать одну строку в каждом cohort (возможно, случайно), так что у меня нет нескольких людей, принадлежащих к одному cohort.

 name cohort group var 
2  Bob  Z  A 2 
3 Charlie  Y  B 1 
5 Earl  X  A 4 

я могу group_by когорты, но я не уверен, как действовать, чтобы создать новый фрейм данных с только строки, которые мне нужны.

+2

Другая база r: 'idx = sapply (split (rownames (p), p $ когорт), образец, 1); p [idx,] ' – user20650

ответ

2

Вы можете сгруппировать по cohort и трубы его sample_n где 1 указывает на то, что вы хотите один образец на каждую группу

library(dplyr) 

p %>% group_by(cohort) %>% sample_n(1) 

Source: local data frame [3 x 4] 
Groups: cohort [3] 

name cohort group var 
(fctr) (fctr) (fctr) (int) 
1 Earl  X  A  4 
2 Dennis  Y  B  3 
3 Alice  Z  A  1 

Второй пробег:

name cohort group var 
(fctr) (fctr) (fctr) (int) 
1 Earl  X  A  4 
2 Charlie  Y  B  1 
3  Bob  Z  A  2 
+0

Эй, спасибо, это прекрасно работает. Есть ли способ сделать это повторяемым? То есть, на том, что RNG основан на 'sample_n', я могу его засеять? – Morpheu5

+1

@ Morpheu5 вы можете использовать 'set.seed (1)' (или любое другое число) каждый раз, прежде чем повторять образец. – PhillipD

3

Вы можете попробовать использовать aggregate с sample, чтобы выбрать значение, чтобы, во-первых, изменение name и group столбцы из фактора на характер:

p$name <- as.character(p$name) ; p$group <- as.character(p$group) 
aggregate(.~cohort, data=p, FUN=function(x) x[sample(seq_along(x), 1)]) 
# cohort name group var 
#1  X Earl  A 4 
#2  Y Dennis  B 1 
#3  Z Bob  A 2 
1

"Возможно случайно, но не обязательно", случается, то, что SQL дает:

library(sqldf) 
sqldf("SELECT * FROM p GROUP BY cohort") 

в этом случае я получаю

> sqldf("SELECT * FROM p GROUP BY cohort") 
    name cohort group var 
1 Earl  X  A 4 
2 Dennis  Y  B 3 
3 Bob  Z  A 2 
+0

Это не похоже на случайный 'replicate (10, sqldf (« SELECT * FROM p GROUP BY cohort »), simplify = FALSE)' – user20650

+0

В этой реализации это не случайно, но SQL не указывает, t знать, что происходит в следующей версии. Исходный плакат не указывал, если случайный был нужен или просто возможность, и я поставил первую строку в своем ответе в качестве предупреждения. Если оригинальный плакат действительно хочет, чтобы это было случайным, что он не уточнил, этот ответ не для него. В противном случае я думаю, что это коротко, элегантно и быстро. – Bernhard

+0

'group by' дало бы последнее наблюдение из группы. –

0

Вы можете использовать библиотеку выборки:

library(sampling) 
n <- length(unique(p$cohort)) 
s <- strata(p, 'cohort', rep(1, n), method = 'srswor') 
p$id <- row.names(p) 
p[p$id %in% s$ID_unit, ] 

 Смежные вопросы

  • Нет связанных вопросов^_^