假设我有一个包含1,000,000个观测值的数据集。变量是年龄,种族,性别。该数据集代表整个美国。
如果给定一定的年龄分布,我如何从该数据集中抽取1,000人的样本?例如。我希望这个数据集有1000人分布如下:
0.3 *年龄0 - 30
0.3 *年龄31-50岁
0.2 *年龄51 - 69
0.2 *年龄70 - 100
有快速的方法吗?我已经创建了一个包含所需年龄分布的1000人样本,但是如何将其与原始数据集结合起来呢?
例如,这就是我创建缅因州人口分布的方式:
set.seed(123)
library(magrittr)
popMaine <- data.frame(min=c(0, 19, 26, 35, 55, 65), max=c(18, 25, 34, 54, 64, 113), prop=c(0.2, 0.07, 0.11, 0.29, 0.14, 0.21))
Mainesample <- sample(nrow(popMaine), 1000, replace=TRUE, prob=popMaine$prop)
Maine <- round(popMaine$min[Mainesample] + runif(1000) * (popMaine$max[Mainesample] - popMaine$min[Mainesample])) %>% data.frame()
names(Texas) <- c("Age")
现在我不知道如何将这个与我拥有整个美国人口的其他数据集结合在一起......我很感激任何帮助,我现在已经停留了很长时间......
答案 0 :(得分:1)
以下是四种不同的方法。两个分别使用splitstackshape
和sampling
个包中的函数,一个使用基数mapply
,另一个使用map2
包中的purrr
(这是一部分) tidyverse
包的集合。)
首先让我们设置一些假数据和采样参数:
# Fake data
set.seed(156)
df = data.frame(age=sample(0:100, 1e6, replace=TRUE))
# Add a grouping variable for age range
df = df$age.groups = cut(df$age, c(0,30,51,70,Inf), right=FALSE)
# Total number of people sampled
n = 1000
# Named vector of sample proportions by group
probs = setNames(c(0.3, 0.3, 0.2, 0.2), levels(df$age.groups))
使用上述抽样参数,我们希望从每个年龄组中抽取n
个probs
个总值。
mapply
mapply
可以将多个参数应用于函数。这里,参数是(1)数据框df
分为四个年龄组,(2)probs*n
,它给出了我们想要从每个年龄组的行数:
df.sample = mapply(a=split(df, df$age.groups), b=probs*n,
function(a,b) {
a[sample(1:nrow(a), b), ]
}, SIMPLIFY=FALSE)
mapply
返回一个包含四个数据框的列表,每个层对应一个数据框。将此列表合并为一个数据框:
df.sample = do.call(rbind, df.sample)
检查抽样:
table(df.sample$age.groups)
[0,30) [30,51) [51,70) [70,Inf) 300 300 200 200
stratified
包splitstackshape
函数
size
参数需要一个命名向量,其中包含每个层的样本数。
library(splitstackshape)
df.sample2 = stratified(df, "age.groups", size=probs*n)
strata
包sampling
函数
此选项是迄今为止最慢的选项。
library(sampling)
# Data frame must be sorted by stratification column(s)
df = df[order(df$age.groups),]
sampled.rows = strata(df, 'age.groups', size=probs*n, method="srswor")
df.sample3 = df[sampled.rows$ID_unit, ]
tidyverse
包 map2
与mapply
类似,它将两个参数并行应用于函数,在本例中为dplyr
包的sample_n
函数。 map2
返回一个包含四个数据框的列表,每个数据框对应一个数据框,我们将这些数据框合并为bind_rows
的单个数据框。
library(dplyr)
library(purrr)
df.sample4 = map2(split(df, df$age.groups), probs*n, sample_n) %>% bind_rows
library(microbenchmark)
Unit: milliseconds expr min lq mean median uq max neval cld mapply 86.77215 110.82979 156.66855 123.95275 145.25115 486.2078 10 a strata 5028.42933 5541.40442 5709.16796 5699.50711 5845.69921 6467.7250 10 b stratified 38.33495 41.76831 89.93954 45.43525 79.18461 408.2346 10 a tidyverse 71.48638 135.49113 143.12011 142.86866 155.72665 192.4174 10 a