-
Notifications
You must be signed in to change notification settings - Fork 0
Swimmer plot #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Swimmer plot #99
Conversation
DanChaltiel
left a comment
There was a problem hiding this comment.
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.
| adm <- recist %>% | ||
| left_join(enrolres %>% select(subjid, date_inclusion), by = "subjid") %>% | ||
| # filter(!is.na(rcresp), rcresp != "Progressive disease") %>% | ||
| filter(!is.na(rcresp)) %>% |
There was a problem hiding this comment.
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 ?
| # filter(!is.na(rcresp), rcresp != "Progressive disease") %>% | ||
| filter(!is.na(rcresp)) %>% | ||
| arrange(subjid, rcdt) %>% # ensure ordered by patient and RECIST | ||
| group_by(subjid) %>% |
There was a problem hiding this comment.
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()
| 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 |
There was a problem hiding this comment.
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 ?
| # group_by(subjid) %>% | ||
| # mutate( | ||
| # # Assign ADMYN: 99% Yes, 1% No | ||
| # ADMYN = sample(c("Yes", "No"), n(), replace = TRUE, prob = c(0.99, 0.01)), |
There was a problem hiding this comment.
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.
| eot <- eot %>% | ||
| mutate( | ||
| # usually after last treatment date but before death | ||
| EOTLADDT = case_when( |
There was a problem hiding this comment.
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
|
|
||
| set.seed(2025) | ||
|
|
||
| fu <- eot %>% |
There was a problem hiding this comment.
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)| arrange(as.numeric(subjid), rcdt) %>% | ||
| mutate(ADMDT_first = first(ADMDT), .by = subjid) %>% | ||
| mutate(ADMDT_last = last(ADMDT), .by = subjid) %>% |
There was a problem hiding this comment.
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 ?
| 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 )) %>% |
There was a problem hiding this comment.
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"
There was a problem hiding this comment.
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...
|
|
||
| # Conversion de la variable visite en facteur | ||
|
|
||
| suivi$visit2 <- factor(suivi$visit, c(1:10), |
There was a problem hiding this comment.
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 ?
|
|
||
|
|
||
| # Final plot -------------------------------------------------------------- | ||
| # Problems in the simulated datas I think that makes the graph a bit weird. |
There was a problem hiding this comment.
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")
}
grstat/R/ae_table_grade.R
Line 189 in 8c69458
grstat/R/waterfall_plot.R
Line 57 in 8c69458
Tu pars du principe que tes données d'input ont une certaine structure (e.g.
data1a une colonnecol1qui est de type numérique), il faut faire des checks pour que les utilisateurs aient un message d'erreur clair.suivi_fu$first_fudevrait toujours être 0 ?