r - 按组使用权重生成随机样本
问题描述
我正在尝试随机抽样一个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 中的采样,然后根据我的需要对其进行自定义。我会很感激任何帮助。
解决方案
在对每个国家进行抽样之前,您可以InputDT
先加入国家频率,如下所示:
InputDT[CountryFreq,
.SD[sample(.N, min(.N, Freq*Sample_Size))],
by=.EACHI,
on=.(Country)]
笔记:
InputDT[i=CountryFreq, on=.(Country)]
使用 Country 作为键将 CountryFreq 与 InputDT 连接起来。
by=.EACHI
j=.SD[sample(.N, min(.N, Freq*Sample_Size))]
对 中的每一行执行此操作i=CountryFreq
。注意by=.EACHI
目前仅适用于 equi-join。
.SD
是 的数据子集InputDT
,即来自InputDT
的Country
每一行中的每个i
数据的每个子集by=.EACHI
。.SD
只是真的在范围内,InputDT
而且只能用在j
。见?data.table
。要了解更多信息,请查看词法范围。Hadley Wickham 的 Advanced R 是一个很好的参考。
sample(.N, min(.N, Freq*Sample_Size))
Freq*Sample_Size
从.SD
while的行数中采样索引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
推荐阅读
- javascript - 离开jQuery,写了一个简单的ajax函数,但是链式方法不会等待
- rust - 函数适用于推断的生命周期,但不适用于显式生命周期
- java - Java charAt() 返回随机整数而不是字母
- google-sheets - 在子表中查找
- delphi - 图像幻灯片效果。BitBlt 闪闪发光
- reactjs - antd datepicker 使用 formik 预填充值
- python - 查找最长重复子串的快速算法
- php - 更改 laravel 项目名称
- python - 图像距离变换不同 xyz 体素大小
- html - 如何使用具有 filterUnits="userSpaceOnUse" 的过滤器隐藏可重用的 svg