R中的离散时间事件历史(生存)模型

机器算法验证 r 生存
2022-03-27 10:22:51

我正在尝试在 R 中拟合离散时间模型,但我不知道该怎么做。

我读过您可以将因变量组织在不同的行中,每个时间观察一个,并将该glm函数与 logit 或 cloglog 链接一起使用。从这个意义上说,我有三列:IDEvent(1 或 0,在每个时间-obs)和Time Elapsed(自观察开始以来),加上其他协变量。

如何编写代码以适应模型?哪个是因变量?我想我可以Event用作因变量,并将 包含Time Elapsed在协变量中。但是会发生什么ID我需要吗?

谢谢。

4个回答

关于数据组织,您基本上是对的。如果您有这样组织的案例:

ID M1 M2 M3 EVENT

您可能希望重新组织数据,使其看起来像这样:

ID TIME EVENT
1  1    0
1  2    1
1  3    1
2  1    0
2  2    0
.  .    .
.  .    .

我称之为从宽格式到长格式的转换。使用函数在 R 中很容易完成,使用包reshape()更容易完成reshape2

我个人会保留该ID领域,因为它可能用于识别混合效应模型中的变异来源。但这不是必需的(正如@BerndWeiss 指出的那样)。以下假设您希望这样做。glm(...,family=binomial)如果不是,请拟合一个没有随机效应项的类似模型。

R 中的lme4包将适合与您正在谈论的模型类似的混合效应逻辑回归模型,除了一个或两个随机效应来解释受试者之间系数的可变性(ID)。如果您的数据存储在名为df.

require(lme4)
ans <- glmer(EVENT ~ TIME + (1+TIME|ID), data=df, family=binomial)

这个特定的模型允许TIMEintercept系数在 ID 上随机变化。换句话说,这是嵌套在个体中的分层线性混合测量模型。

离散时间事件历史模型的另一种形式分解TIME为离散虚拟变量,并将每个虚拟变量作为参数拟合。这本质上是Cox PH 模型的离散情况,因为危险曲线不限于线性(或二次,或者您可以想象转换时间)。TIME但是,如果有很多离散时间段,您可能希望将它们分组为一组可管理的(即小的)离散时间段。

进一步的替代方案涉及转换时间以使您的危险曲线正确。之前的方法基本上可以让你不必这样做,但是之前的方法比这个(和我提出的原始线性案例)更简洁,因为你可能有很多时间点,因此会有很多讨厌的参数。

关于这个主题的一个很好的参考是 Judith Singer 和 John Willet 的Applied Longitudinal Data Analysis: Modeling Change and Event Occurrence

Singer 和 Willett 在这个主题上发表了很多文章。我强烈建议您阅读他们的一些论文您可能还想获得他们的书“Applied Longitudinal Data Analysis: Modeling Change and Event Occurrence”显然是该领域最好的教科书之一。

对于大多数书籍章节,都有可用的R 示例代码(参见第 11 章),它演示了如何构建数据(“人周期格式”)以及如何分析这种数据。对于标准离散时间模型,您不需要 ID 变量,也不需要按照@ndoogan 的建议估计混合效应模型。一个简单的glm(event ~ time + ..., family = "binomial")作品就好了。Singer 和 Willett 还讨论了如何对时间变量(线性、二次等)建模的许多问题

引用我强烈推荐的另外两个参考资料:

  • Allison (1982):“事件历史分析的离散时间方法”( PDF )(Allison 文章还讨论了为什么可以使用标准 glm 而不是混合效果模型)
  • Mills (2011):“介绍生存和事件历史分析”

您可以将时间时间分成多个间隔并执行多周期 logit 模型,如Shumway (2001)中所述。例如,您的时间间隔是。我已经在 R 中实现了这一点,如果您在生存分析中使用的典型停止事件设置中有初始数据,则直接适用。做请注意,所得模型的 t-stats 没有 Shumway (2001) 中提到的校正。(0,1],(1,2],dynamichazard::static_glm

此方法与带有时间假人的 @ndoogan 不同,因为您在所有时间段中只能获得一个常见的截距dynamichazard::static_glm但是,您可以通过dynamichazard::get_survival_case_weights_and_data使用参数调用来获得每个时期的use_weights = FALSE虚拟,自己将时间虚拟指标添加到返回的值中data.frame,然后调用 eg glm

这称为“计数过程”数据。Survival 包有一个非常好的 tmerge() 函数。插入时间相关或累积协变量并相应地划分后续时间非常有用。这个小插图很好地解释了这个过程