Генерация случайной выборки с использованием весов по группам - PullRequest
0 голосов
/ 15 мая 2018

Я пытаюсь случайным образом выбрать 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))

Цель состоит в том, чтобы выбрать идентификаторы по стране.

Вот частота, которую мы хотим:

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, а затем настроить его в соответствии со своими потребностями.Буду признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

Вы можете присоединиться к InputDT с частотой страны, прежде чем выполнять выборку для каждой страны следующим образом:

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

Примечания:

InputDT[i=CountryFreq, on=.(Country)] объединяет CountryFreq с InputDT, используя Country какключ.

by=.EACHI выполняет это j=.SD[sample(.N, min(.N, Freq*Sample_Size))] для каждой строки в i=CountryFreq.Примечание by=.EACHI пока работает только для равноправного соединения.

.SD - это подмножество данных InputDT, то есть каждое подмножество данных из InputDT для каждого Country в каждой строкеi из-за by=.EACHI..SD действительно только в пределах InputDT и может использоваться только в j.Смотри ?data.table.Чтобы узнать больше, ознакомьтесь с лексическим контекстом .Хорошим справочником является Advanced R от Hadley Wickham.

sample(.N, min(.N, Freq*Sample_Size)) семплов Freq*Sample_Size индексы из числа строк из .SD, тогда как min гарантирует, что вы не будете пробовать больше, чем доступные семплы в этой стране.

Наконец, .SD[sample(.N, min(.N, Freq*Sample_Size))] подмножество выбранных строк из .SD.


edit: показать примеры прогонов с консоли 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
0 голосов
/ 15 мая 2018

Мы можем сделать

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

данные

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