Skip to content

Swimmer plot#99

Draft
Lpierott wants to merge 35 commits into
mainfrom
Swimmer-plot
Draft

Swimmer plot#99
Lpierott wants to merge 35 commits into
mainfrom
Swimmer-plot

Conversation

@Lpierott

@Lpierott Lpierott commented Nov 12, 2025

Copy link
Copy Markdown
Contributor
  • Faire une fonction : regarder les autres fonctions
  • flèche que si alive (exemple)
  • Essayer de réduire le nombre de data d'input pour le graphique.
  • Programmation défensive :
    Tu pars du principe que tes données d'input ont une certaine structure (e.g. data1 a une colonne col1 qui est de type numérique), il faut faire des checks pour que les utilisateurs aient un message d'erreur clair.
  • Ajouter des warnings : par exemple si death avant CR, ce n'est pas normal, il faut faire un warning. Par exemple suivi_fu$first_fu devrait toujours être 0 ?

@DanChaltiel DanChaltiel linked an issue Nov 12, 2025 that may be closed by this pull request

@DanChaltiel DanChaltiel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is amazing work Livia!
Here are a few comments to improve the existing code.

Comment thread R/Swimmer plot.R
adm <- recist %>%
left_join(enrolres %>% select(subjid, date_inclusion), by = "subjid") %>%
# filter(!is.na(rcresp), rcresp != "Progressive disease") %>%
filter(!is.na(rcresp)) %>%

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pourquoi filtrer les réponses NA ? On peut avoir une administration quand même non ?

@Lpierott Lpierott Dec 4, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

parce que apres pour simuler le reste des datset ca va etre difficil. Le dataset creer c est juste un example. Le statistician est censse en premier lieux preparer son final dataset avant de faire la swimmer plot.

Comment thread R/Swimmer plot.R Outdated
# filter(!is.na(rcresp), rcresp != "Progressive disease") %>%
filter(!is.na(rcresp)) %>%
arrange(subjid, rcdt) %>% # ensure ordered by patient and RECIST
group_by(subjid) %>%

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tu peux utiliser l'argument .by dans mutate(), au lieu d'utiliser group_by() puis ungroup()

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be done!

Comment thread R/Swimmer plot.R Outdated
Comment on lines +72 to +75
ADMDT = if_else(
row_number() == 1,
pmin(date_inclusion + days(sample(5:15, 1)), rcdt), # 5–15 days after inclusion but before first RECIST
rcdt - days(sample(21:30, 1)) # subsequent admissions: 21–30 days before each RECIST

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pas mal !
Mais je me demande si ça ne fait pas des trucs bizarres parfois.
Je l'aurais fait en 2 étapes : d'abord ADMDT0 qui vaudra pmin(date_inclusion + days(sample(5:15, 1)), rcdt), puis ADMDT qui vaudra ADMDT0 + days(sample(21:30, 1)).
De cette manière, les administrations sont un peu plus découplées des RECIST, c'est plus proche de la réalité non ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chatgpt a un peu changer. Regarde

Comment thread R/Swimmer plot.R Outdated
# group_by(subjid) %>%
# mutate(
# # Assign ADMYN: 99% Yes, 1% No
# ADMYN = sample(c("Yes", "No"), n(), replace = TRUE, prob = c(0.99, 0.01)),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ouais, j'aime bien l'idée de ADMYN mais c'est overkill pour le moment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oui j ai essaye et ca me donne quelque problem donc apres avoir perdu pas mal de temps decu j ai laisser tombe

Comment thread R/Swimmer plot.R
eot <- eot %>%
mutate(
# usually after last treatment date but before death
EOTLADDT = case_when(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Si tu pouvais ajouter des labels à tes tables simulées, ça facilitera beaucoup la lecture :
%>% apply_labels(EOTLADDT="Last treatment date")

Malheureusement, les labels de TrialMaster ne sont pas tous standardisés donc ce n'est pas toujours lisible

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a faire!

Comment thread R/Swimmer plot.R Outdated

set.seed(2025)

fu <- eot %>%

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je ne suis pas sûr de ce que tu as essayé de faire ici mais ça ne fait sans doute pas ce que tu voulais.
sample(1) vaut toujours 1 donc il n'a pas d'effet, mais sample(1:10) ferait planter la fonction.
Ensuite, plutôt que de mettre à NA selon une probabilité pour filtrer les NA, tu peux utiliser la fonction slice_sample() qui fait pareil en plus court :-)
En l'état tu pourrais remplacer par :

eot %>%
  rowwise() %>%
  mutate(
    n_fu = sample(1),  # number of follow-ups per subject
    FUDT = sort(EOTLADDT + days(sample(4:180, n_fu, replace = FALSE)))
  ) %>%
  ungroup() %>%
  slice_sample(prop=0.3)

@Lpierott Lpierott Dec 4, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

est ce que ce code :
mutate(
FUDT = if_else(
runif(n()) < 0.7, # 80% probability
as.Date(NA), # set to missing
FUDT # keep original
)
) %>%
fait la meme chose que slice_sample(prop=0.3)? du coup je change aussi pour le dataset eot?

Comment thread R/Swimmer plot.R Outdated
Comment on lines +232 to +234
arrange(as.numeric(subjid), rcdt) %>%
mutate(ADMDT_first = first(ADMDT), .by = subjid) %>%
mutate(ADMDT_last = last(ADMDT), .by = subjid) %>%

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C'est un peu dangereux de prendre first/last, il vaut mieux utiliser min/max

adm %>%
mutate(
  ADMDT_first = min(ADMDT), 
  ADMDT_last = max(ADMDT), 
  group="Treatment Administration",
  .by = subjid
)

Mais dans la plupart des cas ça fera exactement la même chose.
D'ailleurs, tu ne sélectionnes pas ADMDT_last ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, j ai chnage. et oui je crois pas que j utilise ADMDT_last , mais je crois que je l"utilise pour simuler les dataset.

Comment thread R/Swimmer plot.R Outdated
Comment on lines +357 to +367
mutate(visit=ifelse(group=="Treatment Administration",1, NA)) %>%
mutate(visit=ifelse(group=="Recist" & rcresp=="Complete response" ,2, visit))%>%
mutate(visit=ifelse(group=="Recist" & rcresp=="Partial response" ,2, visit))%>%
mutate(visit=ifelse(group=="Recist" & rcresp=="Stable disease" ,3, visit))%>%
mutate(visit=ifelse(group=="Recist" & rcresp=="Progressive disease" ,4, visit))%>%
mutate(visit=ifelse(group=="Recist" & rcresp=="Not Evaluable" ,5, visit))%>%
mutate(visit=ifelse(group=="End of treatment" ,6, visit)) %>%
mutate(visit=ifelse(group=="Death" ,7, visit)) %>%
mutate(visit=ifelse(group=="Alive at last follow up2" ,8, visit)) %>%
mutate(visit=ifelse(group=="Alive at last follow up" ,9, visit)) %>%
mutate(visit=ifelse(group=="Treatment period",10,visit )) %>%

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChatGPT: "stp, transforme ce code en un seul case_when"

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c vrai , parfois j'oublie ma grande amie...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c fait

Comment thread R/Swimmer plot.R Outdated

# Conversion de la variable visite en facteur

suivi$visit2 <- factor(suivi$visit, c(1:10),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dans le mutate plutôt ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fait

Comment thread R/Swimmer plot.R Outdated


# Final plot --------------------------------------------------------------
# Problems in the simulated datas I think that makes the graph a bit weird.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For each problem that you can identify, you can write a little defensive program:

if(the_thing_is_weird){
  cli_abort("You did something weird")
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

en fait j en ai plus besoin la mais effectivement je fais beaucoup de checks. Mais j ai du mal a utiliser ca.

@DanChaltiel
DanChaltiel marked this pull request as draft December 8, 2025 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Swimerplot RECIST : implémentation

2 participants