#r
#r
Вопрос:
Итак, у меня есть фрейм данных (my.df), который я сгруппировал по переменной «strat». Каждая строка состоит из множества переменных. Пример того, как это выглядит, приведен ниже — я упростил свой файл .df для этого примера, поскольку он довольно большой. Что я хочу сделать дальше, так это нарисовать простую случайную выборку из каждой группы. Если бы я хотел сделать 5 наблюдений из каждой группы, я бы использовал этот код:
new_df <- my.df %>% group_by(strat) %>% sample_n(5)
Однако у меня есть другой указанный размер выборки, который я хочу использовать для выборки для каждой группы. У меня есть эти размеры выборки в векторе nj.
nj <- c(3, 4, 2)
Поэтому в идеале я хотел бы получить 3 наблюдения из моих первых слоев, 4 наблюдения из моих вторых слоев и 2 наблюдения из моего последнего srata. Я не уверен, смогу ли я выполнять выборку по группам, используя каждый уникальный размер выборки (без необходимости выписывать «образец» столько раз, сколько мне нужно)? Заранее спасибо!
мой файл .df выглядит так:
var1 var2 strat
15 3 1
13 5 3
8 6 2
12 70 3
11 10 1
14 4 2
Комментарии:
1.
my.df[sort(unlist(mapply(sample, split(1:nrow(my.df), my.df$strat), pmin(nj,lengths(split(1:nrow(my.df), my.df$strat)))))), ]
должно сработать.
Ответ №1:
Вы можете использовать stratified
из моего пакета «splitstackshape».
Вот некоторые примеры данных:
set.seed(1)
my.df <- data.frame(var1 = sample(100, 20, TRUE),
var2 = runif(20),
strat = sample(3, 20, TRUE))
table(my.df$strat)
#
# 1 2 3
# 5 9 6
Вот как вы можете использовать stratified
:
library(splitstackshape)
# nj needs to be a named vector
nj <- c("1" = 3, "2" = 4, "3" = 2)
stratified(my.df, "strat", nj)
# var1 var2 strat
# 1: 72 0.7942399 1
# 2: 39 0.1862176 1
# 3: 50 0.6684667 1
# 4: 21 0.2672207 2
# 5: 69 0.4935413 2
# 6: 91 0.1255551 2
# 7: 78 0.4112744 2
# 8: 7 0.3403490 3
# 9: 27 0.9347052 3
table(.Last.value$strat)
#
# 1 2 3
# 3 4 2
Ответ №2:
Поскольку ваших данных недостаточно для выборки, давайте рассмотрим этот пример на iris
dataset
library(tidyverse)
nj <- c(3, 5, 6)
set.seed(1)
iris %>% group_split(Species) %>% map2_df(nj, ~sample_n(.x, size = .y))
# A tibble: 14 x 5
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
<dbl> <dbl> <dbl> <dbl> <fct>
1 4.6 3.1 1.5 0.2 setosa
2 4.4 3 1.3 0.2 setosa
3 5.1 3.5 1.4 0.2 setosa
4 6 2.7 5.1 1.6 versicolor
5 6.3 2.5 4.9 1.5 versicolor
6 5.8 2.6 4 1.2 versicolor
7 6.1 2.9 4.7 1.4 versicolor
8 5.8 2.7 4.1 1 versicolor
9 6.4 2.8 5.6 2.2 virginica
10 6.9 3.2 5.7 2.3 virginica
11 6.2 3.4 5.4 2.3 virginica
12 6.9 3.1 5.1 2.3 virginica
13 6.7 3 5.2 2.3 virginica
14 7.2 3.6 6.1 2.5 virginica
Ответ №3:
Вы можете привести nj
значения к выборке в dataframe, а затем использовать sample_n
по группам.
library(dplyr)
df %>%
mutate(nj = nj[strat]) %>%
group_by(strat) %>%
sample_n(size = min(first(nj), n()))
Обратите внимание, что приведенное выше работает, поскольку strat
имеет значение 1, 2, 3. Для общего решения, когда группа не имеет таких значений, вы можете использовать :
df %>%
mutate(nj = nj[match(strat, unique(strat))]) %>%
group_by(strat) %>%
sample_n(size = min(first(nj), n()))
Комментарии:
1. Вы уверены? Если я изменю ваше
nj
значение наnj <- c(3, 1, 1)
. Для данных, которыми вы поделились, он выбирает 2 строки для strat = 1, 1 для strat = 2 и 1 для strat = 3, что, как я полагаю, ожидается. Это ничего не должно менять, но если это сбивает с толку, изменитеnj
какое-либо другое имя в dataframe.