在药物研究中,经常涉及到NT50、EC50、IC50等概念。

NT50(half maximal neutralization titre)是达到一半生物效应的稀释倍数,数字高代表少量药物即可达到药效,因此该数值越高越好。NT50常用于无法确定初始浓度的场景,例如表征血浆对某抗原的中和能力。

EC50/ED50(half maximal effect concentration/dose)是达到一半生物效应的浓度或剂量,越低越好。IC50/ID50(half maximal inhibitory concentration/dose)与之类似,也是越低越好,常用于描述药物的抑制效应,例如中和抗体对病毒入侵细胞的抑制,或小分子抑制剂对靶点的阻断。

IC50案例

获得NT50、EC50或IC50的方法是高度相似的。以IC50为例,在不同给药浓度或稀释梯度下定量检测生物学效应(比如使用荧光定量),可获得类似的表格:

concentration OD
1.4200000 512240
0.2840000 1618240
0.0568000 2849730
0.0113600 3283260
0.0022720 3188540
0.0004544 3969840

这组数据是在检测某抗体(下文称AbX)的假病毒中和能力时产生的。第一列concentration代表抗体浓度,第二列OD代表荧光定量值。

当给药浓度高时,AbX阻止病毒入侵细胞,病毒无法感复制自身,携带的报告基因就无法表达,因此OD值较低。给药浓度低时,大量报告基因被表达,OD值很高。

我们要做的,就是拟合出一条类似这样的曲线,找到达到50%抑制效果时,对应的横坐标浓度。

image.png

拟合这条曲线有很多种做法,显然他们的结果会有所差异。目前较常用的是四参数逻辑斯蒂回归,属于非线性回归模型,常用于生物化学的反应测定。

目标即使用下式,拟合以上浓度、反应强度数据,解出未知参数 c, d, e, b,我们就得到以上曲线了

f(x) = c \ + \ \frac {d-c} {1 \ + \ \exp(b(\log(x) \ - \ \log(e)))}

x为浓度、y为反应强度,c代表反应下限、d代表反应上限,e代表 IC50b代表 IC50处的斜率。

有时我们通过阴性对照、阳性对照或逻辑推理,可以确定反应上下限的值。本次抗体的假病毒中和实验中,反应上限就是不加抗体的对照,数值是3154763;反应下限就是AbX中和力很强、加的剂量也足够多,完全阻断病毒,荧光定量是0。因此,c, d这两个参数我们可以直接输入模型,拟合 e, b即可。

实现拟合的工具也有很多,这里介绍最常用的两种:使用R语言、使用Prism

使用R语言拟合

R语言的drc包可以很方便地实现拟合、可视化,本文使用的版本是 R v4.2.3drc v3.0。首先将实验结果构建为数据帧

library(drc)

x <- c(1.42, 0.284, 0.0568, 0.01136, 0.002272, 0.0004544)
y <- c(512240, 1618240, 2849730, 3283260, 3188540, 3969840)
data <- data.frame(x, y)

然后使用 drm函数拟合。LL.4代表四参数逻辑斯蒂模型,names指定结果中参数显示的名称,不影响计算。fixed允许我们输入已知参数

m <- drm(y~x, data=data, 
         fct=LL.4(
             names=c("Slope", "Lower Limit", "Upper Limit", "IC50"),
             fixed=c(NA, 0, 3154763, NA)
         )
    )

拟合完毕后,打印 m即可获得IC50的值,或者你也可以调用 ED(m, 50)获得(Effective Dose)。后者在需要如 IC80, IC90等数值的时候很有用。

A 'drc' model.

Call:
drm(formula = y ~ x, data = data, fct = LL.4(names = c("Slope", "Lower Limit", "Upper Limit", "IC50"), fixed = c(NA, 0, 3154763, NA)))

Coefficients:
Slope:(Intercept)   IC50:(Intercept)  
           1.2361             0.3166

使用 plot(m),即可获得曲线的基本图像,像这样

image.png|500

如果你更愿意通过 ggplot绘图,以获得更高的自由度,则需要先用 predict函数,借助模型生成一些连续的 x,y数值对(比如100对),保证曲线的平滑度

x_pred <- seq(min(x), max(x), length.out = 100)
y_pred <- predict(m, newdata = data.frame(x = x_pred))

data_pred <- data.frame(x = x_pred, y = y_pred)

然后调用 ggplot绘图

library(ggplot)
ggplot() +
  geom_point(data = data, aes(x = x, y = y)) +
  geom_line(data = data_pred, aes(x = x, y = y), color = "blue") +
  labs(x = "Dose", y = "Response", title = "Dose-Response Curve") +
  scale_x_log10() +
  theme_classic()

image.png|500

可以看到,drc是不区分IC50、EC50还是NT50的。

使用Prism拟合

使用 Prism v10.2.1,在欢迎页选择 CREATE-XY,选择第一个Y选项,点击创建

image.png|1000

粘贴数据到X、Y(Group A)

image.png

依次选择Analyze, Regression and Curves, Nonlinear Regression (Curve Fit)

image.png

选择数据集,保持默认的Data1即可,确认

image.png

选择模型,在 Dose-response -Inhibition下,找到 [Inhibitor] vs. response -- Variable slope (four parameters)。可见,Prism严格区分了IC50(Inhibition)、EC50(Stimulation),并且也区分x是原始值([Inhibitor])还是对数值(log(inhibitor))。

image.png|500

紧接着,在Constrain选项卡下,输入已知的Top和Bottom数值,点击确定
image.png|500

于是得到所需的各项数值。IC50为0.3167,与R语言的结果一致。另外也给出了拟合优度(Goodness of Fit),可以看到​R^2为0.91,说明拟合得不错。

image.png|500

可能你也好奇选择数学形式完全相同的 Dose-response -Stimulation会怎样。结果是拟合错误,显示 Bad initial values,EC50随便给了个数值,且不会给出拟合优度。

image.png|475

最后一个问题,NT50应该用 Dose-response -Stimulation还是 Dose-response -Inhibition?判断标准很简单:如果随x数值增加,y数值减少,用 Inhibition,否则用 Stimulation

总结

以上,我们介绍了NT50、IC50、EC50的概念,并以IC50为例,使用R语言和Prism分别进行了计算。

由于实验条件、上下限设置的不同,同一个药物的IC50略有差异是正常现象,但一般少有数量级的变化。

如果你需要更深入的了解,可以去看 drc包的原始参考文献:Dose-Response Analysis Using R | PLOS ONE