Р: Как я могу изменить свой набор данных для анализа выживания? - PullRequest
0 голосов
/ 25 июня 2019

Я пытаюсь выполнить анализ выживания, используя R. У меня есть набор данных, который выглядит следующим образом image .

Я хочу проанализировать разницу в выживаемости между двумя типами. S6, S12, S18 ... - это месяц наблюдения, который показывает, выжил или умер пациент (6 месяцев, 12 месяцев, 18 месяцев и т. Д.) ...

Поскольку фактический набор данных содержит большое количество пациентов, невозможно рассчитать время выживания вручную.

Желаю вашей поддержки.

1 Ответ

1 голос
/ 26 июня 2019

Я надеюсь, что следующее работает для вас.Дайте мне знать, если есть проблема - я добавил комментарий на каждом шагу, чтобы вы могли понять, что я сделал.Существуют более элегантные решения, использующие Tidyverse для манипулирования данными, но я сделал это быстро, так как сейчас у меня ограниченное время.Если возможно, пожалуйста, предоставьте набор данных в будущем, чтобы было легче определить конкретные проблемы.

# Import the dataset here - I'm generating mine from scratch but import yours using read.csv or similar

df <- data.frame(pt = 1:6, type = rep(0:1, 3), s0 = c("S", "S", "S", "", "S", "S"), 
              s6 = c("S", "", "S", "", "S", "S"), s12 = c("S", "", "D", "", "D", ""))

# Data manipulation starts here
library(tidyr)
# Replace s12 below with the largest followup event you have
long_df <- tidyr::gather(df, followupRaw, status, s0:s12) # Converts to long form which I prefer to work with - ignore warning message if related to attributes not identical
long_df$status <- factor(long_df$status, levels = c("S", "D")) # Converts to factor and coerces blank to NA values (important)
long_df$followup <- as.numeric(substring(long_df$followupRaw, 2)) # Removes the s character to convert each followup to an integer - make sure all followup periods are in the sXX format

# Form final dataframe for survival analysis
survivalDf <- data.frame(patient = unique(df$pt)) # Single row per patient
survivalDf$followupAvailable <- sapply(survivalDf$patient, function(x) (sum(!is.na(long_df[long_df$pt == x, "status"]))) > 0) # Logical vector so that we can idenify what rows have a followup event recorded (T) versus missing (F)
survivalDf <- survivalDf[survivalDf$followupAvailable,] # Remove patients with no followup
survivalDf$type <- sapply(survivalDf$patient, function(x) df[df$pt == x, "type"]) # Add type to final dataframe
survivalDf$lastFollowup <- sapply(survivalDf$patient, function(x) max(long_df[long_df$pt == x & !is.na(long_df$status), "followup"])) # Find last instance of followup
survivalDf$status <- mapply(function(x, y) long_df[long_df$pt == x & long_df$followup == y, "status"], survivalDf$patient, survivalDf$lastFollowup) # Add patient status at last followup
survivalDf$statusKM <- ifelse(survivalDf$status == "S", 0, ifelse(survivalDf$status == "D", 1, survivalDf$status)) # Convert to Kaplan Meier friendly format: 0-censored, 1-death

# Survival analysis here
library(survival)
library(survminer)
km <- survfit(Surv(lastFollowup, statusKM) ~ type, data = survivalDf)
summary(km) # Table of data
ggsurvplot(km, data = survivalDf) # Kaplan Meier of result
...