Data #127
Replies: 6 comments
-
@jwildfire said: Let's convert this to a discussion over in GitHub and talk about it a bit there. Not sure I'll be able to write up a long post about my thinking before the design discussion, but I'll try. Worst case, we can talk it through as part of that meeting. For now, I'll just say the data inputs for gsmApp should follow the specifications for the various data models (mapped/analysis/reporting) defined over in {gsm} as closely as possible. If those data models are not adequate for the {gsmapp} requirements, we should almost certainly consider updating the {gsm} data model as part of a v2.1 release. As long as we follow those specs, I think the approach to loading the data can be designed to be fairly flexible. |
Beta Was this translation helpful? Give feedback.
-
I agree that the data should be created via the gsm workflows, but setting that up should be separate from general running of the app. The data should be processed at deploy-time (and then on whatever cadence we want to update the data), not every time the app is launched by a user nor when a new session begins with the app. The app should expect the data to be saved where it wants it to be saved, and not know about anything that happens before that. |
Beta Was this translation helpful? Give feedback.
-
This would also be a great way to divide up github tasks. Updating
|
Input | Widget_BarChart | Widget_GroupOverview | Widget_ScatterPlot | Widget_TimeSeries |
---|---|---|---|---|
dfResults | x | x | x | x |
lMetric | x | x | x | |
dfMetrics | x | |||
dfGroups | x | x | x | x |
dfBounds | x | |||
vThreshold | x | x | ||
strOutcome | x | x | ||
bAddGroupSelect | x | x | x | |
strGroupLevel | x | |||
strGroupSubset | x | |||
strGroupLabelKey | x |
Section on gsmApp function inputs
Attached below is a mapping of where the various data points are located in the new data model:
sources.xlsx
Beta Was this translation helpful? Give feedback.
-
Here is a more concise list of required inputs:
|
Beta Was this translation helpful? Give feedback.
-
Coming back to this now that I know a lot more about how things work. We've discussed wanting to support multiple input modalities for the core data, from straightforward data.frames (what we have right now) to a database or other dynamically updated source. To make that make sense, I think we should expect the inputs to come in as reactives. That way the user can decide whether their particular data is a file read via The reason to use reactives is that way a running app can automatically update when new data comes in, without having to be stopped/restarted (including if a database changes, via The special case (the whole reason that we're really thinking about all this) is participant data. We shouldn't load all of the participant data for every user, since most of it will never be used by app users (after it's processed by gsm into the summaries). I think we'll want this to be a list of Tested with this simple app: library(shiny)
library(lobstr)
# Globally define a list of reactives.
outVals <- list()
outVals[["1"]] <- shiny::reactive(sample(1:100000, 100000, TRUE))
outVals[["2"]] <- shiny::reactive(sample(1:100000, 100000, TRUE))
outVals[["3"]] <- shiny::reactive(sample(1:100000, 100000, TRUE))
outVals[["4"]] <- shiny::reactive(sample(1:100000, 100000, TRUE))
outVals[["5"]] <- shiny::reactive(sample(1:100000, 100000, TRUE))
ui <- fluidPage(
selectInput("id", "ID", 1:5),
verbatimTextOutput("testOut"),
verbatimTextOutput("sizeOut")
)
server <- function(input, output, session) {
memUsed <- reactiveVal()
observeEvent(input$id, {
memUsed(lobstr::obj_size(outVals))
})
output$testOut <- renderPrint(mean(outVals[[input$id]]()))
output$sizeOut <- renderPrint(memUsed())
}
shinyApp(ui, server) The mem goes up each time you choose a new ID, but doesn't change if you return to a previous ID. I'll need to play around with this with some real data to be SURE that this is the path we want to take, but I think it makes sense. Again, we'll want to provide helpers to make this as straightforward as possible. |
Beta Was this translation helpful? Give feedback.
-
I think it's worthwhile to be more specific about what we're using for each widget/table/etc. I'm going to use a shorthand-ish version of the gsm.template spec to work this out. Tab: Study OverviewModule: Overview Table
(stopping here for now to decide if this is the best way to do this...) |
Beta Was this translation helpful? Give feedback.
-
(moved from Teams discussion)
From my current understanding of usage, I think the apps created/deployed with {gsmApp} should expect specific files (possibly including a directory of 1 or more files, for things like participant-level details), loading them reactively as needed.
Those files should be updated independent of the {gsmApp} package, since where they come from will be Gilead-specific (or, for other users of the open-source package, specific to their workflows). But we might want to export helper functions to help set them up (for example, functions that take data.frames and prep them for the app (if needed) and then save them to the expected locations. Separately, we'll write Gilead-specific things to fetch the data from the database, and run those on whatever cadence makes sense for us.
Alternatively, some data could be purely database-side (eg participant-level data), and fetched on demand... but I feel like that would make things much more complicated (users would have to supply data-fetcher functions + optional change-checker functions to gsmApp::run_app()). But that data gets compiled into the higher-level data, right? So, since we need to fetch it to build that, we probably might as well keep it app-ready at that point. I guess if the participant-level data is really large we might want to keep it restricted to the database, but otherwise things will be much more straightforward if we prep and save it for the app.
Does that all make sense? Are there any flaws in my understanding?
Beta Was this translation helpful? Give feedback.
All reactions