Как создать диаграмму Санки в R, показывающую изменения во времени для того же узла? - PullRequest
0 голосов
/ 31 марта 2019

Я пытаюсь создать диаграмму Санки для моих данных - информация о моих данных приведена ниже.

dput(df_new)
structure(list(Hospital = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 
2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 
5, 5, 5, 5), Patient = c(21, 21, 21, 21, 21, 21, 21, 21, 21, 
21, 21, 21, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 24, 
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 
25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 
26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 
27, 27, 27, 27, 27), Therapy = c("Etanercept", "Etanercept", 
"Etanercept", "Etanercept", "Etanercept", "Etanercept", "Infliximab", 
"Infliximab", "Infliximab", "Infliximab", "Infliximab", "Infliximab", 
"Etanercept", "Etanercept", "Etanercept", "Etanercept", "Etanercept", 
"Etanercept", "Rituximab", "Rituximab", "Rituximab", "Rituximab", 
"Rituximab", "Rituximab", "Adalimumab", "Adalimumab", "Adalimumab", 
"Adalimumab", "Adalimumab", "Adalimumab", "Infliximab", "Infliximab", 
"Infliximab", "Infliximab", "Infliximab", "Infliximab", "Etanercept", 
"Etanercept", "Etanercept", "Etanercept", "Etanercept", "Etanercept", 
"Infliximab", "Infliximab", "Infliximab", "Infliximab", "Infliximab", 
"Infliximab", "Etanercept", "Etanercept", "Etanercept", "Etanercept", 
"Etanercept", "Etanercept", "Rituximab", "Rituximab", "Rituximab", 
"Rituximab", "Rituximab", "Rituximab", "Adalimumab", "Adalimumab", 
"Adalimumab", "Adalimumab", "Adalimumab", "Adalimumab", "Etanercept", 
"Etanercept", "Etanercept", "Etanercept", "Etanercept", "Etanercept", 
"Infliximab", "Infliximab", "Infliximab", "Infliximab", "Infliximab", 
"Infliximab"), `First,Second,Third,Fourth,etc` = c(1, 1, 1, 1, 
1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 1, 
1, 1, 1, 1, 1, 4, 4, 4, 4, 4, 4), QualityLife = c(3, 4, 4, 4, 
2, 2, 2, 5, 6, 6, 6, 8, 1, 3, 3, 4, 4, 5, 3, 5, 6, 6, 7, 7, 2, 
3, 3, 3, 3, 3, 3, 5, 5, 5, 5, 5, 2, 3, 3, 3, 4, 4, 1, 3, 3, 3, 
1, 2, 2, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 4, 4, 2, 
3, 3, 3, 4, 4, 3, 3, 3, 4, 4, 5), FollowUp_time = c(0, 1, 3, 
6, 12, 18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 
12, 18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 
18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 18, 
0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 18), 
    Continuous_time = c(0, 1, 3, 6, 12, 18, 18, 19, 21, 24, 30, 
    36, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 18, 0, 1, 3, 6, 12, 
    18, 36, 37, 39, 42, 48, 54, 0, 1, 3, 6, 12, 18, 0, 1, 3, 
    6, 12, 18, 54, 55, 57, 60, 66, 72, 90, 91, 93, 96, 102, 108, 
    126, 127, 129, 132, 138, 144, 0, 1, 3, 6, 12, 18, 72, 73, 
    75, 78, 84, 90)), row.names = c(NA, -78L), class = "data.frame")

Это медицинское упражнение.Для каждой терапии пациенты спрашивают в 0,1,3,6,12,18 месяцев, каково их качество жизни.Если в определенное время наблюдения качество жизни <определенный параметр, врачи меняют терапию пациента, и я хочу показать это на диаграмме Санки.Я хотел бы, чтобы один узел «Терапия» (категориальная переменная с разными названиями терапии) повторялся во времени, а ось х учитывала время.Кто-нибудь может мне с этим помочь?Я действительно ценю любую помощь. </p>

Это то, что я пытался до сих пор:

### install and load packages
install.packages("ggplot2")
install.packages("readxl")
install.packages("ggforce")

# load packages
library(ggplot2)
library(readxl)
library(ggforce)

### read dataset
dataset_new <- read_excel("Made_up_dataset_new.xlsx")
df_new <- as.data.frame(dataset_new)

df_new$Unit <- 1

df_sankey <- df_new[c("Therapy", "First,Second,Third,Fourth,etc", "Continuous_time","Unit")]

# transform dataframe into appropriate format
df_sankey <- gather_set_data(df_sankey, 1:3)

# define axis-width / sep parameters once here, to be used by each geom layer in the plot
aw <- 0.1
sp <- 0.1

ggplot(df_sankey, 
       aes(x = x, id = id, split = y, value = Unit)) +
  geom_parallel_sets(aes(fill = Therapy), alpha = 0.3, 
                     axis.width = aw, sep = sp) +
  geom_parallel_sets_axes(axis.width = aw, sep = sp) +
  geom_parallel_sets_labels(colour = "white", 
                            angle = 0, size = 3,
                            axis.width = aw, sep = sp) +
  theme_minimal()

Но результат не тот, который я хочу, потому что время сжимается по оси Y, а нена оси х, если это имеет смысл?Пожалуйста, найдите ниже черновик того, что я думал:

enter image description here

Я ценю любую помощь!


Основано на ответе нижеЯ попытался адаптировать код к своему набору данных и запускаю:

df_sankey <- df_new[c("Patient","FirstSecondThird","Therapy")]
head(df_sankey)

df_new$FirstSecondThird <- factor(df_new$FirstSecondThird)

# Plotting it
ggplot(df_sankey, aes(x = FirstSecondThird, stratum = Therapy, alluvium = Patient, fill = Therapy, label = Therapy)) +
  scale_fill_brewer(type = "qual", palette = "Set2") +
  geom_flow(stat = "alluvium", lode.guidance = "rightleft", color = "darkgray") +
  geom_stratum() +
  theme(legend.position = "bottom") +
  ggtitle("Treatment across observation period")

Результат показан ниже, но это не совсем то, что я хочу (как я пытался объяснить в прилагаемом черновике, язнаю, что это очень просто): enter image description here

1 Ответ

2 голосов
/ 31 марта 2019

Ну, у вас есть несколько вариантов. Первое решение, которое сработало для меня, было ggplot / geom_flow:

# requires(ggplot2)
# requires(ggalluvial)

# faking the data for 20 patients
set.seed(42)
individual <- as.character(rep(1:20,each=5))
timeperiod <- paste0(rep(c(0, 18,36,54,72),20),"_week")
therapy <- factor(sample(c("Etanercept", "Infliximab", "Rituximab",  "Adalimumab","Missing"), 100, replace=T))
d <- data.frame(individual, timeperiod, therapy)
head(d)

# Plotting it
ggplot(d, aes(x = timeperiod, stratum = therapy, alluvium = individual, fill = therapy, label = therapy)) +
  scale_fill_brewer(type = "qual", palette = "Set2") +
  geom_flow(stat = "alluvium", lode.guidance = "rightleft", color = "darkgray") +
  geom_stratum() +
  theme(legend.position = "bottom") +
  ggtitle("Treatment across observation period")

enter image description here

Аргумент stat = "alluvium" в geom_flow должен позволять отслеживать отдельных пациентов, но если вы хотите, вы также можете объединить потоки:

ggplot(d, aes(x = timeperiod, stratum = therapy, alluvium = individual, fill = therapy, label = therapy)) +
  scale_fill_brewer(type = "qual", palette = "Set2") +
  geom_flow(color = "darkgray") +
  geom_stratum() +
  theme(legend.position = "bottom") +
  ggtitle("Treatment across observation period")

enter image description here

РЕДАКТИРОВАТЬ 1 : Если вы хотите, чтобы у некоторых пациентов поток был прекращен (например, терапия завершилась), вы можете легко сделать это, установив этих пациентов как NA:

# setting 3 pantients as NA for the last timepoint
d[which(d$individual==3 & d$timeperiod=="72_week"), ]["therapy"] <- NA 
d[which(d$individual==6 & d$timeperiod=="72_week"), ]["therapy"] <- NA 
d[which(d$individual==9 & d$timeperiod=="72_week"), ]["therapy"] <- NA 

# making the plot:
ggplot(d, aes(x = timeperiod, stratum = therapy, alluvium = individual, fill = therapy, label = therapy)) +
scale_fill_brewer(type = "qual", palette = "Set2") +
geom_flow(stat = "alluvium", lode.guidance = "rightleft", color = "darkgray") + 
geom_stratum(alpha=0.75) +
theme(legend.position = "bottom") +
ggtitle("Treatment across observation period")

enter image description here Теперь, если честно, networkD3 тоже работал, но мне просто не удалось заставить его выглядеть достаточно хорошо.

РЕДАКТИРОВАТЬ 2 :

  • Вы также можете использовать geom_alluvium вместо geom_flow. Основное (визуальное) различие между ними заключается в том, что в geom_flow цвет потока наследуется от соседних узлов (либо исходного, либо целевого). В geom_alluvium вместо этого он наследуется от первого узла - например, поток не будет менять цвет при прохождении через узлы.

  • Если вы хотите объединить график с другим графиком, проще всего будет использовать par(mfrow=c(1,2)).

...