首页 > 解决方案 > 如何转换死亡率表以生成 Kaplan-Meier 图

问题描述

我一直在使用 R 中的生存包来使用死亡率数据表生成 Kaplan-Meier 图。我现在正在尝试使用不同格式的新数据生成相同类型的图。我想转换数据,使其与我用来成功制作 Kaplan-Meier 图的输入数据格式相同。

数据 I 通常具有以下格式:

ID Entry_type Departure_type Birth_date Death_date  Lifespan
234 B 1 2008-05-01 2020-01-20 10.986995
549 B 1 2014-05-25 2016-02-09 1.711157
235 B 1 2015-02-01 2017-08-01 2.496920ID

此数据每行有一个人,由他们的 ID 指定。最后一栏是那个人的寿命

我可以使用以下代码从该表中生成 Kaplan-Meier 图:

survival_plot <- ggsurvplot(
    fit = survfit(Surv(Lifespan, Depart.Type) ~ 1, data = life_span_table), 
    xlab = "Years", 
    ylab = "Overall survival probability",
    surv.median.line = "hv",
    title = "Survival Curve",
    legend.title="")

但是,我现在有人口普查记录数据,我正在跟踪一个出生于 1905 年的队列。数据如下所示:

Year Age Total BirthYear CumDeath
1905  0 9262 1905 9262
1906 1 1335 1905 10597
1907 2 514 1905 11111

列的解释器:

Year: The year being recorded.
Age: The age of the individual from the 1905 cohort in that year.
Total: The number of individuals born in 1905 who died in the recorded year.
BirthYear: Always 1905 for this cohort (redundant information)
CumDeath: The total number of people from the cohort who have died at the point of recording (cumulative death). 

因此,这种数据格式不像以前那样每行都有一个单独的数据格式。我觉得使用这些数据制作相同的 Kaplan-Meier 图的唯一方法是重新格式化它,以便每行有一个人,并将他们的 Lifespan 数据添加为新列以适应我通常使用的格式。

寿命可以计算为年份和出生年份之间的差异,但我需要使每个寿命的行数等于每年的总条目数。然后,我可以为每一行添加一个 Entry_Type 和 Departure_Type 列,对于 Entry_type 始终为“B”,对于 Departure_type 始终为“1”。

我通常使用 dplyr 重新格式化表格,但我不确定根据 Total 条目为每个生命周期添加新行的最佳方法。dplyr 可以做到这一点,还是我最好使用循环或 lapply 函数?

任何帮助是极大的赞赏。

标签: rdplyrdatatablesurvival-analysissurvival

解决方案


事实证明,使用 R data.frame 行索引是一个相当简单的练习。考虑这个玩具示例(与您的非常相似):

tt = data.frame(name=c('a', 'b', 'c'), 
                count=c(1, 2, 3))
# extract counts specifying how many times to replicate each row
counts = tt$count
# construct row indexes
row_positions = seq_along(counts)
# or
row_positions = seq(1, nrow(tt))
# inflate vector of row indexes according to the counts
row_pos_replicated = rep(row_positions, counts)
# use inflated indexes to expand frame rows per `count` values
tt_replicated = tt[row_pos_replicated,]

我们只是根据列将行从新框架扩展tt到新框架:tt_replicatedcount

> tt_replicated
       name  count
1      a     1
2      b     2
2.1    b     2
3      c     3
3.1    c     3
3.2    c     3

基于上述并使用更简洁的语法为您的框架解决方案:

census_data = read.csv(text = "Year Age Total BirthYear CumDeath
1905 0 9262 1905 9262
1906 1 1335 1905 10597
1907 2 514 1905 11111", sep="")

census_data_for_KMplot = census_data[rep(seq(1,
                                             nrow(census_data)),
                                         census_data$CumDeath),]

让我们计算每个的行数Year(使用data.table):

> data.table::setDT(census_data_for_KMplot)[, .N, by=Year]
   Year     N
1: 1905  9262
2: 1906 10597
3: 1907 11111

使用data.table速度和更简单的语法(在行索引时注意 no sep=infread和 no ,inside ):[]

library(data.table)

census_data = fread(text = "Year Age Total BirthYear CumDeath
1905 0 9262 1905 9262
1906 1 1335 1905 10597
1907 2 514 1905 11111")

census_data_for_KMplot = census_data[rep(seq_along(census_data$CumDeath), 
                                     census_data$CumDeath)]
census_data_for_KMplot[, .N, by=Year]

   Year     N
1: 1905  9262
2: 1906 10597
3: 1907 11111

推荐阅读