簡體   English   中英

如何生成具有特定要求的人口的隨機子樣本?

[英]How can I generate a random subsample of a population with specific requirements?

假設我有一個混合年齡和性別(可能還有其他屬性)的人群,我想生成一個具有某些屬性的隨機子樣本(可以替換),例如:

  • 樣本量 N
  • 50% 的樣本應年齡<30
  • 20% 的樣本應該是男性

我可以先隨機挑選 N/2 個年齡<30 且年齡>=30 的人,但這可能沒有正確的性別組合。 我可以選擇並確保在年齡<30 人中,20% 是男性,但這過於指定了——我希望整體分布匹配,但不指定任何關於年齡和性別乘積的內容。

如何生成此樣本? 如果我讓它稍微復雜一些並指定范圍怎么辦:

  • 樣本量 N
  • 30 歲以下的 50-80%(該范圍內的均勻概率)
  • 20-30% 男性(該范圍內的均勻概率)

我想有可能迭代地生成這樣一個樣本,交替地修剪它以匹配每個要求直到收斂,但我不知道如何正確地做到這一點。 當然,最愚蠢的方法是生成隨機樣本,如果它們不符合這些要求,則拒絕它們。

編輯:

這是一個樣本,其中 70% 低於 30 歲,20% 為男性:

N <- 100000
orig_u30 <- 0.7
orig_male <- 0.2
set.seed(42)
my_sample <- data.frame(age = sample(c("under 30", "30+"), N, replace = T, 
                                     prob = c(orig_u30, 1 - orig_u30)),
                        gender = sample(c("M", "F"), N, replace = T, 
                                        prob = c(male, 1-male)))
addmargins(prop.table(table(my_sample$age, my_sample$gender)))
                 F       M     Sum
  30+      0.24292 0.05935 0.30227
  under 30 0.55675 0.14098 0.69773
  Sum      0.79967 0.20033 1.00000

假設我們想要一個子樣本,其權重為 40% 低於 30 和 40% 男性。 我們可以通過根據我們想要的與我們擁有的相對比例對每一行應用權重來實現這一點。

old_u30 = mean(my_sample$age == "under 30")
new_u30 = 0.4
weight_u30 = (new_u30 / old_u30) / ((1-new_u30) / (1-old_u30))

old_male = mean(my_sample$gender == "M")
new_male = 0.4
weight_male = (new_male / old_male) / ((1-new_male) / (1-old_male))

my_sample$weight = ifelse(my_sample$age == "under 30", weight_u30, 1) *
  ifelse(my_sample$gender == "M", weight_male, 1)

現在我們對每一行都有一個權重,這將傾向於將其帶到所需的份額:

library(dplyr)
my_subsample <- sample_n(my_sample, 10000, replace = TRUE, weight = my_sample$weight)

addmargins(prop.table(table(my_subsample$age, my_subsample$gender)))

現在是 40% 的男性和 40% 的 30 歲以下:

                F      M    Sum
  30+      0.3683 0.2348 0.6031
  under 30 0.2375 0.1594 0.3969
  Sum      0.6058 0.3942 1.0000

原始答案:生成加權樣本但未加權子樣本

N <- 1000
median_age <- 30
male <- 0.2

my_sample <- data.frame(age = rpois(N, median_age),
           gender = sample(c("M", "F"), N, replace = T, prob = c(male, 1-male)))

median(my_sample$age) # will be 30 most runs
table(my_sample$gender) # will be around 200 / 1000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM