Skip to content

Commit

Permalink
Adding second widget to dropouts page.
Browse files Browse the repository at this point in the history
  • Loading branch information
berryni committed Dec 9, 2024
1 parent d85fdcc commit d3e68af
Show file tree
Hide file tree
Showing 29 changed files with 390 additions and 28 deletions.
15 changes: 6 additions & 9 deletions docs/news/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@
<!-- margin-sidebar -->
<div id="quarto-margin-sidebar" class="sidebar margin-sidebar">

<h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(4)</span></div><div class="category" data-category="CRM">CRM <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Core">Core <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Deepdive">Deepdive <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Dose Escalation">Dose Escalation <span class="quarto-category-count">(2)</span></div><div class="category" data-category="Paper">Paper <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Staged">Staged <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Webinar">Webinar <span class="quarto-category-count">(2)</span></div></div></div>
<h5 class="quarto-listing-category-title">Categories</h5><div class="quarto-listing-category category-default"><div class="category" data-category="">All <span class="quarto-category-count">(4)</span></div><div class="category" data-category="CRM">CRM <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Dose Escalation">Dose Escalation <span class="quarto-category-count">(2)</span></div><div class="category" data-category="FACTS">FACTS <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Help">Help <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Paper">Paper <span class="quarto-category-count">(1)</span></div><div class="category" data-category="Webinar">Webinar <span class="quarto-category-count">(2)</span></div></div></div>
<!-- main -->
<main class="content" id="quarto-document-content">

Expand Down Expand Up @@ -248,7 +248,7 @@ <h1 class="title">News</h1>
</div>
</div>
<div class="list quarto-listing-default">
<div class="quarto-post image-right" data-index="0" data-categories="Core,Staged,Deepdive" data-listing-date-sort="1733464800000" data-listing-file-modified-sort="1733773068593" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="3" data-listing-word-count-sort="564">
<div class="quarto-post image-right" data-index="0" data-categories="FACTS,Help" data-listing-date-sort="1733464800000" data-listing-file-modified-sort="1733785225879" data-listing-date-modified-sort="NaN" data-listing-reading-time-sort="9" data-listing-word-count-sort="1645">
<div class="thumbnail">
<p><a href="../news/posts/2024-12-06-DropoutsDeepdive.html" class="no-external"></a></p><a href="../news/posts/2024-12-06-DropoutsDeepdive.html" class="no-external">
<div class="listing-item-img-placeholder card-img-top" >&nbsp;</div>
Expand All @@ -262,14 +262,11 @@ <h3 class="no-anchor listing-title">
<a href="../news/posts/2024-12-06-DropoutsDeepdive.html" class="no-external"></a>
</div>
<div class="listing-categories">
<div class="listing-category" onclick="window.quartoListingCategory('Core'); return false;">
Core
<div class="listing-category" onclick="window.quartoListingCategory('FACTS'); return false;">
FACTS
</div>
<div class="listing-category" onclick="window.quartoListingCategory('Staged'); return false;">
Staged
</div>
<div class="listing-category" onclick="window.quartoListingCategory('Deepdive'); return false;">
Deepdive
<div class="listing-category" onclick="window.quartoListingCategory('Help'); return false;">
Help
</div>
</div>
<div class="listing-description">
Expand Down
147 changes: 139 additions & 8 deletions docs/news/posts/2024-12-06-DropoutsDeepdive.html
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,8 @@ <h1 class="title">Dropout Rate Explanation</h1>
</div>
</div>
<div class="quarto-categories">
<div class="quarto-category">Core</div>
<div class="quarto-category">Staged</div>
<div class="quarto-category">Deepdive</div>
<div class="quarto-category">FACTS</div>
<div class="quarto-category">Help</div>
</div>
</div>
</div>
Expand Down Expand Up @@ -230,7 +229,26 @@ <h1>How to specify dropouts in FACTS</h1>
<h2 class="anchored" data-anchor-id="dropouts-per-dose">Dropouts Per Dose</h2>
<p>If “Dropouts per Dose” is selected, then each subject has a probability of not having an observable final endpoint value equal to the dropout rate of the dose that subject is randomized to. If each subject has multiple visits and “Dropouts per Dose” is selected, then the conditional probability of dropping out before each visit given that the subject had not dropped out up to the visit before rates are all equal. In other words, if the total dropout rate is π_D, the probability of dropping out between visits i and i+1 given that the subject had not dropped out at visit <span class="math inline">\(i\)</span> is <span class="math display">\[
1-\left(1-\pi_D\right)^{(\frac{1}{V})}\text{ where } V \text{ is the total number of visits.}
\]</span></p>
\]</span> The following interactive widget takes in the desired dropout rate and the number of visits a subject will have during their follow-up, and returns information about the dropout rate that FACTS will simulate by visit.</p>
<p>The columns in the dynamic output table are:</p>
<dl>
<dt>Visit number</dt>
<dd>
<p>The index of the visit that a subject would observe.</p>
</dd>
<dt>Conditional Visit Dropout Rate</dt>
<dd>
<p>The probability that a subject drops out before row specified visit given that they have not dropped out after the previous visit.</p>
</dd>
<dt>Marginal Visit Dropout Rate</dt>
<dd>
<p>The probability that a subject that has not yet been enrolled in the study will dropout before row specified visit and after the previous row’s visit.</p>
</dd>
<dt>Cumulative Dropout Prob.</dt>
<dd>
<p>The probability that a subject will drop out at the row specified visit or before. At the last visit row this value will equal the Desired Dropout Rate.</p>
</dd>
</dl>
<section id="dropout-per-dose-guide" class="level3">
<h3 class="anchored" data-anchor-id="dropout-per-dose-guide">Dropout Per Dose Guide</h3>
<pre class="shinylive-r" data-engine="r"><code>#| '!! shinylive warning !!': |
Expand Down Expand Up @@ -270,9 +288,9 @@ <h3 class="anchored" data-anchor-id="dropout-per-dose-guide">Dropout Per Dose Gu

df = df[,c("Visits", "ConditionalDropoutRate", "MarginalDropoutRate", "TotalDropoutRate")]
colnames(df) = c("Visit number",
"Prob. dropout given not dropped before previous visit",
"Prob. dropout between previous visit and current visit",
"Prob. dropout before visit")
"Conditional Visit Dropout Rate",
"Marginal Visit Dropout Rate",
"Cumulative Dropout Prob.")
df}
}, digits = 4)
}
Expand All @@ -285,7 +303,120 @@ <h2 class="anchored" data-anchor-id="dropouts-per-dose-per-visit">Dropouts Per D
<p>If “Dropouts per Dose per Visit” is selected, then each subject has a user specified probability of dropping out before a visit v that is specified as the conditional probability of dropping out before visit v given that that they had not dropped out by visit v-1. This leads to a total dropout rate π_D for a participant that is equal to:</p>
<p><span class="math display">\[
\pi_D = 1-\Pi_{v=0}^V(1-\pi_v)
\]</span></p>
\]</span> When specifying Dropouts Per Dose Per Visit in FACTS, the user inputs the conditional visit dropout rate for each visit. This can make it not completely intuitive to get the exact desired cumulative dropout rate. The below application allows the user to enter either the conditional visit dropout rates or the marginal visit dropout rates, and provides the implied dropout profile from those inputs. <em>In order to simulate dropouts from the below profile in FACTS, enter the Conditional Visit Dropout Rate into the FACTS Dropout Rate tab.</em></p>
<pre class="shinylive-r" data-engine="r"><code>#| '!! shinylive warning !!': |
#| shinylive does not work in self-contained HTML documents.
#| Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 800

library(shiny)
library(DT)
library(htmltools)

alignCenter &lt;- function(el) {
htmltools::tagAppendAttributes(el,
style="margin-left:auto;margin-right:auto;"
)
}

ui &lt;- fluidPage(
tags$head(
# Note the wrapping of the string in HTML()
tags$style(HTML("
.my_col_class {
align-content: center;
}")
)
),

fluidRow(
titlePanel(h1("Dropout Per Dose Per Visit", align = "center")),
alignCenter(sliderInput("numVisits", "Number of visits:",
min = 1, max = 20, value = 5)),
DTOutput("dataInputTable")
)
)

server &lt;- function(input, output) {

df = data.frame(Visits = 1:5,
ConditionalDropoutRate = 0.05)
df$TotalDropoutRate = 1-cumprod(1-df$ConditionalDropoutRate)
df$MarginalDropoutRate = c(df$TotalDropoutRate[1], df$TotalDropoutRate[-1] - df$TotalDropoutRate[-nrow(df)])
df = df[,c("Visits", "ConditionalDropoutRate", "MarginalDropoutRate", "TotalDropoutRate")]
colnames(df) = c("Visit number",
"Conditional Visit Dropout Rate",
"Marginal Visit Dropout Rate",
"Cumulative Dropout Prob.")

## Render DF to actually change
output$dataInputTable = renderDT(datatable(df, options = list(
digits = 4,
dom = "t",
autoWidth = TRUE,
columnDefs = list(list(width = '150px', targets = 1:4))), selection = 'none', editable = "cell") |&gt; formatRound(2:4, digits = 4))

## Update from Conditional

proxy = dataTableProxy('dataInputTable')

observeEvent(input$dataInputTable_cell_edit, {
info = input$dataInputTable_cell_edit
str(info)
i = info$row
j = info$col
v = info$value
df &lt;&lt;- editData(df, info)
if(j == 2) {
## Update other columns from Conditional
df[,4] &lt;&lt;- 1-cumprod(1-df[,2])
df[,3] &lt;&lt;- c(df[1,4], df[-1,4] - df[-nrow(df),4])
} else if(j == 3) {
## Update other columns from Marginal
df[,4] &lt;&lt;- cumsum(df[,3])
df[,2] &lt;&lt;- c(df[1,3],
df[-1,3]/(1-df[-nrow(df),4]))
} else if(j == 4) {
## Update other columns from Cumulative

df[info$row, 3] &lt;&lt;- df[info$row, 4] - ifelse(info$row == 1, 0, df[info$row-1, 4])
df[info$row, 2] &lt;&lt;- ifelse(info$row == 1, df[info$row,3], df[info$row,3]/(1-df[info$row-1,4]))
df[,4] &lt;&lt;- 1-cumprod(1-df[,2])
df[,3] &lt;&lt;- c(df[1,4], df[-1,4] - df[-nrow(df),4])
}
replaceData(proxy, df)
})

observe({
input$numVisits
nv = input$numVisits
if(nv &gt; nrow(df)) {
if(nrow(df) == 0) {
df &lt;&lt;- data.frame(Visits = 1,
ConditionalDropoutRate = 1-(1-.1)^(1))
df$TotalDropoutRate = 1-cumprod(1-df$ConditionalDropoutRate)
df$MarginalDropoutRate = c(df$TotalDropoutRate[1], df$TotalDropoutRate[-1] - df$TotalDropoutRate[-nrow(df)])
df = df[,c("Visits", "ConditionalDropoutRate", "MarginalDropoutRate", "TotalDropoutRate")]
colnames(df) = c("Visit number",
"Conditional Visit Dropout Rate",
"Marginal Visit Dropout Rate",
"Cumulative Dropout Prob.")
} else {
for(i in 1:(nv-nrow(df))) {
df &lt;&lt;- rbind(df, setNames(data.frame(matrix(c(1+nrow(df), 0.05, 0, 0), nrow = 1)), names(df)))
}
df[,4] &lt;&lt;- 1-cumprod(1-df[,2])
df[,3] &lt;&lt;- c(df[1,4], df[-1,4] - df[-nrow(df),4])
}
} else if(nv &lt; nrow(df)) {
df &lt;&lt;- df[1:nv,]
}
replaceData(proxy, df)
})
}

shinyApp(ui = ui, server = server)</code></pre>


</section>
Expand Down
Loading

0 comments on commit d3e68af

Please sign in to comment.