Сьогодні торкнемося теми, якій приділяється досить мало уваги при побудові вибірки: теми округлення. Оскільки складно опитати 1,4 респондентів, ми змушені працювати з цілими числами. Цілими невід'ємними числами. Подивимося, яким буде результат при застосуванні звичайного округлення (мова йтиме про округлення квот).
library("kableExtra")
# Приклад неокруглених квот. Вигаданий
q <- t(matrix(rep(c(1.9, 1.4, 0.9, 2.3, 2.1, 1.4), 11), 6, 11))
colnames(q) <- c("Чоловіки_18-30", "Чоловіки_31-54", "Чоловіки_55+","Жінки_18-30", "Жінки_31-54", "Жінки_55+")
rownames(q) <- 1:11
# Додамо суму за рядками і стовпчиками
q_total <- cbind(rbind(q, apply(q, 2, sum)), apply(rbind(q, apply(q, 2, sum)), 1, sum))
colnames(q_total)[7] <- "Всього"
rownames(q_total)[12] <- "Всього"
# Як же буде виглядати неокруглений варіант?
q_total %>%
kbl(align = "c") %>%
kable_classic() %>%
column_spec(1, bold = T) %>%
row_spec(0, bold = T) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
| Чоловіки_18-30 | Чоловіки_31-54 | Чоловіки_55+ | Жінки_18-30 | Жінки_31-54 | Жінки_55+ | Всього | |
|---|---|---|---|---|---|---|---|
| 1 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 2 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 3 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 4 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 5 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 6 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 7 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 8 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 9 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 10 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| 11 | 1.9 | 1.4 | 0.9 | 2.3 | 2.1 | 1.4 | 10 |
| Всього | 20.9 | 15.4 | 9.9 | 25.3 | 23.1 | 15.4 | 110 |
Ну ясно, всього треба опитати 110 респондентів, по 10 у кожному селі (порядковий номер від 1 до 11 - замість назви села, просто лінь було називати словами).
# Добре, застосуємо звичайне округлення
q_rnd <- round(q)
q_rnd_total <- cbind(rbind(q_rnd, apply(q_rnd, 2, sum)), apply(rbind(q_rnd, apply(q_rnd, 2, sum)), 1, sum))
colnames(q_rnd_total)[7] <- "Всього"
rownames(q_rnd_total)[12] <- "Всього"
# Які ж результати звичайного округлення?
q_rnd_total %>%
kbl(align = "c") %>%
kable_classic() %>%
column_spec(1, bold = T) %>%
row_spec(0, bold = T) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
| Чоловіки_18-30 | Чоловіки_31-54 | Чоловіки_55+ | Жінки_18-30 | Жінки_31-54 | Жінки_55+ | Всього | |
|---|---|---|---|---|---|---|---|
| 1 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 2 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 3 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 4 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 5 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 6 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 7 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 8 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 9 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 10 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 11 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| Всього | 22 | 11 | 11 | 22 | 22 | 11 | 99 |
Хм, після звичайного округлення загальна кількість респондентів зменшилася на 11 і становить 99. Опитувати треба вже не по 10, а по 9 респондентів у кожному селі. Та й розподіл за статтю і віком досить помітно відрізняється від округленого варіанту.
Що ж тепер робити? Використовувати зважування замість квот? До речі, це теж варіант. Але можна просто...запропонувати інший варіант округлення квот. Я розгляну алгоритм округлення, запропонований А. Пігідою. Про нього можете почитати в ось цій статті: http://dspace.nbuv.gov.ua/bitstream/handle/123456789/90428/09-Pigida.pdf?sequence=1.
А ще про алгоритм можна почитати тут: http://soc-research.info/blog/index_files/Pigida.html
При звичайному округленні "зникає" або "з'являється" залишок від округлення (різниця між неокругленим та округленим числом). Застосування алгоритму, наведеного в статті, дозволяє додавати залишок до випадково обраного ще не округленого числа.
# Округлення за спеціальним алгоритмом
# a - матриця, що містить неокруглені числа
# res - виводити початковий + округлений варіант матриці чи лише округлений?
# *res = T - виводимо початковий + округлений варіант
# *res = F - лише округлений варіант
r_round <- function(a,res = F) {
# Рандомізуємо порядок чисел матриці
r_o <- sample(1:length(a), length(a))
# Залишок від округлення; поки що становить 0
r <- 0
# Матриця з округленими числами (буде)
final <- a
# Округлюємо...
for(i in (1:length(a))) {
final[r_o[i]] <- round(a[r_o[i]] + r)
r <- a[r_o[i]] + r - final[r_o[i]]
}
if (res == F) {
# Виводимо лише округлений варіант матриці
final
} else {
# Виводимо початковий + округлений варіант матриці
both <- list(a, final)
names(both) <- c("Початковий варіант", "Округлений варіант")
both
}
}
Функція, що дозволяє округлювати числа за алгоритмом, наведеним у статті (спеціальним алгоритмом), є. Саме час переглянути результати.
q_rrnd <- r_round(q)
q_rrnd_total <- cbind(rbind(q_rrnd, apply(q_rrnd, 2, sum)), apply(rbind(q_rrnd, apply(q_rrnd, 2, sum)), 1, sum))
colnames(q_rrnd_total)[7] <- "Всього"
rownames(q_rrnd_total)[12] <- "Всього"
# Результати округлення за спеціальним алгоритмом
q_rrnd_total %>%
kbl(align = "c") %>%
kable_classic() %>%
column_spec(1, bold = T) %>%
row_spec(0, bold = T) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
| Чоловіки_18-30 | Чоловіки_31-54 | Чоловіки_55+ | Жінки_18-30 | Жінки_31-54 | Жінки_55+ | Всього | |
|---|---|---|---|---|---|---|---|
| 1 | 2 | 1 | 1 | 2 | 2 | 2 | 10 |
| 2 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 3 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 4 | 2 | 2 | 1 | 2 | 2 | 1 | 10 |
| 5 | 2 | 1 | 1 | 3 | 2 | 2 | 11 |
| 6 | 1 | 2 | 1 | 2 | 2 | 2 | 10 |
| 7 | 2 | 1 | 1 | 2 | 2 | 1 | 9 |
| 8 | 2 | 1 | 1 | 2 | 2 | 2 | 10 |
| 9 | 2 | 1 | 1 | 3 | 2 | 1 | 10 |
| 10 | 2 | 2 | 1 | 3 | 3 | 1 | 12 |
| 11 | 2 | 1 | 1 | 3 | 2 | 1 | 10 |
| Всього | 21 | 14 | 11 | 26 | 23 | 15 | 110 |
Бачимо, що загальна кількість респондентів становить 110, так само, як і для неокругленого варіанту квот. Та й розподіл за статтю і віком не так сильно відрізняється від неокругленого варіанту, правда ж?
# Порівняння розподілу за статтю і віком
zr <- rbind(q_total[12, c(-7)], q_rnd_total[12, c(-7)], q_rrnd_total[12, c(-7)])
rownames(zr) <- c("Неокруглений варіант", "Звичайне округлення", "Округлення за спеціальним алгоритмом")
zr %>%
kbl(align = "c") %>%
kable_classic() %>%
column_spec(1, bold = T) %>%
row_spec(0, bold = T) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = F)
| Чоловіки_18-30 | Чоловіки_31-54 | Чоловіки_55+ | Жінки_18-30 | Жінки_31-54 | Жінки_55+ | |
|---|---|---|---|---|---|---|
| Неокруглений варіант | 20.9 | 15.4 | 9.9 | 25.3 | 23.1 | 15.4 |
| Звичайне округлення | 22.0 | 11.0 | 11.0 | 22.0 | 22.0 | 11.0 |
| Округлення за спеціальним алгоритмом | 21.0 | 14.0 | 11.0 | 26.0 | 23.0 | 15.0 |
Висновок: округлення за спеціальним алгоритмом дозволяє, по-перше, "зберегти" запланований обсяг вибірки. По-друге, зменшити розбіжності між вибірковою та генеральною сукупністю. Саме зменшити, однак не усунути повністю.
P. S. Далі буде...