首页 > 解决方案 > 按组使用权重生成随机样本

问题描述

我正在尝试随机抽样一个data.table使用组。每个组的样本大小将通过将频率乘以 来计算Sample_Size,这是输出中的预期行数data.table

我在 SO 上研究了这个主题。似乎相似的线程(需要对具有多个组的数据集进行随机抽样,每个组具有多个因素根据组随机抽样)假设权重分布均匀,这对我不起作用。

这是测试数据:

InputDT <- data.table::data.table ("Country"=c(rep("A",20),rep("B",10),rep("C",5),rep("D",2)), "ID"=c(1:20,101:110,201:205,301:302))

目标是按国家/地区对 ID 进行抽样。

这是我们想要的频率:

CountryFreq <- 
 data.table::data.table("Country"=unique(InputDT$Country), "Freq"=c(4/10,2/10,2/10,2/10))

这是输出中的行数data.table

 Sample_Size <- 10

通常,我们假设 Sample_Size < nrows(InputDT)

这是手动创建的示例输出:

OutputDT <- structure(list(Country = c("A", "A", "A", "A", "B", "B", "C", 
"C", "D", "D"), ID = c(1, 5, 7, 3, 102, 109, 203, 204, 301, 302
)), .Names = c("Country", "ID"), row.names = c(NA, 10L), class = "data.frame")

这是一个检查频率是否符合需要的测试:

Hmisc::describe(OutputDT$Country)

OutputDT$Country 
       n  missing distinct 
      10        0        4 

Value        A   B   C   D
Frequency    4   2   2   2
Proportion 0.4 0.2 0.2 0.2

有人可以帮帮我吗?我花了将近一天的时间尝试学习 R 中的采样,然后根据我的需要对其进行自定义。我会很感激任何帮助。

标签: rrandomdata.table

解决方案


在对每个国家进行抽样之前,您可以InputDT先加入国家频率,如下所示:

InputDT[CountryFreq,
    .SD[sample(.N, min(.N, Freq*Sample_Size))], 
    by=.EACHI,
    on=.(Country)]

笔记:

InputDT[i=CountryFreq, on=.(Country)]使用 Country 作为键将 CountryFreq 与 InputDT 连接起来。

by=.EACHIj=.SD[sample(.N, min(.N, Freq*Sample_Size))]对 中的每一行执行此操作i=CountryFreq。注意by=.EACHI目前仅适用于 equi-join。

.SD是 的数据子集InputDT,即来自InputDTCountry每一行中的每个i数据的每个子集by=.EACHI.SD只是真的在范围内,InputDT而且只能用在j。见?data.table。要了解更多信息,请查看词法范围。Hadley Wickham 的 Advanced R 是一个很好的参考。

sample(.N, min(.N, Freq*Sample_Size))Freq*Sample_Size.SDwhile的行数中采样索引min可确保您采样的样本不会超过该国家/地区的可用样本。

最后,.SD[sample(.N, min(.N, Freq*Sample_Size))]子集采样的行.SD


编辑:从 R 控制台显示示例运行。

> InputDT[CountryFreq,
+     .SD[sample(.N, min(.N, Freq*Sample_Size))], 
+     by=.EACHI,
+     on=.(Country)]
    Country  ID
 1:       A  19
 2:       A   7
 3:       A   5
 4:       A   3
 5:       B 109
 6:       B 110
 7:       C 203
 8:       C 205
 9:       D 302
10:       D 301
> InputDT[CountryFreq,
+     .SD[sample(.N, min(.N, Freq*Sample_Size))], 
+     by=.EACHI,
+     on=.(Country)]
    Country  ID
 1:       A  12
 2:       A  19
 3:       A  17
 4:       A  10
 5:       B 110
 6:       B 105
 7:       C 202
 8:       C 203
 9:       D 302
10:       D 301
> InputDT[CountryFreq,
+     .SD[sample(.N, min(.N, Freq*Sample_Size))], 
+     by=.EACHI,
+     on=.(Country)]
    Country  ID
 1:       A   9
 2:       A   7
 3:       A  19
 4:       A   6
 5:       B 106
 6:       B 108
 7:       C 205
 8:       C 201
 9:       D 302
10:       D 301

推荐阅读