【问题标题】:Plotting both a GLM and LM of same data绘制相同数据的 GLM 和 LM
【发布时间】:2017-02-24 19:04:17
【问题描述】:

我想绘制相同数据的线性模型 (LM) 和非线性 (GLM) 模型。

16% - 84% 之间的范围应该在 LM 和 GLM 之间对齐,Citation: section 3.5

我已经包含了更完整的代码块,因为我不确定我应该在什么时候尝试切割线性模型。或者在这一点上我搞砸了-我认为是线性模型

下面的代码会产生下图:

我的目标(取自之前的引用链接)。

这是我的数据:

mydata3 <- structure(list(
               dose = c(0, 0, 0, 3, 3, 3, 7.5, 7.5, 7.5, 10,     10, 10, 25, 25, 25, 50, 50, 50), 
               total = c(25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L, 25L), 
               affected = c(1, 0, 1.2, 2.8, 4.8, 9, 2.8, 12.8, 8.6, 4.8, 4.4, 10.2, 6, 20, 14, 12.8, 23.4, 21.6), 
               probability = c(0.04, 0, 0.048, 0.112, 0.192, 0.36, 0.112, 0.512, 0.344, 0.192, 0.176, 0.408, 0.24, 0.8, 0.56, 0.512, 0.936, 0.864)), 
               .Names = c("dose", "total", "affected", "probability"), 
               row.names = c(NA, -18L), 
               class = "data.frame")

我的脚本:

#load libraries

library(ggplot2)
library(drc)  # glm model
library(plyr) # rename function
library(scales) #log plot scale

#Creating linear model
mod_linear <- lm(probability ~ (dose), weights = total, data = mydata3)

#Creating data.frame: note values 3 and 120 refer to 16% and 84% response in sigmoidal plot
line_df <-expand.grid(dose=exp(seq(log(3),log(120),length=200)))

#Extracting values from linear model
p_line_df <- as.data.frame(cbind(dose = line_df,
                               predict(mod_linear, newdata=data.frame(dose = line_df),
                                       interval="confidence",level=0.95)))

#Renaming linear df columns
p_line_df <-rename(p_line_df, c("fit"="probability"))
p_line_df <-rename(p_line_df, c("lwr"="Lower"))
p_line_df <-rename(p_line_df, c("upr"="Upper"))
p_line_df$model <-"Linear"


#Create sigmoidal dose-response curve using drc package
    mod3 <- drm(probability ~ (dose), weights = total, data = mydata3, type ="binomial", fct=LL.2(names=c("Slope:b","ED50:e")))

    #data frame for ggplot2 
    base_DF_3 <-expand.grid(dose=exp(seq(log(1.0000001),log(10000),length=200)))

    #extract data from model
    p_df3 <- as.data.frame(cbind(dose = base_DF_3,
                                 predict(mod3, newdata=data.frame(dose = base_DF_3),
                                         interval="confidence", level=.95)))

#renaming columns
p_df3 <-rename(p_df3, c("Prediction"="probability"))
p_df3$model <-"Sigmoidal" 

#combining Both DataFames
 p_df_all <- rbind(p_df3, p_line_df)

#plotting
ggplot(p_df_all, aes(x=dose,y=probability, group=model))+
    geom_line(aes(x=dose,y=probability,group=model,linetype=model),show.legend = TRUE)+
  scale_x_log10(breaks = c(0.000001, 10^(0:10)),labels = c(0, math_format()(0:10)))

【问题讨论】:

  • glm是广义线性模型,怎么非线性?
  • @SandipanDey:因为它在变换的尺度上是线性的。因此,术语“广义”?
  • @42- 我认为模型是线性还是非线性取决于决策边界的性质(如果是分类模型),例如,逻辑回归是线性模型,因为决策边界是线性的,我们可以用数学方法证明。
  • 看起来您适合 probabilitydose 的线性模型。但是,您在 log10 刻度上绘制剂量。当 x 轴在 log10 刻度上时,希望图表上的线是直的,这意味着您的线性模型应该是 probabilitylog10(dose)
  • @SandipanDey:模型是线性的,因为它使用线性链接函数 (y=mx+b)。 Sigmoidal logit / probit 模型在传统意义上不是线性的,因为它们绘制非线性关系。例如高剂量的死亡率不一定与中等剂量的死亡率具有相同的关系。 GLM 是非线性和线性模型之间的一个棘手的中间地带。

标签: r ggplot2 linear-regression logistic-regression drc


【解决方案1】:

查看您提供的参考资料,作者描述的是使用线性模型来逼​​近(S 形)逻辑函数的中心部分。实现这一点的线性模型是一条通过逻辑曲线拐点的直线,并且在该拐点处与逻辑函数具有相同的斜率。我们可以使用一些基本的代数和微积分来解决这个问题。

?LL.2,我们看到drm拟合的逻辑函数的形式是

f(x) = 1 / {1 + exp(b(log(x) - log(e)))}

我们可以得到这个方程中系数的值

b = mod3$coefficients[1]
e = mod3$coefficients[2]

现在,通过微分,逻辑函数的斜率由下式给出

dy/dx = -(b * exp((log(x)-log(e))*b)) / (1+exp((log(x)-log(e))*b))^ 2

在拐点处,剂量 (x) 等于系数 e,因此拐点处的斜率(大大)简化为

sl50 = -b/4

由于我们也知道拐点出现在probability = 0.5dose = e 的点上,我们可以像这样构造直线(在对数变换坐标中):

linear_probability = sl50 * (log(p_df3$dose) - log(e)) + 0.5

现在,将逻辑函数和线性函数绘制在一起:

p_df3_lin = p_df3
p_df3_lin$model = 'linear'
p_df3_lin$probability = linear_probability

p_df_all <- rbind(p_df3, p_df3_lin)

ggplot(p_df_all, aes(x=dose,y=probability, group=model))+
  geom_line(aes(x=dose,y=probability,group=model,linetype=model),show.legend = TRUE)+
  scale_x_log10(breaks = c(0.000001, 10^(0:10)),labels = c(0, math_format()(0:10))) +
  scale_y_continuous(limits = c(0,1))

【讨论】:

  • 这是对我的问题的一个很好的解构 - 完美运行!谢谢! .只是一个快速的后续问题:您知道我的线性代码如何/为什么导致曲线图吗? mod_linear &lt;- lm(probability ~ (dose), weights = total, data = mydata3)p_line_df &lt;- as.data.frame(cbind(dose = line_df, predict(mod_linear, newdata=data.frame(dose = line_df), interval="confidence",level=0.95)))
  • @Arch,-您将线拟合到未转换的坐标中,然后将其绘制在对数刻度上。这就是为什么它看起来是弯曲的。试试这个,你会明白我的意思:plot(1:100, 1:100, type='l', log = 'x')
猜你喜欢
  • 2018-05-23
  • 1970-01-01
  • 2014-04-21
  • 2018-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-08
相关资源
最近更新 更多