2015-09-21

Phát sinh data gần phân phối chuẩn với thang đo khoảng trong R - Generate a approximately normal distribution with interval scale (simulate Likert) in R

Để tạo data với phân phối chuẩn trong R thì rất dễ dàng với
rnorm(n, mean, sd).

Đôi khi muốn tạo data gần phân phối chuẩn nhưng với thang đo khoảng như thang đo Likert 5 hay Likert 7 mức thì việc dùng rnorm chưa đáp ứng được điều này.

  • Các đầu tiên là dùng rnorm sau đó làm tròn số > vấn đề cần thực hiện làm tròn số như thế nào
  • Một cách để thực hiện (có thể xài được) là sử dụng phân phối nhị thức làm hơi ngược ứng dụng của định lý Moivre Laplace (n lớn và p không quá gần 0 hay 1) để xấp xỉ phân phối nhị thức bằng phân phối chuẩn. Tất nhiên cách này không đúng lắm vì không thỏa mãn đk (n ≥ 30, np ≥ 5) nhưng có thể chấp nhận được. B(n; p) ~ N(np; np(1−p))


Giả sử cần tạo data với phân phối chuẩn N= 200, μ = 3.5, σ² = 0.8

Method 1:
Chia phân phối chuẩn thành 5 đoạn, -1 và 6 để bảo đảm không sinh ra NA do ngoài khoảng (lưu ý μ và 3σ)
xcut <- cut(rnorm(200, 3.5, 0.8), breaks = c(-1, 1, 2, 3, 4, 6))
x <- rep(1:5, as.vector(table(xcut)))
mean(x)
sd(x)
hist(x, col = 'light blue')

Tất nhiên cách này do chia khoảng nên mean và sd có thể không như mong đợi. Nên generate 1 vài lần để có kết quả gần đúng nhất hoặc điều chỉnh input mean và sd.

Method 2:
Thay vì tạo data với phân phối chuẩn thì sẽ tạo data với phân phối nhị thức.

# B(n; p) ~ N(np; np(1−p))
# μ = np
# σ² = np(1−p) = np - np²
# np² = μ - σ² = np - (np - np²)
# p = np² / np = (μ - σ²) / μ
# n = np / p = μ / p = μ²/(μ - σ²)

x <- rbinom(200, ceiling(3.5 * 3.5 / (3.5 - 0.8)), (3.5 - 0.8) / 3.5)
mean(x)
sd(x)
hist(x, col = 'light blue')
write.csv(x, 'data.csv', row.names = F)

Nói chung chạy vài lần kiểm tra mean và sd phù hợp rồi sử dụng kết quả