如何从列联表边距和优势比得出 2x2 细胞计数

机器算法验证 优势比 列联表 流行病学 联立方程
2022-04-10 12:09:10

我确信有一个独特的解决方案,我想我以前已经解决了,但现在它让我把头发拉了出来:

给定 2x2 列联表的边际,例如二元暴露和二元结果的发生率,以及它们的优势比,您如何计算四个单元格的比例(即与通常计算优势比的问题相反) ? 例如

                outcome     no outcome
exposed         a           b               Pr(E)
not exposed     c           d               Pr(Ê)=1-Pr(E)
                Pr(O)       Pr(Ô)=1-Pr(O)   100%

给定方程:

a + b = Pr(E)
b + c = Pr(Ê) = 1 - Pr(E)
a + c = Pr(O)
b + d = Pr(Ô) = 1 - Pr(O)
(a d) / (b c) = 或

以及所有单元格值和优势比为正的约束条件,并且 a + b + c + d 总和为 100%(即,所有内容都表示为比例,尽管您可以扩展方程以包含任意已知的人口计数,如果您希望) 用 Pr(E)、Pr(O) 和 OR 表示每个单元格值。

1个回答

ρ对于优势比,β=Pr(E),γ=Pr(O). 四个独立方程是

{a+b=βa+c=γa+b+c+d=1ad=ρbc.

添加前两个节目

(1)b+c=β+γ2a.

将前两个方程相乘并使用 (1)产量

(2)bc=βγ(β+γ)a+a2.

将第三个方程乘以a, 用第四个重新表达ad并插入(1)(2)

a2+a(β+γ2a)+ρ(βγ(β+γ)a+a2)=a.

在更标准的形式中,这是二次方的零

(3)(ρ1)a2+[(β+γ)(1ρ)1]a+ρβγ.

假如β,γ,ρ与一些一致2×2表中,至少会有一个实零(3),使用任何二次公式很容易找到。对于任何一个零,其余条目的解很容易从原始方程的前三个中找到:

{b=βac=γad=1+aβγ.


至多会有一个有效的解决方案a,由系数的非负性决定。这是R解决方案作为函数的实现f以及使用随机生成的表的测试。测试输出随机表、它的重构值f,以及它们之间差异的度量。通过将测试包装在 中replicate,我已经运行了 10,000 次。最终输出给出了发现的最大差异:直到浮点误差为零,证明了这种方法的正确性。

f <- function(beta, gamma, rho, eps=1e-15) {
  a <- rho-1
  b <- (beta+gamma)*(1-rho)-1
  c_ <- rho*beta*gamma

  if (abs(a) < eps) {
    z <- -c_ / b
  } else {
    d <- b^2 - 4*a*c_
    if (d < eps*eps) s <- 0 else s <- c(-1,1)
    z <- (-b + s*sqrt(max(0, d))) / (2*a)
  }
  y <- vapply(z, function(a) zapsmall(matrix(c(a, gamma-a, beta-a, 1+a-beta-gamma), 2, 2)),
              matrix(0.0, 2, 2))
  i <- apply(y, 3, function(u) all(u >= 0))
  return(y[,,i])
}
set.seed(17)
i<-0
sim <- replicate(1e4, {
  while(TRUE) {
    x <- matrix(round(rexp(4), 2), 2, 2)
    if(all(rowSums(x) > 0) && all(colSums(x) > 0) && x[1,2]*x[2,1] > 0) break
  }
  x <- x / sum(x)
  beta <- rowSums(x)[1]
  gamma <- colSums(x)[1]
  rho <- x[1,1]*x[2,2] / (x[1,2]*x[2,1])

  y<- f(beta, gamma, rho)
  delta <- try(zapsmall(c(1, sqrt(crossprod(as.vector(x-y)))))[2])
  if ("try-error" %in% class(delta)) cat("Error processing ", x, "\n")
  delta
})
max(sim)