【问题标题】:Plotting dose response curves with ggplot2 and drc用 ggplot2 和 drc 绘制剂量反应曲线
【发布时间】:2016-04-21 20:59:37
【问题描述】:

在生物学中,我们经常想要绘制剂量反应曲线。 R 包“drc”非常有用,基础图形可以轻松处理“drm 模型”。但是,我想将我的 drm 曲线添加到 ggplot2。

我的数据集:

 library("drc")
 library("reshape2")
 library("ggplot2")
 demo=structure(list(X = c(0, 1e-08, 3e-08, 1e-07, 3e-07, 1e-06, 3e-06, 
 1e-05, 3e-05, 1e-04, 3e-04), Y1 = c(0, 1, 12, 19, 28, 32, 35, 
 39, NA, 39, NA), Y2 = c(0, 0, 10, 18, 30, 35, 41, 43, NA, 43, 
 NA), Y3 = c(0, 4, 15, 22, 28, 35, 38, 44, NA, 44, NA)), .Names = c("X", 
"Y1", "Y2", "Y3"), class = "data.frame", row.names = c(NA, -11L
))

使用基础图形:

plot(drm(data = reshape2::melt(demo,id.vars = "X"),value~X,fct=LL.4(),na.action = na.omit),type="bars")

生成一个漂亮的 4 参数剂量反应图。

试图在 ggplot2 中绘制相同的图,我偶然发现了 2 个问题。

  1. 没有办法直接添加drm模型曲线。我需要将 4-PL 重写为函数,并以 stat_function 的形式添加,至少可以说很麻烦。

    ggplot(reshape2::melt(demo,id.vars = "X"),aes(X,value)) + 
      geom_point() + 
      stat_function(fun = function(x){
        drm_y=function(x, drm){
          coef(drm)[2]+((coef(drm)[3]-coef(drm)[2])/(1+exp((coef(drm)[1]*(log(x)-log(coef(drm)[4]))))))
        }
    + drm_y(x,drm = drm(data = reshape2::melt(demo,id.vars = "X"), value~X, fct=LL.4(), na.action = na.omit))
     })
    
  2. 如果这还不够,它只有在 scale_x 是连续的情况下才有效。如果我想添加scale_x_log10(),我会得到: Warning message: In log(x): NaNs produced

我知道log10(0) = -Inf 但有一些方法可以处理这个问题。无论是(与 plot.drc 的情况一样),x=0 值都绘制在 x 轴上,基本上是之前最低 x 值的 1/100。 (demo$X[which.min(demo$X)+1]/100) 或在 GraphPad Prism 中,0 从剂量响应曲线中完全省略。

我的问题是:

  1. 有没有办法直接在 ggplot2 中绘制 drm 模型?

  2. 如何将数据集与其对应的 4-PL 曲线拟合链接起来,以使它们以相同的颜色绘制?

【问题讨论】:

  • 我很想在 ggplot 之外对 drm 进行计算,将结果放入 data.frame,然后将其提供给 ggplot

标签: r plot graphics ggplot2 drc


【解决方案1】:

drc 包的作者提供的recent paper 包含提取参数以供 ggplot2 使用的说明。它们不在 ggplot2 中工作,而是从模型中提取数据。这是他们应用于您的数据的解决方案。

demo1 <- reshape2::melt(demo,id.vars = "X") # get numbers ready for use.
demo.LL.4 <- drm(data = demo1,value~X,fct=LL.4(),na.action = na.omit) # run model.

predict 函数可以从drm 模型中提取参数。它与使用curveid 拟合的多条曲线不兼容。

# predictions and confidence intervals.
demo.fits <- expand.grid(conc=exp(seq(log(1.00e-04), log(1.00e-09), length=100))) 
# new data with predictions
pm <- predict(demo.LL.4, newdata=demo.fits, interval="confidence") 
    demo.fits$p <- pm[,1]
    demo.fits$pmin <- pm[,2]
    demo.fits$pmax <- pm[,3]

他们建议转移零浓度以避免 coord_trans 出现问题。

demo1$XX <- demo1$X
demo1$XX[demo1$XX == 0] <- 1.00e-09

然后绘制曲线,省略geom_ribbon 会阻止绘制错误。

ggplot(demo1, aes(x = XX, y = value)) +
  geom_point() +
  geom_ribbon(data=demo.fits, aes(x=conc, y=p, ymin=pmin, ymax=pmax), alpha=0.2) +
  geom_line(data=demo.fits, aes(x=conc, y=p)) +
  coord_trans(x="log") 

要同时绘制多条曲线,可以重复该过程。为每个集合添加 ID。

demo.fits_1 <- data.frame(label = "curve1", demo.fits)

然后使用rbind 组合所有提取的参数。从那里 ggplot 可以处理颜色。

【讨论】:

    【解决方案2】:

    我将回答我自己的问题,希望这能帮助其他面临同样问题的人。

    当然可以使用 ggplot2 和 drc 包绘制剂量反应曲线,如果在线性刻度上绘制,则只需添加 geom_ 或 stat_smooth (method=drm, fct=LL.4(),se=FALSE),如果添加了 scale_x_log10(),则使用 geom_ 或 stat_smooth (method=drm, fct=L.4(),se=FALSE)

    为了能够使用 log10 比例,我将数据转换为:

    demo <- demo %>% 
          mutate(X = 
           ifelse(X == 0, 
                  yes = (sort(demo$X[which.min(sort(demo$X)) + 1]/100)),
                  no = X
                  )
                )         #looks for the pre-lowest value in X and divides it by 100
    

    在本例中,我将 X = 0 值替换为 X = 上一个 X 值的 1/100(在本例中为 1e-10)。但是,您可以像 Prism 一样,通过从数据集中完全省略它来轻松删除弄乱对数绘图的 0 值。 正如我发现的那样,需要注意的一件事是 ggplot 首先缩放轴然后添加数据,这就是代码在尝试 log10(0) 时中断的原因。

    另一个微妙之处是 stat_smooth 函数完全能够使用 method = drm 处理 drm 模型,但它不知道如何拟合“SE”置信区间。选择se = FALSE 从而启用绘图,并且在我的拙见中,无论如何都会使绘图不那么混乱 - 只需添加误差线。

    最后,将fct = LL.4() 更改为fct = L.4() 允许以log10 比例绘制,因为再次首先选择比例,然后完成拟合。因此,即使轴值是非对数的,ggplot 实际上已将数据集转换为 log10,因此拟合函数现在只需 logit-4P(即 L.4())而不是 log-logit-4P(LL .4())。

    geom_smooth() 和 stat_smooth() 函数自然会采用与数据集相同的颜色,无需调整拟合函数的颜色以对应数据点的颜色。

    总结:

    demo <- demo %>% 
          mutate(X = 
           ifelse(X == 0, 
                  yes = (sort(demo$X[which.min(sort(demo$X)) + 1]/100)),
                  no = X
                  )
                )
    demo.long <- reshape2::melt(demo,id.vars = "X") #reshapes the demo dataset to long format
    ggplot(data = demo.long,
           aes(x = X, y = value, col = variable)
          ) + 
       geom_point() + 
       geom_smooth(method = drm, fct = L.4(), se = FALSE) +
       scale_x_log10() #plots out the dataset with the corresponding 4-parameter log-logit dose response curves
    

    【讨论】:

    • 对于R version 3.6.2ggplot2_3.2.1drc_3.0-1,这仅在将“fct”包装到method.args = list()geom_smooth(method = drm, method.args = list(fct = L.4()), se = FALSE)时才有效
    【解决方案3】:

    更新后的答案:geom_smooth(method = drm, method.args = list(fct = L.4()), se = FALSE) 非常有帮助!

    【讨论】:

    猜你喜欢
    • 2021-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 2017-11-24
    相关资源
    最近更新 更多