从数据集

时间:2016-11-01 01:47:11

标签: r distribution population

假设我有一个包含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")

现在我不知道如何将这个与我拥有整个美国人口的其他数据集结合在一起......我很感激任何帮助,我现在已经停留了很长时间......

1 个答案:

答案 0 :(得分:1)

以下是四种不同的方法。两个分别使用splitstackshapesampling个包中的函数,一个使用基数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))

使用上述抽样参数,我们希望从每个年龄组中抽取nprobs个总值。

选项1: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

选项2:来自stratified

splitstackshape函数

size参数需要一个命名向量,其中包含每个层的样本数。

library(splitstackshape)

df.sample2 = stratified(df, "age.groups", size=probs*n)

选项3:来自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, ] 

选项4:tidyverse

map2mapply类似,它将两个参数并行应用于函数,在本例中为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