Odds ratio(OR)从字面上可看出,是两个odds的ratio,其用于:

在病例对照研究(case-control study)中,分析暴露风险因素与疾病(或者用药)的关联程度;主要是反映暴露与疾病之间关联强度的指标,OR常适用于病例对照研究,也可以运用于前瞻性的研究(当观察时间相等时)

与其相似的有个指标relative risk(RR),其可以理解为risk ratio,用于:

在队列研究(cohort study)中,分析暴露因素与发病的关联程度;主要是反映暴露与发病(死亡)关联强度的最有用的指标,RR适用于队列研究或随机对照试验。

以一个例子来说明两者的区别,数据表格如下(Mutated gene对应暴露风险因素,Cancer对应疾病):

Cancer

Normal

Total

Mutated gene

23

117

No mutated gene

6

210

Total

29

327

OR = (23/117) / (6/210) = 6.88RR = (23/140) / (6/216) = 5.91

从上可看出,OR表明暴露组的疾病风险程度是非暴露组的6.88倍,RR表明暴露组发病的风险是非暴露组的5.91倍

OR值的统计学意义:

  • OR>1,暴露与疾病的危险度增加,两者呈正相关
  • OR<1,暴露与疾病的危险度减少,两者呈负相关
  • OR=1,暴露与疾病的危险度无关,两者呈不相关

RR值的统计学意义:

  • OR>1,暴露因素是疾病的危险因素,两者呈正相关
  • OR<1,暴露因素是疾病的保护因素,两者呈负相关
  • OR=1,暴露因素与疾病无关,两者呈不相关

注意点:

当疾病的incidence rate较低时,OR近似于RR,故当疾病很罕见时,常用OR来作为RR的近似值;然而当incidence rate高于10%的时候,OR与RR的差距会变得越来越大,从而使得在这些情况下使用OR就变得并不那么合适了(OR会倾向于给出一个暴露 vs. 非暴露间差距更明显的值,因此导致临床意义不足)

为什么在病例对照研究(case-control study)中无法计算RR值?来自Relative Risk和Odds Ratio

因为我们一开始选定的人群是基于他们发没发生event来定的,所以这时候我们这个研究群体里的的incidence rate并不是target population里真实的incidence rate (事实上,case-control study里的incidence rate一般会远大于实际的incidence rate,因为做case-control study的初衷就是因为target population里的event rate太低),所以我们没法计算RR

计算odds的方法

  • fisher检验

Pearson 卡方检验要求二维列联表只允许 20% 以下格子的期望数小于5,对于 2×2 列联表,应当用 Fisher 精确检验法

A 和 B 两种药物的二维列联表数据,问 A 和 B 两种药物的治疗效果是否相同?显著性水平为
0.05

疗效

有效

无效

A

8

2

B

7

23


 

import scipy.stats as stats
oddsratio, pvalue = stats.fisher_exact([[8, 2], [1, 5]])

 

  • 卡方检验
    见卡方检验的文章
  • 逻辑回归

logistic regression,即假设error terms服从binomial distribution,并使用logit作为link function;然后通过model计算出变量对应的logit(p),即logodds,odds则是等于exp(logodds),而p(predict probabilities )则是odds/(1+odds)

对于Odd Ratios在Logistic regression中的理解可以看:

python scipy代码如下

这里需要注意的是使用的公式是statsmodels.formula.api中的方法

import statsmodels.formula.api as smf
df = pd.read_csv("https://stats.idre.ucla.edu/wp-content/uploads/2016/02/sample.csv")
lreg = smf.logit(formula='hon~female',data=df).fit()
#获取coef值
female_coef_ = res.tables[1].data[2][1].strip()
#计算得到OR值
np.exp(float(female_coef_))
np.exp(lreg.params)

 

可以直接计算

conf = lreg.conf_int()
conf['OR'] = lreg.params
conf.columns = ['Lower CI','Up CI','OR']
np.exp(conf)


使用如下方法也可以得到同样的结果 

 

import pandas as pd
from patsy import dmatrices
import statsmodels.api as sm

y, X = dmatrices( 'hon ~ female', data=df, return_type='dataframe')

mod = sm.Logit(y, X)
res = mod.fit()
print (res.summary())

conf = res.conf_int()
conf['OR'] = res.params
conf.columns = ['Lower CI','Up CI','OR']
np.exp(conf)

 

下面是2x2表计算odd的方法

import statsmodels.api as sm
table = sm.stats.Table2x2(np.array([[73, 756], [14, 826]]))
table.summary(method='normal')

结果

Estimate          SE          LCB   UCB      p-value
  Odds ratio        5.697       3.189 10.178   0.000
  Log odds ratio    1.740 0.296 1.160  2.320   0.000
  Risk ratio        5.283       3.007  9.284   0.000
  Log risk ratio    1.665 0.288 1.101  2.228   0.000