mirror of
https://github.com/agdamsbo/FreesearchR.git
synced 2026-06-19 04:27:30 +02:00
This commit is contained in:
parent
b3434d9dfb
commit
347490605f
20 changed files with 573 additions and 538 deletions
|
|
@ -1 +1 @@
|
|||
app_version <- function()'Version: 25.4.1.250408_1343'
|
||||
app_version <- function()'Version: 25.4.1.250409_1216'
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ data_summary_ui <- function(id) {
|
|||
#' @param data data
|
||||
#' @param color.main main color
|
||||
#' @param color.sec secondary color
|
||||
#' @param ... arguments passed to toastui::datagrid
|
||||
#' @param ... arguments passed to create_overview_datagrid
|
||||
#'
|
||||
#' @name data-summary
|
||||
#' @returns shiny server module
|
||||
|
|
@ -37,7 +37,7 @@ data_summary_server <- function(id,
|
|||
shiny::req(data())
|
||||
data() |>
|
||||
overview_vars() |>
|
||||
create_overview_datagrid() |>
|
||||
create_overview_datagrid(...) |>
|
||||
add_sparkline(
|
||||
column = "vals",
|
||||
color.main = color.main,
|
||||
|
|
@ -176,7 +176,7 @@ overview_vars <- function(data) {
|
|||
#' mtcars |>
|
||||
#' overview_vars() |>
|
||||
#' create_overview_datagrid()
|
||||
create_overview_datagrid <- function(data) {
|
||||
create_overview_datagrid <- function(data,...) {
|
||||
# browser()
|
||||
gridTheme <- getOption("datagrid.theme")
|
||||
if (length(gridTheme) < 1) {
|
||||
|
|
@ -207,7 +207,8 @@ create_overview_datagrid <- function(data) {
|
|||
grid <- toastui::datagrid(
|
||||
data = data,
|
||||
theme = "default",
|
||||
colwidths = "fit"
|
||||
colwidths = "fit",
|
||||
...
|
||||
)
|
||||
|
||||
grid <- toastui::grid_columns(
|
||||
|
|
|
|||
|
|
@ -86,7 +86,10 @@ data_visuals_ui <- function(id, tab_title = "Plots", ...) {
|
|||
),
|
||||
bslib::nav_panel(
|
||||
title = tab_title,
|
||||
shiny::plotOutput(ns("plot"))
|
||||
shiny::plotOutput(ns("plot"),height = "70vh"),
|
||||
shiny::tags$br(),
|
||||
shiny::h4("Plot code:"),
|
||||
shiny::verbatimTextOutput(outputId = ns("code_plot"))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
@ -109,7 +112,8 @@ data_visuals_server <- function(id,
|
|||
|
||||
rv <- shiny::reactiveValues(
|
||||
plot.params = NULL,
|
||||
plot = NULL
|
||||
plot = NULL,
|
||||
code=NULL
|
||||
)
|
||||
|
||||
# ## --- New attempt
|
||||
|
|
@ -302,15 +306,26 @@ data_visuals_server <- function(id,
|
|||
{
|
||||
tryCatch(
|
||||
{
|
||||
shiny::withProgress(message = "Drawing the plot. Hold tight for a moment..", {
|
||||
rv$plot <- create_plot(
|
||||
data = data(),
|
||||
parameters <- list(
|
||||
type = rv$plot.params()[["fun"]],
|
||||
x = input$primary,
|
||||
y = input$secondary,
|
||||
z = input$tertiary
|
||||
)
|
||||
|
||||
shiny::withProgress(message = "Drawing the plot. Hold tight for a moment..", {
|
||||
rv$plot <- rlang::exec(create_plot, !!!append_list(data(),parameters,"data"))
|
||||
# rv$plot <- create_plot(
|
||||
# data = data(),
|
||||
# type = rv$plot.params()[["fun"]],
|
||||
# x = input$primary,
|
||||
# y = input$secondary,
|
||||
# z = input$tertiary
|
||||
# )
|
||||
})
|
||||
|
||||
rv$code <- glue::glue("FreesearchR::create_plot(data,{list2str(parameters)})")
|
||||
|
||||
},
|
||||
# warning = function(warn) {
|
||||
# showNotification(paste0(warn), type = "warning")
|
||||
|
|
@ -323,6 +338,10 @@ data_visuals_server <- function(id,
|
|||
ignoreInit = TRUE
|
||||
)
|
||||
|
||||
output$code_plot <- shiny::renderPrint({
|
||||
cat(rv$code)
|
||||
})
|
||||
|
||||
output$plot <- shiny::renderPlot({
|
||||
shiny::req(rv$plot)
|
||||
rv$plot
|
||||
|
|
|
|||
38
R/helpers.R
38
R/helpers.R
|
|
@ -393,3 +393,41 @@ if_not_missing <- function(data,default=NULL){
|
|||
return(data)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#' Merge list of expressions
|
||||
#'
|
||||
#' @param data list
|
||||
#'
|
||||
#' @returns expression
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' list(
|
||||
#' rlang::call2(.fn = "select",!!!list(c("cyl","disp")),.ns = "dplyr"),
|
||||
#' rlang::call2(.fn = "default_parsing",.ns = "FreesearchR")
|
||||
#' ) |> merge_expression()
|
||||
merge_expression <- function(data){
|
||||
Reduce(
|
||||
f = function(x, y) rlang::expr(!!x %>% !!y),
|
||||
x = data
|
||||
)
|
||||
}
|
||||
|
||||
#' Deparses expression as string, substitutes native pipe and adds assign
|
||||
#'
|
||||
#' @param data expression
|
||||
#'
|
||||
#' @returns string
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' list(
|
||||
#' rlang::call2(.fn = "select",!!!list(c("cyl","disp")),.ns = "dplyr"),
|
||||
#' rlang::call2(.fn = "default_parsing",.ns = "FreesearchR")
|
||||
#' ) |> merge_expression() |> expression_string()
|
||||
expression_string <- function(data,assign.str="data <- "){
|
||||
out <- paste0(assign.str, gsub("%>%","|>\n",paste(gsub('"',"'",deparse(data)),collapse = "")))
|
||||
gsub(" ","",out)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ m_redcap_readUI <- function(id, title = TRUE, url = NULL) {
|
|||
# width = 6,
|
||||
shiny::tags$h4("Data import parameters"),
|
||||
shiny::helpText("Options here will show, when API and uri are typed"),
|
||||
shiny::tags$br(),
|
||||
shiny::uiOutput(outputId = ns("fields")),
|
||||
shiny::tags$div(
|
||||
class = "shiny-input-container",
|
||||
|
|
@ -91,6 +92,7 @@ m_redcap_readUI <- function(id, title = TRUE, url = NULL) {
|
|||
),
|
||||
shiny::helpText("Optionally filter project arms if logitudinal or apply server side data filters")
|
||||
),
|
||||
shiny::tags$br(),
|
||||
shiny::uiOutput(outputId = ns("data_type")),
|
||||
shiny::uiOutput(outputId = ns("fill")),
|
||||
shiny::actionButton(
|
||||
|
|
|
|||
|
|
@ -285,24 +285,22 @@ regression_server <- function(id,
|
|||
## imputed or
|
||||
## minimally adjusted
|
||||
model_lists <- list(
|
||||
"Univariable" = regression_model_uv_list,
|
||||
"Multivariable" = regression_model_list
|
||||
"Univariable" = "regression_model_uv_list",
|
||||
"Multivariable" = "regression_model_list"
|
||||
) |>
|
||||
lapply(\(.fun){
|
||||
ls <- do.call(
|
||||
parameters=list(
|
||||
data = data_r()[regression_vars()],
|
||||
outcome.str = input$outcome_var,
|
||||
fun.descr = input$regression_type
|
||||
)
|
||||
|
||||
do.call(
|
||||
.fun,
|
||||
c(
|
||||
list(data = data_r() |>
|
||||
(\(.x){
|
||||
.x[regression_vars()]
|
||||
})()),
|
||||
list(outcome.str = input$outcome_var),
|
||||
list(fun.descr = input$regression_type)
|
||||
)
|
||||
parameters
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
rv$list$regression$params <- get_fun_options(input$regression_type) |>
|
||||
(\(.x){
|
||||
.x[[1]]
|
||||
|
|
@ -415,7 +413,7 @@ regression_server <- function(id,
|
|||
alt = "Assumptions testing of the multivariable regression model"
|
||||
)
|
||||
|
||||
|
||||
### Creating the regression table
|
||||
shiny::observeEvent(
|
||||
input$load,
|
||||
{
|
||||
|
|
@ -425,20 +423,44 @@ regression_server <- function(id,
|
|||
|
||||
tryCatch(
|
||||
{
|
||||
parameters <- list(
|
||||
add_p = input$add_regression_p == "no"
|
||||
)
|
||||
|
||||
out <- lapply(rv$list$regression$models, \(.x){
|
||||
.x$model
|
||||
}) |>
|
||||
purrr::map(regression_table)
|
||||
purrr::map(\(.x){
|
||||
do.call(
|
||||
regression_table,
|
||||
append_list(.x,parameters,"x")
|
||||
)
|
||||
})
|
||||
|
||||
if (input$add_regression_p == "no") {
|
||||
out <- out |>
|
||||
lapply(\(.x){
|
||||
.x |>
|
||||
gtsummary::modify_column_hide(
|
||||
column = "p.value"
|
||||
)
|
||||
})
|
||||
}
|
||||
# if (input$add_regression_p == "no") {
|
||||
# out <- out |>
|
||||
# lapply(\(.x){
|
||||
# .x |>
|
||||
# gtsummary::modify_column_hide(
|
||||
# column = "p.value"
|
||||
# )
|
||||
# })
|
||||
# }
|
||||
|
||||
rv$list$regression$models |>
|
||||
purrr::imap(\(.x,.i){
|
||||
rv$list$regression$models[[.i]][["code_table"]] <- paste(
|
||||
.x$code,
|
||||
expression_string(rlang::call2(.fn = "regression_table",!!!parameters,.ns = "FreesearchR"),assign.str=NULL),sep="|>\n")
|
||||
})
|
||||
|
||||
list(
|
||||
rv$code$import,
|
||||
rlang::call2(.fn = "select",!!!list(input$import_var),.ns = "dplyr"),
|
||||
rlang::call2(.fn = "default_parsing",.ns = "FreesearchR")
|
||||
) |>
|
||||
merge_expression() |>
|
||||
expression_string()
|
||||
|
||||
rv$list$regression$tables <- out
|
||||
|
||||
|
|
@ -550,16 +572,7 @@ regression_server <- function(id,
|
|||
##############################################################################
|
||||
|
||||
return(shiny::reactive({
|
||||
data <- rv$list
|
||||
# code <- list()
|
||||
#
|
||||
# if (length(code) > 0) {
|
||||
# attr(data, "code") <- Reduce(
|
||||
# f = function(x, y) rlang::expr(!!x %>% !!y),
|
||||
# x = code
|
||||
# )
|
||||
# }
|
||||
return(data)
|
||||
return(rv$list)
|
||||
}))
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ regression_model <- function(data,
|
|||
|
||||
if (is.null(fun)) auto.mode <- TRUE
|
||||
|
||||
if (auto.mode) {
|
||||
if (isTRUE(auto.mode)) {
|
||||
if (is.numeric(data[[outcome.str]])) {
|
||||
fun <- "stats::lm"
|
||||
} else if (is.factor(data[[outcome.str]])) {
|
||||
|
|
@ -318,7 +318,7 @@ supported_functions <- function() {
|
|||
design = "cross-sectional",
|
||||
out.type = "dichotomous",
|
||||
fun = "stats::glm",
|
||||
args.list = list(family = stats::binomial(link = "logit")),
|
||||
args.list = list(family = "binomial"),
|
||||
formula.str = "{outcome.str}~{paste(vars,collapse='+')}",
|
||||
table.fun = "gtsummary::tbl_regression",
|
||||
table.args.list = list()
|
||||
|
|
@ -326,7 +326,7 @@ supported_functions <- function() {
|
|||
polr = list(
|
||||
descr = "Ordinal logistic regression model",
|
||||
design = "cross-sectional",
|
||||
out.type = c("ordinal","categorical"),
|
||||
out.type = c("ordinal", "categorical"),
|
||||
fun = "MASS::polr",
|
||||
args.list = list(
|
||||
Hess = TRUE,
|
||||
|
|
@ -449,6 +449,7 @@ get_fun_options <- function(data) {
|
|||
#' )
|
||||
#' ls <- regression_model_list(data = default_parsing(mtcars), outcome.str = "cyl", fun.descr = "Ordinal logistic regression model")
|
||||
#' summary(ls$model)
|
||||
#' ls <- regression_model_list(data = default_parsing(mtcars), outcome.str = "mpg", fun.descr = "Linear regression model")
|
||||
#'
|
||||
#' ls <- regression_model_list(data = default_parsing(gtsummary::trial), outcome.str = "trt", fun.descr = "Logistic regression model")
|
||||
#' tbl <- gtsummary::tbl_regression(ls$model, exponentiate = TRUE)
|
||||
|
|
@ -458,7 +459,7 @@ get_fun_options <- function(data) {
|
|||
#' outcome.str = "trt",
|
||||
#' fun = "stats::glm",
|
||||
#' formula.str = "{outcome.str}~.",
|
||||
#' args.list = list(family = stats::binomial(link = "logit"))
|
||||
#' args.list = list(family = "binomial")
|
||||
#' )
|
||||
#' tbl2 <- gtsummary::tbl_regression(m, exponentiate = TRUE)
|
||||
#' broom::tidy(ls$model)
|
||||
|
|
@ -509,20 +510,27 @@ regression_model_list <- function(data,
|
|||
}
|
||||
}
|
||||
|
||||
parameters <- list(
|
||||
outcome.str = outcome.str,
|
||||
fun = fun.c,
|
||||
formula.str = formula.str.c,
|
||||
args.list = args.list.c
|
||||
)
|
||||
|
||||
model <- do.call(
|
||||
regression_model,
|
||||
list(
|
||||
data = data,
|
||||
outcome.str = outcome.str,
|
||||
fun = fun.c,
|
||||
formula.str = formula.str.c,
|
||||
args.list = args.list.c
|
||||
append_list(parameters,
|
||||
data = data, "data"
|
||||
)
|
||||
)
|
||||
|
||||
code <- glue::glue(
|
||||
"{fun.c}({paste(Filter(length,list(glue::glue(formula.str.c),'data = data',list2str(args.list.c))),collapse=', ')})"
|
||||
)
|
||||
parameters_print <- list2str(Filter(length,
|
||||
modifyList(parameters, list(
|
||||
formula.str = glue::glue(formula.str.c),
|
||||
args.list = NULL
|
||||
))))
|
||||
|
||||
code <- glue::glue("FreesearchR::regression_model(data,{parameters_print}, args.list=list({list2str(args.list.c)}))",.null = "NULL")
|
||||
|
||||
list(
|
||||
options = options,
|
||||
|
|
@ -566,6 +574,7 @@ list2str <- function(data) {
|
|||
#' lapply(broom::tidy) |>
|
||||
#' dplyr::bind_rows()
|
||||
#' ms <- regression_model_uv_list(data = default_parsing(mtcars), outcome.str = "mpg", fun.descr = "Linear regression model")
|
||||
#' ms$code
|
||||
#' lapply(ms$model, broom::tidy) |> dplyr::bind_rows()
|
||||
#' }
|
||||
regression_model_uv_list <- function(data,
|
||||
|
|
@ -628,28 +637,43 @@ regression_model_uv_list <- function(data,
|
|||
# )
|
||||
# )
|
||||
|
||||
model <- vars |>
|
||||
lapply(\(.var){
|
||||
do.call(
|
||||
regression_model,
|
||||
list(
|
||||
data = data[c(outcome.str, .var)],
|
||||
outcome.str = outcome.str,
|
||||
fun = fun.c,
|
||||
formula.str = formula.str.c,
|
||||
args.list = args.list.c
|
||||
)
|
||||
)
|
||||
})
|
||||
|
||||
|
||||
vars <- "."
|
||||
|
||||
code_raw <- glue::glue(
|
||||
"{fun.c}({paste(Filter(length,list(glue::glue(formula.str.c),'data = .d',list2str(args.list.c))),collapse=', ')})"
|
||||
parameters <- list(
|
||||
outcome.str = outcome.str,
|
||||
fun = fun.c,
|
||||
formula.str = formula.str.c,
|
||||
args.list = args.list.c
|
||||
)
|
||||
|
||||
code <- glue::glue("lapply(data,function(.d){code_raw})")
|
||||
model <- vars |>
|
||||
lapply(\(.var){
|
||||
out <- do.call(
|
||||
regression_model,
|
||||
append_list(parameters,
|
||||
data = data[c(outcome.str, .var)], "data"
|
||||
)
|
||||
)
|
||||
|
||||
## This is the very long version
|
||||
## Handles deeply nested glue string
|
||||
code <- glue::glue("dplyr::select(data,{paste0(paste(names(data[c(outcome.str, .var)]),collapse=','))})|>\nFreesearchR::regression_model({list2str(modifyList(parameters,list(formula.str = glue::glue(gsub('vars','.var',formula.str.c)))))})")
|
||||
REDCapCAST::set_attr(out, code, "code")
|
||||
})
|
||||
|
||||
# vars <- "."
|
||||
#
|
||||
# code_raw <- glue::glue(
|
||||
# "{fun.c}({paste(Filter(length,list(glue::glue(formula.str.c),'data = .d',list2str(args.list.c))),collapse=', ')})"
|
||||
# )
|
||||
# browser()
|
||||
# code <- glue::glue("lapply(data,function(.d){code_raw})")
|
||||
|
||||
code <- model |>
|
||||
lapply(\(.x)REDCapCAST::get_attr(.x, "code")) |>
|
||||
purrr::reduce(c) |>
|
||||
(\(.x){
|
||||
paste0("list(\n", paste(.x, collapse = ",\n"), ")")
|
||||
})()
|
||||
|
||||
|
||||
list(
|
||||
options = options,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue