如何在dplyr中使用整洁的数据进行列联表分析

时间:2017-09-09 21:55:55

标签: r dplyr

假设我有以下数据。

Table  is_exposed  disease   value
1           1        1         4
1           1        0         100
1           0        1         20
1           0        0         80
2           1        1         10
2           1        0         40
2           0        1         15
2           0        0         30

Table表示具有以下形式的每个2x2表。

                   Exposed    Not Exposed        
                 ---------- --------------
Disease             a          b
No Disease          c          d

我如何在dplyr中进行以下计算?

  1. 风险a/(a+b)c/(c+d) [上述数据应为4个值]
  2. 风险差异risk2-risk1 [上述数据应为2个值]
  3. 优势比ad/bc [上述数据应为2个值]
  4. 输出格式

    Table  disease    risk
    1         1       .167
    1         0       .556
    2         1       .2
    2         0       .33
    

    Table risk_diff odds_ratio
    1        .389       .16
    2        .13        .5
    

1 个答案:

答案 0 :(得分:1)

df %>%
  split(df$Table) %>%
  lapply(function(x){
    tab = xtabs(value ~ is_exposed + disease, data = x) %>%
      as.list() %>%
      setNames(c("d", "c", "b", "a")) %>%
      data.frame()
  }) %>%
  do.call(rbind, .) %>%
  mutate(Risk_d1 = a/(a+b),
         Risk_d0 = c/(c+d),
         Risk_diff = Risk_d1-Risk_d0,
         Odds_ratio = (a*d)/(b*c))

#    d   c  b  a   Risk_d1   Risk_d0  Risk_diff Odds_ratio
# 1 80 100 20  4 0.1666667 0.5555556 -0.3888889       0.16
# 2 30  40 15 10 0.4000000 0.5714286 -0.1714286       0.50

注意:

xtabs针对is_exposed创建disease的交叉制表,并将value与每个相应的单元格相关联:

df %>%
  split(df$Table) %>%
  lapply(function(x){
    tab = xtabs(value ~ is_exposed + disease, data = x)
  })

# $`1`
#           disease
# is_exposed   0   1
#          0  80  20
#          1 100   4
# 
# $`2`
#           disease
# is_exposed  0  1
#          0 30 15
#          1 40 10

为了通过abcd引用每个单元格,我使用as.list将每个表格展平并使用setNames因此请指定适当的标签。 lapply会返回一个列表,因此do.call(rbind, .)会合并两个"行"并将其整合到一个数据框中:

df %>%
  split(df$Table) %>%
  lapply(function(x){
    tab = xtabs(value ~ is_exposed + disease, data = x) %>%
      as.list() %>%
      setNames(c("d", "c", "b", "a")) %>%
      data.frame()
  })

# $`1`
# d   c  b a
# 1 80 100 20 4
# 
# $`2`
# d  c  b  a
# 1 30 40 15 10