假设我有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
另一个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
这是在一个管道中使用数据嵌套的另一种解决方案。如果你不使用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