有没有办法从特定的分类变量中过滤固定百分比的样本?
Is there a way to filter a fixed percentage sample from a specific categoric variable?
假设我有 1000 名患者的性别数据。我被要求抽取一个大小为 n 的样本,严格满足其中 65% 必须是男性。
部分样本数据(此处性别分布为50%-50%):
data <- data.frame(patient_id = 1:1000,
sex = append(rep("male", 500),
rep("female", 500))
)
在 dplyr
.
中使用 sample_n
或 sample_frac
无法真正找到解决此任务的方法
对于 n = 500,结果数据应该是这样的,但是随机 patient_ids。
data.frame(patient_id = 1:500,
sex = append(rep("male", 325),
rep("female", 175))
)
如有任何见解,我们将不胜感激。
我们可以使用bind_rows
,分别过滤。首先,让我们设置行数的值,以便在您想要更改百分比时提供灵活性:
library(tidyverse)
number_of_sample <- 500
male_pct <- 0.65
number_of_male <- number_of_sample * male_pct
number_of_female <- number_of_sample - number_of_male
#For reproducibility setting the seed
set.seed(4)
data %>%
filter(sex=='male') %>%
sample_n(size = number_of_male) %>%
bind_rows(data %>%
filter(sex=='female') %>%
sample_n(size = number_of_female))-> sampled_data
检查数字:
sampled_data %>%
group_by(sex) %>%
summarise(count=n())
# A tibble: 2 x 2
sex count
<chr> <int>
1 female 175
2 male 325
这是在一个管道中使用数据嵌套的另一种解决方案。如果您不使用 50/50 拆分,则需要更改比例。
library(tidyverse)
sampled_data = data %>%
group_by(sex) %>%
nest() %>%
ungroup() %>%
mutate(prop = c(0.65, 0.35)) %>%
mutate(samples = map2(data, prop, sample_frac)) %>%
select(-data, - prop) %>%
unnest(samples)
sampled_data %>% count(sex)
# A tibble: 2 × 2
sex n
<fct> <int>
1 female 175
2 male 325
另一个 tidyverse 选项。
library(dplyr)
n <- 150
view <- slice_sample(filter(data, sex == 'male'), n = round(n*0.65)) %>%
bind_rows(slice_sample(filter(data, sex == 'female'), n = round(n*0.35)))
计算行数得到:
count(view, sex)
# sex n
# 1 female 52
# 2 male 98
假设我有 1000 名患者的性别数据。我被要求抽取一个大小为 n 的样本,严格满足其中 65% 必须是男性。
部分样本数据(此处性别分布为50%-50%):
data <- data.frame(patient_id = 1:1000,
sex = append(rep("male", 500),
rep("female", 500))
)
在 dplyr
.
sample_n
或 sample_frac
无法真正找到解决此任务的方法
对于 n = 500,结果数据应该是这样的,但是随机 patient_ids。
data.frame(patient_id = 1:500,
sex = append(rep("male", 325),
rep("female", 175))
)
如有任何见解,我们将不胜感激。
我们可以使用bind_rows
,分别过滤。首先,让我们设置行数的值,以便在您想要更改百分比时提供灵活性:
library(tidyverse)
number_of_sample <- 500
male_pct <- 0.65
number_of_male <- number_of_sample * male_pct
number_of_female <- number_of_sample - number_of_male
#For reproducibility setting the seed
set.seed(4)
data %>%
filter(sex=='male') %>%
sample_n(size = number_of_male) %>%
bind_rows(data %>%
filter(sex=='female') %>%
sample_n(size = number_of_female))-> sampled_data
检查数字:
sampled_data %>%
group_by(sex) %>%
summarise(count=n())
# A tibble: 2 x 2
sex count
<chr> <int>
1 female 175
2 male 325
这是在一个管道中使用数据嵌套的另一种解决方案。如果您不使用 50/50 拆分,则需要更改比例。
library(tidyverse)
sampled_data = data %>%
group_by(sex) %>%
nest() %>%
ungroup() %>%
mutate(prop = c(0.65, 0.35)) %>%
mutate(samples = map2(data, prop, sample_frac)) %>%
select(-data, - prop) %>%
unnest(samples)
sampled_data %>% count(sex)
# A tibble: 2 × 2
sex n
<fct> <int>
1 female 175
2 male 325
另一个 tidyverse 选项。
library(dplyr)
n <- 150
view <- slice_sample(filter(data, sex == 'male'), n = round(n*0.65)) %>%
bind_rows(slice_sample(filter(data, sex == 'female'), n = round(n*0.35)))
计算行数得到:
count(view, sex)
# sex n
# 1 female 52
# 2 male 98