code export works!
Some checks are pending
pkgdown.yaml / pkgdown (push) Waiting to run

This commit is contained in:
Andreas Gammelgaard Damsbo 2025-04-09 12:31:08 +02:00
commit 347490605f
No known key found for this signature in database
20 changed files with 573 additions and 538 deletions

View file

@ -1 +1 @@
app_version <- function()'Version: 25.4.1.250408_1343'
app_version <- function()'Version: 25.4.1.250409_1216'

View file

@ -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(

View file

@ -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

View file

@ -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)
}

View file

@ -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(

View file

@ -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)
}))
}
)

View file

@ -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,