From 04784a7a24bbb6a4c0d1da9e4f372b84e11a5e4a Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Wed, 19 Mar 2025 09:14:36 +0100 Subject: [PATCH 1/3] renaming --- DESCRIPTION | 2 +- freesearcheR.Rproj => FreesearchR.Rproj | 2 +- NAMESPACE | 3 +- NEWS.md | 4 +- QA.md | 2 +- R/app_version.R | 2 +- R/import-file-ext.R | 2 +- R/launch_FreesearchR.R | 24 ++++++++++++ R/regression_plot.R | 29 +++++++++------ R/regression_table.R | 4 +- R/shiny_freesearcheR.R | 37 ------------------- R/update-factor-ext.R | 2 +- README.md | 22 +++++------ inst/apps/{freesearcheR => FreesearchR}/app.R | 14 ++----- .../{freesearcheR => FreesearchR}/launch.R | 0 .../shinyapps.io/agdamsbo/freesearcheR.dcf | 2 +- .../shinyapps.io/agdamsbo/webResearch.dcf | 0 .../cognitiveindex/freesearcheR_dev.dcf | 0 .../cognitiveindex/freesearcheR_extra.dcf | 0 .../{freesearcheR => FreesearchR}/server.R | 0 inst/apps/{freesearcheR => FreesearchR}/ui.R | 0 .../www/intro.html | 0 .../www/intro.md | 0 .../www/notes_visuals.html | 0 .../www/notes_visuals.md | 0 .../www/report.rmd | 0 .../www/umami-app.html | 0 man/launch_FreesearchR.Rd | 23 ++++++++++++ man/launch_freesearcheR.Rd | 17 --------- man/plot.tbl_regression.Rd | 10 ++++- man/regression_table.Rd | 2 +- man/shiny_freesearcheR.Rd | 23 ------------ man/update-factor.Rd | 12 ++++++ .../{freesearcheR.Rmd => FreesearchR.Rmd} | 18 ++++----- 34 files changed, 120 insertions(+), 136 deletions(-) rename freesearcheR.Rproj => FreesearchR.Rproj (89%) create mode 100644 R/launch_FreesearchR.R delete mode 100644 R/shiny_freesearcheR.R rename inst/apps/{freesearcheR => FreesearchR}/app.R (99%) rename inst/apps/{freesearcheR => FreesearchR}/launch.R (100%) rename inst/apps/{freesearcheR => FreesearchR}/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf (91%) rename inst/apps/{freesearcheR => FreesearchR}/rsconnect/shinyapps.io/agdamsbo/webResearch.dcf (100%) rename inst/apps/{freesearcheR => FreesearchR}/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_dev.dcf (100%) rename inst/apps/{freesearcheR => FreesearchR}/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_extra.dcf (100%) rename inst/apps/{freesearcheR => FreesearchR}/server.R (100%) rename inst/apps/{freesearcheR => FreesearchR}/ui.R (100%) rename inst/apps/{freesearcheR => FreesearchR}/www/intro.html (100%) rename inst/apps/{freesearcheR => FreesearchR}/www/intro.md (100%) rename inst/apps/{freesearcheR => FreesearchR}/www/notes_visuals.html (100%) rename inst/apps/{freesearcheR => FreesearchR}/www/notes_visuals.md (100%) rename inst/apps/{freesearcheR => FreesearchR}/www/report.rmd (100%) rename inst/apps/{freesearcheR => FreesearchR}/www/umami-app.html (100%) create mode 100644 man/launch_FreesearchR.Rd delete mode 100644 man/launch_freesearcheR.Rd delete mode 100644 man/shiny_freesearcheR.Rd rename vignettes/{freesearcheR.Rmd => FreesearchR.Rmd} (84%) diff --git a/DESCRIPTION b/DESCRIPTION index abdb6117..c8608892 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,4 +1,4 @@ -Package: freesearcheR +Package: FreesearchR Title: Browser Based Data Analysis Version: 25.3.2 Authors@R: diff --git a/freesearcheR.Rproj b/FreesearchR.Rproj similarity index 89% rename from freesearcheR.Rproj rename to FreesearchR.Rproj index 235efdc1..0791dee7 100644 --- a/freesearcheR.Rproj +++ b/FreesearchR.Rproj @@ -20,4 +20,4 @@ LineEndingConversion: Posix BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source -PackageRoxygenize: rd,collate,namespace +PackageRoxygenize: rd,collate,namespace,vignette diff --git a/NAMESPACE b/NAMESPACE index 336ec69e..a92a98b8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -48,7 +48,7 @@ export(is_consecutive) export(is_datetime) export(is_valid_redcap_url) export(is_valid_token) -export(launch_freesearcheR) +export(launch_FreesearchR) export(line_break) export(m_datafileUI) export(m_redcap_readServer) @@ -81,7 +81,6 @@ export(remove_na_attr) export(repeated_instruments) export(sankey_ready) export(selectInputIcon) -export(shiny_freesearcheR) export(specify_qmd_format) export(subset_types) export(supported_functions) diff --git a/NEWS.md b/NEWS.md index aee2764d..3ef25c70 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,11 +2,11 @@ Focus is on polish and improved ui/ux. -First steps towards an updated name (will be FreesearchR), with renamed repository. Also, the repo will move to an organisation (named FreesearchR). +First steps towards an updated name (will be FreesearchR), with renamed repository. This may introduce some breaking chances for others calling or installing the package. No future changes are planned. A complete transition is planned before attending and presenting a poster at the European Stroke Organisation COnference 2025 in May. Testing file upload conducted and improved. -Working on omproving code export. +Working on improving code export. # freesearcheR 25.3.1 diff --git a/QA.md b/QA.md index 8317ecf9..c17abf4d 100644 --- a/QA.md +++ b/QA.md @@ -1,6 +1,6 @@ # Questions and answers -A complete instructions set is not available, but below are a collection of questions and answers about the project and use of the app. +A complete instructions set [is also available](https://agdamsbo.github.io/FreesearchR/articles/FreesearchR.html), but below are a collection of questions and answers about the project and use of the ***FreesearchR*** app. ## Are you keeping the uploaded data? diff --git a/R/app_version.R b/R/app_version.R index 131837ea..05f35bb9 100644 --- a/R/app_version.R +++ b/R/app_version.R @@ -1 +1 @@ -app_version <- function()'250318_0819' +app_version <- function()'250318_0827' diff --git a/R/import-file-ext.R b/R/import-file-ext.R index 05ac7b64..e93809af 100644 --- a/R/import-file-ext.R +++ b/R/import-file-ext.R @@ -254,7 +254,7 @@ import_file_server <- function(id, parameters <- parameters[which(names(parameters) %in% rlang::fn_fmls_names(get(read_fns[[extension]])))] # parameters <- parameters[which(names(parameters) %in% rlang::fn_fmls_names(read_fns[[extension]]))] imported <- try(rlang::exec(read_fns[[extension]], !!!parameters), silent = TRUE) - code <- rlang::call2(read_fns[[extension]], !!!modifyList(parameters, list(file = input$file$name)), .ns = "freesearcheR") + code <- rlang::call2(read_fns[[extension]], !!!modifyList(parameters, list(file = input$file$name)), .ns = "FreesearchR") if (inherits(imported, "try-error")) { imported <- try(rlang::exec(rio::import, !!!parameters[1]), silent = TRUE) diff --git a/R/launch_FreesearchR.R b/R/launch_FreesearchR.R new file mode 100644 index 00000000..5d22820e --- /dev/null +++ b/R/launch_FreesearchR.R @@ -0,0 +1,24 @@ +#' Easily launch the FreesearchR app +#' +#' @description +#' All data.frames in the global environment will be accessible through the app. +#' +#' @param ... passed on to `shiny::runApp()` +#' +#' @returns shiny app +#' @export +#' +#' @examples +#' \dontrun{ +#' data(mtcars) +#' shiny_FreesearchR(launch.browser = TRUE) +#' } +launch_FreesearchR <- function(...){ + appDir <- system.file("apps", "FreesearchR", package = "FreesearchR") + if (appDir == "") { + stop("Could not find the app directory. Try re-installing `FreesearchR`.", call. = FALSE) + } + + a <- shiny::runApp(appDir = paste0(appDir,"/app.R"), ...) + return(invisible(a)) +} diff --git a/R/regression_plot.R b/R/regression_plot.R index 689b896c..d44a81c4 100644 --- a/R/regression_plot.R +++ b/R/regression_plot.R @@ -15,15 +15,16 @@ #' #' @examples #' \dontrun{ -#' mod <- lm(mpg ~ ., mtcars) +#' mod <- lm(mpg ~ ., default_parsing(mtcars)) #' p <- mod |> #' gtsummary::tbl_regression() |> #' plot(colour = "variable") #' } #' plot.tbl_regression <- function(x, - # remove_header_rows = TRUE, - # remove_reference_rows = FALSE, + plot_ref = TRUE, + remove_header_rows = TRUE, + remove_reference_rows = FALSE, ...) { # check_dots_empty() gtsummary:::check_pkg_installed("ggstats") @@ -32,18 +33,22 @@ plot.tbl_regression <- function(x, # gtsummary:::check_scalar_logical(remove_reference_rows) df_coefs <- x$table_body - # if (isTRUE(remove_header_rows)) { - # df_coefs <- df_coefs |> dplyr::filter(!.data$header_row %in% TRUE) - # } - # if (isTRUE(remove_reference_rows)) { - # df_coefs <- df_coefs |> dplyr::filter(!.data$reference_row %in% TRUE) - # } - - # browser() + browser() + if (isTRUE(remove_header_rows)) { + df_coefs <- df_coefs |> dplyr::filter(!header_row %in% TRUE) + } + if (isTRUE(remove_reference_rows)) { + df_coefs <- df_coefs |> dplyr::filter(!reference_row %in% TRUE) + } + # Removes redundant label df_coefs$label[df_coefs$row_type == "label"] <- "" - df_coefs %>% + # Add estimate value to reference level + if (plot_ref == TRUE){ + df_coefs[df_coefs$var_type == "categorical" & is.na(df_coefs$reference_row),"estimate"] <- if (x$inputs$exponentiate) 1 else 0} + + df_coefs |> ggstats::ggcoef_plot(exponentiate = x$inputs$exponentiate, ...) } diff --git a/R/regression_table.R b/R/regression_table.R index 2b916e0c..c9fa5138 100644 --- a/R/regression_table.R +++ b/R/regression_table.R @@ -81,7 +81,7 @@ #' #' @export #' regression_table.default <- function(x, ..., args.list = NULL, fun = "gtsummary::tbl_regression") { #' # Stripping custom class -#' class(x) <- class(x)[class(x) != "freesearcher_model"] +#' class(x) <- class(x)[class(x) != "freesearchr_model"] #' #' if (any(c(length(class(x)) != 1, class(x) != "lm"))) { #' if (!"exponentiate" %in% names(args.list)) { @@ -110,7 +110,7 @@ regression_table <- function(x, ...) { regression_table_create <- function(x, ..., args.list = NULL, fun = "gtsummary::tbl_regression") { # Stripping custom class - class(x) <- class(x)[class(x) != "freesearcher_model"] + class(x) <- class(x)[class(x) != "freesearchr_model"] if (any(c(length(class(x)) != 1, class(x) != "lm"))) { if (!"exponentiate" %in% names(args.list)) { diff --git a/R/shiny_freesearcheR.R b/R/shiny_freesearcheR.R deleted file mode 100644 index 337376b0..00000000 --- a/R/shiny_freesearcheR.R +++ /dev/null @@ -1,37 +0,0 @@ -#' Launch the freesearcheR tool locally -#' -#' @description -#' All data.frames in the global environment will be accessible through the app. -#' -#' -#' @param ... arguments passed on to `shiny::runApp()` -#' -#' @return shiny app -#' @export -#' -#' @examples -#' \dontrun{ -#' data(mtcars) -#' shiny_freesearcheR(launch.browser = TRUE) -#' } -shiny_freesearcheR <- function(...) { - appDir <- system.file("apps", "freesearcheR", package = "freesearcheR") - if (appDir == "") { - stop("Could not find the app directory. Try re-installing `freesearcheR`.", call. = FALSE) - } - - a <- shiny::runApp(appDir = paste0(appDir,"/app.R"), ...) - return(invisible(a)) -} - - -#' Easily launch the freesearcheR app -#' -#' @param ... passed on to `shiny::runApp()` -#' -#' @returns shiny app -#' @export -#' -launch_freesearcheR <- function(...){ - shiny_freesearcheR(...) -} diff --git a/R/update-factor-ext.R b/R/update-factor-ext.R index 07dc2849..a3943495 100644 --- a/R/update-factor-ext.R +++ b/R/update-factor-ext.R @@ -265,7 +265,7 @@ modal_update_factor <- function(id, #' #' @importFrom shinyWidgets WinBox wbOptions wbControls #' @importFrom htmltools tagList -#' @rdname create-column +#' @rdname update-factor winbox_update_factor <- function(id, title = i18n("Update levels of a factor"), options = shinyWidgets::wbOptions(), diff --git a/README.md b/README.md index 4690ce5d..5a980b80 100644 --- a/README.md +++ b/README.md @@ -1,35 +1,35 @@ -# freesearcheR +# FreesearchR [![Lifecycle: experimental](https://img.shields.io/badge/lifecycle-experimental-orange.svg)](https://lifecycle.r-lib.org/articles/stages.html#experimental) -[![rhub](https://github.com/agdamsbo/freesearcheR/actions/workflows/rhub.yaml/badge.svg)](https://github.com/agdamsbo/freesearcheR/actions/workflows/rhub.yaml) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.14527429.svg)](https://doi.org/10.5281/zenodo.14527429) -[![freesearcheR](https://img.shields.io/badge/Shiny-shinyapps.io-blue?style=flat&labelColor=white&logo=RStudio&logoColor=blue)](https://agdamsbo.shinyapps.io/freesearcheR/) +[![rhub](https://github.com/agdamsbo/FreesearchR/actions/workflows/rhub.yaml/badge.svg)](https://github.com/agdamsbo/FreesearchR/actions/workflows/rhub.yaml) +[![FreesearchR](https://img.shields.io/badge/Shiny-shinyapps.io-blue?style=flat&labelColor=white&logo=RStudio&logoColor=blue)](https://agdamsbo.shinyapps.io/freesearcheR/) -This package is the backbone of the ***freesearcheR***, a free and open-source browser based data exploration and analysis tool for clinicians and researchers with publication ready output. +This package is the backbone of the ***FreesearchR***, a free and open-source browser based data exploration and analysis tool for clinicians and researchers with publication ready output. -This package and the ***freesearcheR***-tool is part of a larger initiative to democratize health data analysis and remove barriers for clinicians to engage in health research. +This package and the ***FreesearchR***-tool is part of a larger initiative to democratize health data analysis and remove barriers for clinicians to engage in health research. -the ***freesearcheR***-tool is online and accessible here: [link to the app freely hosted on shinyapps.io](https://agdamsbo.shinyapps.io/freesearcheR/). All feedback is welcome and can be shared as a GitHub issue. +the ***FreesearchR***-tool is online and accessible here: [link to the app freely hosted on shinyapps.io](https://agdamsbo.shinyapps.io/FreesearchR/). All feedback is welcome and can be shared as a GitHub issue. Initiatives for funding continued development of the tool and surrounding initiatives is ongoing. ## Install locally -The ***freesearcheR***-tool can also be launched locally. Any data.frame available in the global environment will be accessible from the interface. +The ***FreesearchR***-tool can also be launched locally. Any data.frame available in the global environment will be accessible from the interface. ``` require("devtools") -devtools::install_github("agdamsbo/freesearcheR") -library(freesearcheR) +devtools::install_github("agdamsbo/FreesearchR") +library(FreesearchR) # By loading mtcars to the environment, it will be available # in the interface like any other data.frame data(mtcars) -shiny_freesearcheR() +launch_FreesearchR() ``` ## Code of Conduct -Please note that the freesearcheR project is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/1/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. +Please note that the ***FreesearchR*** project is released with a [Contributor Code of Conduct](https://contributor-covenant.org/version/2/1/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms. diff --git a/inst/apps/freesearcheR/app.R b/inst/apps/FreesearchR/app.R similarity index 99% rename from inst/apps/freesearcheR/app.R rename to inst/apps/FreesearchR/app.R index 2e673b39..df1d5c71 100644 --- a/inst/apps/freesearcheR/app.R +++ b/inst/apps/FreesearchR/app.R @@ -10,7 +10,7 @@ #### Current file: R//app_version.R ######## -app_version <- function()'250318_0819' +app_version <- function()'250318_0827' ######## @@ -7214,7 +7214,8 @@ ui_elements <- list( ), shiny::br(), shiny::br(), - shiny::tags$b("Code snippets:"), + shiny::h4("Code snippets"), + shiny::tags$p("Below are the code used to create the final data set. This can be saved for reproducibility. The code may not be 100 % correct, but kan be used for learning and example code to get started on coding yourself."), shiny::verbatimTextOutput(outputId = "code_import"), shiny::verbatimTextOutput(outputId = "code_data"), shiny::verbatimTextOutput(outputId = "code_filter"), @@ -7535,11 +7536,6 @@ server <- function(input, output, session) { ) }) - # shiny::observeEvent(input$reset_confirm, { - # rv$data <- rv$data_original |> default_parsing() - # }) - - ######### ######### Modifications @@ -7612,7 +7608,6 @@ server <- function(input, output, session) { } ) - ######### Subset, rename, reclass updated_data <- update_variables_server( @@ -7626,8 +7621,6 @@ server <- function(input, output, session) { rv$code$modify[[length(rv$code$modify) + 1]] <- attr(rv$data, "code") }) - - ######### Data filter # IDEAFilter has the least cluttered UI, but might have a License issue data_filter <- IDEAFilter::IDEAFilter("data_filter", @@ -7765,7 +7758,6 @@ server <- function(input, output, session) { }) output$code_filter <- shiny::renderPrint({ - shiny::req(rv$code$filter) cat(rv$code$filter) }) diff --git a/inst/apps/freesearcheR/launch.R b/inst/apps/FreesearchR/launch.R similarity index 100% rename from inst/apps/freesearcheR/launch.R rename to inst/apps/FreesearchR/launch.R diff --git a/inst/apps/freesearcheR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf b/inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf similarity index 91% rename from inst/apps/freesearcheR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf rename to inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf index 46995044..76ab2422 100644 --- a/inst/apps/freesearcheR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf +++ b/inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf @@ -5,6 +5,6 @@ account: agdamsbo server: shinyapps.io hostUrl: https://api.shinyapps.io/v1 appId: 13611288 -bundleId: 9958862 +bundleId: 9961770 url: https://agdamsbo.shinyapps.io/freesearcheR/ version: 1 diff --git a/inst/apps/freesearcheR/rsconnect/shinyapps.io/agdamsbo/webResearch.dcf b/inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/webResearch.dcf similarity index 100% rename from inst/apps/freesearcheR/rsconnect/shinyapps.io/agdamsbo/webResearch.dcf rename to inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/webResearch.dcf diff --git a/inst/apps/freesearcheR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_dev.dcf b/inst/apps/FreesearchR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_dev.dcf similarity index 100% rename from inst/apps/freesearcheR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_dev.dcf rename to inst/apps/FreesearchR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_dev.dcf diff --git a/inst/apps/freesearcheR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_extra.dcf b/inst/apps/FreesearchR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_extra.dcf similarity index 100% rename from inst/apps/freesearcheR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_extra.dcf rename to inst/apps/FreesearchR/rsconnect/shinyapps.io/cognitiveindex/freesearcheR_extra.dcf diff --git a/inst/apps/freesearcheR/server.R b/inst/apps/FreesearchR/server.R similarity index 100% rename from inst/apps/freesearcheR/server.R rename to inst/apps/FreesearchR/server.R diff --git a/inst/apps/freesearcheR/ui.R b/inst/apps/FreesearchR/ui.R similarity index 100% rename from inst/apps/freesearcheR/ui.R rename to inst/apps/FreesearchR/ui.R diff --git a/inst/apps/freesearcheR/www/intro.html b/inst/apps/FreesearchR/www/intro.html similarity index 100% rename from inst/apps/freesearcheR/www/intro.html rename to inst/apps/FreesearchR/www/intro.html diff --git a/inst/apps/freesearcheR/www/intro.md b/inst/apps/FreesearchR/www/intro.md similarity index 100% rename from inst/apps/freesearcheR/www/intro.md rename to inst/apps/FreesearchR/www/intro.md diff --git a/inst/apps/freesearcheR/www/notes_visuals.html b/inst/apps/FreesearchR/www/notes_visuals.html similarity index 100% rename from inst/apps/freesearcheR/www/notes_visuals.html rename to inst/apps/FreesearchR/www/notes_visuals.html diff --git a/inst/apps/freesearcheR/www/notes_visuals.md b/inst/apps/FreesearchR/www/notes_visuals.md similarity index 100% rename from inst/apps/freesearcheR/www/notes_visuals.md rename to inst/apps/FreesearchR/www/notes_visuals.md diff --git a/inst/apps/freesearcheR/www/report.rmd b/inst/apps/FreesearchR/www/report.rmd similarity index 100% rename from inst/apps/freesearcheR/www/report.rmd rename to inst/apps/FreesearchR/www/report.rmd diff --git a/inst/apps/freesearcheR/www/umami-app.html b/inst/apps/FreesearchR/www/umami-app.html similarity index 100% rename from inst/apps/freesearcheR/www/umami-app.html rename to inst/apps/FreesearchR/www/umami-app.html diff --git a/man/launch_FreesearchR.Rd b/man/launch_FreesearchR.Rd new file mode 100644 index 00000000..5e1e590c --- /dev/null +++ b/man/launch_FreesearchR.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/launch_FreesearchR.R +\name{launch_FreesearchR} +\alias{launch_FreesearchR} +\title{Easily launch the FreesearchR app} +\usage{ +launch_FreesearchR(...) +} +\arguments{ +\item{...}{passed on to \code{shiny::runApp()}} +} +\value{ +shiny app +} +\description{ +All data.frames in the global environment will be accessible through the app. +} +\examples{ +\dontrun{ +data(mtcars) +shiny_FreesearchR(launch.browser = TRUE) +} +} diff --git a/man/launch_freesearcheR.Rd b/man/launch_freesearcheR.Rd deleted file mode 100644 index 7ec99f8a..00000000 --- a/man/launch_freesearcheR.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/shiny_freesearcheR.R -\name{launch_freesearcheR} -\alias{launch_freesearcheR} -\title{Easily launch the freesearcheR app} -\usage{ -launch_freesearcheR(...) -} -\arguments{ -\item{...}{passed on to \code{shiny::runApp()}} -} -\value{ -shiny app -} -\description{ -Easily launch the freesearcheR app -} diff --git a/man/plot.tbl_regression.Rd b/man/plot.tbl_regression.Rd index 3c5d7db5..daa741a2 100644 --- a/man/plot.tbl_regression.Rd +++ b/man/plot.tbl_regression.Rd @@ -4,7 +4,13 @@ \alias{plot.tbl_regression} \title{Regression coef plot from gtsummary. Slightly modified to pass on arguments} \usage{ -\method{plot}{tbl_regression}(x, ...) +\method{plot}{tbl_regression}( + x, + plot_ref = TRUE, + remove_header_rows = TRUE, + remove_reference_rows = FALSE, + ... +) } \arguments{ \item{x}{(\code{tbl_regression}, \code{tbl_uvregression})\cr @@ -20,7 +26,7 @@ Regression coef plot from gtsummary. Slightly modified to pass on arguments } \examples{ \dontrun{ -mod <- lm(mpg ~ ., mtcars) +mod <- lm(mpg ~ ., default_parsing(mtcars)) p <- mod |> gtsummary::tbl_regression() |> plot(colour = "variable") diff --git a/man/regression_table.Rd b/man/regression_table.Rd index 1fdc1882..71d5238c 100644 --- a/man/regression_table.Rd +++ b/man/regression_table.Rd @@ -93,7 +93,7 @@ regression_table.list <- function(x, ...) { #' @export regression_table.default <- function(x, ..., args.list = NULL, fun = "gtsummary::tbl_regression") { # Stripping custom class - class(x) <- class(x)[class(x) != "freesearcher_model"] + class(x) <- class(x)[class(x) != "freesearchr_model"] if (any(c(length(class(x)) != 1, class(x) != "lm"))) { if (!"exponentiate" \%in\% names(args.list)) { diff --git a/man/shiny_freesearcheR.Rd b/man/shiny_freesearcheR.Rd deleted file mode 100644 index 93d8707c..00000000 --- a/man/shiny_freesearcheR.Rd +++ /dev/null @@ -1,23 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/shiny_freesearcheR.R -\name{shiny_freesearcheR} -\alias{shiny_freesearcheR} -\title{Launch the freesearcheR tool locally} -\usage{ -shiny_freesearcheR(...) -} -\arguments{ -\item{...}{arguments passed on to \code{shiny::runApp()}} -} -\value{ -shiny app -} -\description{ -All data.frames in the global environment will be accessible through the app. -} -\examples{ -\dontrun{ -data(mtcars) -shiny_freesearcheR(launch.browser = TRUE) -} -} diff --git a/man/update-factor.Rd b/man/update-factor.Rd index 8f55a588..c5810be9 100644 --- a/man/update-factor.Rd +++ b/man/update-factor.Rd @@ -5,6 +5,7 @@ \alias{update_factor_ui} \alias{update_factor_server} \alias{modal_update_factor} +\alias{winbox_update_factor} \title{Module to Reorder the Levels of a Factor Variable} \usage{ update_factor_ui(id) @@ -18,6 +19,13 @@ modal_update_factor( size = "l", footer = NULL ) + +winbox_update_factor( + id, + title = i18n("Update levels of a factor"), + options = shinyWidgets::wbOptions(), + controls = shinyWidgets::wbControls() +) } \arguments{ \item{id}{Module ID.} @@ -39,6 +47,10 @@ pass \code{\link[bslib:bs_theme]{bslib::bs_theme()}} to the \code{theme} argumen like \code{\link[shiny:fluidPage]{fluidPage()}}).} \item{footer}{UI for footer. Use \code{NULL} for no footer.} + +\item{options}{List of options, see \code{\link[shinyWidgets:wbOptions]{wbOptions()}}.} + +\item{controls}{List of controls, see \code{\link[shinyWidgets:wbControls]{wbControls()}}.} } \value{ A \code{\link[shiny:reactive]{shiny::reactive()}} function returning the data. diff --git a/vignettes/freesearcheR.Rmd b/vignettes/FreesearchR.Rmd similarity index 84% rename from vignettes/freesearcheR.Rmd rename to vignettes/FreesearchR.Rmd index 566cc953..86ea6ec0 100644 --- a/vignettes/freesearcheR.Rmd +++ b/vignettes/FreesearchR.Rmd @@ -1,8 +1,8 @@ --- -title: "freesearcheR" +title: "FreesearchR" output: rmarkdown::html_vignette vignette: > - %\VignetteIndexEntry{freesearcheR} + %\VignetteIndexEntry{FreesearchR} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- @@ -11,9 +11,9 @@ vignette: > knitr::opts_chunk$set(echo = TRUE,eval = FALSE) ``` -# Getting started with ***freesearcheR*** +# Getting started with ***FreesearchR*** -Below is a simple walk-trough and basic instructions for the functions on the freesearcheR app. +Below is a simple walk-trough and basic instructions for the functions on the FreesearchR app. ## Launching @@ -21,13 +21,13 @@ The easiest way to get started is to launch [the hosted version of the app on sh Additionally you have the option to run the app locally with access to any data in your current working environment. -To do this, open *R* (or RStudio or similar), and run the following code to install the latest version of ***freesearcheR*** and launch the app: +To do this, open *R* (or RStudio or similar), and run the following code to install the latest version of ***FreesearchR*** and launch the app: -``` {r} +```{r} require("pak") -pak::pak("agdamsbo/freesearcheR") -library(freesearcheR) -freesearcheR::launch_freesearcheR() +pak::pak("agdamsbo/FreesearchR") +library(FreesearchR) +FreesearchR::launch_FreesearchR() ``` As a small note, a standalone Windows app version is on the drawing board as well, but no time frame is available. From 111393c73f1d35ee201b65078febdc6ce482c10c Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Wed, 19 Mar 2025 13:10:56 +0100 Subject: [PATCH 2/3] updated docs + boxplot --- .Rbuildignore | 2 +- DESCRIPTION | 4 +- NAMESPACE | 5 + NEWS.md | 4 +- R/app_version.R | 2 +- R/cut-variable-dates.R | 7 +- R/data-import.R | 22 +- R/data_plots.R | 178 +++++++++- R/helpers.R | 5 +- R/plot_box.R | 80 +++++ R/plot_euler.R | 6 +- R/regression_plot.R | 64 +++- _pkgdown.yml | 2 +- inst/apps/FreesearchR/app.R | 545 +++++++++++++++++++++-------- inst/apps/FreesearchR/server.R | 4 +- inst/apps/FreesearchR/ui.R | 8 +- inst/apps/FreesearchR/www/intro.md | 6 +- man/allign_axes.Rd | 17 + man/limit_log.Rd | 27 ++ man/symmetrical_scale_x_log10.Rd | 21 ++ man/wrap_plot_list.Rd | 19 + renv.lock | 89 +++-- renv/activate.R | 97 +++-- 23 files changed, 908 insertions(+), 306 deletions(-) create mode 100644 R/plot_box.R create mode 100644 man/allign_axes.Rd create mode 100644 man/limit_log.Rd create mode 100644 man/symmetrical_scale_x_log10.Rd create mode 100644 man/wrap_plot_list.Rd diff --git a/.Rbuildignore b/.Rbuildignore index 99a38721..ed3805c2 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -1,6 +1,6 @@ ^renv$ ^renv\.lock$ -^freesearcheR\.Rproj$ +^FreesearchR\.Rproj$ ^\.Rproj\.user$ ^LICENSE\.md$ ^dev$ diff --git a/DESCRIPTION b/DESCRIPTION index c8608892..38476ff5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -80,6 +80,6 @@ Suggests: rsconnect, knitr, rmarkdown -URL: https://github.com/agdamsbo/freesearcheR, https://agdamsbo.github.io/freesearcheR/ -BugReports: https://github.com/agdamsbo/freesearcheR/issues +URL: https://github.com/agdamsbo/FreesearchR, https://agdamsbo.github.io/FreesearchR/ +BugReports: https://github.com/agdamsbo/FreesearchR/issues VignetteBuilder: knitr diff --git a/NAMESPACE b/NAMESPACE index a92a98b8..aa34d84c 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,8 @@ S3method(plot,tbl_regression) export(add_class_icon) export(add_sparkline) export(all_but) +export(allign_axes) +export(append_list) export(argsstring2list) export(baseline_table) export(clean_date) @@ -49,6 +51,7 @@ export(is_datetime) export(is_valid_redcap_url) export(is_valid_token) export(launch_FreesearchR) +export(limit_log) export(line_break) export(m_datafileUI) export(m_redcap_readServer) @@ -85,6 +88,7 @@ export(specify_qmd_format) export(subset_types) export(supported_functions) export(supported_plots) +export(symmetrical_scale_x_log10) export(tbl_merge) export(update_factor_server) export(update_factor_ui) @@ -95,6 +99,7 @@ export(vertical_stacked_bars) export(wide2long) export(winbox_cut_variable) export(winbox_update_factor) +export(wrap_plot_list) export(write_quarto) importFrom(classInt,classIntervals) importFrom(data.table,as.data.table) diff --git a/NEWS.md b/NEWS.md index 3ef25c70..33529824 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,8 +1,8 @@ -# freesearcheR 25.3.2 +# FreesearchR 25.3.2 Focus is on polish and improved ui/ux. -First steps towards an updated name (will be FreesearchR), with renamed repository. This may introduce some breaking chances for others calling or installing the package. No future changes are planned. A complete transition is planned before attending and presenting a poster at the European Stroke Organisation COnference 2025 in May. +Updating name (will be FreesearchR), with renamed repository and some graphics are comng. This may introduce some breaking chances for others calling or installing the package. No future changes are planned. A complete transition is planned before attending and presenting a poster at the European Stroke Organisation Conference 2025 in May. Testing file upload conducted and improved. diff --git a/R/app_version.R b/R/app_version.R index 05f35bb9..b4900e38 100644 --- a/R/app_version.R +++ b/R/app_version.R @@ -1 +1 @@ -app_version <- function()'250318_0827' +app_version <- function()'250319_1306' diff --git a/R/cut-variable-dates.R b/R/cut-variable-dates.R index 9e2d238f..c14c72fa 100644 --- a/R/cut-variable-dates.R +++ b/R/cut-variable-dates.R @@ -102,13 +102,16 @@ library(shiny) #' f <- d_t |> cut(2) #' readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "03:02:20", NA)) |> cut(breaks = lubridate::as_datetime(c(hms::as_hms(levels(f)), hms::as_hms(max(d_t, na.rm = TRUE) + 1))), right = FALSE) cut.hms <- function(x, breaks, ...) { + ## as_hms keeps returning warnings on tz(); ignored + suppressWarnings({ if (hms::is_hms(breaks)) { - breaks <- lubridate::as_datetime(breaks, tz = "UTC") + breaks <- lubridate::as_datetime(breaks) } - x <- lubridate::as_datetime(x, tz = "UTC") + x <- lubridate::as_datetime(x) out <- cut.POSIXt(x, breaks = breaks, ...) attr(out, which = "brks") <- hms::as_hms(lubridate::as_datetime(attr(out, which = "brks"))) attr(out, which = "levels") <- as.character(hms::as_hms(lubridate::as_datetime(attr(out, which = "levels")))) + }) out } diff --git a/R/data-import.R b/R/data-import.R index 8b74135f..8ef1dacd 100644 --- a/R/data-import.R +++ b/R/data-import.R @@ -59,27 +59,7 @@ data_import_server <- function(id) { id = ns("file_import"), show_data_in = "popup", trigger_return = "change", - return_class = "data.frame", - read_fns = list( - ods = import_ods, - dta = function(file) { - haven::read_dta( - file = file, - .name_repair = "unique_quiet" - ) - }, - csv = import_delim, - tsv = import_delim, - txt = import_delim, - xls = import_xls, - xlsx = import_xls, - rds = function(file) { - readr::read_rds( - file = file, - name_repair = "unique_quiet" - ) - } - ) + return_class = "data.frame" ) shiny::observeEvent(data_file$data(), { diff --git a/R/data_plots.R b/R/data_plots.R index f5aa63d7..ccc14b85 100644 --- a/R/data_plots.R +++ b/R/data_plots.R @@ -112,6 +112,99 @@ data_visuals_server <- function(id, plot = NULL ) + # ## --- New attempt + # + # rv$plot.params <- shiny::reactive({ + # get_plot_options(input$type) |> purrr::pluck(1) + # }) + # + # c(output, + # list(shiny::renderUI({ + # columnSelectInput( + # inputId = ns("primary"), + # data = data, + # placeholder = "Select variable", + # label = "Response variable", + # multiple = FALSE + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$primary) + # # browser() + # + # if (!input$primary %in% names(data())) { + # plot_data <- data()[1] + # } else { + # plot_data <- data()[input$primary] + # } + # + # plots <- possible_plots( + # data = plot_data + # ) + # + # plots_named <- get_plot_options(plots) |> + # lapply(\(.x){ + # stats::setNames(.x$descr, .x$note) + # }) + # + # vectorSelectInput( + # inputId = ns("type"), + # selected = NULL, + # label = shiny::h4("Plot type"), + # choices = Reduce(c, plots_named), + # multiple = FALSE + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$type) + # + # cols <- c( + # rv$plot.params()[["secondary.extra"]], + # all_but( + # colnames(subset_types( + # data(), + # rv$plot.params()[["secondary.type"]] + # )), + # input$primary + # ) + # ) + # + # columnSelectInput( + # inputId = ns("secondary"), + # data = data, + # selected = cols[1], + # placeholder = "Please select", + # label = if (isTRUE(rv$plot.params()[["secondary.multi"]])) "Additional variables" else "Secondary variable", + # multiple = rv$plot.params()[["secondary.multi"]], + # maxItems = rv$plot.params()[["secondary.max"]], + # col_subset = cols, + # none_label = "No variable" + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$type) + # columnSelectInput( + # inputId = ns("tertiary"), + # data = data, + # placeholder = "Please select", + # label = "Grouping variable", + # multiple = FALSE, + # col_subset = c( + # "none", + # all_but( + # colnames(subset_types( + # data(), + # rv$plot.params()[["tertiary.type"]] + # )), + # input$primary, + # input$secondary + # ) + # ), + # none_label = "No stratification" + # ) + # }) + # )|> setNames(c("primary","type","secondary","tertiary")),keep.null = TRUE) + output$primary <- shiny::renderUI({ columnSelectInput( inputId = ns("primary"), @@ -364,6 +457,16 @@ supported_plots <- function() { tertiary.type = c("dichotomous", "ordinal"), secondary.extra = NULL ), + plot_box = list( + fun = "plot_box", + descr = "Box plot", + note = "A classic way to plot data distribution by groups", + primary.type = c("continuous", "dichotomous", "ordinal"), + secondary.type = c("dichotomous", "ordinal"), + secondary.multi = FALSE, + tertiary.type = c("dichotomous", "ordinal"), + secondary.extra = "none" + ), plot_euler = list( fun = "plot_euler", descr = "Euler diagram", @@ -535,18 +638,49 @@ line_break <- function(data, lineLength = 20, fixed = FALSE) { } -wrap_plot_list <- function(data) { - if (length(data) > 1) { - out <- data |> - allign_axes() |> - patchwork::wrap_plots(guides = "collect", axes = "collect", axis_titles = "collect") +#' Wrapping +#' +#' @param data list of ggplot2 objects +#' @param tag_levels passed to patchwork::plot_annotation if given. Default is NULL +#' +#' @returns list of ggplot2 objects +#' @export +#' +wrap_plot_list <- function(data, tag_levels = NULL) { + if (ggplot2::is.ggplot(data[[1]])) { + if (length(data) > 1) { + out <- data |> + (\(.x){ + if (rlang::is_named(.x)) { + purrr::imap(.x, \(.y, .i){ + .y + ggplot2::ggtitle(.i) + }) + } else { + .x + } + })() |> + allign_axes() |> + patchwork::wrap_plots(guides = "collect", axes = "collect", axis_titles = "collect") + if (!is.null(tag_levels)) { + out <- out + patchwork::plot_annotation(tag_levels = tag_levels) + } + } else { + out <- data + } } else { - out <- data + cli::cli_abort("Can only wrap lists of {.cls ggplot} objects") } out } +#' Alligns axes between plots +#' +#' @param ... ggplot2 objects or list of ggplot2 objects +#' +#' @returns list of ggplot2 objects +#' @export +#' allign_axes <- function(...) { # https://stackoverflow.com/questions/62818776/get-axis-limits-from-ggplot-object # https://github.com/thomasp85/patchwork/blob/main/R/plot_multipage.R#L150 @@ -558,16 +692,30 @@ allign_axes <- function(...) { cli::cli_abort("Can only align {.cls ggplot} objects or a list of them") } - # browser() - yr <- purrr::map(p, ~ ggplot2::layer_scales(.x)$y$get_limits()) |> - unlist() |> - range() |> - unique() + yr <- clean_common_axis(p, "y") - xr <- purrr::map(p, ~ ggplot2::layer_scales(.x)$x$get_limits()) |> - unlist() |> - range() |> - unique() + xr <- clean_common_axis(p, "x") p |> purrr::map(~ .x + ggplot2::xlim(xr) + ggplot2::ylim(yr)) } + +#' Extract and clean axis ranges +#' +#' @param p plot +#' @param axis axis. x or y. +#' +#' @returns vector +#' @export +#' +clean_common_axis <- function(p, axis) { + purrr::map(p, ~ ggplot2::layer_scales(.x)[[axis]]$get_limits()) |> + unlist() |> + (\(.x){ + if (is.numeric(.x)) { + range(.x) + } else { + .x + } + })() |> + unique() +} diff --git a/R/helpers.R b/R/helpers.R index 166fef0f..4e24796a 100644 --- a/R/helpers.R +++ b/R/helpers.R @@ -215,7 +215,9 @@ default_parsing <- function(data) { out <- data |> REDCapCAST::parse_data() |> REDCapCAST::as_factor() |> - REDCapCAST::numchar2fct() + REDCapCAST::numchar2fct(numeric.threshold = 8,character.throshold = 10) |> + REDCapCAST::as_logical() |> + REDCapCAST::fct_drop() purrr::map2(out,name_labels,\(.x,.l){ if (!(is.na(.l) | .l=="")) { @@ -275,6 +277,7 @@ remove_empty_cols <- function(data,cutoff=.7){ #' @param index index name #' #' @returns list +#' @export #' #' @examples #' ls_d <- list(test=c(1:20)) diff --git a/R/plot_box.R b/R/plot_box.R new file mode 100644 index 00000000..6f16e79b --- /dev/null +++ b/R/plot_box.R @@ -0,0 +1,80 @@ +#' Beautiful box plot(s) +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' mtcars |> plot_box(x = "mpg", y = "cyl", z = "gear") +#' mtcars |> +#' default_parsing() |> +#' plot_box(x = "mpg", y = "cyl", z = "gear") +plot_box <- function(data, x, y, z = NULL) { + if (!is.null(z)) { + ds <- split(data, data[z]) + } else { + ds <- list(data) + } + + out <- lapply(ds, \(.ds){ + plot_box_single( + data = .ds, + x = x, + y = y + ) + }) + + wrap_plot_list(out) + # patchwork::wrap_plots(out,guides = "collect") +} + + + + +#' Create nice box-plots +#' +#' @name data-plots +#' +#' @returns +#' @export +#' +#' @examples +#' mtcars |> plot_box_single("mpg","cyl") +plot_box_single <- function(data, x, y=NULL, seed = 2103) { + set.seed(seed) + + if (is.null(y)) { + y <- "All" + data[[y]] <- y + } + + discrete <- !outcome_type(data[[y]]) %in% "continuous" + + data |> + ggplot2::ggplot(ggplot2::aes(x = !!dplyr::sym(x), y = !!dplyr::sym(y), fill = !!dplyr::sym(y), group = !!dplyr::sym(y))) + + ggplot2::geom_boxplot(linewidth = 1.8, outliers = FALSE) + + ## THis could be optional in future + ggplot2::geom_jitter(color = "black", size = 2, alpha = 0.9) + + ggplot2::coord_flip() + + viridis::scale_fill_viridis(discrete = discrete, option = "D") + + # ggplot2::theme_void() + + ggplot2::theme_bw(base_size = 24) + + ggplot2::theme( + legend.position = "none", + # panel.grid.major = element_blank(), + # panel.grid.minor = element_blank(), + # axis.text.y = element_blank(), + # axis.title.y = element_blank(), + # text = ggplot2::element_text(size = 20), + # axis.text = ggplot2::element_blank(), + # plot.title = element_blank(), + panel.background = ggplot2::element_rect(fill = "white"), + plot.background = ggplot2::element_rect(fill = "white"), + panel.border = ggplot2::element_blank(), + panel.grid.major = ggplot2::element_blank(), + panel.grid.minor = ggplot2::element_blank(), + axis.line = ggplot2::element_line(colour = "black"), + axis.ticks = ggplot2::element_line(colour = "black") + ) +} diff --git a/R/plot_euler.R b/R/plot_euler.R index d1de1897..bd8a1aba 100644 --- a/R/plot_euler.R +++ b/R/plot_euler.R @@ -78,9 +78,6 @@ ggeulerr <- function( #' mtcars |> plot_euler("vs", "am", seed = 1) plot_euler <- function(data, x, y, z = NULL, seed = 2103) { set.seed(seed = seed) - - # data <- data[c(...,z)] - if (!is.null(z)) { ds <- split(data, data[z]) } else { @@ -93,6 +90,7 @@ plot_euler <- function(data, x, y, z = NULL, seed = 2103) { plot_euler_single() }) +# names(out) wrap_plot_list(out) # patchwork::wrap_plots(out, guides = "collect") } @@ -116,7 +114,7 @@ plot_euler_single <- function(data) { ggeulerr(shape = "circle") + ggplot2::theme_void() + ggplot2::theme( - legend.position = "right", + legend.position = "none", # panel.grid.major = element_blank(), # panel.grid.minor = element_blank(), # axis.text.y = element_blank(), diff --git a/R/regression_plot.R b/R/regression_plot.R index d44a81c4..777fbd3a 100644 --- a/R/regression_plot.R +++ b/R/regression_plot.R @@ -33,7 +33,7 @@ plot.tbl_regression <- function(x, # gtsummary:::check_scalar_logical(remove_reference_rows) df_coefs <- x$table_body - browser() + if (isTRUE(remove_header_rows)) { df_coefs <- df_coefs |> dplyr::filter(!header_row %in% TRUE) } @@ -48,22 +48,16 @@ plot.tbl_regression <- function(x, if (plot_ref == TRUE){ df_coefs[df_coefs$var_type == "categorical" & is.na(df_coefs$reference_row),"estimate"] <- if (x$inputs$exponentiate) 1 else 0} - df_coefs |> + p <- df_coefs |> ggstats::ggcoef_plot(exponentiate = x$inputs$exponentiate, ...) + + if (x$inputs$exponentiate){ + p <- symmetrical_scale_x_log10(p) + } + p } -# default_parsing(mtcars) |> lapply(class) -# -# purrr::imap(mtcars,\(.x,.i){ -# if (.i %in% c("vs","am","gear","carb")){ -# as.factor(.x) -# } else .x -# }) |> dplyr::bind_cols() -# -# - - #' Wrapper to pivot gtsummary table data to long for plotting #' #' @param list a custom regression models list @@ -103,3 +97,47 @@ merge_long <- function(list, model.names) { l_merged } + + +#' Easily round log scale limits for nice plots +#' +#' @param data data +#' @param fun rounding function (floor/ceiling) +#' @param ... ignored +#' +#' @returns numeric vector +#' @export +#' +#' @examples +#' limit_log(-.1,floor) +#' limit_log(.1,ceiling) +#' limit_log(-2.1,ceiling) +#' limit_log(2.1,ceiling) +limit_log <- function(data,fun,...){ + fun(10^-floor(data)*10^data)/10^-floor(data) +} + +#' Ensure symmetrical plot around 1 on a logarithmic x scale for ratio plots +#' +#' @param plot ggplot2 plot +#' @param breaks breaks used and mirrored +#' @param ... ignored +#' +#' @returns ggplot2 object +#' @export +#' +symmetrical_scale_x_log10 <- function(plot,breaks=c(1,2,3,5,10),...){ + rx <- ggplot2::layer_scales(plot)$x$get_limits() + + x_min <- floor(10*rx[1])/10 + x_max <- ceiling(10*rx[2])/10 + + rx_min <- limit_log(rx[1],floor) + rx_max <- limit_log(rx[2],ceiling) + + max_abs_x <- max(abs(c(x_min,x_max))) + + ticks <- log10(breaks)+(ceiling(max_abs_x)-1) + browser() + plot + ggplot2::scale_x_log10(limits=c(rx_min,rx_max),breaks=create_log_tics(10^ticks[ticks<=max_abs_x])) +} diff --git a/_pkgdown.yml b/_pkgdown.yml index 9c5b6aea..bc78e979 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -1,4 +1,4 @@ -url: https://agdamsbo.github.io/freesearcheR/ +url: https://agdamsbo.github.io/FreesearchR/ template: bslib: version: 5 diff --git a/inst/apps/FreesearchR/app.R b/inst/apps/FreesearchR/app.R index df1d5c71..75be00f6 100644 --- a/inst/apps/FreesearchR/app.R +++ b/inst/apps/FreesearchR/app.R @@ -1,20 +1,20 @@ ######## -#### Current file: /Users/au301842/freesearcheR/inst/apps/freesearcheR/functions.R +#### Current file: /Users/au301842/FreesearchR/inst/apps/FreesearchR/functions.R ######## ######## -#### Current file: R//app_version.R +#### Current file: R//app_version.R ######## -app_version <- function()'250318_0827' +app_version <- function()'250319_1306' ######## -#### Current file: R//baseline_table.R +#### Current file: R//baseline_table.R ######## #' Print a flexible baseline characteristics table @@ -42,7 +42,7 @@ baseline_table <- function(data, fun.args = NULL, fun = gtsummary::tbl_summary, ######## -#### Current file: R//contrast_text.R +#### Current file: R//contrast_text.R ######## #' @title Contrast Text Color @@ -99,7 +99,7 @@ contrast_text <- function(background, ######## -#### Current file: R//correlations-module.R +#### Current file: R//correlations-module.R ######## #' Data correlations evaluation module @@ -260,7 +260,7 @@ cor_demo_app() ######## -#### Current file: R//custom_SelectInput.R +#### Current file: R//custom_SelectInput.R ######## #' A selectizeInput customized for data frames with column labels @@ -447,7 +447,7 @@ vectorSelectInput <- function(inputId, ######## -#### Current file: R//cut-variable-dates.R +#### Current file: R//cut-variable-dates.R ######## library(datamods) @@ -554,13 +554,16 @@ library(shiny) #' f <- d_t |> cut(2) #' readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "03:02:20", NA)) |> cut(breaks = lubridate::as_datetime(c(hms::as_hms(levels(f)), hms::as_hms(max(d_t, na.rm = TRUE) + 1))), right = FALSE) cut.hms <- function(x, breaks, ...) { + ## as_hms keeps returning warnings on tz(); ignored + suppressWarnings({ if (hms::is_hms(breaks)) { - breaks <- lubridate::as_datetime(breaks, tz = "UTC") + breaks <- lubridate::as_datetime(breaks) } - x <- lubridate::as_datetime(x, tz = "UTC") + x <- lubridate::as_datetime(x) out <- cut.POSIXt(x, breaks = breaks, ...) attr(out, which = "brks") <- hms::as_hms(lubridate::as_datetime(attr(out, which = "brks"))) attr(out, which = "levels") <- as.character(hms::as_hms(lubridate::as_datetime(attr(out, which = "levels")))) + }) out } @@ -1089,7 +1092,7 @@ plot_histogram <- function(data, column, bins = 30, breaks = NULL, color = "#112 ######## -#### Current file: R//data_plots.R +#### Current file: R//data_plots.R ######## # source(here::here("functions.R")) @@ -1206,6 +1209,99 @@ data_visuals_server <- function(id, plot = NULL ) + # ## --- New attempt + # + # rv$plot.params <- shiny::reactive({ + # get_plot_options(input$type) |> purrr::pluck(1) + # }) + # + # c(output, + # list(shiny::renderUI({ + # columnSelectInput( + # inputId = ns("primary"), + # data = data, + # placeholder = "Select variable", + # label = "Response variable", + # multiple = FALSE + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$primary) + # # browser() + # + # if (!input$primary %in% names(data())) { + # plot_data <- data()[1] + # } else { + # plot_data <- data()[input$primary] + # } + # + # plots <- possible_plots( + # data = plot_data + # ) + # + # plots_named <- get_plot_options(plots) |> + # lapply(\(.x){ + # stats::setNames(.x$descr, .x$note) + # }) + # + # vectorSelectInput( + # inputId = ns("type"), + # selected = NULL, + # label = shiny::h4("Plot type"), + # choices = Reduce(c, plots_named), + # multiple = FALSE + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$type) + # + # cols <- c( + # rv$plot.params()[["secondary.extra"]], + # all_but( + # colnames(subset_types( + # data(), + # rv$plot.params()[["secondary.type"]] + # )), + # input$primary + # ) + # ) + # + # columnSelectInput( + # inputId = ns("secondary"), + # data = data, + # selected = cols[1], + # placeholder = "Please select", + # label = if (isTRUE(rv$plot.params()[["secondary.multi"]])) "Additional variables" else "Secondary variable", + # multiple = rv$plot.params()[["secondary.multi"]], + # maxItems = rv$plot.params()[["secondary.max"]], + # col_subset = cols, + # none_label = "No variable" + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$type) + # columnSelectInput( + # inputId = ns("tertiary"), + # data = data, + # placeholder = "Please select", + # label = "Grouping variable", + # multiple = FALSE, + # col_subset = c( + # "none", + # all_but( + # colnames(subset_types( + # data(), + # rv$plot.params()[["tertiary.type"]] + # )), + # input$primary, + # input$secondary + # ) + # ), + # none_label = "No stratification" + # ) + # }) + # )|> setNames(c("primary","type","secondary","tertiary")),keep.null = TRUE) + output$primary <- shiny::renderUI({ columnSelectInput( inputId = ns("primary"), @@ -1458,6 +1554,16 @@ supported_plots <- function() { tertiary.type = c("dichotomous", "ordinal"), secondary.extra = NULL ), + plot_box = list( + fun = "plot_box", + descr = "Box plot", + note = "A classic way to plot data distribution by groups", + primary.type = c("continuous", "dichotomous", "ordinal"), + secondary.type = c("dichotomous", "ordinal"), + secondary.multi = FALSE, + tertiary.type = c("dichotomous", "ordinal"), + secondary.extra = "none" + ), plot_euler = list( fun = "plot_euler", descr = "Euler diagram", @@ -1629,18 +1735,49 @@ line_break <- function(data, lineLength = 20, fixed = FALSE) { } -wrap_plot_list <- function(data) { - if (length(data) > 1) { - out <- data |> - allign_axes() |> - patchwork::wrap_plots(guides = "collect", axes = "collect", axis_titles = "collect") +#' Wrapping +#' +#' @param data list of ggplot2 objects +#' @param tag_levels passed to patchwork::plot_annotation if given. Default is NULL +#' +#' @returns list of ggplot2 objects +#' @export +#' +wrap_plot_list <- function(data, tag_levels = NULL) { + if (ggplot2::is.ggplot(data[[1]])) { + if (length(data) > 1) { + out <- data |> + (\(.x){ + if (rlang::is_named(.x)) { + purrr::imap(.x, \(.y, .i){ + .y + ggplot2::ggtitle(.i) + }) + } else { + .x + } + })() |> + allign_axes() |> + patchwork::wrap_plots(guides = "collect", axes = "collect", axis_titles = "collect") + if (!is.null(tag_levels)) { + out <- out + patchwork::plot_annotation(tag_levels = tag_levels) + } + } else { + out <- data + } } else { - out <- data + cli::cli_abort("Can only wrap lists of {.cls ggplot} objects") } out } +#' Alligns axes between plots +#' +#' @param ... ggplot2 objects or list of ggplot2 objects +#' +#' @returns list of ggplot2 objects +#' @export +#' allign_axes <- function(...) { # https://stackoverflow.com/questions/62818776/get-axis-limits-from-ggplot-object # https://github.com/thomasp85/patchwork/blob/main/R/plot_multipage.R#L150 @@ -1652,23 +1789,37 @@ allign_axes <- function(...) { cli::cli_abort("Can only align {.cls ggplot} objects or a list of them") } - # browser() - yr <- purrr::map(p, ~ ggplot2::layer_scales(.x)$y$get_limits()) |> - unlist() |> - range() |> - unique() + yr <- clean_common_axis(p, "y") - xr <- purrr::map(p, ~ ggplot2::layer_scales(.x)$x$get_limits()) |> - unlist() |> - range() |> - unique() + xr <- clean_common_axis(p, "x") p |> purrr::map(~ .x + ggplot2::xlim(xr) + ggplot2::ylim(yr)) } +#' Extract and clean axis ranges +#' +#' @param p plot +#' @param axis axis. x or y. +#' +#' @returns vector +#' @export +#' +clean_common_axis <- function(p, axis) { + purrr::map(p, ~ ggplot2::layer_scales(.x)[[axis]]$get_limits()) |> + unlist() |> + (\(.x){ + if (is.numeric(.x)) { + range(.x) + } else { + .x + } + })() |> + unique() +} + ######## -#### Current file: R//data-import.R +#### Current file: R//data-import.R ######## data_import_ui <- function(id) { @@ -1732,27 +1883,7 @@ data_import_server <- function(id) { id = ns("file_import"), show_data_in = "popup", trigger_return = "change", - return_class = "data.frame", - read_fns = list( - ods = import_ods, - dta = function(file) { - haven::read_dta( - file = file, - .name_repair = "unique_quiet" - ) - }, - csv = import_delim, - tsv = import_delim, - txt = import_delim, - xls = import_xls, - xlsx = import_xls, - rds = function(file) { - readr::read_rds( - file = file, - name_repair = "unique_quiet" - ) - } - ) + return_class = "data.frame" ) shiny::observeEvent(data_file$data(), { @@ -1845,7 +1976,7 @@ data_import_demo_app <- function() { ######## -#### Current file: R//data-summary.R +#### Current file: R//data-summary.R ######## #' Data summary module @@ -2154,7 +2285,7 @@ add_class_icon <- function(grid, column = "class") { ######## -#### Current file: R//file-import-module.R +#### Current file: R//file-import-module.R ######## #' Shiny UI module to load a data file @@ -2285,7 +2416,7 @@ file_app() ######## -#### Current file: R//helpers.R +#### Current file: R//helpers.R ######## #' Wrapper function to get function from character vector referring to function from namespace. Passed to 'do.call()' @@ -2505,7 +2636,9 @@ default_parsing <- function(data) { out <- data |> REDCapCAST::parse_data() |> REDCapCAST::as_factor() |> - REDCapCAST::numchar2fct() + REDCapCAST::numchar2fct(numeric.threshold = 8,character.throshold = 10) |> + REDCapCAST::as_logical() |> + REDCapCAST::fct_drop() purrr::map2(out,name_labels,\(.x,.l){ if (!(is.na(.l) | .l=="")) { @@ -2565,6 +2698,7 @@ remove_empty_cols <- function(data,cutoff=.7){ #' @param index index name #' #' @returns list +#' @export #' #' @examples #' ls_d <- list(test=c(1:20)) @@ -2599,7 +2733,7 @@ missing_fraction <- function(data){ ######## -#### Current file: R//import-file-ext.R +#### Current file: R//import-file-ext.R ######## #' @title Import data from a file @@ -2858,7 +2992,7 @@ import_file_server <- function(id, parameters <- parameters[which(names(parameters) %in% rlang::fn_fmls_names(get(read_fns[[extension]])))] # parameters <- parameters[which(names(parameters) %in% rlang::fn_fmls_names(read_fns[[extension]]))] imported <- try(rlang::exec(read_fns[[extension]], !!!parameters), silent = TRUE) - code <- rlang::call2(read_fns[[extension]], !!!modifyList(parameters, list(file = input$file$name)), .ns = "freesearcheR") + code <- rlang::call2(read_fns[[extension]], !!!modifyList(parameters, list(file = input$file$name)), .ns = "FreesearchR") if (inherits(imported, "try-error")) { imported <- try(rlang::exec(rio::import, !!!parameters[1]), silent = TRUE) @@ -3174,7 +3308,118 @@ import_file_demo_app <- function() { ######## -#### Current file: R//plot_euler.R +#### Current file: R//launch_FreesearchR.R +######## + +#' Easily launch the FreesearchR app +#' +#' @description +#' All data.frames in the global environment will be accessible through the app. +#' +#' @param ... passed on to `shiny::runApp()` +#' +#' @returns shiny app +#' @export +#' +#' @examples +#' \dontrun{ +#' data(mtcars) +#' shiny_FreesearchR(launch.browser = TRUE) +#' } +launch_FreesearchR <- function(...){ + appDir <- system.file("apps", "FreesearchR", package = "FreesearchR") + if (appDir == "") { + stop("Could not find the app directory. Try re-installing `FreesearchR`.", call. = FALSE) + } + + a <- shiny::runApp(appDir = paste0(appDir,"/app.R"), ...) + return(invisible(a)) +} + + +######## +#### Current file: R//plot_box.R +######## + +#' Beautiful box plot(s) +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' mtcars |> plot_box(x = "mpg", y = "cyl", z = "gear") +#' mtcars |> +#' default_parsing() |> +#' plot_box(x = "mpg", y = "cyl", z = "gear") +plot_box <- function(data, x, y, z = NULL) { + if (!is.null(z)) { + ds <- split(data, data[z]) + } else { + ds <- list(data) + } + + out <- lapply(ds, \(.ds){ + plot_box_single( + data = .ds, + x = x, + y = y + ) + }) + + wrap_plot_list(out) + # patchwork::wrap_plots(out,guides = "collect") +} + + + + +#' Create nice box-plots +#' +#' @name data-plots +#' +#' @returns +#' @export +#' +#' @examples +#' mtcars |> plot_box_single("mpg","cyl") +plot_box_single <- function(data, x, y=NULL, seed = 2103) { + set.seed(seed) + + if (is.null(y)) { + y <- "All" + data[[y]] <- y + } + + discrete <- !outcome_type(data[[y]]) %in% "continuous" + + data |> + ggplot2::ggplot(ggplot2::aes(x = !!dplyr::sym(x), y = !!dplyr::sym(y), fill = !!dplyr::sym(y), group = !!dplyr::sym(y))) + + ggplot2::geom_boxplot(linewidth = 1.8, outliers = FALSE) + + ## THis could be optional in future + ggplot2::geom_jitter(color = "black", size = 2, alpha = 0.9) + + ggplot2::coord_flip() + + # viridis::scale_fill_viridis(discrete = discrete, option = "C") + + # ggplot2::theme_void() + + ggplot2::theme( + legend.position = "none", + # panel.grid.major = element_blank(), + # panel.grid.minor = element_blank(), + # axis.text.y = element_blank(), + # axis.title.y = element_blank(), + text = ggplot2::element_text(size = 20), + # axis.text = ggplot2::element_blank(), + # plot.title = element_blank(), + panel.background = ggplot2::element_rect(fill = "white"), + plot.background = ggplot2::element_rect(fill = "white"), + panel.border = ggplot2::element_blank() + ) +} + + +######## +#### Current file: R//plot_euler.R ######## #' Area proportional venn diagrams @@ -3257,9 +3502,6 @@ ggeulerr <- function( #' mtcars |> plot_euler("vs", "am", seed = 1) plot_euler <- function(data, x, y, z = NULL, seed = 2103) { set.seed(seed = seed) - - # data <- data[c(...,z)] - if (!is.null(z)) { ds <- split(data, data[z]) } else { @@ -3272,6 +3514,7 @@ plot_euler <- function(data, x, y, z = NULL, seed = 2103) { plot_euler_single() }) +# names(out) wrap_plot_list(out) # patchwork::wrap_plots(out, guides = "collect") } @@ -3295,7 +3538,7 @@ plot_euler_single <- function(data) { ggeulerr(shape = "circle") + ggplot2::theme_void() + ggplot2::theme( - legend.position = "right", + legend.position = "none", # panel.grid.major = element_blank(), # panel.grid.minor = element_blank(), # axis.text.y = element_blank(), @@ -3311,7 +3554,7 @@ plot_euler_single <- function(data) { ######## -#### Current file: R//plot_hbar.R +#### Current file: R//plot_hbar.R ######## #' Nice horizontal stacked bars (Grotta bars) @@ -3412,7 +3655,7 @@ vertical_stacked_bars <- function(data, ######## -#### Current file: R//plot_ridge.R +#### Current file: R//plot_ridge.R ######## #' Plot nice ridge plot @@ -3446,7 +3689,7 @@ plot_ridge <- function(data, x, y, z = NULL, ...) { ######## -#### Current file: R//plot_sankey.R +#### Current file: R//plot_sankey.R ######## #' Readying data for sankey plot @@ -3652,7 +3895,7 @@ plot_sankey_single <- function(data, x, y, color.group = c("x", "y"), colors = N ######## -#### Current file: R//plot_scatter.R +#### Current file: R//plot_scatter.R ######## #' Beautiful violin plot @@ -3683,7 +3926,7 @@ plot_scatter <- function(data, x, y, z = NULL) { ######## -#### Current file: R//plot_violin.R +#### Current file: R//plot_violin.R ######## #' Beatiful violin plot @@ -3716,7 +3959,7 @@ plot_violin <- function(data, x, y, z = NULL) { ######## -#### Current file: R//redcap_read_shiny_module.R +#### Current file: R//redcap_read_shiny_module.R ######## #' Shiny module to browser and export REDCap data @@ -4303,14 +4546,14 @@ redcap_demo_app <- function() { ######## -#### Current file: R//redcap.R +#### Current file: R//redcap.R ######## ######## -#### Current file: R//regression_model.R +#### Current file: R//regression_model.R ######## #' Create a regression model programatically @@ -4952,7 +5195,7 @@ regression_model_uv_list <- function(data, ######## -#### Current file: R//regression_plot.R +#### Current file: R//regression_plot.R ######## #' Regression coef plot from gtsummary. Slightly modified to pass on arguments @@ -4972,15 +5215,16 @@ regression_model_uv_list <- function(data, #' #' @examples #' \dontrun{ -#' mod <- lm(mpg ~ ., mtcars) +#' mod <- lm(mpg ~ ., default_parsing(mtcars)) #' p <- mod |> #' gtsummary::tbl_regression() |> #' plot(colour = "variable") #' } #' plot.tbl_regression <- function(x, - # remove_header_rows = TRUE, - # remove_reference_rows = FALSE, + plot_ref = TRUE, + remove_header_rows = TRUE, + remove_reference_rows = FALSE, ...) { # check_dots_empty() gtsummary:::check_pkg_installed("ggstats") @@ -4989,33 +5233,31 @@ plot.tbl_regression <- function(x, # gtsummary:::check_scalar_logical(remove_reference_rows) df_coefs <- x$table_body - # if (isTRUE(remove_header_rows)) { - # df_coefs <- df_coefs |> dplyr::filter(!.data$header_row %in% TRUE) - # } - # if (isTRUE(remove_reference_rows)) { - # df_coefs <- df_coefs |> dplyr::filter(!.data$reference_row %in% TRUE) - # } - # browser() + if (isTRUE(remove_header_rows)) { + df_coefs <- df_coefs |> dplyr::filter(!header_row %in% TRUE) + } + if (isTRUE(remove_reference_rows)) { + df_coefs <- df_coefs |> dplyr::filter(!reference_row %in% TRUE) + } + # Removes redundant label df_coefs$label[df_coefs$row_type == "label"] <- "" - df_coefs %>% + # Add estimate value to reference level + if (plot_ref == TRUE){ + df_coefs[df_coefs$var_type == "categorical" & is.na(df_coefs$reference_row),"estimate"] <- if (x$inputs$exponentiate) 1 else 0} + + p <- df_coefs |> ggstats::ggcoef_plot(exponentiate = x$inputs$exponentiate, ...) + + if (x$inputs$exponentiate){ + p <- symmetrical_scale_x_log10(p) + } + p } -# default_parsing(mtcars) |> lapply(class) -# -# purrr::imap(mtcars,\(.x,.i){ -# if (.i %in% c("vs","am","gear","carb")){ -# as.factor(.x) -# } else .x -# }) |> dplyr::bind_cols() -# -# - - #' Wrapper to pivot gtsummary table data to long for plotting #' #' @param list a custom regression models list @@ -5057,8 +5299,52 @@ merge_long <- function(list, model.names) { } +#' Easily round log scale limits for nice plots +#' +#' @param data data +#' @param fun rounding function (floor/ceiling) +#' @param ... ignored +#' +#' @returns numeric vector +#' @export +#' +#' @examples +#' limit_log(-.1,floor) +#' limit_log(.1,ceiling) +#' limit_log(-2.1,ceiling) +#' limit_log(2.1,ceiling) +limit_log <- function(data,fun,...){ + fun(10^-floor(data)*10^data)/10^-floor(data) +} + +#' Ensure symmetrical plot around 1 on a logarithmic x scale for ratio plots +#' +#' @param plot ggplot2 plot +#' @param breaks breaks used and mirrored +#' @param ... ignored +#' +#' @returns ggplot2 object +#' @export +#' +symmetrical_scale_x_log10 <- function(plot,breaks=c(1,2,3,5,10),...){ + rx <- ggplot2::layer_scales(plot)$x$get_limits() + + x_min <- floor(10*rx[1])/10 + x_max <- ceiling(10*rx[2])/10 + + rx_min <- limit_log(rx[1],floor) + rx_max <- limit_log(rx[2],ceiling) + + max_abs_x <- max(abs(c(x_min,x_max))) + + ticks <- log10(breaks)+(ceiling(max_abs_x)-1) + browser() + plot + ggplot2::scale_x_log10(limits=c(rx_min,rx_max),breaks=create_log_tics(10^ticks[ticks<=max_abs_x])) +} + + ######## -#### Current file: R//regression_table.R +#### Current file: R//regression_table.R ######## #' Create table of regression model @@ -5144,7 +5430,7 @@ merge_long <- function(list, model.names) { #' #' @export #' regression_table.default <- function(x, ..., args.list = NULL, fun = "gtsummary::tbl_regression") { #' # Stripping custom class -#' class(x) <- class(x)[class(x) != "freesearcher_model"] +#' class(x) <- class(x)[class(x) != "freesearchr_model"] #' #' if (any(c(length(class(x)) != 1, class(x) != "lm"))) { #' if (!"exponentiate" %in% names(args.list)) { @@ -5173,7 +5459,7 @@ regression_table <- function(x, ...) { regression_table_create <- function(x, ..., args.list = NULL, fun = "gtsummary::tbl_regression") { # Stripping custom class - class(x) <- class(x)[class(x) != "freesearcher_model"] + class(x) <- class(x)[class(x) != "freesearchr_model"] if (any(c(length(class(x)) != 1, class(x) != "lm"))) { if (!"exponentiate" %in% names(args.list)) { @@ -5209,7 +5495,7 @@ tbl_merge <- function(data) { ######## -#### Current file: R//report.R +#### Current file: R//report.R ######## #' Split vector by an index and embed addition @@ -5297,50 +5583,7 @@ modify_qmd <- function(file, format) { ######## -#### Current file: R//shiny_freesearcheR.R -######## - -#' Launch the freesearcheR tool locally -#' -#' @description -#' All data.frames in the global environment will be accessible through the app. -#' -#' -#' @param ... arguments passed on to `shiny::runApp()` -#' -#' @return shiny app -#' @export -#' -#' @examples -#' \dontrun{ -#' data(mtcars) -#' shiny_freesearcheR(launch.browser = TRUE) -#' } -shiny_freesearcheR <- function(...) { - appDir <- system.file("apps", "freesearcheR", package = "freesearcheR") - if (appDir == "") { - stop("Could not find the app directory. Try re-installing `freesearcheR`.", call. = FALSE) - } - - a <- shiny::runApp(appDir = paste0(appDir,"/app.R"), ...) - return(invisible(a)) -} - - -#' Easily launch the freesearcheR app -#' -#' @param ... passed on to `shiny::runApp()` -#' -#' @returns shiny app -#' @export -#' -launch_freesearcheR <- function(...){ - shiny_freesearcheR(...) -} - - -######## -#### Current file: R//theme.R +#### Current file: R//theme.R ######## #' Custom theme based on unity @@ -5422,7 +5665,7 @@ gg_theme_export <- function(){ ######## -#### Current file: R//update-factor-ext.R +#### Current file: R//update-factor-ext.R ######## @@ -5692,7 +5935,7 @@ modal_update_factor <- function(id, #' #' @importFrom shinyWidgets WinBox wbOptions wbControls #' @importFrom htmltools tagList -#' @rdname create-column +#' @rdname update-factor winbox_update_factor <- function(id, title = i18n("Update levels of a factor"), options = shinyWidgets::wbOptions(), @@ -5719,7 +5962,7 @@ winbox_update_factor <- function(id, ######## -#### Current file: R//update-variables-ext.R +#### Current file: R//update-variables-ext.R ######## library(data.table) @@ -6501,7 +6744,7 @@ clean_date <- function(data){ ######## -#### Current file: R//wide2long.R +#### Current file: R//wide2long.R ######## #' Alternative pivoting method for easily pivoting based on name pattern @@ -6660,7 +6903,7 @@ grepl_fix <- function(data, pattern, type = c("prefix", "infix", "suffix")) { ######## -#### Current file: /Users/au301842/freesearcheR/inst/apps/freesearcheR/ui.R +#### Current file: /Users/au301842/FreesearchR/inst/apps/FreesearchR/ui.R ######## # ns <- NS(id) @@ -6672,7 +6915,7 @@ ui_elements <- list( ######### ############################################################################## "home" = bslib::nav_panel( - title = "freesearcheR", + title = "FreesearchR", shiny::fluidRow( shiny::column(width = 2), shiny::column( @@ -7263,10 +7506,10 @@ ui <- bslib::page_fixed( # add the name of the tab you want to use as title in data-value shiny::HTML( ".container-fluid > .nav > li > - a[data-value='freesearcheR'] {font-size: 28px}" + a[data-value='FreesearchR'] {font-size: 28px}" ) ), - title = "freesearcheR", + title = "FreesearchR", theme = light, shiny::useBusyIndicators(), bslib::page_navbar( @@ -7289,7 +7532,7 @@ ui <- bslib::page_fixed( ), shiny::p( style = "margin: 1; color: #888;", - "AG Damsbo | v", app_version(), " | AGPLv3 license | ", shiny::tags$a("Source on Github", href = "https://github.com/agdamsbo/FreesearchR/", target = "_blank", rel = "noopener noreferrer") + "AG Damsbo | v", app_version(), " | ",shiny::tags$a("AGPLv3 license", href = "https://github.com/agdamsbo/FreesearchR/blob/main/LICENSE.md", target = "_blank", rel = "noopener noreferrer")," | ", shiny::tags$a("Source on Github", href = "https://github.com/agdamsbo/FreesearchR/", target = "_blank", rel = "noopener noreferrer") ), ) ) @@ -7297,7 +7540,7 @@ ui <- bslib::page_fixed( ######## -#### Current file: /Users/au301842/freesearcheR/inst/apps/freesearcheR/server.R +#### Current file: /Users/au301842/FreesearchR/inst/apps/FreesearchR/server.R ######## library(readr) @@ -7328,7 +7571,7 @@ library(IDEAFilter) library(shinyWidgets) library(DT) library(gtsummary) -# library(freesearcheR) +# library(FreesearchR) # source("functions.R") @@ -7476,7 +7719,7 @@ server <- function(input, output, session) { paste(collapse = "") |> paste("|> dplyr::select(", paste(input$import_var, collapse = ","), ") |> - freesearcheR::default_parsing()") |> + FreesearchR::default_parsing()") |> (\(.x){ paste0("data <- ", .x) })() @@ -8279,7 +8522,7 @@ server <- function(input, output, session) { ######## -#### Current file: /Users/au301842/freesearcheR/inst/apps/freesearcheR/launch.R +#### Current file: /Users/au301842/FreesearchR/inst/apps/FreesearchR/launch.R ######## shinyApp(ui, server) diff --git a/inst/apps/FreesearchR/server.R b/inst/apps/FreesearchR/server.R index 52b41740..59b49170 100644 --- a/inst/apps/FreesearchR/server.R +++ b/inst/apps/FreesearchR/server.R @@ -26,7 +26,7 @@ library(IDEAFilter) library(shinyWidgets) library(DT) library(gtsummary) -# library(freesearcheR) +# library(FreesearchR) # source("functions.R") @@ -174,7 +174,7 @@ server <- function(input, output, session) { paste(collapse = "") |> paste("|> dplyr::select(", paste(input$import_var, collapse = ","), ") |> - freesearcheR::default_parsing()") |> + FreesearchR::default_parsing()") |> (\(.x){ paste0("data <- ", .x) })() diff --git a/inst/apps/FreesearchR/ui.R b/inst/apps/FreesearchR/ui.R index e6bdc816..cdbd7697 100644 --- a/inst/apps/FreesearchR/ui.R +++ b/inst/apps/FreesearchR/ui.R @@ -7,7 +7,7 @@ ui_elements <- list( ######### ############################################################################## "home" = bslib::nav_panel( - title = "freesearcheR", + title = "FreesearchR", shiny::fluidRow( shiny::column(width = 2), shiny::column( @@ -598,10 +598,10 @@ ui <- bslib::page_fixed( # add the name of the tab you want to use as title in data-value shiny::HTML( ".container-fluid > .nav > li > - a[data-value='freesearcheR'] {font-size: 28px}" + a[data-value='FreesearchR'] {font-size: 28px}" ) ), - title = "freesearcheR", + title = "FreesearchR", theme = light, shiny::useBusyIndicators(), bslib::page_navbar( @@ -624,7 +624,7 @@ ui <- bslib::page_fixed( ), shiny::p( style = "margin: 1; color: #888;", - "AG Damsbo | v", app_version(), " | AGPLv3 license | ", shiny::tags$a("Source on Github", href = "https://github.com/agdamsbo/FreesearchR/", target = "_blank", rel = "noopener noreferrer") + "AG Damsbo | v", app_version(), " | ",shiny::tags$a("AGPLv3 license", href = "https://github.com/agdamsbo/FreesearchR/blob/main/LICENSE.md", target = "_blank", rel = "noopener noreferrer")," | ", shiny::tags$a("Source on Github", href = "https://github.com/agdamsbo/FreesearchR/", target = "_blank", rel = "noopener noreferrer") ), ) ) diff --git a/inst/apps/FreesearchR/www/intro.md b/inst/apps/FreesearchR/www/intro.md index 337fd2c7..b7c83771 100644 --- a/inst/apps/FreesearchR/www/intro.md +++ b/inst/apps/FreesearchR/www/intro.md @@ -1,6 +1,6 @@ # Welcome -This is the ***freesearcheR*** data analysis tool. We intend the ***freesearcheR*** to be a powerful and free tool for easy data evaluation and analysis at the hands of the clinician. If you need more advanced tools for regression models or plotting, you'll probably be better off using *R* or similar directly on your own machine. +This is the ***FreesearchR*** 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. If you need more advanced tools for regression models or plotting, you'll probably be better off using *R* or similar directly on your own machine. 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. @@ -24,6 +24,6 @@ There are some simple steps to go through (see corresponding tabs in the top): 1. Export the the analyses results for MS Word or [LibreOffice](https://www.libreoffice.org/) as well as the data with preserved metadata. -Have a look at the [documentations page](https://agdamsbo.github.io/freesearcheR/) for further project description. If you're interested in the source code, then go on, [have a look](https://github.com/agdamsbo/freesearcheR)! +The full [project documentation is here](https://agdamsbo.github.io/FreesearchR/) for documenting the project, functions, road map and more. If you're interested in the source code, then [everything is open and you are free to read, copy, modify and improve](https://github.com/agdamsbo/FreesearchR), and please let us know if you want to contribute! -If you encounter anything strange or the app doesn't act as expected. Please [report on Github](https://github.com/agdamsbo/freesearcheR/issues). +Contributions can be reporting issues, suggesting new functionality, improving code or any other feedback. [It all goes here](https://github.com/agdamsbo/FreesearchR/issues). diff --git a/man/allign_axes.Rd b/man/allign_axes.Rd new file mode 100644 index 00000000..5bb4a39e --- /dev/null +++ b/man/allign_axes.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data_plots.R +\name{allign_axes} +\alias{allign_axes} +\title{Alligns axes between plots} +\usage{ +allign_axes(...) +} +\arguments{ +\item{...}{ggplot2 objects or list of ggplot2 objects} +} +\value{ +list of ggplot2 objects +} +\description{ +Alligns axes between plots +} diff --git a/man/limit_log.Rd b/man/limit_log.Rd new file mode 100644 index 00000000..55bcf3ce --- /dev/null +++ b/man/limit_log.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/regression_plot.R +\name{limit_log} +\alias{limit_log} +\title{Easily round log scale limits for nice plots} +\usage{ +limit_log(data, fun, ...) +} +\arguments{ +\item{data}{data} + +\item{fun}{rounding function (floor/ceiling)} + +\item{...}{ignored} +} +\value{ +numeric vector +} +\description{ +Easily round log scale limits for nice plots +} +\examples{ +limit_log(-.1,floor) +limit_log(.1,ceiling) +limit_log(-2.1,ceiling) +limit_log(2.1,ceiling) +} diff --git a/man/symmetrical_scale_x_log10.Rd b/man/symmetrical_scale_x_log10.Rd new file mode 100644 index 00000000..24341dfe --- /dev/null +++ b/man/symmetrical_scale_x_log10.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/regression_plot.R +\name{symmetrical_scale_x_log10} +\alias{symmetrical_scale_x_log10} +\title{Ensure symmetrical plot around 1 on a logarithmic x scale for ratio plots} +\usage{ +symmetrical_scale_x_log10(plot, breaks = c(1, 2, 3, 5, 10), ...) +} +\arguments{ +\item{plot}{ggplot2 plot} + +\item{breaks}{breaks used and mirrored} + +\item{...}{ignored} +} +\value{ +ggplot2 object +} +\description{ +Ensure symmetrical plot around 1 on a logarithmic x scale for ratio plots +} diff --git a/man/wrap_plot_list.Rd b/man/wrap_plot_list.Rd new file mode 100644 index 00000000..d1e8fd19 --- /dev/null +++ b/man/wrap_plot_list.Rd @@ -0,0 +1,19 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data_plots.R +\name{wrap_plot_list} +\alias{wrap_plot_list} +\title{Wrapping} +\usage{ +wrap_plot_list(data, tag_levels = NULL) +} +\arguments{ +\item{data}{list of ggplot2 objects} + +\item{tag_levels}{passed to patchwork::plot_annotation if given. Default is NULL} +} +\value{ +list of ggplot2 objects +} +\description{ +Wrapping +} diff --git a/renv.lock b/renv.lock index bf442bf5..72de09ff 100644 --- a/renv.lock +++ b/renv.lock @@ -188,9 +188,9 @@ }, "Hmisc": { "Package": "Hmisc", - "Version": "5.2-2", + "Version": "5.2-3", "Source": "Repository", - "Date": "2025-01-10", + "Date": "2025-03-16", "Title": "Harrell Miscellaneous", "Authors@R": "c(person(given = \"Frank E\", family = \"Harrell Jr\", role = c(\"aut\", \"cre\"), email = \"fh@fharrell.com\", comment = c(ORCID = \"0000-0002-8271-5493\")), person(given = \"Charles\", family = \"Dupont\", role = \"ctb\", email = \"charles.dupont@vumc.org\", comment = \"contributed several functions and maintains latex functions\"))", "Maintainer": "Frank E Harrell Jr ", @@ -674,11 +674,11 @@ }, "RcppArmadillo": { "Package": "RcppArmadillo", - "Version": "14.2.3-1", + "Version": "14.4.0-1", "Source": "Repository", "Type": "Package", "Title": "'Rcpp' Integration for the 'Armadillo' Templated Linear Algebra Library", - "Date": "2025-02-05", + "Date": "2025-02-17", "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Romain\", \"Francois\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Doug\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Binxiang\", \"Ni\", role = \"aut\"), person(\"Conrad\", \"Sanderson\", role = \"aut\", comment = c(ORCID = \"0000-0002-0049-4501\")))", "Description": "'Armadillo' is a templated C++ linear algebra library (by Conrad Sanderson) that aims towards a good balance between speed and ease of use. Integer, floating point and complex numbers are supported, as well as a subset of trigonometric and statistics functions. Various matrix decompositions are provided through optional integration with LAPACK and ATLAS libraries. The 'RcppArmadillo' package includes the header files from the templated 'Armadillo' library. Thus users do not need to install 'Armadillo' itself in order to use 'RcppArmadillo'. From release 7.800.0 on, 'Armadillo' is licensed under Apache License 2; previous releases were under licensed as MPL 2.0 from version 3.800.0 onwards and LGPL-3 prior to that; 'RcppArmadillo' (the 'Rcpp' bindings/bridge to Armadillo) is licensed under the GNU GPL version 2 or later, as is the rest of 'Rcpp'.", "License": "GPL (>= 2)", @@ -749,11 +749,11 @@ }, "Rdpack": { "Package": "Rdpack", - "Version": "2.6.2", + "Version": "2.6.3", "Source": "Repository", "Type": "Package", "Title": "Update and Manipulate Rd Documentation Objects", - "Authors@R": "c( person(given = c(\"Georgi\", \"N.\"), family = \"Boshnakov\", role = c(\"aut\", \"cre\"), email = \"georgi.boshnakov@manchester.ac.uk\"), person(given = \"Duncan\", family = \"Murdoch\", role = \"ctb\", email = \"murdoch.duncan@gmail.com\") )", + "Authors@R": "c( person(given = c(\"Georgi\", \"N.\"), family = \"Boshnakov\", role = c(\"aut\", \"cre\"), email = \"georgi.boshnakov@manchester.ac.uk\", comment = c(ORCID = \"0000-0003-2839-346X\")), person(given = \"Duncan\", family = \"Murdoch\", role = \"ctb\", email = \"murdoch.duncan@gmail.com\") )", "Description": "Functions for manipulation of R documentation objects, including functions reprompt() and ereprompt() for updating 'Rd' documentation for functions, methods and classes; 'Rd' macros for citations and import of references from 'bibtex' files for use in 'Rd' files and 'roxygen2' comments; 'Rd' macros for evaluating and inserting snippets of 'R' code and the results of its evaluation or creating graphics on the fly; and many functions for manipulation of references and Rd files.", "URL": "https://geobosh.github.io/Rdpack/ (doc), https://github.com/GeoBosh/Rdpack (devel)", "BugReports": "https://github.com/GeoBosh/Rdpack/issues", @@ -777,13 +777,13 @@ "LazyLoad": "yes", "RoxygenNote": "7.1.1", "NeedsCompilation": "no", - "Author": "Georgi N. Boshnakov [aut, cre], Duncan Murdoch [ctb]", + "Author": "Georgi N. Boshnakov [aut, cre] (), Duncan Murdoch [ctb]", "Maintainer": "Georgi N. Boshnakov ", "Repository": "CRAN" }, "V8": { "Package": "V8", - "Version": "6.0.1", + "Version": "6.0.2", "Source": "Repository", "Type": "Package", "Title": "Embedded JavaScript and WebAssembly Engine for R", @@ -1990,10 +1990,10 @@ }, "cluster": { "Package": "cluster", - "Version": "2.1.8", + "Version": "2.1.8.1", "Source": "Repository", - "VersionNote": "Last CRAN: 2.1.7 on 2024-12-06; 2.1.6 on 2023-11-30; 2.1.5 on 2023-11-27", - "Date": "2024-12-10", + "VersionNote": "Last CRAN: 2.1.8 on 2024-12-10; 2.1.7 on 2024-12-06; 2.1.6 on 2023-11-30; 2.1.5 on 2023-11-27", + "Date": "2025-03-11", "Priority": "recommended", "Title": "\"Finding Groups in Data\": Cluster Analysis Extended Rousseeuw et al.", "Description": "Methods for Cluster analysis. Much extended the original from Peter Rousseeuw, Anja Struyf and Mia Hubert, based on Kaufman and Rousseeuw (1990) \"Finding Groups in Data\".", @@ -2123,7 +2123,7 @@ }, "commonmark": { "Package": "commonmark", - "Version": "1.9.2", + "Version": "1.9.5", "Source": "Repository", "Type": "Package", "Title": "High Performance CommonMark and Github Markdown Rendering in R", @@ -2137,7 +2137,7 @@ "testthat", "xml2" ], - "RoxygenNote": "7.2.3", + "RoxygenNote": "7.3.2", "Language": "en-US", "Encoding": "UTF-8", "NeedsCompilation": "yes", @@ -3719,7 +3719,7 @@ }, "ggeffects": { "Package": "ggeffects", - "Version": "2.2.0", + "Version": "2.2.1", "Source": "Repository", "Type": "Package", "Encoding": "UTF-8", @@ -5246,11 +5246,11 @@ }, "knitr": { "Package": "knitr", - "Version": "1.49", + "Version": "1.50", "Source": "Repository", "Type": "Package", "Title": "A General-Purpose Package for Dynamic Report Generation in R", - "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Abhraneel\", \"Sarma\", role = \"ctb\"), person(\"Adam\", \"Vogt\", role = \"ctb\"), person(\"Alastair\", \"Andrew\", role = \"ctb\"), person(\"Alex\", \"Zvoleff\", role = \"ctb\"), person(\"Amar\", \"Al-Zubaidi\", role = \"ctb\"), person(\"Andre\", \"Simon\", role = \"ctb\", comment = \"the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de\"), person(\"Aron\", \"Atkins\", role = \"ctb\"), person(\"Aaron\", \"Wolen\", role = \"ctb\"), person(\"Ashley\", \"Manton\", role = \"ctb\"), person(\"Atsushi\", \"Yasumoto\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8335-495X\")), person(\"Ben\", \"Baumer\", role = \"ctb\"), person(\"Brian\", \"Diggs\", role = \"ctb\"), person(\"Brian\", \"Zhang\", role = \"ctb\"), person(\"Bulat\", \"Yapparov\", role = \"ctb\"), person(\"Cassio\", \"Pereira\", role = \"ctb\"), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person(\"David\", \"Hall\", role = \"ctb\"), person(\"David\", \"Hugh-Jones\", role = \"ctb\"), person(\"David\", \"Robinson\", role = \"ctb\"), person(\"Doug\", \"Hemken\", role = \"ctb\"), person(\"Duncan\", \"Murdoch\", role = \"ctb\"), person(\"Elio\", \"Campitelli\", role = \"ctb\"), person(\"Ellis\", \"Hughes\", role = \"ctb\"), person(\"Emily\", \"Riederer\", role = \"ctb\"), person(\"Fabian\", \"Hirschmann\", role = \"ctb\"), person(\"Fitch\", \"Simeon\", role = \"ctb\"), person(\"Forest\", \"Fang\", role = \"ctb\"), person(c(\"Frank\", \"E\", \"Harrell\", \"Jr\"), role = \"ctb\", comment = \"the Sweavel package at inst/misc/Sweavel.sty\"), person(\"Garrick\", \"Aden-Buie\", role = \"ctb\"), person(\"Gregoire\", \"Detrez\", role = \"ctb\"), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Hao\", \"Zhu\", role = \"ctb\"), person(\"Heewon\", \"Jeon\", role = \"ctb\"), person(\"Henrik\", \"Bengtsson\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Ian\", \"Lyttle\", role = \"ctb\"), person(\"Hodges\", \"Daniel\", role = \"ctb\"), person(\"Jacob\", \"Bien\", role = \"ctb\"), person(\"Jake\", \"Burkhead\", role = \"ctb\"), person(\"James\", \"Manton\", role = \"ctb\"), person(\"Jared\", \"Lander\", role = \"ctb\"), person(\"Jason\", \"Punyon\", role = \"ctb\"), person(\"Javier\", \"Luraschi\", role = \"ctb\"), person(\"Jeff\", \"Arnold\", role = \"ctb\"), person(\"Jenny\", \"Bryan\", role = \"ctb\"), person(\"Jeremy\", \"Ashkenas\", role = c(\"ctb\", \"cph\"), comment = \"the CSS file at inst/misc/docco-classic.css\"), person(\"Jeremy\", \"Stephens\", role = \"ctb\"), person(\"Jim\", \"Hester\", role = \"ctb\"), person(\"Joe\", \"Cheng\", role = \"ctb\"), person(\"Johannes\", \"Ranke\", role = \"ctb\"), person(\"John\", \"Honaker\", role = \"ctb\"), person(\"John\", \"Muschelli\", role = \"ctb\"), person(\"Jonathan\", \"Keane\", role = \"ctb\"), person(\"JJ\", \"Allaire\", role = \"ctb\"), person(\"Johan\", \"Toloe\", role = \"ctb\"), person(\"Jonathan\", \"Sidi\", role = \"ctb\"), person(\"Joseph\", \"Larmarange\", role = \"ctb\"), person(\"Julien\", \"Barnier\", role = \"ctb\"), person(\"Kaiyin\", \"Zhong\", role = \"ctb\"), person(\"Kamil\", \"Slowikowski\", role = \"ctb\"), person(\"Karl\", \"Forner\", role = \"ctb\"), person(c(\"Kevin\", \"K.\"), \"Smith\", role = \"ctb\"), person(\"Kirill\", \"Mueller\", role = \"ctb\"), person(\"Kohske\", \"Takahashi\", role = \"ctb\"), person(\"Lorenz\", \"Walthert\", role = \"ctb\"), person(\"Lucas\", \"Gallindo\", role = \"ctb\"), person(\"Marius\", \"Hofert\", role = \"ctb\"), person(\"Martin\", \"Modrák\", role = \"ctb\"), person(\"Michael\", \"Chirico\", role = \"ctb\"), person(\"Michael\", \"Friendly\", role = \"ctb\"), person(\"Michal\", \"Bojanowski\", role = \"ctb\"), person(\"Michel\", \"Kuhlmann\", role = \"ctb\"), person(\"Miller\", \"Patrick\", role = \"ctb\"), person(\"Nacho\", \"Caballero\", role = \"ctb\"), person(\"Nick\", \"Salkowski\", role = \"ctb\"), person(\"Niels Richard\", \"Hansen\", role = \"ctb\"), person(\"Noam\", \"Ross\", role = \"ctb\"), person(\"Obada\", \"Mahdi\", role = \"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role = \"ctb\", comment=c(ORCID = \"0000-0002-9101-3362\")), person(\"Pedro\", \"Faria\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\"), person(\"Ramnath\", \"Vaidyanathan\", role = \"ctb\"), person(\"Richard\", \"Cotton\", role = \"ctb\"), person(\"Robert\", \"Krzyzanowski\", role = \"ctb\"), person(\"Rodrigo\", \"Copetti\", role = \"ctb\"), person(\"Romain\", \"Francois\", role = \"ctb\"), person(\"Ruaridh\", \"Williamson\", role = \"ctb\"), person(\"Sagiru\", \"Mati\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1413-3974\")), person(\"Scott\", \"Kostyshak\", role = \"ctb\"), person(\"Sebastian\", \"Meyer\", role = \"ctb\"), person(\"Sietse\", \"Brouwer\", role = \"ctb\"), person(c(\"Simon\", \"de\"), \"Bernard\", role = \"ctb\"), person(\"Sylvain\", \"Rousseau\", role = \"ctb\"), person(\"Taiyun\", \"Wei\", role = \"ctb\"), person(\"Thibaut\", \"Assus\", role = \"ctb\"), person(\"Thibaut\", \"Lamadon\", role = \"ctb\"), person(\"Thomas\", \"Leeper\", role = \"ctb\"), person(\"Tim\", \"Mastny\", role = \"ctb\"), person(\"Tom\", \"Torsney-Weir\", role = \"ctb\"), person(\"Trevor\", \"Davis\", role = \"ctb\"), person(\"Viktoras\", \"Veitas\", role = \"ctb\"), person(\"Weicheng\", \"Zhu\", role = \"ctb\"), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Zachary\", \"Foster\", role = \"ctb\"), person(\"Zhian N.\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Abhraneel\", \"Sarma\", role = \"ctb\"), person(\"Adam\", \"Vogt\", role = \"ctb\"), person(\"Alastair\", \"Andrew\", role = \"ctb\"), person(\"Alex\", \"Zvoleff\", role = \"ctb\"), person(\"Amar\", \"Al-Zubaidi\", role = \"ctb\"), person(\"Andre\", \"Simon\", role = \"ctb\", comment = \"the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de\"), person(\"Aron\", \"Atkins\", role = \"ctb\"), person(\"Aaron\", \"Wolen\", role = \"ctb\"), person(\"Ashley\", \"Manton\", role = \"ctb\"), person(\"Atsushi\", \"Yasumoto\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8335-495X\")), person(\"Ben\", \"Baumer\", role = \"ctb\"), person(\"Brian\", \"Diggs\", role = \"ctb\"), person(\"Brian\", \"Zhang\", role = \"ctb\"), person(\"Bulat\", \"Yapparov\", role = \"ctb\"), person(\"Cassio\", \"Pereira\", role = \"ctb\"), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person(\"David\", \"Hall\", role = \"ctb\"), person(\"David\", \"Hugh-Jones\", role = \"ctb\"), person(\"David\", \"Robinson\", role = \"ctb\"), person(\"Doug\", \"Hemken\", role = \"ctb\"), person(\"Duncan\", \"Murdoch\", role = \"ctb\"), person(\"Elio\", \"Campitelli\", role = \"ctb\"), person(\"Ellis\", \"Hughes\", role = \"ctb\"), person(\"Emily\", \"Riederer\", role = \"ctb\"), person(\"Fabian\", \"Hirschmann\", role = \"ctb\"), person(\"Fitch\", \"Simeon\", role = \"ctb\"), person(\"Forest\", \"Fang\", role = \"ctb\"), person(c(\"Frank\", \"E\", \"Harrell\", \"Jr\"), role = \"ctb\", comment = \"the Sweavel package at inst/misc/Sweavel.sty\"), person(\"Garrick\", \"Aden-Buie\", role = \"ctb\"), person(\"Gregoire\", \"Detrez\", role = \"ctb\"), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Hao\", \"Zhu\", role = \"ctb\"), person(\"Heewon\", \"Jeon\", role = \"ctb\"), person(\"Henrik\", \"Bengtsson\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Ian\", \"Lyttle\", role = \"ctb\"), person(\"Hodges\", \"Daniel\", role = \"ctb\"), person(\"Jacob\", \"Bien\", role = \"ctb\"), person(\"Jake\", \"Burkhead\", role = \"ctb\"), person(\"James\", \"Manton\", role = \"ctb\"), person(\"Jared\", \"Lander\", role = \"ctb\"), person(\"Jason\", \"Punyon\", role = \"ctb\"), person(\"Javier\", \"Luraschi\", role = \"ctb\"), person(\"Jeff\", \"Arnold\", role = \"ctb\"), person(\"Jenny\", \"Bryan\", role = \"ctb\"), person(\"Jeremy\", \"Ashkenas\", role = c(\"ctb\", \"cph\"), comment = \"the CSS file at inst/misc/docco-classic.css\"), person(\"Jeremy\", \"Stephens\", role = \"ctb\"), person(\"Jim\", \"Hester\", role = \"ctb\"), person(\"Joe\", \"Cheng\", role = \"ctb\"), person(\"Johannes\", \"Ranke\", role = \"ctb\"), person(\"John\", \"Honaker\", role = \"ctb\"), person(\"John\", \"Muschelli\", role = \"ctb\"), person(\"Jonathan\", \"Keane\", role = \"ctb\"), person(\"JJ\", \"Allaire\", role = \"ctb\"), person(\"Johan\", \"Toloe\", role = \"ctb\"), person(\"Jonathan\", \"Sidi\", role = \"ctb\"), person(\"Joseph\", \"Larmarange\", role = \"ctb\"), person(\"Julien\", \"Barnier\", role = \"ctb\"), person(\"Kaiyin\", \"Zhong\", role = \"ctb\"), person(\"Kamil\", \"Slowikowski\", role = \"ctb\"), person(\"Karl\", \"Forner\", role = \"ctb\"), person(c(\"Kevin\", \"K.\"), \"Smith\", role = \"ctb\"), person(\"Kirill\", \"Mueller\", role = \"ctb\"), person(\"Kohske\", \"Takahashi\", role = \"ctb\"), person(\"Lorenz\", \"Walthert\", role = \"ctb\"), person(\"Lucas\", \"Gallindo\", role = \"ctb\"), person(\"Marius\", \"Hofert\", role = \"ctb\"), person(\"Martin\", \"Modrák\", role = \"ctb\"), person(\"Michael\", \"Chirico\", role = \"ctb\"), person(\"Michael\", \"Friendly\", role = \"ctb\"), person(\"Michal\", \"Bojanowski\", role = \"ctb\"), person(\"Michel\", \"Kuhlmann\", role = \"ctb\"), person(\"Miller\", \"Patrick\", role = \"ctb\"), person(\"Nacho\", \"Caballero\", role = \"ctb\"), person(\"Nick\", \"Salkowski\", role = \"ctb\"), person(\"Niels Richard\", \"Hansen\", role = \"ctb\"), person(\"Noam\", \"Ross\", role = \"ctb\"), person(\"Obada\", \"Mahdi\", role = \"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role = \"ctb\", comment=c(ORCID = \"0000-0002-9101-3362\")), person(\"Pedro\", \"Faria\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\"), person(\"Ramnath\", \"Vaidyanathan\", role = \"ctb\"), person(\"Richard\", \"Cotton\", role = \"ctb\"), person(\"Robert\", \"Krzyzanowski\", role = \"ctb\"), person(\"Rodrigo\", \"Copetti\", role = \"ctb\"), person(\"Romain\", \"Francois\", role = \"ctb\"), person(\"Ruaridh\", \"Williamson\", role = \"ctb\"), person(\"Sagiru\", \"Mati\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1413-3974\")), person(\"Scott\", \"Kostyshak\", role = \"ctb\"), person(\"Sebastian\", \"Meyer\", role = \"ctb\"), person(\"Sietse\", \"Brouwer\", role = \"ctb\"), person(c(\"Simon\", \"de\"), \"Bernard\", role = \"ctb\"), person(\"Sylvain\", \"Rousseau\", role = \"ctb\"), person(\"Taiyun\", \"Wei\", role = \"ctb\"), person(\"Thibaut\", \"Assus\", role = \"ctb\"), person(\"Thibaut\", \"Lamadon\", role = \"ctb\"), person(\"Thomas\", \"Leeper\", role = \"ctb\"), person(\"Tim\", \"Mastny\", role = \"ctb\"), person(\"Tom\", \"Torsney-Weir\", role = \"ctb\"), person(\"Trevor\", \"Davis\", role = \"ctb\"), person(\"Viktoras\", \"Veitas\", role = \"ctb\"), person(\"Weicheng\", \"Zhu\", role = \"ctb\"), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Zachary\", \"Foster\", role = \"ctb\"), person(\"Zhian N.\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", "Description": "Provides a general-purpose tool for dynamic report generation in R using Literate Programming techniques.", "Depends": [ "R (>= 3.6.0)" @@ -5260,7 +5260,7 @@ "highr (>= 0.11)", "methods", "tools", - "xfun (>= 0.48)", + "xfun (>= 0.51)", "yaml (>= 2.1.19)" ], "Suggests": [ @@ -5290,7 +5290,7 @@ "testit", "tibble", "tikzDevice (>= 0.10)", - "tinytex (>= 0.46)", + "tinytex (>= 0.56)", "webshot", "rstudioapi", "svglite" @@ -5301,10 +5301,10 @@ "Encoding": "UTF-8", "VignetteBuilder": "litedown, knitr", "SystemRequirements": "Package vignettes based on R Markdown v2 or reStructuredText require Pandoc (http://pandoc.org). The function rst2pdf() requires rst2pdf (https://github.com/rst2pdf/rst2pdf).", - "Collate": "'block.R' 'cache.R' 'utils.R' 'citation.R' 'hooks-html.R' 'plot.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R' 'themes.R' 'header.R' 'hooks-asciidoc.R' 'hooks-chunk.R' 'hooks-extra.R' 'hooks-latex.R' 'hooks-md.R' 'hooks-rst.R' 'hooks-textile.R' 'hooks.R' 'output.R' 'package.R' 'pandoc.R' 'params.R' 'parser.R' 'pattern.R' 'rocco.R' 'spin.R' 'table.R' 'template.R' 'utils-conversion.R' 'utils-rd2html.R' 'utils-string.R' 'utils-sweave.R' 'utils-upload.R' 'utils-vignettes.R' 'zzz.R'", + "Collate": "'block.R' 'cache.R' 'citation.R' 'hooks-html.R' 'plot.R' 'utils.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R' 'themes.R' 'header.R' 'hooks-asciidoc.R' 'hooks-chunk.R' 'hooks-extra.R' 'hooks-latex.R' 'hooks-md.R' 'hooks-rst.R' 'hooks-textile.R' 'hooks.R' 'output.R' 'package.R' 'pandoc.R' 'params.R' 'parser.R' 'pattern.R' 'rocco.R' 'spin.R' 'table.R' 'template.R' 'utils-conversion.R' 'utils-rd2html.R' 'utils-string.R' 'utils-sweave.R' 'utils-upload.R' 'utils-vignettes.R' 'zzz.R'", "RoxygenNote": "7.3.2", "NeedsCompilation": "no", - "Author": "Yihui Xie [aut, cre] (), Abhraneel Sarma [ctb], Adam Vogt [ctb], Alastair Andrew [ctb], Alex Zvoleff [ctb], Amar Al-Zubaidi [ctb], Andre Simon [ctb] (the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de), Aron Atkins [ctb], Aaron Wolen [ctb], Ashley Manton [ctb], Atsushi Yasumoto [ctb] (), Ben Baumer [ctb], Brian Diggs [ctb], Brian Zhang [ctb], Bulat Yapparov [ctb], Cassio Pereira [ctb], Christophe Dervieux [ctb], David Hall [ctb], David Hugh-Jones [ctb], David Robinson [ctb], Doug Hemken [ctb], Duncan Murdoch [ctb], Elio Campitelli [ctb], Ellis Hughes [ctb], Emily Riederer [ctb], Fabian Hirschmann [ctb], Fitch Simeon [ctb], Forest Fang [ctb], Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty), Garrick Aden-Buie [ctb], Gregoire Detrez [ctb], Hadley Wickham [ctb], Hao Zhu [ctb], Heewon Jeon [ctb], Henrik Bengtsson [ctb], Hiroaki Yutani [ctb], Ian Lyttle [ctb], Hodges Daniel [ctb], Jacob Bien [ctb], Jake Burkhead [ctb], James Manton [ctb], Jared Lander [ctb], Jason Punyon [ctb], Javier Luraschi [ctb], Jeff Arnold [ctb], Jenny Bryan [ctb], Jeremy Ashkenas [ctb, cph] (the CSS file at inst/misc/docco-classic.css), Jeremy Stephens [ctb], Jim Hester [ctb], Joe Cheng [ctb], Johannes Ranke [ctb], John Honaker [ctb], John Muschelli [ctb], Jonathan Keane [ctb], JJ Allaire [ctb], Johan Toloe [ctb], Jonathan Sidi [ctb], Joseph Larmarange [ctb], Julien Barnier [ctb], Kaiyin Zhong [ctb], Kamil Slowikowski [ctb], Karl Forner [ctb], Kevin K. Smith [ctb], Kirill Mueller [ctb], Kohske Takahashi [ctb], Lorenz Walthert [ctb], Lucas Gallindo [ctb], Marius Hofert [ctb], Martin Modrák [ctb], Michael Chirico [ctb], Michael Friendly [ctb], Michal Bojanowski [ctb], Michel Kuhlmann [ctb], Miller Patrick [ctb], Nacho Caballero [ctb], Nick Salkowski [ctb], Niels Richard Hansen [ctb], Noam Ross [ctb], Obada Mahdi [ctb], Pavel N. Krivitsky [ctb] (), Pedro Faria [ctb], Qiang Li [ctb], Ramnath Vaidyanathan [ctb], Richard Cotton [ctb], Robert Krzyzanowski [ctb], Rodrigo Copetti [ctb], Romain Francois [ctb], Ruaridh Williamson [ctb], Sagiru Mati [ctb] (), Scott Kostyshak [ctb], Sebastian Meyer [ctb], Sietse Brouwer [ctb], Simon de Bernard [ctb], Sylvain Rousseau [ctb], Taiyun Wei [ctb], Thibaut Assus [ctb], Thibaut Lamadon [ctb], Thomas Leeper [ctb], Tim Mastny [ctb], Tom Torsney-Weir [ctb], Trevor Davis [ctb], Viktoras Veitas [ctb], Weicheng Zhu [ctb], Wush Wu [ctb], Zachary Foster [ctb], Zhian N. Kamvar [ctb] (), Posit Software, PBC [cph, fnd]", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Abhraneel Sarma [ctb], Adam Vogt [ctb], Alastair Andrew [ctb], Alex Zvoleff [ctb], Amar Al-Zubaidi [ctb], Andre Simon [ctb] (the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de), Aron Atkins [ctb], Aaron Wolen [ctb], Ashley Manton [ctb], Atsushi Yasumoto [ctb] (), Ben Baumer [ctb], Brian Diggs [ctb], Brian Zhang [ctb], Bulat Yapparov [ctb], Cassio Pereira [ctb], Christophe Dervieux [ctb], David Hall [ctb], David Hugh-Jones [ctb], David Robinson [ctb], Doug Hemken [ctb], Duncan Murdoch [ctb], Elio Campitelli [ctb], Ellis Hughes [ctb], Emily Riederer [ctb], Fabian Hirschmann [ctb], Fitch Simeon [ctb], Forest Fang [ctb], Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty), Garrick Aden-Buie [ctb], Gregoire Detrez [ctb], Hadley Wickham [ctb], Hao Zhu [ctb], Heewon Jeon [ctb], Henrik Bengtsson [ctb], Hiroaki Yutani [ctb], Ian Lyttle [ctb], Hodges Daniel [ctb], Jacob Bien [ctb], Jake Burkhead [ctb], James Manton [ctb], Jared Lander [ctb], Jason Punyon [ctb], Javier Luraschi [ctb], Jeff Arnold [ctb], Jenny Bryan [ctb], Jeremy Ashkenas [ctb, cph] (the CSS file at inst/misc/docco-classic.css), Jeremy Stephens [ctb], Jim Hester [ctb], Joe Cheng [ctb], Johannes Ranke [ctb], John Honaker [ctb], John Muschelli [ctb], Jonathan Keane [ctb], JJ Allaire [ctb], Johan Toloe [ctb], Jonathan Sidi [ctb], Joseph Larmarange [ctb], Julien Barnier [ctb], Kaiyin Zhong [ctb], Kamil Slowikowski [ctb], Karl Forner [ctb], Kevin K. Smith [ctb], Kirill Mueller [ctb], Kohske Takahashi [ctb], Lorenz Walthert [ctb], Lucas Gallindo [ctb], Marius Hofert [ctb], Martin Modrák [ctb], Michael Chirico [ctb], Michael Friendly [ctb], Michal Bojanowski [ctb], Michel Kuhlmann [ctb], Miller Patrick [ctb], Nacho Caballero [ctb], Nick Salkowski [ctb], Niels Richard Hansen [ctb], Noam Ross [ctb], Obada Mahdi [ctb], Pavel N. Krivitsky [ctb] (), Pedro Faria [ctb], Qiang Li [ctb], Ramnath Vaidyanathan [ctb], Richard Cotton [ctb], Robert Krzyzanowski [ctb], Rodrigo Copetti [ctb], Romain Francois [ctb], Ruaridh Williamson [ctb], Sagiru Mati [ctb] (), Scott Kostyshak [ctb], Sebastian Meyer [ctb], Sietse Brouwer [ctb], Simon de Bernard [ctb], Sylvain Rousseau [ctb], Taiyun Wei [ctb], Thibaut Assus [ctb], Thibaut Lamadon [ctb], Thomas Leeper [ctb], Tim Mastny [ctb], Tom Torsney-Weir [ctb], Trevor Davis [ctb], Viktoras Veitas [ctb], Weicheng Zhu [ctb], Wush Wu [ctb], Zachary Foster [ctb], Zhian N. Kamvar [ctb] (), Posit Software, PBC [cph, fnd]", "Maintainer": "Yihui Xie ", "Repository": "CRAN" }, @@ -5808,11 +5808,11 @@ }, "mime": { "Package": "mime", - "Version": "0.12", + "Version": "0.13", "Source": "Repository", "Type": "Package", "Title": "Map Filenames to MIME Types", - "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Jeffrey\", \"Horner\", role = \"ctb\"), person(\"Beilei\", \"Bian\", role = \"ctb\") )", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Jeffrey\", \"Horner\", role = \"ctb\"), person(\"Beilei\", \"Bian\", role = \"ctb\") )", "Description": "Guesses the MIME type from a filename extension using the data derived from /etc/mime.types in UNIX-type systems.", "Imports": [ "tools" @@ -5820,10 +5820,10 @@ "License": "GPL", "URL": "https://github.com/yihui/mime", "BugReports": "https://github.com/yihui/mime/issues", - "RoxygenNote": "7.1.1", + "RoxygenNote": "7.3.2", "Encoding": "UTF-8", "NeedsCompilation": "yes", - "Author": "Yihui Xie [aut, cre] (), Jeffrey Horner [ctb], Beilei Bian [ctb]", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Jeffrey Horner [ctb], Beilei Bian [ctb]", "Maintainer": "Yihui Xie ", "Repository": "CRAN" }, @@ -6050,17 +6050,16 @@ }, "nloptr": { "Package": "nloptr", - "Version": "2.1.1", + "Version": "2.2.1", "Source": "Repository", "Type": "Package", "Title": "R Interface to NLopt", - "Authors@R": "c(person(\"Jelmer\", \"Ypma\", role = \"aut\", email = \"uctpjyy@ucl.ac.uk\"), person(c(\"Steven\", \"G.\"), \"Johnson\", role = \"aut\", comment = \"author of the NLopt C library\"), person(\"Aymeric\", \"Stamm\", role = c(\"ctb\", \"cre\"), email = \"aymeric.stamm@cnrs.fr\", comment = c(ORCID = \"0000-0002-8725-3654\")), person(c(\"Hans\", \"W.\"), \"Borchers\", role = \"ctb\", email = \"hwborchers@googlemail.com\"), person(\"Dirk\", \"Eddelbuettel\", role = \"ctb\", email = \"edd@debian.org\"), person(\"Brian\", \"Ripley\", role = \"ctb\", comment = \"build process on multiple OS\"), person(\"Kurt\", \"Hornik\", role = \"ctb\", comment = \"build process on multiple OS\"), person(\"Julien\", \"Chiquet\", role = \"ctb\"), person(\"Avraham\", \"Adler\", role = \"ctb\", email = \"Avraham.Adler@gmail.com\", comment = c(ORCID = \"0000-0002-3039-0703\")), person(\"Xiongtao\", \"Dai\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\", email = \"jeroen@berkeley.edu\"))", + "Authors@R": "c(person(\"Jelmer\", \"Ypma\", role = \"aut\", email = \"uctpjyy@ucl.ac.uk\"), person(c(\"Steven\", \"G.\"), \"Johnson\", role = \"aut\", comment = \"author of the NLopt C library\"), person(\"Aymeric\", \"Stamm\", role = c(\"ctb\", \"cre\"), email = \"aymeric.stamm@cnrs.fr\", comment = c(ORCID = \"0000-0002-8725-3654\")), person(c(\"Hans\", \"W.\"), \"Borchers\", role = \"ctb\", email = \"hwborchers@googlemail.com\"), person(\"Dirk\", \"Eddelbuettel\", role = \"ctb\", email = \"edd@debian.org\"), person(\"Brian\", \"Ripley\", role = \"ctb\", comment = \"build process on multiple OS\"), person(\"Kurt\", \"Hornik\", role = \"ctb\", comment = \"build process on multiple OS\"), person(\"Julien\", \"Chiquet\", role = \"ctb\"), person(\"Avraham\", \"Adler\", role = \"ctb\", email = \"Avraham.Adler@gmail.com\", comment = c(ORCID = \"0000-0002-3039-0703\")), person(\"Xiongtao\", \"Dai\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\", email = \"jeroen@berkeley.edu\"), person(\"Tomas\", \"Kalibera\", role = \"ctb\"), person(\"Mikael\", \"Jagan\", role = \"ctb\"))", "Description": "Solve optimization problems using an R interface to NLopt. NLopt is a free/open-source library for nonlinear optimization, providing a common interface for a number of different free optimization routines available online as well as original implementations of various other algorithms. See for more information on the available algorithms. Building from included sources requires 'CMake'. On Linux and 'macOS', if a suitable system build of NLopt (2.7.0 or later) is found, it is used; otherwise, it is built from included sources via 'CMake'. On Windows, NLopt is obtained through 'rwinlib' for 'R <= 4.1.x' or grabbed from the appropriate toolchain for 'R >= 4.2.0'.", "License": "LGPL (>= 3)", "SystemRequirements": "cmake (>= 3.2.0) which is used only on Linux or macOS systems when no system build of nlopt (>= 2.7.0) can be found.", - "Biarch": "true", "Encoding": "UTF-8", - "RoxygenNote": "7.3.1", + "RoxygenNote": "7.3.2", "Suggests": [ "knitr", "rmarkdown", @@ -6071,7 +6070,8 @@ "URL": "https://github.com/astamm/nloptr, https://astamm.github.io/nloptr/", "BugReports": "https://github.com/astamm/nloptr/issues", "NeedsCompilation": "yes", - "Author": "Jelmer Ypma [aut], Steven G. Johnson [aut] (author of the NLopt C library), Aymeric Stamm [ctb, cre] (), Hans W. Borchers [ctb], Dirk Eddelbuettel [ctb], Brian Ripley [ctb] (build process on multiple OS), Kurt Hornik [ctb] (build process on multiple OS), Julien Chiquet [ctb], Avraham Adler [ctb] (), Xiongtao Dai [ctb], Jeroen Ooms [ctb]", + "UseLTO": "yes", + "Author": "Jelmer Ypma [aut], Steven G. Johnson [aut] (author of the NLopt C library), Aymeric Stamm [ctb, cre] (), Hans W. Borchers [ctb], Dirk Eddelbuettel [ctb], Brian Ripley [ctb] (build process on multiple OS), Kurt Hornik [ctb] (build process on multiple OS), Julien Chiquet [ctb], Avraham Adler [ctb] (), Xiongtao Dai [ctb], Jeroen Ooms [ctb], Tomas Kalibera [ctb], Mikael Jagan [ctb]", "Maintainer": "Aymeric Stamm ", "Repository": "CRAN" }, @@ -7881,7 +7881,7 @@ }, "renv": { "Package": "renv", - "Version": "1.1.2", + "Version": "1.1.3", "Source": "Repository", "Type": "Package", "Title": "Project Environments", @@ -8453,7 +8453,7 @@ }, "see": { "Package": "see", - "Version": "0.10.0", + "Version": "0.11.0", "Source": "Repository", "Type": "Package", "Title": "Model Visualisation Toolbox for 'easystats' and 'ggplot2'", @@ -8470,15 +8470,15 @@ "stats" ], "Imports": [ - "bayestestR (>= 0.15.1)", - "correlation (>= 0.8.6)", - "datawizard (>= 1.0.0)", + "bayestestR (>= 0.15.2)", + "correlation (>= 0.8.7)", + "datawizard (>= 1.0.1)", "effectsize (>= 1.0.0)", "ggplot2 (>= 3.5.1)", - "insight (>= 1.0.1)", - "modelbased (>= 0.8.9)", + "insight (>= 1.1.0)", + "modelbased (>= 0.10.0)", "patchwork (>= 1.3.0)", - "parameters (>= 0.24.1)", + "parameters (>= 0.24.2)", "performance (>= 0.13.0)" ], "Suggests": [ @@ -8489,6 +8489,7 @@ "DHARMa", "emmeans", "factoextra", + "Formula", "ggdag", "ggdist", "ggraph", @@ -8497,7 +8498,6 @@ "ggside", "glmmTMB", "grid", - "httr", "httr2", "lavaan", "lme4", @@ -8511,7 +8511,6 @@ "metafor", "NbClust", "nFactors", - "poorman", "psych", "qqplotr (>= 0.0.6)", "randomForest", @@ -9611,7 +9610,7 @@ }, "tzdb": { "Package": "tzdb", - "Version": "0.4.0", + "Version": "0.5.0", "Source": "Repository", "Title": "Time Zone Database Information", "Authors@R": "c( person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = c(\"aut\", \"cre\")), person(\"Howard\", \"Hinnant\", role = \"cph\", comment = \"Author of the included date library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", @@ -9620,20 +9619,20 @@ "URL": "https://tzdb.r-lib.org, https://github.com/r-lib/tzdb", "BugReports": "https://github.com/r-lib/tzdb/issues", "Depends": [ - "R (>= 3.5.0)" + "R (>= 4.0.0)" ], "Suggests": [ "covr", "testthat (>= 3.0.0)" ], "LinkingTo": [ - "cpp11 (>= 0.4.2)" + "cpp11 (>= 0.5.2)" ], "Biarch": "yes", "Config/Needs/website": "tidyverse/tidytemplate", "Config/testthat/edition": "3", "Encoding": "UTF-8", - "RoxygenNote": "7.2.3", + "RoxygenNote": "7.3.2", "NeedsCompilation": "yes", "Author": "Davis Vaughan [aut, cre], Howard Hinnant [cph] (Author of the included date library), Posit Software, PBC [cph, fnd]", "Maintainer": "Davis Vaughan ", @@ -9953,7 +9952,7 @@ }, "writexl": { "Package": "writexl", - "Version": "1.5.1", + "Version": "1.5.2", "Source": "Repository", "Type": "Package", "Title": "Export Data Frames to Excel 'xlsx' Format", @@ -10030,7 +10029,7 @@ }, "xml2": { "Package": "xml2", - "Version": "1.3.7", + "Version": "1.3.8", "Source": "Repository", "Title": "Parse XML", "Authors@R": "c( person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Jeroen\", \"Ooms\", email = \"jeroenooms@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"R Foundation\", role = \"ctb\", comment = \"Copy of R-project homepage cached as example\") )", diff --git a/renv/activate.R b/renv/activate.R index c9f59425..623cc4e7 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,7 +2,7 @@ local({ # the requested version of renv - version <- "1.1.2" + version <- "1.1.3" attr(version, "sha") <- NULL # the project directory @@ -695,11 +695,19 @@ local({ } - renv_bootstrap_platform_prefix <- function() { + renv_bootstrap_platform_prefix_default <- function() { - # construct version prefix - version <- paste(R.version$major, R.version$minor, sep = ".") - prefix <- paste("R", numeric_version(version)[1, 1:2], sep = "-") + # read version component + version <- Sys.getenv("RENV_PATHS_VERSION", unset = "R-%v") + + # expand placeholders + placeholders <- list( + list("%v", format(getRversion()[1, 1:2])), + list("%V", format(getRversion()[1, 1:3])) + ) + + for (placeholder in placeholders) + version <- gsub(placeholder[[1L]], placeholder[[2L]], version, fixed = TRUE) # include SVN revision for development versions of R # (to avoid sharing platform-specific artefacts with released versions of R) @@ -708,10 +716,19 @@ local({ identical(R.version[["nickname"]], "Unsuffered Consequences") if (devel) - prefix <- paste(prefix, R.version[["svn rev"]], sep = "-r") + version <- paste(version, R.version[["svn rev"]], sep = "-r") + + version + + } + + renv_bootstrap_platform_prefix <- function() { + + # construct version prefix + version <- renv_bootstrap_platform_prefix_default() # build list of path components - components <- c(prefix, R.version$platform) + components <- c(version, R.version$platform) # include prefix if provided by user prefix <- renv_bootstrap_platform_prefix_impl() @@ -950,14 +967,14 @@ local({ } renv_bootstrap_validate_version_dev <- function(version, description) { - + expected <- description[["RemoteSha"]] if (!is.character(expected)) return(FALSE) - + pattern <- sprintf("^\\Q%s\\E", version) grepl(pattern, expected, perl = TRUE) - + } renv_bootstrap_validate_version_release <- function(version, description) { @@ -1198,86 +1215,89 @@ local({ } renv_json_read_patterns <- function() { - + list( - + # objects - list("{", "\t\n\tobject(\t\n\t"), - list("}", "\t\n\t)\t\n\t"), - + list("{", "\t\n\tobject(\t\n\t", TRUE), + list("}", "\t\n\t)\t\n\t", TRUE), + # arrays - list("[", "\t\n\tarray(\t\n\t"), - list("]", "\n\t\n)\n\t\n"), - + list("[", "\t\n\tarray(\t\n\t", TRUE), + list("]", "\n\t\n)\n\t\n", TRUE), + # maps - list(":", "\t\n\t=\t\n\t") - + list(":", "\t\n\t=\t\n\t", TRUE), + + # newlines + list("\\u000a", "\n", FALSE) + ) - + } renv_json_read_envir <- function() { envir <- new.env(parent = emptyenv()) - + envir[["+"]] <- `+` envir[["-"]] <- `-` - + envir[["object"]] <- function(...) { result <- list(...) names(result) <- as.character(names(result)) result } - + envir[["array"]] <- list - + envir[["true"]] <- TRUE envir[["false"]] <- FALSE envir[["null"]] <- NULL - + envir - + } renv_json_read_remap <- function(object, patterns) { - + # repair names if necessary if (!is.null(names(object))) { - + nms <- names(object) for (pattern in patterns) nms <- gsub(pattern[[2L]], pattern[[1L]], nms, fixed = TRUE) names(object) <- nms - + } - + # repair strings if necessary if (is.character(object)) { for (pattern in patterns) object <- gsub(pattern[[2L]], pattern[[1L]], object, fixed = TRUE) } - + # recurse for other objects if (is.recursive(object)) for (i in seq_along(object)) object[i] <- list(renv_json_read_remap(object[[i]], patterns)) - + # return remapped object object - + } renv_json_read_default <- function(file = NULL, text = NULL) { # read json text text <- paste(text %||% readLines(file, warn = FALSE), collapse = "\n") - + # convert into something the R parser will understand patterns <- renv_json_read_patterns() transformed <- text for (pattern in patterns) transformed <- gsub(pattern[[1L]], pattern[[2L]], transformed, fixed = TRUE) - + # parse it rfile <- tempfile("renv-json-", fileext = ".R") on.exit(unlink(rfile), add = TRUE) @@ -1287,9 +1307,10 @@ local({ # evaluate in safe environment result <- eval(json, envir = renv_json_read_envir()) - # fix up strings if necessary + # fix up strings if necessary -- do so only with reversible patterns + patterns <- Filter(function(pattern) pattern[[3L]], patterns) renv_json_read_remap(result, patterns) - + } From 1b425b5a946eaa0a50c27938b49b504ad49428e6 Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Wed, 19 Mar 2025 13:28:34 +0100 Subject: [PATCH 3/3] clean --- R/app_version.R | 2 +- R/regression_plot.R | 2 +- inst/apps/FreesearchR/app.R | 15 ++++++++---- .../shinyapps.io/agdamsbo/freesearcheR.dcf | 2 +- inst/apps/FreesearchR/www/notes_visuals.md | 4 ++-- inst/apps/FreesearchR/www/references.bib | 24 +++++++++++++++++++ inst/apps/FreesearchR/www/report.rmd | 10 ++++---- 7 files changed, 44 insertions(+), 15 deletions(-) create mode 100644 inst/apps/FreesearchR/www/references.bib diff --git a/R/app_version.R b/R/app_version.R index b4900e38..d3c4a1b4 100644 --- a/R/app_version.R +++ b/R/app_version.R @@ -1 +1 @@ -app_version <- function()'250319_1306' +app_version <- function()'250319_1327' diff --git a/R/regression_plot.R b/R/regression_plot.R index 777fbd3a..adb0a471 100644 --- a/R/regression_plot.R +++ b/R/regression_plot.R @@ -138,6 +138,6 @@ symmetrical_scale_x_log10 <- function(plot,breaks=c(1,2,3,5,10),...){ max_abs_x <- max(abs(c(x_min,x_max))) ticks <- log10(breaks)+(ceiling(max_abs_x)-1) - browser() + plot + ggplot2::scale_x_log10(limits=c(rx_min,rx_max),breaks=create_log_tics(10^ticks[ticks<=max_abs_x])) } diff --git a/inst/apps/FreesearchR/app.R b/inst/apps/FreesearchR/app.R index 75be00f6..59101fcc 100644 --- a/inst/apps/FreesearchR/app.R +++ b/inst/apps/FreesearchR/app.R @@ -10,7 +10,7 @@ #### Current file: R//app_version.R ######## -app_version <- function()'250319_1306' +app_version <- function()'250319_1327' ######## @@ -3400,20 +3400,25 @@ plot_box_single <- function(data, x, y=NULL, seed = 2103) { ## THis could be optional in future ggplot2::geom_jitter(color = "black", size = 2, alpha = 0.9) + ggplot2::coord_flip() + - # viridis::scale_fill_viridis(discrete = discrete, option = "C") + + viridis::scale_fill_viridis(discrete = discrete, option = "D") + # ggplot2::theme_void() + + ggplot2::theme_bw(base_size = 24) + ggplot2::theme( legend.position = "none", # panel.grid.major = element_blank(), # panel.grid.minor = element_blank(), # axis.text.y = element_blank(), # axis.title.y = element_blank(), - text = ggplot2::element_text(size = 20), + # text = ggplot2::element_text(size = 20), # axis.text = ggplot2::element_blank(), # plot.title = element_blank(), panel.background = ggplot2::element_rect(fill = "white"), plot.background = ggplot2::element_rect(fill = "white"), - panel.border = ggplot2::element_blank() + panel.border = ggplot2::element_blank(), + panel.grid.major = ggplot2::element_blank(), + panel.grid.minor = ggplot2::element_blank(), + axis.line = ggplot2::element_line(colour = "black"), + axis.ticks = ggplot2::element_line(colour = "black") ) } @@ -5338,7 +5343,7 @@ symmetrical_scale_x_log10 <- function(plot,breaks=c(1,2,3,5,10),...){ max_abs_x <- max(abs(c(x_min,x_max))) ticks <- log10(breaks)+(ceiling(max_abs_x)-1) - browser() + plot + ggplot2::scale_x_log10(limits=c(rx_min,rx_max),breaks=create_log_tics(10^ticks[ticks<=max_abs_x])) } diff --git a/inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf b/inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf index 76ab2422..de976fae 100644 --- a/inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf +++ b/inst/apps/FreesearchR/rsconnect/shinyapps.io/agdamsbo/freesearcheR.dcf @@ -5,6 +5,6 @@ account: agdamsbo server: shinyapps.io hostUrl: https://api.shinyapps.io/v1 appId: 13611288 -bundleId: 9961770 +bundleId: 9969300 url: https://agdamsbo.shinyapps.io/freesearcheR/ version: 1 diff --git a/inst/apps/FreesearchR/www/notes_visuals.md b/inst/apps/FreesearchR/www/notes_visuals.md index 6ae6f704..58e3a758 100644 --- a/inst/apps/FreesearchR/www/notes_visuals.md +++ b/inst/apps/FreesearchR/www/notes_visuals.md @@ -1,6 +1,6 @@ # Basic visualisations -This section on plotting data is kept very minimal, and includes only the most common plot types for clinical projects. +The goal of ***FreesearchR*** is to keep things simple. Visuals can get very complicated. We provide a selection of plots, that helps visualise typical clinical and will be enough for most use cases, and for publishing to most journals. If you want to go further, have a look at these sites with suggestions and sample code for data plotting: @@ -8,4 +8,4 @@ If you want to go further, have a look at these sites with suggestions and sampl - [*R* Graph gallery](https://r-graph-gallery.com/): Another gallery with great graphs -- [grphics principles](https://graphicsprinciples.github.io/): Easy to follow recommendations for clear visuals. +- [graphics principles](https://graphicsprinciples.github.io/): Easy to follow recommendations for clear visuals. diff --git a/inst/apps/FreesearchR/www/references.bib b/inst/apps/FreesearchR/www/references.bib new file mode 100644 index 00000000..ca20ec82 --- /dev/null +++ b/inst/apps/FreesearchR/www/references.bib @@ -0,0 +1,24 @@ + +@book{andreasgammelgaarddamsbo2025, + title = {agdamsbo/freesearcheR: freesearcheR 25.3.1}, + author = {Andreas Gammelgaard Damsbo, }, + year = {2025}, + month = {03}, + date = {2025-03-06}, + publisher = {Zenodo}, + doi = {10.5281/ZENODO.14527429}, + url = {https://zenodo.org/doi/10.5281/zenodo.14527429} +} + +@article{Aam2020, + title = {Post-stroke Cognitive Impairment{\textemdash}Impact of Follow-Up Time and Stroke Subtype on Severity and Cognitive Profile: The Nor-COAST Study}, + author = {Aam, Stina and Einstad, Marte Stine and Munthe-Kaas, Ragnhild and Lydersen, Stian and Ihle-Hansen, Hege and Knapskog, Anne Brita and {Ellekjær}, Hanne and Seljeseth, Yngve and Saltvedt, Ingvild}, + year = {2020}, + date = {2020}, + journal = {Frontiers in Neurology}, + pages = {1--10}, + volume = {11}, + number = {July}, + doi = {10.3389/fneur.2020.00699}, + note = {Citation Key: Aam2020} +} diff --git a/inst/apps/FreesearchR/www/report.rmd b/inst/apps/FreesearchR/www/report.rmd index aacd48c5..803c520b 100644 --- a/inst/apps/FreesearchR/www/report.rmd +++ b/inst/apps/FreesearchR/www/report.rmd @@ -1,8 +1,8 @@ --- -title: "freesearcheR data report" +title: "FreesearchR data report" date: "Report generated `r gsub('(\\D)0', '\\1', format(Sys.time(), '%A, %d.%m.%Y'))`" format: docx -author: freesearcheR data analysis tool +author: FreesearchR data analysis tool toc: false params: data.file: NA @@ -13,7 +13,6 @@ knitr::opts_chunk$set(echo = FALSE, message = FALSE, warning = FALSE) # glue::glue("{format(lubridate::today(),'%A')}, {lubridate::day(lubridate::today())}.{lubridate::month(lubridate::today())}.{lubridate::year(lubridate::today())}") ``` - ```{r} web_data <- readr::read_rds(file = params$data.file) library(gtsummary) @@ -42,11 +41,11 @@ vec2sentence <- function(data, sep.word = "and") { ## Introduction -Research should be free and open with easy access for all. The freesearcheR tool attempts to help lower the bar to participate in contributing to science by making guided data analysis easily accessible in the web-browser. +Research should be free and open with easy access for all. The FreesearchR tool attempts to help lower the bar to participate in contributing to science by making guided data analysis easily accessible in the web-browser. ## Methods -Analyses were conducted in the *freesearcheR* data analysis web-tool based on R version 4.4.1. +Analyses were conducted in the *FreesearchR* data analysis web-tool based on R version 4.4.1. ## Results @@ -70,3 +69,4 @@ knitr::knit_print(tbl_merge(reg_tbl)) ## Discussion Good luck on your further work! +