从日期制作用于生存分析的删失变量
Making censored variables for surival analysis from dates
我是 R 的初学者,我想对我拥有的灯泡的数据集进行生存分析。我想计算灯泡的寿命,所以我需要计算第 2 行 date_broken
和第 1 行 date_solved
之间的时间段。
我知道我可以使用 difftime(time, time2, units = "days")
来计算 相同 行中 date_fixed
和 date_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
来总结,否则差异将毫无意义。
我在这里展示了一个使用包 lubridate
和 data.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/),但在我的脖子上,生活是为了生活,而不是编码,甚至我有时也会用螺丝刀(虽然是旧的)搅拌油漆).
我是 R 的初学者,我想对我拥有的灯泡的数据集进行生存分析。我想计算灯泡的寿命,所以我需要计算第 2 行 date_broken
和第 1 行 date_solved
之间的时间段。
我知道我可以使用 difftime(time, time2, units = "days")
来计算 相同 行中 date_fixed
和 date_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
来总结,否则差异将毫无意义。
我在这里展示了一个使用包 lubridate
和 data.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/),但在我的脖子上,生活是为了生活,而不是编码,甚至我有时也会用螺丝刀(虽然是旧的)搅拌油漆).