从日期制作用于生存分析的删失变量

Making censored variables for surival analysis from dates

我是 R 的初学者,我想对我拥有的灯泡的数据集进行生存分析。我想计算灯泡的寿命,所以我需要计算第 2 行 date_broken 和第 1 行 date_solved 之间的时间段。

我知道我可以使用 difftime(time, time2, units = "days") 来计算 相同 行中 date_fixeddate_broken 之间的时间,但是我会计算灯泡坏掉的时间,这不是我感兴趣的。

我在下面提供了一小部分数据样本。对于特定位置的每个灯泡,我都有关于它坏掉的日期和修好日期的信息。

(除了下面示例中给出的列,我还有其他应该具有预测价值的特征。)

#  date_broken date_fixed lightbulb location
# 1   26-2-2015  17-3-2015     1        A
# 2   19-3-2015  26-3-2015     1        A
# 3   26-3-2015  26-3-2015     1        A
# 4   17-4-2015  29-4-2015     2        B
# 5   19-6-2015  25-6-2015     2        B
# 6    9-7-2015  30-7-2015     2        B



ds <- data.frame(  date_broken = c("26-2-2015", "19-3-2015",
                                   "26-3-2015", "17-4-2015",
                                   "19-6-2015", "9-7-2015"), 
                   date_fixed = c("17-3-2015", "26-3-2015",  "26-3-2015", "29-4-2015", "25-6-2015", "30-7-2015"),
                   lightbulb = c("1`", "1", "1", "2", "2", "2"), location = c("A", "A", "A", "B", "B", "B"))

这应该有帮助

library(dplyr)
ds2 <- ds %>% 
    group_by(lightbulb) %>%
    mutate(tp = as.Date(date_broken, "%d-%m-%Y") - 
                  as.Date(lag(date_fixed,1), "%d-%m-%Y"))

首先,您需要按照@Gaurav 的建议确定日期。然后,你需要用 lightbulb 来总结,否则差异将毫无意义。 我在这里展示了一个使用包 lubridatedata.table:

的替代方案
library(lubridate)
library(data.table)
ds$date_broken <- dmy(ds$date_broken)
ds$date_fixed <- dmy(ds$date_fixed)
setDT(ds)

setDT(ds)[, dt := difftime(date_fixed, shift(date_broken, 1L, type="lag"), "days"), by = lightbulb]
ds

产生:

   ##    date_broken date_fixed lightbulb location      dt
   ## 1:  2015-02-26 2015-03-17         1        A NA days
   ## 2:  2015-03-19 2015-03-26         1        A 28 days
   ## 3:  2015-03-26 2015-03-26         1        A  7 days
   ## 4:  2015-04-17 2015-04-29         2        B NA days
   ## 5:  2015-06-19 2015-06-25         2        B 69 days
   ## 6:  2015-07-09 2015-07-30         2        B 41 days

对于未来的机会,当您产生一些预期的结果以及您的问题时会很有帮助。

我真的很喜欢 R 中那些令人印象深刻的管道运算符。它们非常优雅,如果有人有现成的解决方案,那就太棒了。

我主要做循环,可能是因为我喜欢我看到发生了什么的东西,并且我可以边调试边调试。 (几十年前我也是在 BASIC 环境下长大的——但不要告诉任何人。)

无论如何,这是我的方法,与我正在做的事情非常相似,希望使用序列计数器能增加一点价值。这可能用作回归变量(协变量或分层)或可以作为子集的变量,例如假设您可能希望将后来的失败与早期的失败分开查看。序列计数器的生存曲线在我的工作中提供了很多信息。

首先转换日期...

 ## convert dates. once done it's done
 ds$date_broken <- as.Date(ds$date_broken, "%d-%m-%Y")
 ds$date_fixed <- as.Date(ds$date_fixed, "%d-%m-%Y")

添加一个序列计数器列(称为 seq)以跟踪失败次数

ds$seq <- 1

填充该计数器列

for (rdx in 2:nrow(ds)) {
    ## if same item, increment count. If new item, start new count at seq = 1
    ifelse(ds$lightbulb[rdx] == ds$lightbulb[rdx-1], ds$seq[rdx] <- ds$seq[rdx-1]+1, 1) 
}

现在添加差异列

ds$diff <- NA

填充差异列

for (rdx in 2:nrow(ds)) {
    ## if same item, difference is current failure date minus previous in-service date
    ifelse(ds$seq[rdx] != 1, ds$diff[rdx] <- ds$date_broken[rdx] - ds$date_fixed[rdx-1], NA) 
}

嗯,这对我很有用,无论是概念化还是实施。请注意,有些人确实对循环有点着迷(http://paleocave.sciencesortof.com/2013/03/writing-a-for-loop-in-r/),但在我的脖子上,生活是为了生活,而不是编码,甚至我有时也会用螺丝刀(虽然是旧的)搅拌油漆).