如何模拟不同类型的缺失数据

机器算法验证 r 模拟 缺失数据 随机生成
2022-03-26 02:42:27

您如何创建缺失机制(MAR、MCAR、NMAR)?可以直接生成还是通过模型来生成?

1个回答

Rubin 定义了三种类型的缺失数据:

  1. 完全随机缺失 (MCAR)

    当数据丢失的概率很简单,并且该概率与您研究中的任何其他内容无关时,就会发生 MCAR。例如,患者可能会因为高速公路上发生事故而错过后续访问,而他们根本无法进行访问。

  2. 随机失踪(MAR)

    当缺失与您研究中的信息相关时发生 MAR,但预测缺失的所有相关信息都在现有数据集中。一个例子可能是一项减肥研究,如果人们的轨迹是他们正在增加体重,他们就会退出。如果您可以在任何人退出之前估计每个人的轨迹,并看到那些斜率为正的人随后退出,您可以将其视为 MAR。

  3. 随机不丢失 (NMAR)

    NMAR 与 MAR 类似,缺失与研究中发生的情况有关,但不同之处在于与缺失相关的数据包含在缺失的数据中。例如,如果您正在研究治疗眩晕/“头晕”,但只要患者真的头晕,他们就不会出现在后续访问中。因此,所有高值都丢失了,它们丢失是因为它们很高!

换句话说,缺失的类型指定了产生缺失本身的机制,因此如果您了解该机制的工作原理,您只需编写代码来复制它。例如,如果您希望 7% 的数据完全随机丢失,请从均匀分布中为数据集中的每个值绘制一个数字,如果它 <.07,则将该值替换为NANA对于随机缺失,模拟逻辑回归数据生成过程,该过程使用数据集中将继续不缺失的信息输出每个值缺失(即,被替换)的概率。(有关模拟逻辑回归数据生成过程的示例,请在此处查看我的答案:逻辑回归模拟,以显示当 Y=1 罕见时截距有偏差.) 您可以使用类似的逻辑回归数据生成过程而不是随机生成缺失,其中缺失的概率是 y 值本身的函数(即,可能被替换的值NA)。

这是一个例子:

##### generic data setup:
set.seed(977) # this makes the simulation exactly reproducible
ni     = 100  # 100 people
nj     =  10  # 10 week study
id     = rep(1:ni, each=nj)
cond   = rep(c("control", "diet"), each=nj*(ni/2))
base   = round(rep(rnorm(ni, mean=250, sd=10), each=nj))
week   = rep(1:nj, times=ni)
y      = round(base + rnorm(ni*nj, mean=0, sd=1))

# MCAR
prop.m = .07  # 7% missingness
mcar   = runif(ni*nj, min=0, max=1)
y.mcar = ifelse(mcar<prop.m, NA, y)  # unrelated to anything
View(cbind(id, week, cond, base, y, y.mcar))

# MAR
y.mar = matrix(y, ncol=nj, nrow=ni, byrow=TRUE)
for(i in 1:ni){
  for(j in 4:nj){
    dif1 = y.mar[i,j-2]-y.mar[i,j-3]
    dif2 = y.mar[i,j-1]-y.mar[i,j-2]
    if(dif1>0 & dif2>0){  # if weight goes up twice, drops out
      y.mar[i,j:nj] = NA;  break
    }
  }
}
y.mar = as.vector(t(y.mar))
View(cbind(id, week, cond, base, y, y.mar))

# NMAR
sort.y = sort(y, decreasing=TRUE)
nmar   = sort.y[ceiling(prop.m*length(y))]
y.nmar = ifelse(y>nmar, NA, y)  # doesn't show up when heavier
View(cbind(id, week, cond, base, y, y.nmar))