使用权重按组生成随机样本

时间:2018-05-15 03:43:58

标签: r random data.table

我正在尝试使用群组随机抽样data.table。每个组的样本大小将通过将频率乘以Sample_Size来计算,data.table是输出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)) 中的预期行数。

我在SO上研究过这个话题。似乎类似的线程(Need to randomly sample a data set with multiple groups each with multiple factorstake randomly sample based on groups)假设权重均匀分布,这对我不起作用。

这是测试数据:

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

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

这是我们想要的频率:

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

以下是检查频率是否符合要求的测试:

json

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

2 个答案:

答案 0 :(得分:1)

我们可以做到

InputDT[, rbindlist(Map(function(x, y) x[sample(seq_len(nrow(x)), y)], 
        split(.SD, Country), freq))]

数据

freq <- c(4, 2, 2, 2)

答案 1 :(得分:1)

您可以先为国家/地区频率加入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。

.SDInputDT数据的子集,即InputDT每个Country的{​​{1}}数据的每个子集,因为i 1}}。 by=.EACHI仅在.SD的范围内,且只能在InputDT中使用。见j。要了解更多信息,请查看词汇范围。一个很好的参考是Hadley Wickham的Advanced R.。

?data.table样本来自sample(.N, min(.N, Freq*Sample_Size))Freq*Sample_Size的{​​{1}}索引,.SD确保您不会在该国家/地区对可用样本进行采样。

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

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

.SD