-
Notifications
You must be signed in to change notification settings - Fork 0
Ajout de la vignette ORR #67
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?
Changes from 15 commits
be1d976
d146eae
5bf6a5f
946a74c
48b99b2
15a2cff
c80f642
92fc2d7
ff14792
fdd50ce
632fb01
143d76e
32ce6ba
82ee36d
001e307
95c1633
254b93d
bf6e996
58e8819
88a17a1
a01ec89
0550e9c
88d5aac
e71b263
2b1c24d
696b9c9
8377084
02138da
f0891bd
fb3055b
7944ed8
de9770c
589ed82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
#' @importFrom dplyr select | ||
#' @importFrom GenBinomApps clopper.pearson.ci | ||
#' @importFrom flextable as_flextable surround delete_rows footnote as_paragraph | ||
#' @importFrom officer fp_border | ||
#' @importFrom cli cli_abort | ||
|
||
ORR_table = function(id = recist$SUBJID, global_response = recist$RCRESP, date = recist$RCDT, confirmed = FALSE, show_CBR = FALSE){ | ||
`%notin%` <- Negate(`%in%`) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Il y a vraiment besoin d'un opérateur en plus ? if(x %notin% b) ...
if(! x %in% b) ... |
||
if(length(id) ==0){ | ||
cli_abort("id must be defined") | ||
} | ||
if(length(date) ==0){ | ||
cli_abort("date must be defined") | ||
} | ||
if(length(global_response) ==0){ | ||
cli_abort("global_response must be defined") | ||
} | ||
if(length(id) != length(global_response) | length(id) != length(date) | length(date) != length(global_response)){ | ||
cli_abort("id, global_reponse and date should have the same length") | ||
} | ||
if(length(confirmed) > 1){ | ||
cli_abort("confirmed shoulb be TRUE or FALSE (default = FALSE)") | ||
} | ||
if(length(show_CBR) > 1){ | ||
cli_abort("show_CBR shoulb be TRUE or FALSE (default = FALSE)") | ||
} | ||
if(confirmed %notin% c(TRUE,FALSE,NA)){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. tu peux utiliser les fonctions du fichier assertion.R |
||
cli_abort("confirmed shoulb be TRUE or FALSE (default = FALSE)") | ||
} | ||
if(show_CBR %notin% c(TRUE,FALSE,NA)){ | ||
cli_abort("show_CBR shoulb be TRUE or FALSE (default = FALSE)") | ||
} | ||
if(is.Date(date)!= TRUE){ | ||
cli_abort("date shoul be in as.Date format") | ||
} | ||
|
||
data = data.frame(subjid = id, rcresp = global_response, rcdt = date) | ||
|
||
#Si un patient a une seule visite recist (la premiere) puis aucune autre, on le modifie en Not evaluable | ||
data = data %>% | ||
distinct(subjid,rcresp,rcdt) %>% | ||
arrange(as.numeric(subjid), rcdt) %>% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cette ligne plantera dans toutes les études où SUBJID n'est pas numérique |
||
mutate(n = n(), .by = subjid) %>% | ||
mutate(rcresp = ifelse(n==1, "Not evaluable",as.character(rcresp))) | ||
|
||
data$rcresp <- factor(data$rcresp, levels = c("Complete response", "Partial response", "Stable disease", "Progressive disease", "Not evaluable")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Au secours, du base R 😱😱 |
||
|
||
recist_2 = data %>% | ||
mutate(rcresp_num=as.numeric(as.factor(rcresp))) %>% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Attention, tu fais des hypothèses fortes sur le contenu de |
||
filter(!is.na(rcresp_num) & !is.na(rcdt) & !is.na(subjid)) %>% | ||
mutate(previous_rcresp_num=lag(rcresp_num), | ||
previous_date=lag(rcdt), | ||
delta_date=as.numeric(rcdt - previous_date), | ||
delta_date= ifelse(is.na(delta_date),0,delta_date), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. essaie d'espacer un peu ton code : espaces avant et après les |
||
delta_date_before_PD_or_end = cumsum(delta_date), | ||
delta_date_before_PD_or_end = ifelse(rcresp=="Progressive disease" ,0,delta_date_before_PD_or_end), | ||
delta_date_before_PD_or_end= replace_na(delta_date_before_PD_or_end,0), | ||
duree_suivi_max = max(delta_date_before_PD_or_end), | ||
bestresponse_withinprotocole=ifelse(previous_rcresp_num==rcresp_num, 1, 0 ), | ||
.by = subjid) | ||
|
||
if (is.na(confirmed) | confirmed == FALSE){ | ||
final_best_response=recist_2 %>% | ||
mutate(bestresponse=min(rcresp_num), | ||
.by = subjid) %>% | ||
filter(bestresponse==rcresp_num) %>% | ||
slice_head(by=subjid) %>% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. je crois que tu peux remplacer ces 4 lignes par |
||
mutate(Overall_ORR= ifelse(rcresp=="Complete response" | rcresp=="Partial response",1,0), | ||
CBR = ifelse(duree_suivi_max >= 152 | rcresp=="Complete response" | rcresp=="Partial response",1,0)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pourquoi |
||
} | ||
else if(confirmed == TRUE){ | ||
recist_2 <- recist_2 %>% | ||
mutate( | ||
meilleur_reponse = case_when( | ||
rcresp_num == 1 & previous_rcresp_num == 1 & delta_date >= 28 ~ 1, | ||
rcresp_num == 1 & previous_rcresp_num == 1 & delta_date < 28 ~ 3, | ||
rcresp_num == 1 & previous_rcresp_num == 2 & delta_date >= 28 ~ 2, | ||
rcresp_num == 1 & previous_rcresp_num == 2 & delta_date < 28 ~ 3, | ||
rcresp_num == 1 & previous_rcresp_num == 3 ~ 3, | ||
rcresp_num == 1 & previous_rcresp_num == 4 ~ 4, | ||
rcresp_num == 1 & previous_rcresp_num == 5 ~ 5, | ||
|
||
rcresp_num == 2 & previous_rcresp_num <= 2 & delta_date >= 28 ~ 2, | ||
rcresp_num == 2 & previous_rcresp_num <= 2 & delta_date < 28 ~ 3, | ||
rcresp_num == 2 & previous_rcresp_num == 3 ~ 3, | ||
rcresp_num == 2 & previous_rcresp_num == 4 ~ 4, | ||
rcresp_num == 2 & previous_rcresp_num == 5 ~ 5, | ||
|
||
is.na(previous_rcresp_num) & rcresp_num == 4 ~ 4, | ||
|
||
TRUE ~ rcresp_num | ||
) | ||
) | ||
|
||
final_best_response=recist_2 %>% | ||
mutate(bestresponse=min(meilleur_reponse), | ||
.by=subjid | ||
) %>% | ||
filter(bestresponse==meilleur_reponse) %>% | ||
slice_head(by=subjid) %>% | ||
mutate(Overall_ORR= ifelse(rcresp=="Complete response" | rcresp=="Partial response",1,0), | ||
CBR = ifelse(duree_suivi_max >= 152 | rcresp=="Complete response" | rcresp=="Partial response",1,0)) | ||
} | ||
|
||
total <- length(unique(final_best_response$subjid)) | ||
CR <- length(final_best_response$rcresp[final_best_response$rcresp == "Complete response"]) | ||
PR <- length(final_best_response$rcresp[final_best_response$rcresp == "Partial response"]) | ||
SD <- length(final_best_response$rcresp[final_best_response$rcresp == "Stable disease"]) | ||
PD <- length(final_best_response$rcresp[final_best_response$rcresp == "Progressive disease"]) | ||
NE <- length(final_best_response$rcresp[final_best_response$rcresp == "Not evaluable"]) | ||
Overall_ORR <- CR + PR | ||
CBR <- length(final_best_response$CBR[final_best_response$CBR==1]) | ||
|
||
CR_CP <- clopper.pearson.ci(CR,total,CI="two.sided", alpha = 0.05) | ||
PR_CP <- clopper.pearson.ci(PR,total,CI="two.sided", alpha = 0.05) | ||
SD_CP <- clopper.pearson.ci(SD,total,CI="two.sided", alpha = 0.05) | ||
PD_CP <- clopper.pearson.ci(PD,total,CI="two.sided", alpha = 0.05) | ||
NE_CP <- clopper.pearson.ci(NE,total,CI="two.sided", alpha = 0.05) | ||
Overall_ORR_CP <- clopper.pearson.ci(Overall_ORR,total,CI="two.sided", alpha = 0.05) | ||
CBR_CP <- clopper.pearson.ci(CBR,total,CI="two.sided", alpha = 0.05) | ||
|
||
CR_CP_IC <- paste0("[",round(CR_CP$Lower.limit*100,1),";",round(CR_CP$Upper.limit*100,1),"]") | ||
PR_CP_IC <- paste0("[",round(PR_CP$Lower.limit*100,1),";",round(PR_CP$Upper.limit*100,1),"]") | ||
SD_CP_IC <- paste0("[",round(SD_CP$Lower.limit*100,1),";",round(SD_CP$Upper.limit*100,1),"]") | ||
PD_CP_IC <- paste0("[",round(PD_CP$Lower.limit*100,1),";",round(PD_CP$Upper.limit*100,1),"]") | ||
NE_CP_IC <- paste0("[",round(NE_CP$Lower.limit*100,1),";",round(NE_CP$Upper.limit*100,1),"]") | ||
Overall_ORR_CP_IC <- paste0("[",round(Overall_ORR_CP$Lower.limit*100,1),";",round(Overall_ORR_CP$Upper.limit*100,1),"]") | ||
CBR_CP_IC <- paste0("[",round(CBR_CP$Lower.limit*100,1),";",round(CBR_CP$Upper.limit*100,1),"]") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Attention, beaucoup de baseR et beaucoup de répétitions (DRY), donc risque d'erreur et mauvaise maintenabilité.
|
||
|
||
if (is.na(show_CBR) | show_CBR == FALSE){ | ||
IC_95 <- c(Overall_ORR_CP_IC, | ||
CR_CP_IC, | ||
PR_CP_IC, | ||
SD_CP_IC, | ||
PD_CP_IC, | ||
NE_CP_IC) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Bon alors là je vais dire le contraire, c'est un peu trop aéré 😂 |
||
|
||
Name <- c("Overall ORR", | ||
"Complete response (CR)", | ||
"Partial response (PR)", | ||
"Stable disease (SD)", | ||
"Progressive disease (PD)", | ||
"Not evaluable (NE)") | ||
|
||
N <- c(Overall_ORR, | ||
CR, | ||
PR, | ||
SD, | ||
PD, | ||
NE) | ||
|
||
Percentage <- c(round(Overall_ORR/total*100,1), | ||
round(CR/total*100,1), | ||
round(PR/total*100,1), | ||
round(SD/total*100,1), | ||
round(PD/total*100,1), | ||
round(NE/total*100,1)) | ||
} | ||
else if(show_CBR == TRUE){IC_95 <- c(Overall_ORR_CP_IC, | ||
CR_CP_IC, | ||
PR_CP_IC, | ||
SD_CP_IC, | ||
PD_CP_IC, | ||
NE_CP_IC, | ||
CBR_CP_IC) | ||
|
||
Name <- c("Overall ORR", | ||
"Complete response (CR)", | ||
"Partial response (PR)", | ||
"Stable disease (SD)", | ||
"Progressive disease (PD)", | ||
"Not evaluable (NE)", | ||
"Clinical Benefit Rate (CBR)") | ||
|
||
N <- c(Overall_ORR, | ||
CR, | ||
PR, | ||
SD, | ||
PD, | ||
NE, | ||
CBR) | ||
|
||
Percentage <- c(round(Overall_ORR/total*100,1), | ||
round(CR/total*100,1), | ||
round(PR/total*100,1), | ||
round(SD/total*100,1), | ||
round(PD/total*100,1), | ||
round(NE/total*100,1), | ||
round(CBR/total*100,1)) | ||
} | ||
|
||
Best_Response_during_treatment <- as.data.frame(cbind(Name,N,Percentage,IC_95)) | ||
if (is.na(confirmed) | confirmed == FALSE){ | ||
nom_col = c("Unconfirmed Best Response during treatment",paste0("N=",total),"%","IC 95%") | ||
} | ||
else if(confirmed == TRUE){ | ||
nom_col = c("Confirmed Best Response during treatment",paste0("N=",total),"%","IC 95%") | ||
} | ||
|
||
colnames(Best_Response_during_treatment) <- nom_col | ||
Best_Response_during_treatment = Best_Response_during_treatment %>% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Il faut toujours séparer le fond et la forme. |
||
as_flextable(show_coltype = F, include.row_percent = FALSE, include.column_percent = FALSE, include.table_percent = FALSE) %>% | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
delete_rows(i=1, part = "footer") %>% | ||
bold(bold = TRUE, part = "header") %>% | ||
surround(i = c(1,6), j = 1:4, border.bottom = fp_border(color = "black", style = "solid", width = 1), part = "body") | ||
|
||
if (is.na(confirmed) | confirmed == FALSE){ | ||
Best_Response_during_treatment = Best_Response_during_treatment %>% | ||
footnote( i = 1, j = c(4), | ||
value = as_paragraph( | ||
c("Clopper-Pearson (Exact) method was used for confidence interval")), | ||
ref_symbols =c("*"), part = "header") %>% | ||
valign(valign = "bottom", part = "header") | ||
} | ||
else if(confirmed == TRUE){ | ||
Best_Response_during_treatment = Best_Response_during_treatment %>% | ||
footnote( i = 1, j = c(4,1), | ||
value = as_paragraph( | ||
c("Clopper-Pearson (Exact) method was used for confidence interval", | ||
"For CR & PR confirmation of response had to be be demonstrated with an assessment 4 weeks or later from the initial response for response. *As stated in the protocol: «For equivocal findings of progression (e.g., very small and uncertain new lesions; cystic changes or necrosis in existing lesions), treatment may continue until the next scheduled assessment». Therefore, some patients had a response after a progressive disease response, in that case best response was examine before and after PD. Scans conducted after initiating new anti-cancer therapy were not included in the ORR analyses")), | ||
ref_symbols =c("*","1"), part = "header") %>% | ||
valign(valign = "bottom", part = "header") | ||
} | ||
|
||
if (is.na(show_CBR) | show_CBR == FALSE){ | ||
Best_Response_during_treatment = Best_Response_during_treatment %>% | ||
bold(i = c(1), j = 1, bold = TRUE, part = "body") | ||
} | ||
else if(show_CBR == TRUE & confirmed == TRUE){ | ||
Best_Response_during_treatment = Best_Response_during_treatment %>% | ||
footnote( i = c(7), j = 1, | ||
value = as_paragraph( | ||
c("CBR was defined as the presence of at least a partial response (PR), complete response (CR), or stable disease (SD) lasting at least six months (using a window of +/-1 month for the RECIST date).")), | ||
ref_symbols = c("2"), part = "body") %>% | ||
valign(valign = "bottom", part = "header") %>% | ||
bold(i = c(1,7), j = 1, bold = TRUE, part = "body") | ||
} | ||
else if(show_CBR == TRUE & (is.na(confirmed) | confirmed == FALSE)){ | ||
Best_Response_during_treatment = Best_Response_during_treatment %>% | ||
footnote( i = c(7), j = 1, | ||
value = as_paragraph( | ||
c("CBR was defined as the presence of at least a partial response (PR), complete response (CR), or stable disease (SD) lasting at least six months (using a window of +/-1 month for the RECIST date).")), | ||
ref_symbols = c("1"), part = "body") %>% | ||
valign(valign = "bottom", part = "header") %>% | ||
bold(i = c(1,7), j = 1, bold = TRUE, part = "body") | ||
} | ||
Best_Response_during_treatment | ||
} |
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 grstat, on utilise des interfaces
tidyverse
, pas base R comme iciça veut dire que le premier argument est quasi toujours une dataframe
donc il vaut mieux avoir dans tes arguments d'abord
data
, puis un moyen d'identifier les colonnes, par exemplesubjid="SUBJID", resp="RCRESP"
.Attention, tes valeurs par défaut attendent qu'un objet
recist
existe, ce qui fera planter la fonction dans quasi tous les cas de figures réels.