Случайная выборка строк из подмножества кадра данных R [дубликат]


На этот вопрос уже есть ответ здесь:

Есть ли хороший способ получить выборку строк из части фрейма данных?

Если у меня есть только такие данные, как

gender <- c("F", "M", "M", "F", "F", "M", "F", "F")
age    <- c(23, 25, 27, 29, 31, 33, 35, 37)

Тогда я могу легко выбрать возраст трех из Fs с помощью

sample(age[gender == "F"], 3)

И получить что-то вроде

[1] 31 35 29

Но если я превращу эти данные в фрейм данных

mydf <- data.frame(gender, age) 

Я не могу использовать очевидное

sample(mydf[mydf$gender == "F", ], 3)

Хотя я могу придумать что-то замысловатое с абсурдным количеством скобок, таких как

mydf[sample((1:nrow(mydf))[mydf$gender == "F"], 3), ]

И получить то, что я хочу, что-то вроде

  gender age
7      F  35
4      F  29
1      F  23
Есть ли лучший способ, который отнимает у меня меньше времени, чтобы научиться писать?
3 12

3 ответа:

Ваш замысловатый способ в значительной степени заключается в том, как это сделать - я думаю, что все ответы будут вариациями на эту тему.

Например, мне нравится сначала генерировать индексы mydf$gender=="F":

idx <- which(mydf$gender=="F")

Затем я делаю выборку из этого:

mydf[ sample(idx,3), ]

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

mydf[ sample( which(mydf$gender=='F'), 3 ), ]

В то время как "уиииии я хакер!- часть меня предпочитает однолинейность, разумная часть меня. говорит, что даже при том, что двухлинейка-это две линии, это гораздо понятнее - это просто ваш выбор.

Вы говорите я не могу использовать очевидное:

sample(mydf[mydf$gender == "F", ], 3)

Но вы могли бы написать свою собственную функцию для этого:

sample.df <- function(df, n) df[sample(nrow(df), n), , drop = FALSE]

Затем запустите его на вашем выборе подмножества:

sample.df(mydf[mydf$gender == "F", ], 3)
#   gender age
# 5      F  31
# 4      F  29
# 1      F  23

(Лично я нахожу sample.df(subset(mydf, gender == "F"), 3) более легким для чтения.)

Теперь это проще с улучшенной версией sample в моем пакете:

library(devtools); install_github('kimisc', 'krlmlr')

library(kimisc)
sample.rows(subset(mydf, gender == "F"), 3)

Смотрите также Этот связанный ответ для получения более подробной информации.