ui refinements

This commit is contained in:
Andreas Gammelgaard Damsbo 2024-12-19 11:34:25 +01:00
parent a2f3aa5481
commit aad2fb5760
No known key found for this signature in database
4 changed files with 413 additions and 283 deletions

View file

@ -158,6 +158,7 @@ cut.hms <- function(x, breaks, ...) {
cut.POSIXt <- function(x, breaks, right = FALSE, include.lowest = TRUE, start.on.monday=TRUE, ...) { cut.POSIXt <- function(x, breaks, right = FALSE, include.lowest = TRUE, start.on.monday=TRUE, ...) {
breaks_o <- breaks breaks_o <- breaks
# browser() # browser()
@ -178,6 +179,10 @@ cut.POSIXt <- function(x, breaks, right = FALSE, include.lowest = TRUE, start.on
days <- days[c(7,1:6)] days <- days[c(7,1:6)]
} }
out <- factor(weekdays(x),levels=days) |> forcats::fct_drop() out <- factor(weekdays(x),levels=days) |> forcats::fct_drop()
} else if (identical(breaks,"month_only")){
ms <- paste0("1970-",1:12,"-01") |> as.Date() |> months()
out <- factor(months(x),levels=ms) |> forcats::fct_drop()
} else { } else {
## Doesn't really work very well for breaks other than the special character cases as right border is excluded ## Doesn't really work very well for breaks other than the special character cases as right border is excluded
out <- base::cut.POSIXt(x, breaks=breaks,right=right,...) |> forcats::fct_drop() out <- base::cut.POSIXt(x, breaks=breaks,right=right,...) |> forcats::fct_drop()
@ -186,7 +191,7 @@ cut.POSIXt <- function(x, breaks, right = FALSE, include.lowest = TRUE, start.on
l <- levels(out) l <- levels(out)
if (is.numeric(breaks_o)) { if (is.numeric(breaks_o)) {
l <- breaks l <- breaks
} else if (is.character(breaks) && length(breaks) == 1 && !identical(breaks,"weekday")) { } else if (is.character(breaks) && length(breaks) == 1 && !(identical(breaks,"weekday") | identical(breaks,"month_only"))) {
if (include.lowest) { if (include.lowest) {
if (right) { if (right) {
l <- c(l, min(as.character(x))) l <- c(l, min(as.character(x)))
@ -220,6 +225,10 @@ cut.Date <- function(x,breaks,start.on.monday=TRUE,...){
days <- days[c(7,1:6)] days <- days[c(7,1:6)]
} }
out <- factor(weekdays(x),levels=days) |> forcats::fct_drop() out <- factor(weekdays(x),levels=days) |> forcats::fct_drop()
} else if (identical(breaks,"month_only")){
ms <- paste0("1970-",1:12,"-01") |> as.Date() |> months()
out <- factor(months(x),levels=ms) |> forcats::fct_drop()
} else { } else {
## Doesn't really work very well for breaks other than the special character cases as right border is excluded ## Doesn't really work very well for breaks other than the special character cases as right border is excluded
out <- base::cut.Date(x, breaks=breaks,...) |> forcats::fct_drop() out <- base::cut.Date(x, breaks=breaks,...) |> forcats::fct_drop()
@ -421,6 +430,7 @@ cut_variable_server <- function(id, data_r = reactive(NULL)) {
"weekday", "weekday",
"week", "week",
"month", "month",
"month_only",
"quarter", "quarter",
"year" "year"
) )
@ -447,7 +457,7 @@ cut_variable_server <- function(id, data_r = reactive(NULL)) {
inputId = session$ns("method"), inputId = session$ns("method"),
label = i18n("Method:"), label = i18n("Method:"),
choices = choices, choices = choices,
selected = "quantile", selected = NULL,
width = "100%" width = "100%"
) )
}) })
@ -490,6 +500,7 @@ cut_variable_server <- function(id, data_r = reactive(NULL)) {
"weekday", "weekday",
"week", "week",
"month", "month",
"month_only",
"quarter", "quarter",
"year" "year"
)) { )) {
@ -523,7 +534,7 @@ cut_variable_server <- function(id, data_r = reactive(NULL)) {
variable <- req(input$variable) variable <- req(input$variable)
data[[paste0(variable, "_cut")]] <- cut( data[[paste0(variable, "_cut")]] <- cut(
x = data[[variable]], x = data[[variable]],
breaks = if (input$method %in% c("day", "weekday", "week", "month", "quarter", "year", "hour")) input$method else breaks_r()$brks, breaks = if (input$method %in% c("day", "weekday", "week", "month", "month_only", "quarter", "year", "hour")) input$method else breaks_r()$brks,
include.lowest = input$include_lowest, include.lowest = input$include_lowest,
right = input$right right = input$right
) )
@ -663,6 +674,137 @@ plot_histogram <- function(data, column, bins = 30, breaks = NULL, color = "#112
} }
########
#### Current file: R//file-import-module.R
########
m_datafileUI <- function(id) {
ns <- shiny::NS(id)
shiny::tagList(
shiny::fileInput(
inputId = ns("file"),
label = "Upload a file",
multiple = FALSE,
accept = c(
".csv",
".xlsx",
".xls",
".dta",
".ods",
".rds"
)
),
shiny::h4("Parameter specifications"),
shiny::helpText(shiny::em("Select the desired variables and press 'Submit'")),
shiny::uiOutput(ns("include_vars")),
DT::DTOutput(ns("data_input")),
shiny::actionButton(ns("submit"), "Submit")
)
}
m_datafileServer <- function(id, output.format = "df") {
shiny::moduleServer(id, function(input, output, session, ...) {
ns <- shiny::NS(id)
ds <- shiny::reactive({
REDCapCAST::read_input(input$file$datapath) |> REDCapCAST::parse_data()
})
output$include_vars <- shiny::renderUI({
shiny::req(input$file)
shiny::selectizeInput(
inputId = ns("include_vars"),
selected = NULL,
label = "Covariables to include",
choices = colnames(ds()),
multiple = TRUE
)
})
base_vars <- shiny::reactive({
if (is.null(input$include_vars)) {
out <- colnames(ds())
} else {
out <- input$include_vars
}
out
})
output$data_input <-
DT::renderDT({
shiny::req(input$file)
ds()[base_vars()]
})
shiny::eventReactive(input$submit, {
# shiny::req(input$file)
data <- shiny::isolate({
ds()[base_vars()]
})
file_export(data,
output.format = output.format,
tools::file_path_sans_ext(input$file$name)
)
})
})
}
file_app <- function() {
ui <- shiny::fluidPage(
m_datafileUI("data"),
# DT::DTOutput(outputId = "redcap_prev")
toastui::datagridOutput2(outputId = "redcap_prev")
)
server <- function(input, output, session) {
m_datafileServer("data", output.format = "list")
}
shiny::shinyApp(ui, server)
}
file_app()
tdm_data_upload <- teal::teal_data_module(
ui <- function(id) {
shiny::fluidPage(
m_datafileUI(id)
)
},
server = function(id) {
m_datafileServer(id, output.format = "teal")
}
)
tdm_data_read <- teal::teal_data_module(
ui <- function(id) {
shiny::fluidPage(
m_redcap_readUI(id = "redcap")
)
},
server = function(id) {
moduleServer(
id,
function(input, output, session) {
ns <- session$ns
m_redcap_readServer(id = "redcap", output.format = "teal")
}
)
}
)
######## ########
#### Current file: R//helpers.R #### Current file: R//helpers.R
######## ########
@ -835,9 +977,6 @@ file_export <- function(data, output.format = c("df", "teal", "list"), filename,
} }
########
#### Current file: R//modules.R
########
@ -846,78 +985,19 @@ file_export <- function(data, output.format = c("df", "teal", "list"), filename,
m_datafileUI <- function(id) {
ns <- shiny::NS(id)
shiny::tagList( default_parsing <- function(data){
shiny::fileInput( data |>
inputId = ns("file"), REDCapCAST::parse_data() |>
label = "Upload a file", REDCapCAST::as_factor() |>
multiple = FALSE, REDCapCAST::numchar2fct()
accept = c(
".csv",
".xlsx",
".xls",
".dta",
".ods",
".rds"
)
),
shiny::h4("Parameter specifications"),
shiny::helpText(shiny::em("Select the desired variables and press 'Submit'")),
shiny::uiOutput(ns("include_vars")),
DT::DTOutput(ns("data_input")),
shiny::actionButton(ns("submit"), "Submit")
)
} }
m_datafileServer <- function(id, output.format = "df") {
shiny::moduleServer(id, function(input, output, session, ...) {
ns <- shiny::NS(id)
ds <- shiny::reactive({
REDCapCAST::read_input(input$file$datapath) |> REDCapCAST::parse_data()
})
output$include_vars <- shiny::renderUI({
shiny::req(input$file)
shiny::selectizeInput(
inputId = ns("include_vars"),
selected = NULL,
label = "Covariables to include",
choices = colnames(ds()),
multiple = TRUE
)
})
base_vars <- shiny::reactive({
if (is.null(input$include_vars)) {
out <- colnames(ds())
} else {
out <- input$include_vars
}
out
})
output$data_input <-
DT::renderDT({
shiny::req(input$file)
ds()[base_vars()]
})
shiny::eventReactive(input$submit, {
# shiny::req(input$file)
data <- shiny::isolate({
ds()[base_vars()]
})
file_export(data,
output.format = output.format,
tools::file_path_sans_ext(input$file$name)
)
})
})
}
########
#### Current file: R//redcap_read_shiny_module.R
########
@ -1187,7 +1267,11 @@ m_redcap_readServer <- function(id, output.format = c("df", "teal", "list")) {
) )
} }
tdm_redcap_read <- teal::teal_data_module( tdm_redcap_read <- teal::teal_data_module(
ui <- function(id) { ui <- function(id) {
shiny::fluidPage( shiny::fluidPage(
m_redcap_readUI(id) m_redcap_readUI(id)
@ -1198,16 +1282,13 @@ tdm_redcap_read <- teal::teal_data_module(
} }
) )
tdm_data_upload <- teal::teal_data_module(
ui <- function(id) {
shiny::fluidPage(
m_datafileUI(id)
)
},
server = function(id) {
m_datafileServer(id, output.format = "teal")
}
)
redcap_app <- function() { redcap_app <- function() {
@ -1284,43 +1365,6 @@ redcap_app <- function() {
} }
redcap_app()
file_app <- function() {
ui <- shiny::fluidPage(
m_datafileUI("data"),
# DT::DTOutput(outputId = "redcap_prev")
toastui::datagridOutput2(outputId = "redcap_prev")
)
server <- function(input, output, session) {
m_datafileServer("data", output.format = "list")
}
shiny::shinyApp(ui, server)
}
file_app()
tdm_data_read <- teal::teal_data_module(
ui <- function(id) {
shiny::fluidPage(
m_redcap_readUI(id = "redcap")
)
},
server = function(id) {
moduleServer(
id,
function(input, output, session) {
ns <- session$ns
m_redcap_readServer(id = "redcap", output.format = "teal")
}
)
}
)
######## ########
#### Current file: R//regression_model.R #### Current file: R//regression_model.R
######## ########
@ -1809,10 +1853,7 @@ shiny_webResearch <- function(data = NULL, ...) {
custom_theme <- function(...){ custom_theme <- function(...,
bslib::bs_theme(
...,
# preset = "united",
version = 5, version = 5,
primary = "#1E4A8F", primary = "#1E4A8F",
secondary = "#FF6F61", secondary = "#FF6F61",
@ -1829,7 +1870,16 @@ custom_theme <- function(...){
# heading_font = bslib::font_google("Noto Serif"), # heading_font = bslib::font_google("Noto Serif"),
# heading_font = bslib::font_google("Alice"), # heading_font = bslib::font_google("Alice"),
heading_font = bslib::font_google("Public Sans",wght = "700"), heading_font = bslib::font_google("Public Sans",wght = "700"),
code_font = bslib::font_google("Open Sans") code_font = bslib::font_google("Open Sans")){
bslib::bs_theme(
...,
version = version,
primary = primary,
secondary = secondary,
bootswatch = bootswatch,
base_font = base_font,
heading_font = heading_font,
code_font = code_font
) )
} }
@ -1866,7 +1916,7 @@ ui_elements <- list(
choices = c( choices = c(
"File upload" = "file", "File upload" = "file",
"REDCap server" = "redcap", "REDCap server" = "redcap",
"Sample data" = "env" "Local data" = "env"
), ),
# checkIcon = list( # checkIcon = list(
# yes = icon("square-check"), # yes = icon("square-check"),
@ -1903,7 +1953,14 @@ ui_elements <- list(
DT::DTOutput(outputId = "redcap_prev") DT::DTOutput(outputId = "redcap_prev")
), ),
shiny::br(), shiny::br(),
shiny::actionButton(inputId = "act_start", label = "Start") shiny::actionButton(
inputId = "act_start",
label = "Start",
width = "100%",
icon = shiny::icon("play")
),
shiny::br(),
shiny::br()
), ),
############################################################################## ##############################################################################
######### #########
@ -2135,16 +2192,30 @@ dark <- custom_theme(
# Fonts to consider: # Fonts to consider:
# https://webdesignerdepot.com/17-open-source-fonts-youll-actually-love/ # https://webdesignerdepot.com/17-open-source-fonts-youll-actually-love/
ui <- bslib::page( ui <- bslib::page_fluid(
title = "freesearcheR", title = "freesearcheR",
theme = light, theme = light,
shiny::useBusyIndicators(), shiny::useBusyIndicators(),
bslib::page_navbar( bslib::page_navbar(
id = "main_panel", id = "main_panel",
# header = shiny::tags$header(shiny::p("Data is only stored temporarily for analysis and deleted immediately afterwards.")),
ui_elements$import, ui_elements$import,
ui_elements$overview, ui_elements$overview,
ui_elements$analyze, ui_elements$analyze,
ui_elements$docs ui_elements$docs,
# bslib::nav_spacer(),
# bslib::nav_item(shinyWidgets::materialSwitch(inputId = "mode", label = icon("moon"), right=TRUE,status = "success")),
fillable = TRUE,
footer = shiny::tags$footer(
style = "background-color: #14131326; padding: 4px; text-align: center; bottom: 0; width: 100%;",
shiny::p(
style = "margin: 1",
"Data is only stored for analyses and deleted immediately afterwards."),
shiny::p(
style = "margin: 1; color: #888;",
"Andreas G Damsbo | AGPLv3 license | ", shiny::tags$a("Source on Github", href = "https://github.com/agdamsbo/webResearch/")
),
)
) )
) )
@ -2194,8 +2265,7 @@ library(DT)
# light <- custom_theme() # light <- custom_theme()
# #
# dark <- custom_theme(bg = "#000", # dark <- custom_theme(bg = "#000",fg="#fff")
# fg="#fff")
@ -2204,15 +2274,35 @@ server <- function(input, output, session) {
## everything else. ## everything else.
files.to.keep <- list.files("www/") files.to.keep <- list.files("www/")
output$docs_file <- renderUI({
# shiny::includeHTML("www/docs.html")
HTML(readLines("www/docs.html"))
})
##############################################################################
#########
######### Night mode (just very popular, not really needed)
#########
##############################################################################
# observeEvent(input$dark_mode,{ # observeEvent(input$dark_mode,{
# session$setCurrentTheme( # session$setCurrentTheme(
# if (isTRUE(input$dark_mode)) dark else light # if (isTRUE(input$dark_mode)) dark else light
# )}) # )})
output$docs_file <- renderUI({ # observe({
# shiny::includeHTML("www/docs.html") # if(input$dark_mode==TRUE)
HTML(readLines("www/docs.html")) # session$setCurrentTheme(bs_theme_update(theme = custom_theme(version = 5)))
}) # if(input$dark_mode==FALSE)
# session$setCurrentTheme(bs_theme_update(theme = custom_theme(version = 5, bg = "#000",fg="#fff")))
# })
##############################################################################
#########
######### Setting reactive values
#########
##############################################################################
rv <- shiny::reactiveValues( rv <- shiny::reactiveValues(
list = list(), list = list(),
@ -2282,32 +2372,32 @@ server <- function(input, output, session) {
rv$data_original <- from_env$data() rv$data_original <- from_env$data()
}) })
ds <- shiny::reactive({ # ds <-
# input$file1 will be NULL initially. After the user selects # shiny::reactive({
# and uploads a file, head of that data file by default, # # input$file1 will be NULL initially. After the user selects
# or all rows if selected, will be shown. # # and uploads a file, head of that data file by default,
# if (v$input) { # # or all rows if selected, will be shown.
# out <- webResearch_data # # if (v$input) {
# } else if (input$source == "file") { # # out <- webResearch_data
# req(data_file$data()) # # } else if (input$source == "file") {
# out <- data_file$data() # # req(data_file$data())
# } else if (input$source == "redcap") { # # out <- data_file$data()
# req(purrr::pluck(data_redcap(), "data")()) # # } else if (input$source == "redcap") {
# out <- purrr::pluck(data_redcap(), "data")() # # req(purrr::pluck(data_redcap(), "data")())
# } # # out <- purrr::pluck(data_redcap(), "data")()
# # }
req(rv$data_original) #
rv$data_original <- rv$data_original |> # req(rv$data_original)
REDCapCAST::parse_data() |> #
REDCapCAST::as_factor() |> # rv$ds <- "loaded"
REDCapCAST::numchar2fct() #
# rv$data <- rv$data_original
rv$ds <- "loaded" #
#
rv$data <- rv$data_original # # rv$data <- rv$data_original
#
rv$data_original # # rv$data_original
}) # })
############################################################################## ##############################################################################
######### #########
@ -2317,8 +2407,8 @@ server <- function(input, output, session) {
######### Modifications ######### Modifications
shiny::observeEvent(rv$data_original, rv$data <- rv$data_original) shiny::observeEvent(rv$data_original, rv$data <- rv$data_original |> default_parsing())
shiny::observeEvent(input$data_reset, rv$data <- rv$data_original) shiny::observeEvent(input$data_reset, rv$data <- rv$data_original |> default_parsing())
## Using modified version of the datamods::cut_variable_server function ## Using modified version of the datamods::cut_variable_server function
## Further modifications are needed to have cut/bin options based on class of variable ## Further modifications are needed to have cut/bin options based on class of variable
@ -2635,7 +2725,7 @@ server <- function(input, output, session) {
showNotification(paste0(warn), type = "warning") showNotification(paste0(warn), type = "warning")
}, },
error = function(err) { error = function(err) {
showNotification(paste0("There was the following error. Inspect your data and adjust settings. Error: ",err), type = "err") showNotification(paste0("There was the following error. Inspect your data and adjust settings. Error: ", err), type = "err")
} }
) )
rv$ready <- "ready" rv$ready <- "ready"

View file

@ -39,8 +39,7 @@ library(DT)
# light <- custom_theme() # light <- custom_theme()
# #
# dark <- custom_theme(bg = "#000", # dark <- custom_theme(bg = "#000",fg="#fff")
# fg="#fff")
@ -49,15 +48,35 @@ server <- function(input, output, session) {
## everything else. ## everything else.
files.to.keep <- list.files("www/") files.to.keep <- list.files("www/")
output$docs_file <- renderUI({
# shiny::includeHTML("www/docs.html")
HTML(readLines("www/docs.html"))
})
##############################################################################
#########
######### Night mode (just very popular, not really needed)
#########
##############################################################################
# observeEvent(input$dark_mode,{ # observeEvent(input$dark_mode,{
# session$setCurrentTheme( # session$setCurrentTheme(
# if (isTRUE(input$dark_mode)) dark else light # if (isTRUE(input$dark_mode)) dark else light
# )}) # )})
output$docs_file <- renderUI({ # observe({
# shiny::includeHTML("www/docs.html") # if(input$dark_mode==TRUE)
HTML(readLines("www/docs.html")) # session$setCurrentTheme(bs_theme_update(theme = custom_theme(version = 5)))
}) # if(input$dark_mode==FALSE)
# session$setCurrentTheme(bs_theme_update(theme = custom_theme(version = 5, bg = "#000",fg="#fff")))
# })
##############################################################################
#########
######### Setting reactive values
#########
##############################################################################
rv <- shiny::reactiveValues( rv <- shiny::reactiveValues(
list = list(), list = list(),
@ -127,32 +146,32 @@ server <- function(input, output, session) {
rv$data_original <- from_env$data() rv$data_original <- from_env$data()
}) })
ds <- shiny::reactive({ # ds <-
# input$file1 will be NULL initially. After the user selects # shiny::reactive({
# and uploads a file, head of that data file by default, # # input$file1 will be NULL initially. After the user selects
# or all rows if selected, will be shown. # # and uploads a file, head of that data file by default,
# if (v$input) { # # or all rows if selected, will be shown.
# out <- webResearch_data # # if (v$input) {
# } else if (input$source == "file") { # # out <- webResearch_data
# req(data_file$data()) # # } else if (input$source == "file") {
# out <- data_file$data() # # req(data_file$data())
# } else if (input$source == "redcap") { # # out <- data_file$data()
# req(purrr::pluck(data_redcap(), "data")()) # # } else if (input$source == "redcap") {
# out <- purrr::pluck(data_redcap(), "data")() # # req(purrr::pluck(data_redcap(), "data")())
# } # # out <- purrr::pluck(data_redcap(), "data")()
# # }
req(rv$data_original) #
rv$data_original <- rv$data_original |> # req(rv$data_original)
REDCapCAST::parse_data() |> #
REDCapCAST::as_factor() |> # rv$ds <- "loaded"
REDCapCAST::numchar2fct() #
# rv$data <- rv$data_original
rv$ds <- "loaded" #
#
rv$data <- rv$data_original # # rv$data <- rv$data_original
#
rv$data_original # # rv$data_original
}) # })
############################################################################## ##############################################################################
######### #########
@ -162,8 +181,8 @@ server <- function(input, output, session) {
######### Modifications ######### Modifications
shiny::observeEvent(rv$data_original, rv$data <- rv$data_original) shiny::observeEvent(rv$data_original, rv$data <- rv$data_original |> default_parsing())
shiny::observeEvent(input$data_reset, rv$data <- rv$data_original) shiny::observeEvent(input$data_reset, rv$data <- rv$data_original |> default_parsing())
## Using modified version of the datamods::cut_variable_server function ## Using modified version of the datamods::cut_variable_server function
## Further modifications are needed to have cut/bin options based on class of variable ## Further modifications are needed to have cut/bin options based on class of variable
@ -480,7 +499,7 @@ server <- function(input, output, session) {
showNotification(paste0(warn), type = "warning") showNotification(paste0(warn), type = "warning")
}, },
error = function(err) { error = function(err) {
showNotification(paste0("There was the following error. Inspect your data and adjust settings. Error: ",err), type = "err") showNotification(paste0("There was the following error. Inspect your data and adjust settings. Error: ", err), type = "err")
} }
) )
rv$ready <- "ready" rv$ready <- "ready"

View file

@ -26,7 +26,7 @@ ui_elements <- list(
choices = c( choices = c(
"File upload" = "file", "File upload" = "file",
"REDCap server" = "redcap", "REDCap server" = "redcap",
"Sample data" = "env" "Local data" = "env"
), ),
# checkIcon = list( # checkIcon = list(
# yes = icon("square-check"), # yes = icon("square-check"),
@ -63,7 +63,14 @@ ui_elements <- list(
DT::DTOutput(outputId = "redcap_prev") DT::DTOutput(outputId = "redcap_prev")
), ),
shiny::br(), shiny::br(),
shiny::actionButton(inputId = "act_start", label = "Start") shiny::actionButton(
inputId = "act_start",
label = "Start",
width = "100%",
icon = shiny::icon("play")
),
shiny::br(),
shiny::br()
), ),
############################################################################## ##############################################################################
######### #########
@ -295,15 +302,29 @@ dark <- custom_theme(
# Fonts to consider: # Fonts to consider:
# https://webdesignerdepot.com/17-open-source-fonts-youll-actually-love/ # https://webdesignerdepot.com/17-open-source-fonts-youll-actually-love/
ui <- bslib::page( ui <- bslib::page_fluid(
title = "freesearcheR", title = "freesearcheR",
theme = light, theme = light,
shiny::useBusyIndicators(), shiny::useBusyIndicators(),
bslib::page_navbar( bslib::page_navbar(
id = "main_panel", id = "main_panel",
# header = shiny::tags$header(shiny::p("Data is only stored temporarily for analysis and deleted immediately afterwards.")),
ui_elements$import, ui_elements$import,
ui_elements$overview, ui_elements$overview,
ui_elements$analyze, ui_elements$analyze,
ui_elements$docs ui_elements$docs,
# bslib::nav_spacer(),
# bslib::nav_item(shinyWidgets::materialSwitch(inputId = "mode", label = icon("moon"), right=TRUE,status = "success")),
fillable = TRUE,
footer = shiny::tags$footer(
style = "background-color: #14131326; padding: 4px; text-align: center; bottom: 0; width: 100%;",
shiny::p(
style = "margin: 1",
"Data is only stored for analyses and deleted immediately afterwards."),
shiny::p(
style = "margin: 1; color: #888;",
"Andreas G Damsbo | AGPLv3 license | ", shiny::tags$a("Source on Github", href = "https://github.com/agdamsbo/webResearch/")
),
)
) )
) )

View file

@ -1,16 +1,16 @@
# Welcome # Welcome
This is the ***freesearchR*** web data analysis tool. The ***freesearchR*** is an opinioated tool for easy data evaluation and analysis at the hands of the clinician. We intend it to be a powerful to, that is easy and secure to use. This is the ***freesearchR*** web data analysis tool. We intend the ***freesearchR*** to be a powerful and free tool for easy data evaluation and analysis at the hands of the clinician.
By intention, this tool has been designed to be simple to use with a minimum of mandatory options to keep the workflow streamlined, while also including a few options to go even further. By intention, this tool has been designed to be simple to use with a minimum of mandatory options to keep the workflow streamlined, while also including a few options to go even further.
There are four simple steps to go through: There are four simple steps to go through:
1. Import data (this can be a spreadsheet on your machine or direct export from a REDCap server) 1. Import data (a spreadsheet/file on your machine, direct export from a REDCap server, or a local file provided with a package)
2. A *optional* step of data modification (change variable classes and creating categorical variables (factors) from numeric or time data) 2. An *optional* step of data modification (change variable classes and creating categorical variables (factors) from numeric or time data)
3. Data analysis of cross-sectionally designed studies 3. Data analysis of cross-sectionally designed studies (more study designs are planned to be included)
- Classic baseline charactieristics (options to stratify and compare variables) - Classic baseline charactieristics (options to stratify and compare variables)
@ -18,4 +18,4 @@ There are four simple steps to go through:
- Evaluation of model assumptions - Evaluation of model assumptions
4. Export the the analyses results as .docx or .odt. 4. Export the the analyses results as for MS Word or [LibreOffice](https://www.libreoffice.org/).