Title: | 'Shiny' Modules for General Tasks |
---|---|
Description: | 'Shiny' apps can often make use of the same key elements, this package provides modules for common tasks (data upload, wrangling data, figure generation and saving the app state), and also a framework for developing. These modules can react and interact as well as generate code to create reproducible analyses. |
Authors: | John Harrold [aut, cre] |
Maintainer: | John Harrold <[email protected]> |
License: | BSD_2_clause + file LICENSE |
Version: | 0.1.8 |
Built: | 2024-11-20 15:29:53 UTC |
Source: | https://github.com/john-harrold/formods |
Fetches the code to generate results seen in the app
ASM_fetch_code(state)
ASM_fetch_code(state)
state |
ASM state from |
The ASM module does not generate code
# Creating a state object for testing sess_res = ASM_test_mksession() state = sess_res$state code = ASM_fetch_code(state)
# Creating a state object for testing sess_res = ASM_test_mksession() state = sess_res$state code = ASM_fetch_code(state)
Gets either the file name specified by the user or the default value if that is null
ASM_fetch_dlfn(state, extension = ".zip")
ASM_fetch_dlfn(state, extension = ".zip")
state |
ASM state from |
extension |
File extension for the download (default: ".zip") |
character object with the download file name
# Creating a state object for testing sess_res = ASM_test_mksession() state = sess_res$state dlfn = ASM_fetch_dlfn(state) dlfn
# Creating a state object for testing sess_res = ASM_test_mksession() state = sess_res$state dlfn = ASM_fetch_dlfn(state) dlfn
Merges default app options with the changes made in the UI
ASM_fetch_state(id, input, session, FM_yaml_file, MOD_yaml_file)
ASM_fetch_state(id, input, session, FM_yaml_file, MOD_yaml_file)
id |
Shiny module ID |
input |
Shiny input variable |
session |
Shiny session variable |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
list containing the current state of the app including default values from the yaml file as well as any changes made by the user. The list has the following structure:
yaml: Full contents of the supplied yaml file.
MC: Module components of the yaml file.
ASM:
isgood: Boolean object indicating if the file was successfully loaded.
checksum: This is an MD5 sum of the loaded state file
MOD_TYPE: Character data containing the type of module "ASM"
id: Character data containing the module id module in the session variable.
FM_yaml_file: App configuration file with FM as main section.
MOD_yaml_file: Module configuration file with MC as main section.
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = ASM_test_mksession() session = sess_res$session input = sess_res$input # Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml") # We need to specify the ID of the ASM module id = "ASM" state = ASM_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file) state
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = ASM_test_mksession() session = sess_res$session input = sess_res$input # Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml") # We need to specify the ID of the ASM module id = "ASM" state = ASM_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file) state
Creates a list of the initialized module state
ASM_init_state(FM_yaml_file, MOD_yaml_file, id, session)
ASM_init_state(FM_yaml_file, MOD_yaml_file, id, session)
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id |
ID string for the module. |
session |
Shiny session variable |
list containing an empty ASM state
# Within shiny the session variable will exist, # this creates an example here for testing purposes: sess_res = ASM_test_mksession() session = sess_res$session state = ASM_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml"), id = "ASM", session = session) state
# Within shiny the session variable will exist, # this creates an example here for testing purposes: sess_res = ASM_test_mksession() session = sess_res$session state = ASM_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml"), id = "ASM", session = session) state
Converts the current ASM state into a preload list.
ASM_mk_preload(state)
ASM_mk_preload(state)
state |
ASM state object |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
yaml_list: Lists with preload components.
sess_res = ASM_test_mksession() state = sess_res$state res = ASM_mk_preload(state)
sess_res = ASM_test_mksession() state = sess_res$state res = ASM_mk_preload(state)
Creates a list of the initialized module state
ASM_onload(state, session)
ASM_onload(state, session)
state |
ASM state object |
session |
Shiny session variable |
ASM state object
Populates the supplied session variable with information from list of sources.
ASM_preload( session, src_list, yaml_res = NULL, mod_ID = NULL, react_state = list(), quickload = FALSE )
ASM_preload( session, src_list, yaml_res = NULL, mod_ID = NULL, react_state = list(), quickload = FALSE )
session |
Shiny session variable (in app) or a list (outside of app) |
src_list |
List of preload data (all read together with module IDs at the top level) |
yaml_res |
Result of reading in the formods (fm_cfg) and module (mod_cfg) yaml files |
mod_ID |
Module ID of the module being loaded. |
react_state |
Reactive shiny object (in app) or a list (outside of app) used to trigger reactions |
quickload |
Logical |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
session: Session object
input: The value of the shiny input at the end of the session initialization.
state: App state.
react_state: The react_state
components.
Reads in the app state from yaml files.
ASM_read_app_state(sources = NULL)
ASM_read_app_state(sources = NULL)
sources |
Vector of at corresponds with the ID used to call the modules UI elements |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
src_list: List containing the result of reading all of the sources.
yaml_res: Lists with elements for each module ID found in src_list with elements holding the modules configuration file "mod_cfg"
and the modules formods configuration file "fm_cfg"
res = ASM_read_app_state(sources=system.file(package="formods", "preload", "UD_preload.yaml"))
res = ASM_read_app_state(sources=system.file(package="formods", "preload", "UD_preload.yaml"))
Server function for the Save State Shiny Module
ASM_Server( id, FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml"), deployed = FALSE, react_state = NULL, mod_ids )
ASM_Server( id, FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml"), deployed = FALSE, react_state = NULL, mod_ids )
id |
An ID string that corresponds with the ID used to call the modules UI elements |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
deployed |
Boolean variable indicating whether the app is deployed or not. |
react_state |
Variable passed to server to allow reaction outside of module ( |
mod_ids |
Vector of module IDs and order they are needed (used for code generation). |
UD Server object
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
Populates the supplied session variable for testing.
ASM_test_mksession(session = list())
ASM_test_mksession(session = list())
session |
Shiny session variable (in app) or a list (outside of app) |
The ASM portion of the 'all_sess_res' returned from ASM_set_app_state
ASM_set_app_state
sess_res = ASM_test_mksession()
sess_res = ASM_test_mksession()
Called from download handler and used to write a saved state value if that is null
ASM_write_state(state, session, file, mod_ids)
ASM_write_state(state, session, file, mod_ids)
state |
ASM state from |
session |
Shiny session variable |
file |
File name to write zipped state. |
mod_ids |
Vector of module IDs and order they are needed (used for code generation). |
This function only writes the state and has no return value.
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = ASM_test_mksession() session = sess_res$session input = sess_res$input # Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml") # We need to specify the ID of the ASM module id = "ASM" state = ASM_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file) ASM_write_state(state, session, file = tempfile(fileext=".zip"), mod_ids = c("UD"))
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = ASM_test_mksession() session = sess_res$session input = sess_res$input # Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "ASM.yaml") # We need to specify the ID of the ASM module id = "ASM" state = ASM_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file) ASM_write_state(state, session, file = tempfile(fileext=".zip"), mod_ids = c("UD"))
Takes UI input and tries to figure out if it's numeric or text
autocast(ui_input, quote_char = TRUE)
autocast(ui_input, quote_char = TRUE)
ui_input |
UI input from a shiny form |
quote_char |
TRUE will include double quotes in the character string |
Best guess of type casting applied to the ui_input
number = autocast('10') text = autocast('ten')
number = autocast('10') text = autocast('ten')
Adds the wrangling element to the current data view.
DW_add_wrangling_element(state, dwb_res, dwee_res)
DW_add_wrangling_element(state, dwb_res, dwee_res)
state |
DW state from |
dwb_res |
Output from |
dwee_res |
Output from |
state with data set attached
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
Takes the current state of the app and appends data views to an xlsx report object.
DW_append_report(state, rpt, rpttype, gen_code_only = FALSE)
DW_append_report(state, rpt, rpttype, gen_code_only = FALSE)
state |
DW state from |
rpt |
Report with the current content of the report which will be appended to in
this function. For details on the structure see the documentation for |
rpttype |
Type of report to generate (supported "xlsx"). |
gen_code_only |
Boolean value indicating that only code should be
generated ( |
list containing the following elements
isgood: Return status of the function.
hasrptele: Boolean indicator if the module has any reportable elements.
code: Code to generate reporting elements.
msgs: Messages to be passed back to the user.
rpt: Report with any additions passed back to the user.
# We need a state object to use below sess_res = DW_test_mksession() state = sess_res$state rpt = list(summary = list(), sheets=list()) rpt_res = DW_append_report(state, rpt = rpt, rpttype = "xlsx") # Shows if report elements are present rpt_res$hasrptele # Code chunk to generate report element cat(paste(rpt_res$code, collapse="\n")) # Tabular summary of data views rpt_res$rpt$summary
# We need a state object to use below sess_res = DW_test_mksession() state = sess_res$state rpt = list(summary = list(), sheets=list()) rpt_res = DW_append_report(state, rpt = rpt, rpttype = "xlsx") # Shows if report elements are present rpt_res$hasrptele # Code chunk to generate report element cat(paste(rpt_res$code, collapse="\n")) # Tabular summary of data views rpt_res$rpt$summary
Attaches a dataset to the DW state supplied.
DW_attach_ds(state, id_UD, session)
DW_attach_ds(state, id_UD, session)
state |
DW state from |
id_UD |
ID string for the upload data module used to handle uploads |
session |
Shiny session variable |
state with data set attached
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input # We also need a state variable state = sess_res$state # We need to identify the UD module with the data id_UD = "UD" state = DW_attach_ds(state, id_UD, session)
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input # We also need a state variable state = sess_res$state # We need to identify the UD module with the data id_UD = "UD" state = DW_attach_ds(state, id_UD, session)
Takes the current state and a string containing a data wranlging command and evaluates it.
dw_eval_element(state, cmd)
dw_eval_element(state, cmd)
state |
DW state from |
cmd |
string containing the data wrangling command |
list with the following elements
isgood: Return status of the function.
msgs: Messages to be passed back to the user.
DS: Wrangled dataset.
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
Fetches the code to generate results seen in the app
DW_fetch_code(state)
DW_fetch_code(state)
state |
DW state from |
Character object vector with the lines of code and isgood)
# This will create a formods DW state object for the example sess_res = DW_test_mksession() state = sess_res$state code = DW_fetch_code(state) cat(code)
# This will create a formods DW state object for the example sess_res = DW_test_mksession() state = sess_res$state code = DW_fetch_code(state) cat(code)
Takes a DW state and returns the current active view
DW_fetch_current_view(state)
DW_fetch_current_view(state)
state |
DW state from |
List containing the details of the active data view. The structure
of this list is the same as the structure of state$DW$views
in the output of
DW_fetch_state()
.
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
Fetches the datasets contained in the module.
DW_fetch_ds(state)
DW_fetch_ds(state)
state |
UD state from |
Character object vector with the lines of code
list containing the following elements
isgood: Return status of the function.
hasds: Boolean indicator if the module has any datasets
msgs: Messages to be passed back to the user.
ds: List with datasets. Each list element has the name of the R-object for that dataset. Each element has the following structure:
label: Text label for the dataset
MOD_TYPE: Short name for the type of module.
id: module ID
idx: unique numerical ID to identify this dataset in the module.
DS: Dataframe containing the actual dataset.
DSMETA: Metadata describing DS, see FM_fetch_ds()
for
details on the format.
code: Complete code to build dataset.
checksum: Module checksum.
DSchecksum: Dataset checksum.
# We need a state variable sess_res = DW_test_mksession() state = sess_res$state ds = DW_fetch_ds(state)
# We need a state variable sess_res = DW_test_mksession() state = sess_res$state ds = DW_fetch_ds(state)
Merges default app options with the changes made in the UI
DW_fetch_state( id, input, session, FM_yaml_file, MOD_yaml_file, id_UD, react_state )
DW_fetch_state( id, input, session, FM_yaml_file, MOD_yaml_file, id_UD, react_state )
id |
Shiny module ID |
input |
Shiny input variable |
session |
Shiny session variable |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id_UD |
ID string for the upload data module used to handle uploads or the name of the list element in react_state where the data set is stored. |
react_state |
Variable passed to server to allow reaction outside of
module ( |
List containing the current state of the DM module including default values from the yaml file as well as any changes made by the user. The structure of the list is defined below.
yaml: Contents of the yaml file.
MC: Module components of the yaml file.
DW: Data wrangling state
isgood: Boolean status of the state. FALSE if the dataset identified by id_UD is bad.
checksum: MD5 sum indicating if there was a change in the datasets within the view. Use this to trigger updates in respose to changes in this module.
button_counters: List of counters to detect button clicks.
code_previous: Loading code from the UD field.
current_view: View id of the current active data wrangling view.
UD: Copy of the "UD"
field of the id_UD
from the react_state
input.
ui: Current value of form elements in the UI
ui_hold: List of hold elements to disable updates before a full ui referesh is complete.
view_cntr: Counter for tracking view ids, value contains the id of the last view created.
views: List of data wrangling views. Each view has the following structure:
checksum: MD5 sum of WDS
code: Code to generate WDS from start to finish
code_dw_only: Code for just the wrangling portion.
code_previous: Code to load data and assign to view object.
elements_table: Table of data wrangling elements.
id: Character id (view_idx
)
idx: Numeric id (1
)
isgood: Boolean status of the data view. False if evaluation fails
key: User key (short description)
view_ds_object_name: Object name for this data view
WDS: Current value of the data view with all of the successful commands in elements_table evaluated.
MOD_TYPE: Character data containing the type of module "DW"
id: Character data containing the module id
FM_yaml_file: App configuration file with FM as main section.
MOD_yaml_file: Module configuration file with MC as main section. module in the session variable.
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input # Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "DW.yaml") # We need to specify both the DW module id as well as the # id of the UD module that feeds into it. id = "DW" id_UD = "UD" # Creating an empty state object state = DW_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file, id_UD = "UD", react_state = NULL)
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input # Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "DW.yaml") # We need to specify both the DW module id as well as the # id of the UD module that feeds into it. id = "DW" id_UD = "UD" # Creating an empty state object state = DW_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file, id_UD = "UD", react_state = NULL)
Walks through the DW state object to see if there are any datasets available
DW_hasds(state)
DW_hasds(state)
state |
DW state from |
Logical TRUE if there is a dataset or FALSE otherwise.
sess_res = DW_test_mksession() state = sess_res[["state"]] DW_hasds(state)
sess_res = DW_test_mksession() state = sess_res[["state"]] DW_hasds(state)
Creates a list of the initialized module state
DW_init_state(FM_yaml_file, MOD_yaml_file, id, id_UD, session)
DW_init_state(FM_yaml_file, MOD_yaml_file, id, id_UD, session)
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id |
Shiny module ID |
id_UD |
ID string for the upload data module used to handle uploads or the name of the list element in react_state where the data set is stored. |
session |
Shiny session variable
module ( |
list containing an empty DW state
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input state = DW_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "DW.yaml"), id = "DW", id_UD = "UD", session = session) state
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input state = DW_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "DW.yaml"), id = "DW", id_UD = "UD", session = session) state
Converts the current DW state into a preload list.
DW_mk_preload(state)
DW_mk_preload(state)
state |
DW state object |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
yaml_list: Lists with preload components.
sess_res = DW_test_mksession() state = sess_res$state res = DW_mk_preload(state)
sess_res = DW_test_mksession() state = sess_res$state res = DW_mk_preload(state)
Appends a new empty data wrangling view to the DW state object and makes this new view the active view.
DW_new_view(state)
DW_new_view(state)
state |
DW state from |
DW state object containing a new data view and that view set as the
current active view. See the help for DW_fetch_state()
for view
format.
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
Populates the supplied session variable with information from list of sources.
DW_preload( session, src_list, yaml_res, mod_ID = NULL, react_state = list(), quickload = FALSE )
DW_preload( session, src_list, yaml_res, mod_ID = NULL, react_state = list(), quickload = FALSE )
session |
Shiny session variable (in app) or a list (outside of app) |
src_list |
List of preload data (all read together with module IDs at the top level) |
yaml_res |
List data from module yaml config |
mod_ID |
Module ID of the module being loaded |
react_state |
Reactive shiny object (in app) or a list (outside of app) used to trigger reactions. |
quickload |
Logical |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
session: Session object
input: The value of the shiny input at the end of the session initialization.
state: App state.
react_state: The react_state
components.
Server function for the data wrangling module
DW_Server( id, id_ASM = "ASM", id_UD = "UD", FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "DW.yaml"), deployed = FALSE, react_state = NULL )
DW_Server( id, id_ASM = "ASM", id_UD = "UD", FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "DW.yaml"), deployed = FALSE, react_state = NULL )
id |
An ID string that corresponds with the ID used to call the modules UI elements |
id_ASM |
ID string for the app state managment module used to save and load app states |
id_UD |
ID string for the upload data module used to handle uploads or the name of the list element in react_state where the data set is stored. |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with DW as main section. |
deployed |
Boolean variable indicating whether the app is deployed or not. |
react_state |
Variable passed to server to allow reaction outside of
module ( |
DW Server object
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
Takes a DW state and an updated view and sets that view to the current view_id
DW_set_current_view(state, dw_view)
DW_set_current_view(state, dw_view)
state |
DW state from |
dw_view |
Data view list of the format returned from |
DW state object with the value of dw_view
set to the current view id.
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
Populates the supplied session variable for testing.
DW_test_mksession(session = list())
DW_test_mksession(session = list())
session |
Shiny session variable (in app) or a list (outside of app) |
The DW portion of the 'all_sess_res' returned from FM_app_preload
sess_res = DW_test_mksession()
sess_res = DW_test_mksession()
Takes a DW state and updates the checksum used to trigger downstream updates
DW_update_checksum(state)
DW_update_checksum(state)
state |
DW state from |
DW state object with the checksum updated
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input # We also need a state variable state = sess_res$state state = DW_update_checksum(state)
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession() session = sess_res$session input = sess_res$input # We also need a state variable state = sess_res$state state = DW_update_checksum(state)
Takes the current ui elements and constructs the appropriate data wrangling command from the user input.
dwrs_builder(state)
dwrs_builder(state)
state |
DW state from |
list containing the following elements
isgood: Return status of the function
cmd: Data wrangling R command
action: The action being performed
pll: Preload list (pll) containing components to save with mk_preload.
desc: Verbose description of the action
msgs: Messages to be passed back to the user
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
library(formods) # The example requires a formods DW state object state = DW_test_mksession()$state state[["DW"]][["ui"]][["select_dw_element"]] = "filter" state[["DW"]][["ui"]][["select_fds_filter_column"]] = "EVID" state[["DW"]][["ui"]][["select_fds_filter_operator"]] = "==" state[["DW"]][["ui"]][["fds_filter_rhs"]] = 0 # This builds the data wrangling statement based on # elemets scraped from the UI dwb_res = dwrs_builder(state) # Here we evaluate the resulting command: dwee_res = dw_eval_element(state, dwb_res[["cmd"]]) # Next we add this wrangling element to the state state = DW_add_wrangling_element(state, dwb_res, dwee_res) # This creates a new data view and makes it active state = DW_new_view(state) # Here we can pluck out that data view from the state current_view = DW_fetch_current_view(state) # This will update the key in this view current_view[["key"]] = "My new view" # And this will place it back into the state state = DW_set_current_view(state, current_view)
Takes the current ui elements and constructs the appropriate
ggplot commands forom the user input. The plot commands assume the existance
of a ggplot object p
.
fers_builder(state)
fers_builder(state)
state |
FG state from |
list containing the following elements
isgood: Return status of the function.
cmd: ggplot R command as a character string
element: The type of element being added
pll: Preload list (pll) containing components to save with mk_preload.
desc: Verbose description of the element
msgs: Messages to be passed back to the user
sess_res = FG_test_mksession() state = sess_res$state fb_res = fers_builder(state)
sess_res = FG_test_mksession() state = sess_res$state fb_res = fers_builder(state)
When some buttons are clicked they will change the state of the system, but other UI components will not detect that change correctly. So those triggers are put on hold. This will fetch hold status for a specified inputId
fetch_hold(state, inputId = NULL)
fetch_hold(state, inputId = NULL)
state |
module state with all of the current ui elements populated |
inputId |
The input ID of the UI element that was put on hold |
Boolean value with the hold status
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession(session=list()) session = sess_res$session input = sess_res$input # For this example we also need a state variable state = sess_res$state # This sets a hold on the specified inputID. This is normally done in # your XX_fetch_state() function. state = set_hold(state, inputId = "select_dw_views") # This will fetch the hold status of the specified inputID. fetch_hold(state, inputId = "select_dw_views") # This will remove the hold and is normally done in one of the UI outputs # with a priority set to ensure it happens after the rest of the UI has # refreshed. state = remove_hold(state, session, inputId = "select_dw_views")
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession(session=list()) session = sess_res$session input = sess_res$input # For this example we also need a state variable state = sess_res$state # This sets a hold on the specified inputID. This is normally done in # your XX_fetch_state() function. state = set_hold(state, inputId = "select_dw_views") # This will fetch the hold status of the specified inputID. fetch_hold(state, inputId = "select_dw_views") # This will remove the hold and is normally done in one of the UI outputs # with a priority set to ensure it happens after the rest of the UI has # refreshed. state = remove_hold(state, session, inputId = "select_dw_views")
The specified package version is extracted and returned. This can simply be the version installed from CRAN or if a development version from GitHub is used details from that will be returned.
fetch_package_version(pkgname)
fetch_package_version(pkgname)
pkgname |
Name of package |
String with the version information
# This package should exist fetch_package_version('digest') # This package should not exist fetch_package_version('bad package name')
# This package should exist fetch_package_version('digest') # This package should not exist fetch_package_version('bad package name')
Description
FG_append_report(state, rpt, rpttype, gen_code_only = FALSE)
FG_append_report(state, rpt, rpttype, gen_code_only = FALSE)
state |
FG state from |
rpt |
Report with the current content of the report which will be appended to in
this function. For details on the structure see the documentation for |
rpttype |
Type of report to generate (supported "xlsx", "pptx", "docx"). |
gen_code_only |
Boolean value indicating that only code should be
generated ( |
list containing the following elements
isgood: Return status of the function.
hasrptele: Boolean indicator if the module has any reportable elements.
code: Data wrangling R command.
msgs: Messages to be passed back to the user.
rpt: Report with any additions passed back to the user.
sess_res = FG_test_mksession() state = sess_res$state # This will read in the default PowerPoint report template rpt = onbrand::read_template( template = system.file(package="onbrand","templates","report.pptx"), mapping = system.file(package="onbrand","templates","report.yaml")) rpt_res = FG_append_report(state = state, rpt = rpt, rpttype = "pptx", gen_code_only=TRUE) # Shows if report elements are present rpt_res$hasrptele # Code chunk to generate report element cat(paste(rpt_res$code, collapse="\n"))
sess_res = FG_test_mksession() state = sess_res$state # This will read in the default PowerPoint report template rpt = onbrand::read_template( template = system.file(package="onbrand","templates","report.pptx"), mapping = system.file(package="onbrand","templates","report.yaml")) rpt_res = FG_append_report(state = state, rpt = rpt, rpttype = "pptx", gen_code_only=TRUE) # Shows if report elements are present rpt_res$hasrptele # Code chunk to generate report element cat(paste(rpt_res$code, collapse="\n"))
Takes the current state and rebuilds the active figure. If the elements table has a row flagged for deletion, it will be deleted. If the cmd input is not NULL it will attempt to append that element to the figure.
FG_build( state, del_row = NULL, cmd = NULL, pll = NULL, element = "unknown", desc = "unknown" )
FG_build( state, del_row = NULL, cmd = NULL, pll = NULL, element = "unknown", desc = "unknown" )
state |
FG state from |
del_row |
Row number to be deleted (NULL if no rows need to be deleted) |
cmd |
String containing the plotting command. Set to NULL to initialize a new figure or force a rebuild after a dataset update. |
pll |
Preload list for the plotting command. Set to NULL to initialize a new figure or force a rebuild after a dataset update. |
element |
Short name for the figure element being performed, eg. point |
desc |
Verbose description for the action being performed |
list with the following elements
isgood: Return status of the function.
msgs: Messages to be passed back to the user.
pages: List with each element containing a ggplot object (p
) and the code to generate that object (code
)
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
Used to extract the specified page from the current figure.
FG_extract_page(state, page)
FG_extract_page(state, page)
state |
FG state from |
page |
Page number to extract |
ggplot object with the specified page.
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
Fetches the code to generate results seen in the app
FG_fetch_code(state)
FG_fetch_code(state)
state |
UD state from |
Character object vector with the lines of code
# This will create a populated FG state object: sess_res = FG_test_mksession() state = sess_res$state code = FG_fetch_code(state) cat(paste(code, collapse="\n"))
# This will create a populated FG state object: sess_res = FG_test_mksession() state = sess_res$state code = FG_fetch_code(state) cat(paste(code, collapse="\n"))
Takes a FG state and returns the current active figure
FG_fetch_current_fig(state)
FG_fetch_current_fig(state)
state |
FG state from |
List containing the details of the active figure. The structure
of this list is the same as the structure of state$FG$figs
in the output of
FG_fetch_state()
.
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
Merges default app options with the changes made in the UI
FG_fetch_state( id, input, session, FM_yaml_file, MOD_yaml_file, id_ASM = NULL, id_UD = NULL, id_DW = NULL, react_state )
FG_fetch_state( id, input, session, FM_yaml_file, MOD_yaml_file, id_ASM = NULL, id_UD = NULL, id_DW = NULL, react_state )
id |
Shiny module ID |
input |
Shiny input variable |
session |
Shiny session variable |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id_ASM |
ID string for the app state management module used to save and load app states |
id_UD |
ID string for the upload data module used to handle uploads or the name of the list element in react_state where the data set is stored. |
id_DW |
ID string for the data wrangling module to process any uploaded data |
react_state |
Variable passed to server to allow reaction outside of module ( |
list containing the current state of the app including default values from the yaml file as well as any changes made by the user. The structure of the list is defined below:
yaml: Contents of the yaml file.
MC: Module components of the yaml file.
FG: Data wrangling state
isgood: Boolean status of the state. Currently just TRUE
button_counters: List of counters to detect button clicks.
ui_msg: Message returned when users perform actions.
ui: Current value of form elements in the UI.
ui_ids: Vector of UI elements for the module.
ui_hold: List of hold elements to disable updates before a full ui referesh is complete.
checksum: checksum of the FG module used to detect changes in the module.
aes_elements: Plot elements defined by aesthetics (i.e. the X in geom_X)
current_fig: fig_id of the currently figure.
fig_cntr: Counter for figures, incremented each time a new figure is created.
DSV: Available data sets from the UD and DW modules.
figs: List of figures. Each view has the following structure:
add_isgood: JMH
checksum: Checksum of the figure used to detect changes in the figure.
code: Code to generate figure from start to finish.
code_fg_only: Code to just generate the figure.
code_previous: Code to load and/or wrangle the dataset.
elements_table: Table of figure generation elements.
fg_object_name: JMH
fig_dsview: Name of the dataset view for the current figure (also the R object name of the dataset view).
fobj: JMH
id: Character id (fig_idx
)
idx: Numeric id (1
)
isgood: Boolean status of the figure. FALSE if evaluation/build fails.
key: Figure key acts as a title/caption (user editable)
msgs: JMH
notes: Figure notes (user editable)
num_pages: JMH
page: JMH
MOD_TYPE: Character data containing the type of module "DW"
id: Character data containing the module id module in the session variable.
FM_yaml_file: App configuration file with FM as main section.
MOD_yaml_file: Module configuration file with MC as main section.
# Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "FG.yaml") # We need to specify both the FG module id as well as the # id of the UD module that feeds into it. id = "FG" id_UD = "UD" id_DW = "DW" # These would be the Shiny input and session variables input = list() session = list() # Creating an empty state object state = FG_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file, id_UD = id_UD, id_DW = id_DW, react_state = NULL) state
# Configuration files FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "FG.yaml") # We need to specify both the FG module id as well as the # id of the UD module that feeds into it. id = "FG" id_UD = "UD" id_DW = "DW" # These would be the Shiny input and session variables input = list() session = list() # Creating an empty state object state = FG_fetch_state(id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file, id_UD = id_UD, id_DW = id_DW, react_state = NULL) state
Creates a list of the initialized module state
FG_init_state(FM_yaml_file, MOD_yaml_file, id, id_UD, id_DW, session)
FG_init_state(FM_yaml_file, MOD_yaml_file, id, id_UD, id_DW, session)
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id |
Shiny module ID |
id_UD |
ID string for the upload data module used to handle uploads or the name of the list element in react_state where the data set is stored. |
id_DW |
ID string for the data wrangling module to process any uploaded data |
session |
Shiny session variable |
list containing an empty app state object
# These would be the Shiny input and session variables input = list() session = list() state = FG_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "FG.yaml"), id = "FG", id_UD = "UD", id_DW = "DW", session = session) state
# These would be the Shiny input and session variables input = list() session = list() state = FG_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "FG.yaml"), id = "FG", id_UD = "UD", id_DW = "DW", session = session) state
Converts the current FG state into a preload list.
FG_mk_preload(state)
FG_mk_preload(state)
state |
FG state object |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
yaml_list: Lists with preload components.
sess_res = FG_test_mksession() state = sess_res$state res = FG_mk_preload(state)
sess_res = FG_test_mksession() state = sess_res$state res = FG_mk_preload(state)
Creates a new figure in a FG module
FG_new_fig(state)
FG_new_fig(state)
state |
FG state from |
FG state object containing a new empty figure and that figure set as the current active figure
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
Populates the supplied session variable with information from list of sources.
FG_preload( session, src_list, yaml_res, mod_ID = NULL, react_state = list(), quickload = FALSE )
FG_preload( session, src_list, yaml_res, mod_ID = NULL, react_state = list(), quickload = FALSE )
session |
Shiny session variable (in app) or a list (outside of app) |
src_list |
List of preload data (all read together with module IDs at the top level) |
yaml_res |
List data from module yaml config |
mod_ID |
Module ID of the module being loaded. |
react_state |
Reactive shiny object (in app) or a list (outside of app) used to trigger reactions. |
quickload |
Logical |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
session: Session object
input: The value of the shiny input at the end of the session initialization.
state: App state.
react_state: The react_state
components.
Server function for the figure generation module
FG_Server( id, FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "FG.yaml"), id_ASM = "ASM", id_UD = "UD", id_DW = "DW", deployed = FALSE, react_state = NULL )
FG_Server( id, FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "FG.yaml"), id_ASM = "ASM", id_UD = "UD", id_DW = "DW", deployed = FALSE, react_state = NULL )
id |
An ID string that corresponds with the ID used to call the module's UI function |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id_ASM |
ID string for the app state management module used to save and load app states |
id_UD |
ID string for the upload data module used to handle uploads or the name of the list element in react_state where the data set is stored. |
id_DW |
ID string for the data wrangling module to process any uploaded data |
deployed |
Boolean variable indicating whether the app is deployed or not. |
react_state |
Variable passed to server to allow reaction outside of module ( |
FG Server object
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
Takes a FG state and a figure list and sets that figure list as the value for the active figure
FG_set_current_fig(state, fig)
FG_set_current_fig(state, fig)
state |
FG state from |
fig |
Figure list from |
State with the current figure updated
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
library(formods) # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = FG_test_mksession() session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This sets the current active figure to Fig_1 state[["FG"]][["current_fig"]] = "Fig_1" # If this is a paginated figure, and we can access a specific pg_1 = FG_extract_page(state, 1) # This will give you access to the current figure directly: current_fig = FG_fetch_current_fig(state) # For example this will set the key for that figure: current_fig$key = "Individual profiles by cohort (multiple pages)" # Once you're done you can put it back into the state: state = FG_set_current_fig(state, current_fig) # If you made any changes to the actual figure, this will # force a rebuild of the current figure: state = FG_build( state=state, del_row = NULL, cmd = NULL) # To create a new empty figure you can do this: state = FG_new_fig(state)
Populates the supplied session variable for testing.
FG_test_mksession(session = list())
FG_test_mksession(session = list())
session |
Shiny session variable (in app) or a list (outside of app) |
The FG portion of the 'all_sess_res' returned from FM_app_preload
sess_res = FG_test_mksession()
sess_res = FG_test_mksession()
Called after any changes to figures, this function will update the checksum of the module. This allows other modules to determine if there were any changes to the figures within it.
FG_update_checksum(state)
FG_update_checksum(state)
state |
FG state from |
state with checksum updated.
# This will create a populated FG state object: sess_res = FG_test_mksession() state = sess_res$state state = FG_update_checksum(state)
# This will create a populated FG state object: sess_res = FG_test_mksession() state = sess_res$state state = FG_update_checksum(state)
Adds a tool tip to a user element.
FM_add_ui_tooltip( state, uiele, tooltip = "mytooltip", position = "right", size = "medium" )
FM_add_ui_tooltip( state, uiele, tooltip = "mytooltip", position = "right", size = "medium" )
state |
Current module state after yaml file has been read. |
uiele |
UI element to add the toooltip to. |
tooltip |
Text containing the tool tip. |
position |
Position of the tooltip. |
size |
size of the tooltip |
If tooltips are enabled and the suggested packages are installed then a uiele with the tooltip added will be returned. Otherwise it will just return the original uiele unchanged.
if(interactive()){ # We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state uiele = shiny::textInput(inputId = "my input", label="example input") uiele = FM_add_ui_tooltip(state, uiele) }
if(interactive()){ # We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state uiele = shiny::textInput(inputId = "my input", label="example input") uiele = FM_add_ui_tooltip(state, uiele) }
Populates session data for testing or to load a specific analysis.
FM_app_preload( session, sources = NULL, react_state = list(), quickload = FALSE )
FM_app_preload( session, sources = NULL, react_state = list(), quickload = FALSE )
session |
Shiny session variable (in app) or a list (outside of app) |
sources |
Vector of at corresponds with the ID used to call the modules UI elements |
react_state |
Reactive shiny object (in app) or a list (outside of app) used to trigger reactions |
quickload |
Logical |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
all_sess_res: List containing the result for each module stored in the list name with the module ID.
session: Returning the session variable to be used in scripting (not in app).
sources=system.file(package="formods", "preload", "UD.yaml") res = FM_app_preload(session=list(), sources=sources)
sources=system.file(package="formods", "preload", "UD.yaml") res = FM_app_preload(session=list(), sources=sources)
Takes a character string and builds a comment so it will be formatted as a section at the specified level in RStudio
FM_build_comment(level = 1, comment_str)
FM_build_comment(level = 1, comment_str)
level |
Integer (1 (default),2, or 3) indicating the section level of the comment. |
comment_str |
Character object. |
Formatted comment.
FM_build_comment(1, "This is a level 1 header") FM_build_comment(2, paste0(rep("Long string repeated.", 5), collapse=" "))
FM_build_comment(1, "This is a level 1 header") FM_build_comment(2, paste0(rep("Long string repeated.", 5), collapse=" "))
Takes the current state of the app and builds a script to reproduce the analysis within the app.
FM_fetch_app_code(session, state, mod_ids)
FM_fetch_app_code(session, state, mod_ids)
session |
Shiny session variable |
state |
module state after yaml read |
mod_ids |
Vector of module IDs and order they are needed (used for code generation). |
list with the following elements:
isgood: Boolean indicating the whether code generation was
successful
(TRUE
)
msgs: Any messages generated
code: Code to regenerate the app
# We need a Shiny session object to use this function: sess_res = DW_test_mksession() session = sess_res$session state = sess_res$state app_code = FM_fetch_app_code(session = session, state = state, mod_ids = c("UD", "DW")) cat(app_code$code)
# We need a Shiny session object to use this function: sess_res = DW_test_mksession() session = sess_res$session state = sess_res$state app_code = FM_fetch_app_code(session = session, state = state, mod_ids = c("UD", "DW")) cat(app_code$code)
Returns diagnostic information about the app
FM_fetch_app_info(session)
FM_fetch_app_info(session)
session |
Shiny session variable. |
List with information about the app with the following structure
uiele: All system information as UI elements to be used in shiny apps.
uiele_packages: UI element for installed packages to be used in shiny apps.
uiele_options: UI element for current options.
uiele_modules: UI element for loaded formods modules to be used in shiny apps.
msgs: System information as text to be used in a report/terminal.
si_packages Dataframe with currently used packages.
si_options Dataframe with current options
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session app_info = FM_fetch_app_info(session) app_info$msgs
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session app_info = FM_fetch_app_info(session) app_info$msgs
Returns the entire state of the App
FM_fetch_app_state(session)
FM_fetch_app_state(session)
session |
Shiny session variable. |
App state or NULL if it's not defined.
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session app_state = FM_fetch_app_state(session) app_state
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session app_state = FM_fetch_app_state(session) app_state
Use this to get information about the currently supported modules. This includes short names, UI elements,
FM_fetch_current_mods()
FM_fetch_current_mods()
list with details about the currently supported modules.
FM_fetch_current_mods()
FM_fetch_current_mods()
Takes a data frame and information in the site configureation to produce formatting information to make it easier for the user to see data type information.
FM_fetch_data_format(df, state)
FM_fetch_data_format(df, state)
df |
Raw dataframe to be built into an rhandsontable. |
state |
Current module state after yaml file has been read. |
list with the following elements:
col_heads: List (element for each column) of formatting information for column headers to be use with rhandsontable.
col_subtext: List (element for each column) of subtext to be displayed in selections using 'pickerInput' from the 'shinyWidgets' package.
# We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") sheet = "DATA" df = readxl::read_excel(path=data_file_local, sheet=sheet) hfmt = FM_fetch_data_format(df, state) # Column header formatting head(as.vector(unlist( hfmt[["col_heads"]]))) # Column select subtext head(as.vector(unlist( hfmt[["col_subtext"]])))
# We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") sheet = "DATA" df = readxl::read_excel(path=data_file_local, sheet=sheet) hfmt = FM_fetch_data_format(df, state) # Column header formatting head(as.vector(unlist( hfmt[["col_heads"]]))) # Column select subtext head(as.vector(unlist( hfmt[["col_subtext"]])))
For a given state and session this function will determine the module ids that are dependent as well as any packages the module elements might depend on.
FM_fetch_deps(state, session)
FM_fetch_deps(state, session)
state |
Current module state after yaml file has been read |
session |
Shiny session variable |
list with the following elements:
mod_ids Dependent module ids.
packages List of package dependencies.
package_code Library commands to load packages.
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state mod_deps = FM_fetch_deps(state, session)
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state mod_deps = FM_fetch_deps(state, session)
Loops through each specified module ID or all modules if no ID was specified. For each ID, an attempt will be made to extract any datasets available.
FM_fetch_ds(state, session, ids = NULL)
FM_fetch_ds(state, session, ids = NULL)
state |
Current module state after yaml file has been read |
session |
Shiny session variable |
ids |
Vector of ID strings for the modules containing the datasets or NULL for all datasets available. |
list containing the current dataset with the following format:
isgood: Boolean indicating the whether a dataset was found
(FALSE
)
ds: List of datasets with element names corresponding to the R object name for that dataset. This has the following format
label: Text label for the dataset (used to display to the user)
DS: Data frame with the dataset
DSMETA: Data frame with metadata about the colunns of the
dataset in DS
. The data frame should have the following columns:
col1: column 1
code: Code to generate the dataset.
checksum: Module checksum when the dataset was pulled
DSchecksum: Checksum of the dataframe in DS
catalog: Dataframe containing the a tabular catalog of the datasets found.
label: Text label
object: Name of the R Object containing the data frame
MOD_TYPE: Short name of the type of module
id: Module ID
idx: Numerical identifyer within the module
checksum: Module checksum
DSchecksum: Checksum of the dataset
code: Code to generate the dataset
modules: List with an entry for each module. The element name is
the short name. Each of these is a list with an entry that is the shiny module
ID. For each of these there is a checksum. For example to access the
checksum of a DW module with a module ID of 'my_id', you would use the
following: res$modules$DW$my_id
.
# We need a module state and a Shiny session variable # to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state ds = FM_fetch_ds(state, session) ds$catalog
# We need a module state and a Shiny session variable # to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state ds = FM_fetch_ds(state, session) ds$catalog
Use this to get the path to the formods log file
FM_fetch_log_path(state)
FM_fetch_log_path(state)
state |
module state after yaml read |
Character string with the path to the log file.
# Within shiny a session variable will exist, # this creates one here for testing purposes: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_fetch_log_path(state)
# Within shiny a session variable will exist, # this creates one here for testing purposes: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_fetch_log_path(state)
Loops through each specified module ID or all modules if no ID was specified. For each ID, an attempt will be made to extract any models available.
FM_fetch_mdl(state, session, ids = NULL)
FM_fetch_mdl(state, session, ids = NULL)
state |
Current module state after yaml file has been read |
session |
Shiny session variable |
ids |
Vector of ID strings for the modules containing models or NULL for all modules with models available. |
list containing the current dataset with the following format:
isgood: General logical indicator of successfully.
hasmdl: Logical indicating if at least one model was found.
modules: List of module checksums.
mdl: Result of MM_fetch_mdl, see vignette("making_modules", package = "formods")
catalog: Dataframe containing the a tabular catalog of the models found.
label: Text label for the model (e.g. one-compartment model).
MOD_TYPE: Type of module.
id: Module ID.
rx_obj: The rxode2 object.
rx_obj_name: The rxode2 object name that holds the model.
ts_obj: List of timescale information for the system and
details of other timescales (list(system="weeks", details = list(days=list(verb="days", conv=86400)))
)
ts_obj_name: The object name that holds the timescale for this model.
fcn_def: Text to define the model.
MDLMETA: Notes about the model.
code: Code to generate the model.
checksum: Module checksum.
MDLchecksum: Model checksum.
# We need a module state and a Shiny session variable # to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state mdl = FM_fetch_mdl(state, session) mdl$catalog
# We need a module state and a Shiny session variable # to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state mdl = FM_fetch_mdl(state, session) mdl$catalog
Fetches the module state from the userdata under the specified id
FM_fetch_mod_state(session, id)
FM_fetch_mod_state(session, id)
session |
Shiny session variable. |
id |
ID string for the module. |
module state or NULL if it's not defined.
# We need a Shiny session variable to use this function: sess_res = UD_test_mksession() session = sess_res$session state = FM_fetch_mod_state(session, "UD")
# We need a Shiny session variable to use this function: sess_res = UD_test_mksession() session = sess_res$session state = FM_fetch_mod_state(session, "UD")
Use this to get the path to the temporary directory where formods stores user files.
FM_fetch_user_files_path(state)
FM_fetch_user_files_path(state)
state |
module state after yaml read |
Character string with the path to the log file.
# We need a state object to use this function: sess_res = UD_test_mksession() state = sess_res$state user_dir = FM_fetch_user_files_path(state) user_dir
# We need a state object to use this function: sess_res = UD_test_mksession() state = sess_res$state user_dir = FM_fetch_user_files_path(state) user_dir
Generates a report from the states of the different modules. The type of report is based on the file extension of file_name.
FM_generate_report( state, session, file_dir, file_name, ph = list(), gen_code_only = FALSE, rpterrors = TRUE )
FM_generate_report( state, session, file_dir, file_name, ph = list(), gen_code_only = FALSE, rpterrors = TRUE )
state |
Module state requesting the report generation |
session |
Shiny session variable |
file_dir |
path to the location where the file should be written. |
file_name |
base_filename (acceptable extensions are xlsx, docx, or pptx). |
ph |
List containing placeholders used when generating Word documents
(e.g., |
gen_code_only |
Boolean value indicating that only code should be
generated ( |
rpterrors |
Boolean variable to generate reports with errors. |
This function will look through the loaded modules and find those with reporting enabbled. If reporting is enabled it will look for reporting functions for that module. Reporting functions should be of the following format (name and arguments):
XX_append_report(state, rpt, rpttype)
Where XX
is the module short name. The state is the current state of the
module. The rpt contains the current content of the report. This will
vary based on the report type:
xlsx: List with two elements. The first is summary
a data
frame with two columns. The first column is called Sheet_Name
and
the second column is called Description
. This is a catalog of
sheets added to the report by the user and can be appended to using rbind.
The second element in xlsx rpt is another list with element names
corresponding to the report sheet names and the values corresponding to
dataframes to be exported in the report.
pptx or docx: Corresponding onbrand reporting object.
List with the following elements
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: if(interactive()){ sess_res = FG_test_mksession(session=list(), full_session=FALSE) session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This is the directory to write the report: file_dir = tempdir() # This is the file name that determines the type of report to write: file_name = "my_report.pptx" #file_name = "my_report.docx" rpt_res = FM_generate_report(state = state, session = session, file_dir = file_dir, file_name = file_name, gen_code_only = TRUE, rpterrors = TRUE) # This contains the exit status of the report generation rpt_res$isgood # This is the underlying code that was used to generate the report cat(paste0(rpt_res$code, collapse="\n")) }
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: if(interactive()){ sess_res = FG_test_mksession(session=list(), full_session=FALSE) session = sess_res$session input = sess_res$input # This will create a populated FG state object: state = sess_res$state # This is the directory to write the report: file_dir = tempdir() # This is the file name that determines the type of report to write: file_name = "my_report.pptx" #file_name = "my_report.docx" rpt_res = FM_generate_report(state = state, session = session, file_dir = file_dir, file_name = file_name, gen_code_only = TRUE, rpterrors = TRUE) # This contains the exit status of the report generation rpt_res$isgood # This is the underlying code that was used to generate the report cat(paste0(rpt_res$code, collapse="\n")) }
Initializes a formods state object with common elements.
FM_init_state( FM_yaml_file, MOD_yaml_file, id, dep_mod_ids = c(), MT, button_counters, ui_ids, ui_hold, session )
FM_init_state( FM_yaml_file, MOD_yaml_file, id, dep_mod_ids = c(), MT, button_counters, ui_ids, ui_hold, session )
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id |
Shiny module ID. |
dep_mod_ids |
Vector of module ids this module depends on. |
MT |
Type of module using the short name (e.g. "UD", "FG", etc.). |
button_counters |
Vector of button UI elements that need to be tracked. |
ui_ids |
List of UI ids in the module. |
ui_hold |
Vector of UI elements that require holding. |
session |
Shiny session variable |
List with state initialized.
# Within shiny a session variable will exist, # this creates examples here for testing purposes: sess_res = UD_test_mksession() session = sess_res$session state = FM_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml"), id = "UD", MT = "UD", button_counters = NULL, ui_ids = NULL, ui_hold = NULL, session = session) state
# Within shiny a session variable will exist, # this creates examples here for testing purposes: sess_res = UD_test_mksession() session = sess_res$session state = FM_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml"), id = "UD", MT = "UD", button_counters = NULL, ui_ids = NULL, ui_hold = NULL, session = session) state
Add the supplied txt and the module type to the log file and display it to the console.
FM_le(state, entry, escape_braces = TRUE, entry_type = "alert")
FM_le(state, entry, escape_braces = TRUE, entry_type = "alert")
state |
Module state after yaml read |
entry |
Text to add |
escape_braces |
Set to |
entry_type |
Set to either "alert"(default), "danger", "info", "success", or "warning" |
Boolean value indicating success (TRUE
) or failure (FALSE
).
# We need a module state to use this function: sess_res = UD_test_mksession() state = sess_res$state FM_le(state, "This is a normal message") FM_le(state, "This is a danger message", entry_type="danger") FM_le(state, "This is a info message", entry_type="info") FM_le(state, "This is a success message", entry_type="success") FM_le(state, "This is a warning message", entry_type="warning")
# We need a module state to use this function: sess_res = UD_test_mksession() state = sess_res$state FM_le(state, "This is a normal message") FM_le(state, "This is a danger message", entry_type="danger") FM_le(state, "This is a info message", entry_type="info") FM_le(state, "This is a success message", entry_type="success") FM_le(state, "This is a warning message", entry_type="warning")
Writes a message to the console depending on whether cli is installed or not.
FM_message(line, escape_braces = TRUE, entry_type = "alert")
FM_message(line, escape_braces = TRUE, entry_type = "alert")
line |
Text to display |
escape_braces |
Set to |
entry_type |
Set to either "alert"(default), "danger", "info", "success", "warning", "h1", "h2", or "h3" |
Returns NULL
mr = FM_message("This is a normal message") mr = FM_message("This is a danger message", entry_type="danger") mr = FM_message("This is a info message", entry_type="info") mr = FM_message("This is a success message", entry_type="success") mr = FM_message("This is a warning message", entry_type="warning") mr = FM_message("This is an H1 header", entry_type="h1") mr = FM_message("This is an H2 header", entry_type="h2") mr = FM_message("This is an H3 header", entry_type="h3")
mr = FM_message("This is a normal message") mr = FM_message("This is a danger message", entry_type="danger") mr = FM_message("This is a info message", entry_type="info") mr = FM_message("This is a success message", entry_type="success") mr = FM_message("This is a warning message", entry_type="warning") mr = FM_message("This is an H1 header", entry_type="h1") mr = FM_message("This is an H2 header", entry_type="h2") mr = FM_message("This is an H3 header", entry_type="h3")
Populates session data for testing or to load a specific analysis.
FM_mk_app_preload(session)
FM_mk_app_preload(session)
session |
Shiny session variable (in app) or a list (outside of app) |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
yaml_list: Lists with preload components.
session: Returning the session variable to be used in scripting (not in app).
sources=system.file(package="formods", "preload", "UD.yaml") sess_res = ASM_set_app_state(session=list(), sources=sources) mkp_res = ASM_mk_app_preload(sess_res$session)
sources=system.file(package="formods", "preload", "UD.yaml") sess_res = ASM_set_app_state(session=list(), sources=sources) mkp_res = ASM_mk_app_preload(sess_res$session)
Takes a vector of messages and returns a ggplot object with the text in the figure. This can be used in automated figure generation to cascade an error message to the end user.
FM_mk_error_fig(msgs)
FM_mk_error_fig(msgs)
msgs |
Vector of error messages |
ggplot object
FM_mk_error_fig("Oh nos! You've made a mistake!")
FM_mk_error_fig("Oh nos! You've made a mistake!")
Generates a notification that should only show once.
FM_notify(state, session)
FM_notify(state, session)
state |
Module state generating the notification |
session |
Shiny session variable |
Boolean variable indicating if the notification was triggered
if(interactive()){ library(formods) library(shiny) library(shinydashboard) #https://fontawesome.com/icons?from=io ui <- dashboardPage( skin="red", dashboardHeader(title="Test Notifications"), dashboardSidebar( sidebarMenu( menuItem("Notifications", tabName="example", icon=icon("table")) ) ), dashboardBody( tabItems( tabItem(tabName="example", fluidRow( shiny::actionButton("set_notification", "Set Notification"), shiny::textInput("user_text", label="Notify Text Here", value="Notify me"), shiny::actionButton("show_notification", "Show Notification") ) ) ) ) ) # Main app server server <- function(input, output, session) { # Need formods state object sess_res = UD_test_mksession(session, id="UD") # Captures input and sets the notification observeEvent(input$set_notification, { state = FM_fetch_mod_state(session, id="UD") state = FM_set_notification(state, notify_text = isolate(input$user_text), notify_id = "example") FM_set_mod_state(session, id="UD", state) }) # Displays the notification observeEvent(input$show_notification, { state = FM_fetch_mod_state(session, id="UD") FM_notify(state, session) }) } shinyApp(ui, server) }
if(interactive()){ library(formods) library(shiny) library(shinydashboard) #https://fontawesome.com/icons?from=io ui <- dashboardPage( skin="red", dashboardHeader(title="Test Notifications"), dashboardSidebar( sidebarMenu( menuItem("Notifications", tabName="example", icon=icon("table")) ) ), dashboardBody( tabItems( tabItem(tabName="example", fluidRow( shiny::actionButton("set_notification", "Set Notification"), shiny::textInput("user_text", label="Notify Text Here", value="Notify me"), shiny::actionButton("show_notification", "Show Notification") ) ) ) ) ) # Main app server server <- function(input, output, session) { # Need formods state object sess_res = UD_test_mksession(session, id="UD") # Captures input and sets the notification observeEvent(input$set_notification, { state = FM_fetch_mod_state(session, id="UD") state = FM_set_notification(state, notify_text = isolate(input$user_text), notify_id = "example") FM_set_mod_state(session, id="UD", state) }) # Displays the notification observeEvent(input$show_notification, { state = FM_fetch_mod_state(session, id="UD") FM_notify(state, session) }) } shinyApp(ui, server) }
Start a modal screen pause.
FM_pause_screen(state, session, message)
FM_pause_screen(state, session, message)
state |
Current module state after yaml file has been read. |
session |
Shiny session variable. |
message |
Optional message for the pause. |
Pauses the screen and has no return value.
# We need a module state object and Shiny session objects to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_pause_screen(state, session) FM_resume_screen(state, session)
# We need a module state object and Shiny session objects to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_pause_screen(state, session) FM_resume_screen(state, session)
When displaying information in a pull down this function can be used to sort those options.
FM_pretty_sort(unsrt_data)
FM_pretty_sort(unsrt_data)
unsrt_data |
Unsorted data. |
sorted data
# This is the full path to a test data file: data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") # Excel files need a sheet specification: sheet = "DATA" # We will also attach the sheets along with it df = readxl::read_excel(path=data_file_local, sheet=sheet) # Regular sorting: sort(unique(df$Cohort)) FM_pretty_sort(unique(df$Cohort))
# This is the full path to a test data file: data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") # Excel files need a sheet specification: sheet = "DATA" # We will also attach the sheets along with it df = readxl::read_excel(path=data_file_local, sheet=sheet) # Regular sorting: sort(unique(df$Cohort)) FM_pretty_sort(unique(df$Cohort))
Any errors that need to be passed back to the user can be set with this function.
FM_proc_include(state, session)
FM_proc_include(state, session)
state |
formods State object. |
session |
Shiny session variable. |
No return value, sets message in supplied session variable.
# We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state session = sess_res$session FM_proc_include(state, session)
# We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state session = sess_res$session FM_proc_include(state, session)
Stops Modal Screen Pause
FM_resume_screen(state, session)
FM_resume_screen(state, session)
state |
Current module state after yaml file has been read. |
session |
Shiny session variable. |
No return value, called to disable screen pause.
# We need a module state object and Shiny session objects to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_pause_screen(state, session) FM_resume_screen(state, session)
# We need a module state object and Shiny session objects to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_pause_screen(state, session) FM_resume_screen(state, session)
Takes a loaded app state and overwrites the current app state
FM_set_app_state(session, app_state, set_holds = TRUE)
FM_set_app_state(session, app_state, set_holds = TRUE)
session |
Shiny session variable. |
app_state |
Loaded app state. |
set_holds |
If TRUE (default) the holds will be set for all of the modules present in the app state. |
No return value, just updates the app state in the session variable.
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session app_state = FM_fetch_app_state(session) FM_set_app_state(session, app_state)
# We need a Shiny session object to use this function: sess_res = UD_test_mksession() session = sess_res$session app_state = FM_fetch_app_state(session) FM_set_app_state(session, app_state)
Sets the module state from the userdata under the specified id
FM_set_mod_state(session, id, state)
FM_set_mod_state(session, id, state)
session |
Shiny session variable |
id |
ID string for the module. |
state |
Module state to set. |
Session variable with the module state set.
# We need a Shiny session variable and a module state # object to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_set_mod_state(session, "UD", state)
# We need a Shiny session variable and a module state # object to use this function: sess_res = UD_test_mksession() session = sess_res$session state = sess_res$state FM_set_mod_state(session, "UD", state)
Generates a notification that should only show once.
FM_set_notification(state, notify_text, notify_id, type = "info")
FM_set_notification(state, notify_text, notify_id, type = "info")
state |
Module state generating the notification |
notify_text |
Text to go in the notification |
notify_id |
Unique string for this notification |
type |
- Can be either "success", "failure", "info" (default), or "warning" |
Module state with notification text set
if(interactive()){ library(formods) library(shiny) library(shinydashboard) #https://fontawesome.com/icons?from=io ui <- dashboardPage( skin="red", dashboardHeader(title="Test Notifications"), dashboardSidebar( sidebarMenu( menuItem("Notifications", tabName="example", icon=icon("table")) ) ), dashboardBody( tabItems( tabItem(tabName="example", fluidRow( shiny::actionButton("set_notification", "Set Notification"), shiny::textInput("user_text", label="Notify Text Here", value="Notify me"), shiny::actionButton("show_notification", "Show Notification") ) ) ) ) ) # Main app server server <- function(input, output, session) { # Need formods state object sess_res = UD_test_mksession(session, id="UD") # Captures input and sets the notification observeEvent(input$set_notification, { state = FM_fetch_mod_state(session, id="UD") state = FM_set_notification(state, notify_text = isolate(input$user_text), notify_id = "example") FM_set_mod_state(session, id="UD", state) }) # Displays the notification observeEvent(input$show_notification, { state = FM_fetch_mod_state(session, id="UD") FM_notify(state, session) }) } shinyApp(ui, server) }
if(interactive()){ library(formods) library(shiny) library(shinydashboard) #https://fontawesome.com/icons?from=io ui <- dashboardPage( skin="red", dashboardHeader(title="Test Notifications"), dashboardSidebar( sidebarMenu( menuItem("Notifications", tabName="example", icon=icon("table")) ) ), dashboardBody( tabItems( tabItem(tabName="example", fluidRow( shiny::actionButton("set_notification", "Set Notification"), shiny::textInput("user_text", label="Notify Text Here", value="Notify me"), shiny::actionButton("show_notification", "Show Notification") ) ) ) ) ) # Main app server server <- function(input, output, session) { # Need formods state object sess_res = UD_test_mksession(session, id="UD") # Captures input and sets the notification observeEvent(input$set_notification, { state = FM_fetch_mod_state(session, id="UD") state = FM_set_notification(state, notify_text = isolate(input$user_text), notify_id = "example") FM_set_mod_state(session, id="UD", state) }) # Displays the notification observeEvent(input$show_notification, { state = FM_fetch_mod_state(session, id="UD") FM_notify(state, session) }) } shinyApp(ui, server) }
Any errors that need to be passed back to the user can be set with this function.
FM_set_ui_msg(state, msgs, append = FALSE)
FM_set_ui_msg(state, msgs, append = FALSE)
state |
formods State object. |
msgs |
Character vector of messages. |
append |
When |
state with ui message set.
# We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state state = FM_set_ui_msg(state, "Something happend.")
# We need a module state object to use this function: sess_res = UD_test_mksession() state = sess_res$state state = FM_set_ui_msg(state, "Something happend.")
Attempts to execute the text in cmd. This is done in a try/catch environment to capture any errors.
FM_tc(cmd, tc_env, capture)
FM_tc(cmd, tc_env, capture)
cmd |
Character object containing the R command to evaluate in the try/catch block |
tc_env |
list of with names corresponding to object names and corresponding Values to define in the try/catch environment |
capture |
Character vector of values to capture after the command is successfully captured |
list with the following fields:
isgood: Boolean indicating the whether the evaluation was successful.
error: If the evaluation failed this contains the error object.
msgs: Character vector of messages and/or errors.
capture: List with names of objects to be captured and values corresponding to those captured objects.
# Successful command res_good = FM_tc("good_cmd=ls()", list(), c("good_cmd")) res_good # Failed command res_bad = FM_tc("bad_cmd =not_a_command()", list(), c("bad_cmd")) res_bad
# Successful command res_good = FM_tc("good_cmd=ls()", list(), c("good_cmd")) res_good # Failed command res_bad = FM_tc("bad_cmd =not_a_command()", list(), c("bad_cmd")) res_bad
Shiny apps can often make use of the same key elements, this package provides modules for common tasks (data upload, wrangling data, figure generation and saving the app state). These modules can react and interact as well as generate code to create reproducible analyses.
Maintainer: John Harrold [email protected] (ORCID)
https://formods.ubiquity.tools/
Looks at the suggested dependencies and checks to make sure
formods_check(verbose = TRUE)
formods_check(verbose = TRUE)
verbose |
Logical indicating if messages should be displayed |
List with the following elements:
all_found: Boolean indicating if all packages were found
found_pkgs: Character vector of found packages
missing_pkgs: Character vector of missing packages
fcres = formods_check()
fcres = formods_check()
Depreciated please use has_updated instead: Takes a UI element value and an older value and determines if it has been modified
has_changed(ui_val = NULL, old_val = NULL, init_value = c(""))
has_changed(ui_val = NULL, old_val = NULL, init_value = c(""))
ui_val |
Current value from the UI. |
old_val |
Last value of of the element. |
init_value |
Default value for reading in UI data when it has not been defined. |
Boolean result of the comparison
changed_true = has_changed(ui_val = "a", old_val = "") changed_true changed_false = has_changed(ui_val = "a", old_val = "a") changed_false
changed_true = has_changed(ui_val = "a", old_val = "") changed_true changed_false = has_changed(ui_val = "a", old_val = "a") changed_false
Takes a UI element value and an older value and determines if it has been modified
has_updated(ui_val = NULL, old_val = NULL, init_val = NULL)
has_updated(ui_val = NULL, old_val = NULL, init_val = NULL)
ui_val |
Current value from the UI. |
old_val |
Last value of of the element. defined. |
init_val |
List of values to skip. These are values expected to be assigned on initialization. For buttons it may be 0. For others it may be "". |
Boolean result of the comparison
changed_true = has_updated(ui_val = "a", old_val = "") changed_true changed_false = has_updated(ui_val = "a", old_val = "a") changed_false
changed_true = has_updated(ui_val = "a", old_val = "") changed_true changed_false = has_updated(ui_val = "a", old_val = "a") changed_false
Creates a link to a Shiny icon
icon_link(href, target = "_blank", icon_name = "circle-info")
icon_link(href, target = "_blank", icon_name = "circle-info")
href |
URL to link to. |
target |
New tab name. |
icon_name |
Name of icon to use (arguemnt to shiny::icon, default: "circle-info") |
A list with a shiny.tag class that can be converted into an HTML string via as.character() and saved to a file with save_html(). Note if href is NULL
then NULL
is returned.
icon_link(href="https://formods.ubiquity.tools")
icon_link(href="https://formods.ubiquity.tools")
Determines if the specified package is installed.
is_installed(pkgname)
is_installed(pkgname)
pkgname |
Name of package |
Logical indicating if the packages is installed or not
# This package should exist is_installed('digest') # This package should not exist is_installed('bad package name')
# This package should exist is_installed('digest') # This package should not exist is_installed('bad package name')
linspace
Function from MatlabCreates a vector of n elements equally spaced apart.
linspace(a, b, n = 100)
linspace(a, b, n = 100)
a |
initial number |
b |
final number |
n |
number of elements (integer >= 2) |
vector of numbers from a
to b
with
n
linearly spaced apart
linspace(0,100, 20)
linspace(0,100, 20)
If you want to create a new formods module this function will create the template files for you.
new_module_template( SN = "NM", Module_Name = "New Module", package = "pkgname", element = "analysis", file_dir = tempdir() )
new_module_template( SN = "NM", Module_Name = "New Module", package = "pkgname", element = "analysis", file_dir = tempdir() )
SN |
Module short name |
Module_Name |
Module long name |
package |
Name of package that will contain the module |
element |
What you would call the thing the module provides for example the FG module provides "figures", the DW module provides "data views". |
file_dir |
Directory to save file |
list with the following elements:
mc: Module components.
server: Server.R file.
yaml: Yaml configureation file.
Each of these is a list with paths to the respective files:
source: Template source.
dest: Destination file name.
dest_full: Full path to the destination file name.
new_module_template()
new_module_template()
When some buttons are clicked they will change the state of the system, but other UI components will not detect that change correctly. So those triggers are put on hold. This will remove the hold after those UI components have updated.
remove_hold(state, session, inputId)
remove_hold(state, session, inputId)
state |
module state with all of the current ui elements populated |
session |
Shiny session variable |
inputId |
The input ID of the UI element that was put on hold |
No return value, called to remove holds.
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession(session=list()) session = sess_res$session input = sess_res$input # For this example we also need a state variable state = sess_res$state # This sets a hold on the specified inputID. This is normally done in # your XX_fetch_state() function. state = set_hold(state, inputId = "select_dw_views") # This will fetch the hold status of the specified inputID. fetch_hold(state, inputId = "select_dw_views") # This will remove the hold and is normally done in one of the UI outputs # with a priority set to ensure it happens after the rest of the UI has # refreshed. state = remove_hold(state, session, inputId = "select_dw_views")
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession(session=list()) session = sess_res$session input = sess_res$input # For this example we also need a state variable state = sess_res$state # This sets a hold on the specified inputID. This is normally done in # your XX_fetch_state() function. state = set_hold(state, inputId = "select_dw_views") # This will fetch the hold status of the specified inputID. fetch_hold(state, inputId = "select_dw_views") # This will remove the hold and is normally done in one of the UI outputs # with a priority set to ensure it happens after the rest of the UI has # refreshed. state = remove_hold(state, session, inputId = "select_dw_views")
Attempts to evaluate a string as a chunk of R code. If that succeeds it will return the result. If not it will return the original text.
render_str(estr = "")
render_str(estr = "")
estr |
String to render. |
String containing the evaled as a character or the original string
res = render_str(estr="ls()")
res = render_str(estr="ls()")
When some buttons are clicked they will change the state of the system, but other UI components will not detect that change correctly. So those triggers are put on hold. This will set the hold for a specified inputId or all ids if that value is set to NULL
set_hold(state, inputId = NULL)
set_hold(state, inputId = NULL)
state |
module state with all of the current ui elements populated |
inputId |
The input ID of the UI element that was put on hold or
|
state with hold or holds set
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession(session=list()) session = sess_res$session input = sess_res$input # For this example we also need a state variable state = sess_res$state # This sets a hold on the specified inputID. This is normally done in # your XX_fetch_state() function. state = set_hold(state, inputId = "select_dw_views") # This will fetch the hold status of the specified inputID. fetch_hold(state, inputId = "select_dw_views") # This will remove the hold and is normally done in one of the UI outputs # with a priority set to ensure it happens after the rest of the UI has # refreshed. state = remove_hold(state, session, inputId = "select_dw_views")
# Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = DW_test_mksession(session=list()) session = sess_res$session input = sess_res$input # For this example we also need a state variable state = sess_res$state # This sets a hold on the specified inputID. This is normally done in # your XX_fetch_state() function. state = set_hold(state, inputId = "select_dw_views") # This will fetch the hold status of the specified inputID. fetch_hold(state, inputId = "select_dw_views") # This will remove the hold and is normally done in one of the UI outputs # with a priority set to ensure it happens after the rest of the UI has # refreshed. state = remove_hold(state, session, inputId = "select_dw_views")
Attaches a dataset to the UD state supplied.
UD_attach_ds( state, clean = NULL, isgood = TRUE, load_msg = NULL, data_file_local = NULL, data_file_ext = NULL, data_file = NULL, sheet = NULL, sheets = NULL, code = "", object_name = NULL, contents = NULL )
UD_attach_ds( state, clean = NULL, isgood = TRUE, load_msg = NULL, data_file_local = NULL, data_file_ext = NULL, data_file = NULL, sheet = NULL, sheets = NULL, code = "", object_name = NULL, contents = NULL )
state |
UD state module. |
clean |
Boolean switch to determine if the headers in the loaded dataset was cleaned. |
isgood |
Boolean object indicating if the file was successfully loaded. |
load_msg |
Text message indicated the success or any problems encountered when uploading the file. |
data_file_local |
Full path to the data file on the server. |
data_file_ext |
File extension of the uploaded file. |
data_file |
Dataset file name without the path. |
sheet |
If the uploaded file is an excel file, this is the currently selected sheet. |
sheets |
If the uploaded file is an excel file, this is a character vector of the sheets present in that file. |
code |
Code to load dataset. |
object_name |
Name of the dataset object created when code is evaluated. |
contents |
Data frame containting the contents of the data file. |
state with data set attached
# We need a module state object to use this function: id="UD" sess_res = UD_test_mksession(session=list()) state = sess_res$state # This is the full path to a test data file: data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") # Excel file extension data_file_ext = "xlsx" # Base file name data_file = "TEST_DATA.xlsx" # Excel files need a sheet specification: sheet = "DATA" # We will also attach the sheets along with it sheets = readxl::excel_sheets(data_file_local) ds_read_res = UD_ds_read(state, data_file_ext = data_file_ext, data_file_local = data_file_local, data_file = data_file, sheets = sheets, sheet = sheet) # This would contain the loading code that will cascade down # to the other modules when generating snippets and # reproducible scripts code = ds_read_res$code # This is the R Object name that is used internally # and in generated scripts. Should be the same as in # the code above object_name = ds_read_res$object_name # This is the actual dataset: contents = ds_read_res$contents state = UD_attach_ds( state, data_file_local = data_file_local, data_file_ext = ".xlsx", data_file = data_file, sheet = sheet, sheets = sheets, code = code, object_name = object_name, contents = contents) state
# We need a module state object to use this function: id="UD" sess_res = UD_test_mksession(session=list()) state = sess_res$state # This is the full path to a test data file: data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") # Excel file extension data_file_ext = "xlsx" # Base file name data_file = "TEST_DATA.xlsx" # Excel files need a sheet specification: sheet = "DATA" # We will also attach the sheets along with it sheets = readxl::excel_sheets(data_file_local) ds_read_res = UD_ds_read(state, data_file_ext = data_file_ext, data_file_local = data_file_local, data_file = data_file, sheets = sheets, sheet = sheet) # This would contain the loading code that will cascade down # to the other modules when generating snippets and # reproducible scripts code = ds_read_res$code # This is the R Object name that is used internally # and in generated scripts. Should be the same as in # the code above object_name = ds_read_res$object_name # This is the actual dataset: contents = ds_read_res$contents state = UD_attach_ds( state, data_file_local = data_file_local, data_file_ext = ".xlsx", data_file = data_file, sheet = sheet, sheets = sheets, code = code, object_name = object_name, contents = contents) state
Generates the code for loading a dataset and returns both the code and the contents
UD_ds_read( state, data_file_ext = NULL, data_file_local = NULL, data_file = NULL, sheets = NULL, sheet = NULL )
UD_ds_read( state, data_file_ext = NULL, data_file_local = NULL, data_file = NULL, sheets = NULL, sheet = NULL )
state |
UD state from |
data_file_ext |
File extension of the uploaded file (e.g. "xlsx", "csv", etc). |
data_file_local |
Full path to the data file on the server. |
data_file |
Dataset file name without the path. |
sheets |
If the uploaded file is an excel file, this is a character vector of the sheets present in that file. |
sheet |
If the uploaded file is an excel file, this is the currently selected sheet. |
list with the elements of the dataset (contents, object_name, code, and isgood)
# We need a module state object to use this function: id="UD" sess_res = UD_test_mksession(session=list()) state = sess_res$state # This is the full path to a test data file: data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") # Excel file extension data_file_ext = "xlsx" # Base file name data_file = "TEST_DATA.xlsx" # Excel files need a sheet specification: sheet = "DATA" # We will also attach the sheets along with it sheets = readxl::excel_sheets(data_file_local) ds_read_res = UD_ds_read(state, data_file_ext = data_file_ext, data_file_local = data_file_local, data_file = data_file, sheets = sheets, sheet = sheet) ds_read_res
# We need a module state object to use this function: id="UD" sess_res = UD_test_mksession(session=list()) state = sess_res$state # This is the full path to a test data file: data_file_local = system.file(package="formods", "test_data", "TEST_DATA.xlsx") # Excel file extension data_file_ext = "xlsx" # Base file name data_file = "TEST_DATA.xlsx" # Excel files need a sheet specification: sheet = "DATA" # We will also attach the sheets along with it sheets = readxl::excel_sheets(data_file_local) ds_read_res = UD_ds_read(state, data_file_ext = data_file_ext, data_file_local = data_file_local, data_file = data_file, sheets = sheets, sheet = sheet) ds_read_res
Fetches the code to generate results seen in the app
UD_fetch_code(state)
UD_fetch_code(state)
state |
UD state from |
Character object vector with the lines of code
# This creates a session variable that will be available in Shiny state = UD_test_mksession(session=list())$state UD_fetch_code(state)
# This creates a session variable that will be available in Shiny state = UD_test_mksession(session=list())$state UD_fetch_code(state)
Fetches the datasets contained in the module.
UD_fetch_ds(state)
UD_fetch_ds(state)
state |
UD state from |
Character object vector with the lines of code
list containing the following elements
isgood: Return status of the function.
hasds: Boolean indicator if the module has any datasets
msgs: Messages to be passed back to the user.
ds: List with datasets. Each list element has the name of the R-object for that dataset. Each element has the following structure:
label: Text label for the dataset
MOD_TYPE: Short name for the type of module.
id: module ID
idx: unique numerical ID to identify this dataset in the module.
DS: Dataframe containing the actual dataset.
DSMETA: Metadata describing DS, see FM_fetch_ds()
for
details on the format.
code: Complete code to build dataset.
checksum: Module checksum.
DSchecksum: Dataset checksum.
# YAML configuration files from the package: FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml") # This is the module id: id = "UD" # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = UD_test_mksession(session=list()) session = sess_res$session input = sess_res$input state = UD_fetch_state( id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file ) ds_res = UD_fetch_ds(state)
# YAML configuration files from the package: FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml") # This is the module id: id = "UD" # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = UD_test_mksession(session=list()) session = sess_res$session input = sess_res$input state = UD_fetch_state( id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file ) ds_res = UD_fetch_ds(state)
Merges default app options with the changes made in the UI
UD_fetch_state(id, id_ASM, input, session, FM_yaml_file, MOD_yaml_file)
UD_fetch_state(id, id_ASM, input, session, FM_yaml_file, MOD_yaml_file)
id |
Shiny module ID |
id_ASM |
ID string for the app state management module used to save and load app states |
input |
Shiny input variable |
session |
Shiny session variable |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
list containing the current state of the app including default values from the yaml file as well as any changes made by the user. The list has the following structure:
yaml: Full contents of the supplied yaml file.
MC: Module components of the yaml file.
DS: Loaded dataset with the following elements
isgood: Boolean object indicating if the file was successfully loaded.
load_msg: Text message indicated the success or any problems encountered when uploading the file.
data_file_local: Full path to the data file on the server.
data_file: Dataset file name without the path.
data_file_ext: File extension of the uploaded file.
sheet: If the uploaded file is an excel file, this is the currently selected sheet.
sheets: If the uploaded file is an excel file, this is a character vector of the sheets present in that file.
contents: Data frame containting the contents of the data file.
checksum: This is an MD5 sum of the contents element and can be used to detect changes in the loaded file.
MOD_TYPE: Character data containing the type of module "UD"
id: Character data containing the module id module in the session variable.
FM_yaml_file: App configuration file with FM as main section.
MOD_yaml_file: Module configuration file with MC as main section.
# YAML configuration files from the package: FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml") # This is the module id: id = "UD" # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = UD_test_mksession(session=list()) session = sess_res$session input = sess_res$input state = UD_fetch_state( id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file )
# YAML configuration files from the package: FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml") MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml") # This is the module id: id = "UD" # Within shiny both session and input variables will exist, # this creates examples here for testing purposes: sess_res = UD_test_mksession(session=list()) session = sess_res$session input = sess_res$input state = UD_fetch_state( id = id, input = input, session = session, FM_yaml_file = FM_yaml_file, MOD_yaml_file = MOD_yaml_file )
Creates a list of the initialized module state
UD_init_state(FM_yaml_file, MOD_yaml_file, id, session)
UD_init_state(FM_yaml_file, MOD_yaml_file, id, session)
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
id |
ID string for the module. |
session |
Shiny session variable |
list containing an empty UD state
# Within shiny a session variable will exist, # this creates one here for testing purposes: sess_res = UD_test_mksession(session=list()) session = sess_res$session state = UD_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml"), id = "UD", session = session) state
# Within shiny a session variable will exist, # this creates one here for testing purposes: sess_res = UD_test_mksession(session=list()) session = sess_res$session state = UD_init_state( FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml"), id = "UD", session = session) state
Converts the current ASM state into a preload list.
UD_mk_preload(state)
UD_mk_preload(state)
state |
UD state object |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
yaml_list: Lists with preload components.
sess_res = UD_test_mksession() state = sess_res$state res = UD_mk_preload(state)
sess_res = UD_test_mksession() state = sess_res$state res = UD_mk_preload(state)
Populates the supplied session variable with information from list of sources.
UD_preload( session, src_list, yaml_res, mod_ID = NULL, react_state = list(), quickload = FALSE )
UD_preload( session, src_list, yaml_res, mod_ID = NULL, react_state = list(), quickload = FALSE )
session |
Shiny session variable (in app) or a list (outside of app) |
src_list |
List of preload data (all read together with module IDs at the top level) |
yaml_res |
List data from module yaml config |
mod_ID |
Module ID of the module being loaded. |
react_state |
Reactive shiny object (in app) or a list (outside of app) used to trigger reactions. |
quickload |
Logical |
list with the following elements
isgood: Boolean indicating the exit status of the function.
msgs: Messages to be passed back to the user.
session: Session object
input: The value of the shiny input at the end of the session initialization.
state: App state.
react_state: The react_state
components.
Server function for the Data Uplaod Shiny Module
UD_Server( id, id_ASM = "ASM", FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml"), deployed = FALSE, react_state = NULL )
UD_Server( id, id_ASM = "ASM", FM_yaml_file = system.file(package = "formods", "templates", "formods.yaml"), MOD_yaml_file = system.file(package = "formods", "templates", "UD.yaml"), deployed = FALSE, react_state = NULL )
id |
An ID string that corresponds with the ID used to call the modules UI elements |
id_ASM |
ID string for the app state management module used to save and load app states |
FM_yaml_file |
App configuration file with FM as main section. |
MOD_yaml_file |
Module configuration file with MC as main section. |
deployed |
Boolean variable indicating whether the app is deployed or not. |
react_state |
Variable passed to server to allow reaction outside of module ( |
UD Server object
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
if(interactive()){ # These are suggested packages library(shinydashboard) library(ggpubr) library(plotly) library(shinybusy) library(prompter) library(utils) library(clipr) library(formods) CSS <- " .wrapfig { float: right; shape-margin: 20px; margin-right: 20px; margin-bottom: 20px; } " # Default to not deployed if(!exists("deployed")){ deployed = FALSE } #https://fontawesome.com/icons?from=io data_url = "https://github.com/john-harrold/formods/raw/master/inst/test_data/TEST_DATA.xlsx" ui <- dashboardPage( skin="black", dashboardHeader(title="formods"), dashboardSidebar( sidebarMenu( menuItem("Source Data", tabName="upload", icon=icon("table")) , menuItem("Wrangle", tabName="wrangle", icon=icon("hat-cowboy")), menuItem("Plot", tabName="plot", icon=icon("chart-line")), menuItem("App State", tabName="app_state", icon=icon("archive")), menuItem("App Info", tabName="sysinfo", icon=icon("book-medical")) ) ), dashboardBody( tags$head( tags$style(HTML(CSS)) ), tabItems( tabItem(tabName="app_state", box(title="Manage App State", htmlOutput(NS("ASM", "ui_asm_compact")))), tabItem(tabName="upload", box(title="Load Data", width=12, fluidRow( prompter::use_prompt(), column(width=6, htmlOutput(NS("UD", "UD_ui_compact"))), column(width=6, tags$p( tags$img( class = "wrapfig", src = "https://github.com/john-harrold/formods/raw/master/man/figures/logo.png", width = 100, alt = "formods logo" ), 'Formods is a set of modules and an framework for developing modules which interact and create code to replicate analyses performed within an app. To experiment download this', tags$a("test dataset", href=data_url), 'and upload it into the App using the form on the left.')) ) ) ), tabItem(tabName="wrangle", box(title="Transform and Create Views of Your Data", width=12, htmlOutput(NS("DW", "DW_ui_compact")))), tabItem(tabName="plot", box(title="Visualize Data", width=12, htmlOutput(NS("FG", "FG_ui_compact")))), tabItem(tabName="sysinfo", box(title="System Details", width=12, shinydashboard::tabBox( width = 12, title = NULL, shiny::tabPanel(id="sys_modules", title=tagList(shiny::icon("ghost"), "Modules"), htmlOutput(NS("ASM", "ui_asm_sys_modules")) ), shiny::tabPanel(id="sys_packages", title=tagList(shiny::icon("ghost"), "Packages"), htmlOutput(NS("ASM", "ui_asm_sys_packages")) ), shiny::tabPanel(id="sys_log", title=tagList(shiny::icon("clipboard-list"), "App Log"), verbatimTextOutput(NS("ASM", "ui_asm_sys_log")) ), shiny::tabPanel(id="sys_options", title=tagList(shiny::icon("sliders"), "R Options"), htmlOutput(NS("ASM", "ui_asm_sys_options")) ) ) )) ) ) ) # Main app server server <- function(input, output, session) { # Empty reactive object to track and react to # changes in the module state outside of the module react_FM = reactiveValues() # This is the list of module ids used for reproducible script generation. The # order here is important. mod_ids = c("UD", "DW", "FG") #Populating with test data #FG_test_mksession(session) sources = c(system.file(package="formods", "preload", "ASM_preload.yaml"), system.file(package="formods", "preload", "UD_preload.yaml"), system.file(package="formods", "preload", "DW_preload.yaml"), system.file(package="formods", "preload", "FG_preload.yaml")) res = FM_app_preload(session=session, sources=sources) # Module servers formods::ASM_Server(id="ASM", deployed = deployed, react_state = react_FM, mod_ids = mod_ids) formods::UD_Server( id="UD", id_ASM = "ASM", deployed = deployed, react_state = react_FM) formods::DW_Server( id="DW", id_ASM = "ASM",id_UD = "UD", deployed = deployed, react_state = react_FM) formods::FG_Server( id="FG", id_ASM = "ASM",id_UD = "UD", id_DW = "DW", deployed = deployed, react_state = react_FM) } shinyApp(ui, server) }
Populates the supplied session variable for testing.
UD_test_mksession(session = list())
UD_test_mksession(session = list())
session |
Shiny session variable (in app) or a list (outside of app) |
The UD portion of the 'all_sess_res' returned from FM_app_preload
sess_res = UD_test_mksession()
sess_res = UD_test_mksession()
Takes an object that is a factor and returns an unfactored vector with the same type by the value removed
unfactor(fctobj)
unfactor(fctobj)
fctobj |
Factorized object |
Object with factors removed
df = data.frame( text = c("a", "b", "c"), float = c( 1 , 2 , 3 )) df$float = as.factor(df$float) # This is a factor df$float # This is not a factor unfactor(df$float)
df = data.frame( text = c("a", "b", "c"), float = c( 1 , 2 , 3 )) df$float = as.factor(df$float) # This is a factor df$float # This is not a factor unfactor(df$float)
If you are developing a package within a repository (i.e. git) and want to create a new formods module this function will create the template files for you and install them in the correct location.
use_formods( SN = "NM", Module_Name = "New Module", package = "pkgname", element = "analysis", overwrite = FALSE, repo_root = NULL )
use_formods( SN = "NM", Module_Name = "New Module", package = "pkgname", element = "analysis", overwrite = FALSE, repo_root = NULL )
SN |
Module short name |
Module_Name |
Module long name |
package |
Name of package that will contain the module |
element |
What you would call the thing the module provides for example the FG module provides "figures", the DW module provides "data views" |
overwrite |
Boolean to indicate if you should overwrite files |
repo_root |
Root of the repository. |
Same as the return value for new_module_template()
if(FALSE){ use_formods(repo_root=tempdir()) }
if(FALSE){ use_formods(repo_root=tempdir()) }