diff --git a/CITATION.cff b/CITATION.cff index 8629fb7c..86c9ebe0 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -8,7 +8,7 @@ message: 'To cite package "FreesearchR" in publications use:' type: software license: AGPL-3.0-or-later title: 'FreesearchR: Easy data analysis for clinicians' -version: 26.4.1 +version: 26.4.2 doi: 10.5281/zenodo.14527429 identifiers: - type: url diff --git a/DESCRIPTION b/DESCRIPTION index 89673630..69564bc2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: FreesearchR Title: Easy data analysis for clinicians -Version: 26.4.1 +Version: 26.4.2 Authors@R: c( person("Andreas Gammelgaard", "Damsbo",email="agdamsbo@clin.au.dk", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-7559-1154")), diff --git a/NAMESPACE b/NAMESPACE index 9ede131b..9e036c3f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -116,6 +116,7 @@ export(modify_qmd) export(names2val) export(overview_vars) export(pipe_string) +export(plot_bar) export(plot_bar_single) export(plot_box) export(plot_box_single) diff --git a/NEWS.md b/NEWS.md index fbff9355..785ee46a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# FreesearchR 26.4.2 + +Bug fixes and revised color choices. + # FreesearchR 26.4.1 Minor adjustments and bug fixes including streamlining icon use to only use phosphoricons across the app. diff --git a/R/app_version.R b/R/app_version.R index 4f474ec7..2cbd2cc4 100644 --- a/R/app_version.R +++ b/R/app_version.R @@ -1 +1 @@ -app_version <- function()'26.4.1' +app_version <- function()'26.4.2' diff --git a/R/create-column-mod.R b/R/create-column-mod.R index c2b6d403..6047aa33 100644 --- a/R/create-column-mod.R +++ b/R/create-column-mod.R @@ -76,7 +76,7 @@ create_column_ui <- function(id) { actionButton( inputId = ns("compute"), label = tagList( - phosphoricons::ph("pencil"), i18n$t("Create column") + phosphoricons::ph("pencil",weight = "bold"), i18n$t("Create column") ), class = "btn-outline-primary", width = "100%" @@ -84,7 +84,7 @@ create_column_ui <- function(id) { actionButton( inputId = ns("remove"), label = tagList( - phosphoricons::ph("x-circle"), + phosphoricons::ph("x-circle",weight = "bold"), i18n$t("Cancel") ), class = "btn-outline-danger", diff --git a/R/cut-variable-ext.R b/R/cut-variable-ext.R index b7d8eb80..84418736 100644 --- a/R/cut-variable-ext.R +++ b/R/cut-variable-ext.R @@ -64,7 +64,7 @@ cut_variable_ui <- function(id) { toastui::datagridOutput2(outputId = ns("count")), actionButton( inputId = ns("create"), - label = tagList(phosphoricons::ph("scissors"), i18n$t("Create factor variable")), + label = tagList(phosphoricons::ph("scissors",weight = "bold"), i18n$t("Create factor variable")), class = "btn-outline-primary float-end" ), tags$div(class = "clearfix") diff --git a/R/hosted_version.R b/R/hosted_version.R index 6e001f53..33aaf67c 100644 --- a/R/hosted_version.R +++ b/R/hosted_version.R @@ -1 +1 @@ -hosted_version <- function()'v26.4.1-260402' +hosted_version <- function()'v26.4.2-260410' diff --git a/R/import-file-ext.R b/R/import-file-ext.R index 709a55c1..6d78e381 100644 --- a/R/import-file-ext.R +++ b/R/import-file-ext.R @@ -714,7 +714,7 @@ make_success_alert <- function(data, i18n$t("Data ready to be imported!") ), sprintf( - i18n$t("Data has %s obs. of %s variables."), + i18n$t("The data set has %s obs. in %s variables."), nrow(data), ncol(data) ), @@ -725,7 +725,7 @@ make_success_alert <- function(data, i18n$t("Data successfully imported!") ), sprintf( - i18n$t("Data has %s obs. of %s variables."), + i18n$t("The data set has %s obs. in %s variables."), nrow(data), ncol(data) ), diff --git a/R/missings-module.R b/R/missings-module.R index bb247b18..eeb46edd 100644 --- a/R/missings-module.R +++ b/R/missings-module.R @@ -37,7 +37,7 @@ data_missings_ui <- function(id, ...) { inputId = ns("act_miss"), label = i18n$t("Evaluate"), width = "100%", - icon = phosphoricons::ph("calculator"), + icon = phosphoricons::ph("calculator",weight = "bold"), # icon = shiny::icon("calculator"), disabled = TRUE ) diff --git a/R/plot_bar.R b/R/plot_bar.R index f820cc6b..0535b6f3 100644 --- a/R/plot_bar.R +++ b/R/plot_bar.R @@ -1,5 +1,29 @@ -plot_bar <- function(data, pri, sec, ter = NULL, style = c("stack", "dodge", "fill"), - color.palette = "viridis", max_level = 30, ...) { +#' Title +#' +#' @name data-plots +#' +#' @param style barplot style passed to geom_bar position argument. +#' One of c("stack", "dodge", "fill") +#' +#' @returns ggplot list object +#' @export +#' +#' @examples +#' mtcars |> +#' dplyr::mutate(cyl = factor(cyl), am = factor(am)) |> +#' plot_bar(pri = "cyl", sec = "am", style = "fill") +#' +#' mtcars |> +#' dplyr::mutate(dplyr::across(tidyselect::all_of(c("cyl","am","gear")),factor)) |> +#' plot_bar(pri = "cyl", sec = "gear", ter = "am", style = "stack",color.palette="turbo") +plot_bar <- function(data, + pri, + sec = NULL, + ter = NULL, + style = c("stack", "dodge", "fill"), + color.palette = "viridis", + max_level = 30, + ...) { style <- match.arg(style) if (!is.null(ter)) { @@ -8,7 +32,7 @@ plot_bar <- function(data, pri, sec, ter = NULL, style = c("stack", "dodge", "fi ds <- list(data) } - out <- lapply(ds, \(.ds){ + out <- lapply(ds, \(.ds) { plot_bar_single( data = .ds, pri = pri, @@ -19,7 +43,10 @@ plot_bar <- function(data, pri, sec, ter = NULL, style = c("stack", "dodge", "fi ) }) - wrap_plot_list(out, title = glue::glue(i18n$t("Grouped by {get_label(data,ter)}")), ...) + wrap_plot_list(out, + title = glue::glue(i18n$t("Grouped by {get_label(data,ter)}")), + y.axis.percentage = TRUE, + ...) } @@ -41,7 +68,11 @@ plot_bar <- function(data, pri, sec, ter = NULL, style = c("stack", "dodge", "fi #' mtcars |> #' dplyr::mutate(cyl = factor(cyl), am = factor(am)) |> #' plot_bar_single(pri = "cyl", style = "stack",color.palette="turbo") -plot_bar_single <- function(data, pri, sec = NULL, style = c("stack", "dodge", "fill"), max_level = 30, +plot_bar_single <- function(data, + pri, + sec = NULL, + style = c("stack", "dodge", "fill"), + max_level = 30, color.palette = "viridis") { style <- match.arg(style) @@ -51,16 +82,11 @@ plot_bar_single <- function(data, pri, sec = NULL, style = c("stack", "dodge", " p_data <- as.data.frame(table(data[c(pri, sec)])) |> dplyr::mutate(dplyr::across(tidyselect::any_of(c(pri, sec)), forcats::as_factor), - p = Freq / NROW(data) - ) + p = Freq / NROW(data)) if (nrow(p_data) > max_level) { - p_data <- sort_by( - p_data, - p_data[["Freq"]], - decreasing = TRUE - ) |> + p_data <- sort_by(p_data, p_data[["Freq"]], decreasing = TRUE) |> head(max_level) } @@ -73,39 +99,31 @@ plot_bar_single <- function(data, pri, sec = NULL, style = c("stack", "dodge", " fill <- pri } - p <- ggplot2::ggplot( - p_data, - ggplot2::aes( - x = .data[[pri]], - y = p, - fill = .data[[fill]] - ) - ) + + p <- ggplot2::ggplot(p_data, ggplot2::aes(x = .data[[pri]], y = p, fill = .data[[fill]])) + ggplot2::geom_bar(position = style, stat = "identity") + - ggplot2::scale_y_continuous(labels = scales::percent) + - scale_fill_generate(palette=color.palette) + - ggplot2::ylab("Percentage") + - ggplot2::xlab(get_label(data,pri))+ - ggplot2::guides(fill = ggplot2::guide_legend(title = get_label(data,fill))) + scale_fill_generate(palette = color.palette) + + ggplot2::xlab(get_label(data, pri)) + + ggplot2::guides(fill = ggplot2::guide_legend(title = get_label(data, fill))) ## To handle large number of levels and long level names - if (nrow(p_data) > 10 | any(nchar(as.character(p_data[[pri]])) > 6)) { + if (nrow(p_data) > 10 | + any(nchar(as.character(p_data[[pri]])) > 6)) { p <- p + # ggplot2::guides(fill = "none") + - ggplot2::theme( - axis.text.x = ggplot2::element_text( - angle = 90, - vjust = 1, hjust = 1 - ))+ - ggplot2::theme( - axis.text.x = ggplot2::element_text(vjust = 0.5) - ) + ggplot2::theme(axis.text.x = ggplot2::element_text( + angle = 90, + vjust = 1, + hjust = 1 + )) + + ggplot2::theme(axis.text.x = ggplot2::element_text(vjust = 0.5)) - if (is.null(sec)){ + if (is.null(sec)) { p <- p + ggplot2::guides(fill = "none") } } - p + p + + ggplot2::scale_y_continuous(labels = scales::percent) + + ggplot2::ylab("Percentage") } diff --git a/R/separate_string.R b/R/separate_string.R index 0aa64e6c..61063b53 100644 --- a/R/separate_string.R +++ b/R/separate_string.R @@ -50,7 +50,7 @@ string_split_ui <- function(id) { ), actionButton( inputId = ns("create"), - label = tagList(phosphoricons::ph("pencil"), i18n$t("Apply split")), + label = tagList(phosphoricons::ph("pencil",weight = "bold"), i18n$t("Apply split")), class = "btn-outline-primary float-end" ), tags$div(class = "clearfix") diff --git a/R/sysdata.rda b/R/sysdata.rda index 443516d1..c56ca282 100644 Binary files a/R/sysdata.rda and b/R/sysdata.rda differ diff --git a/R/ui_elements.R b/R/ui_elements.R index 2cd23878..6686879d 100644 --- a/R/ui_elements.R +++ b/R/ui_elements.R @@ -124,7 +124,7 @@ ui_elements <- function(selection) { inputId = "modal_initial_view", label = i18n$t("Quick overview"), width = "100%", - icon = phosphoricons::ph("binoculars"), + icon = phosphoricons::ph("binoculars",weight = "bold"), # icon = shiny::icon("binoculars"), disabled = FALSE ), @@ -169,7 +169,7 @@ ui_elements <- function(selection) { inputId = "act_start", label = i18n$t("Let's begin!"), width = "100%", - icon = phosphoricons::ph("play"), + icon = phosphoricons::ph("play",weight = "bold"), # icon = shiny::icon("play"), disabled = TRUE ), @@ -460,7 +460,7 @@ ui_elements <- function(selection) { inputId = "act_eval", label = i18n$t("Evaluate"), width = "100%", - icon = phosphoricons::ph("calculator"), + icon = phosphoricons::ph("calculator",weight = "bold"), # icon = shiny::icon("calculator"), disabled = TRUE ), diff --git a/R/update-factor-ext.R b/R/update-factor-ext.R index e8699886..98d24dae 100644 --- a/R/update-factor-ext.R +++ b/R/update-factor-ext.R @@ -44,7 +44,7 @@ update_factor_ui <- function(id) { actionButton( disabled = TRUE, inputId = ns("drop_levels"), - label = tagList(phosphoricons::ph("trash"), i18n$t("Drop empty")), + label = tagList(phosphoricons::ph("trash",weight = "bold"), i18n$t("Drop empty")), class = "btn-outline-primary mb-3", width = "100%" ) @@ -55,7 +55,7 @@ update_factor_ui <- function(id) { actionButton( inputId = ns("sort_levels"), label = tagList( - phosphoricons::ph("sort-ascending"), + phosphoricons::ph("sort-ascending",weight = "bold"), i18n$t("Sort by levels") ), class = "btn-outline-primary mb-3", @@ -68,7 +68,7 @@ update_factor_ui <- function(id) { actionButton( inputId = ns("sort_occurrences"), label = tagList( - phosphoricons::ph("sort-ascending"), + phosphoricons::ph("sort-ascending",weight = "bold"), i18n$t("Sort by count") ), class = "btn-outline-primary mb-3", @@ -92,7 +92,7 @@ update_factor_ui <- function(id) { actionButton( inputId = ns("create"), label = tagList( - phosphoricons::ph("arrow-clockwise"), + phosphoricons::ph("arrow-clockwise",weight = "bold"), i18n$t("Update factor variable") ), class = "btn-outline-primary" diff --git a/R/update-variables-ext.R b/R/update-variables-ext.R index 17542646..b5dc5ab0 100644 --- a/R/update-variables-ext.R +++ b/R/update-variables-ext.R @@ -30,7 +30,7 @@ update_variables_ui <- function(id, title = "") { placement = "bottom-end", shiny::actionButton( inputId = ns("settings"), - label = phosphoricons::ph("gear"), + label = phosphoricons::ph("gear",weight = "bold"), class = "pull-right float-right" ), shinyWidgets::textInputIcon( @@ -75,7 +75,7 @@ update_variables_ui <- function(id, title = "") { shiny::actionButton( inputId = ns("validate"), label = htmltools::tagList( - phosphoricons::ph("arrow-circle-right", title = i18n$t("Apply changes")), + phosphoricons::ph("arrow-circle-right", title = i18n$t("Apply changes"),weight = "bold"), i18n$t("Apply changes") ), width = "100%" diff --git a/SESSION.md b/SESSION.md index d1466928..1e301770 100644 --- a/SESSION.md +++ b/SESSION.md @@ -4,18 +4,18 @@ |setting |value | |:-----------|:------------------------------------------| |version |R version 4.5.2 (2025-10-31) | -|os |macOS Tahoe 26.4 | +|os |macOS Tahoe 26.4.1 | |system |aarch64, darwin20 | |ui |RStudio | |language |(EN) | |collate |en_US.UTF-8 | |ctype |en_US.UTF-8 | |tz |Europe/Copenhagen | -|date |2026-04-01 | +|date |2026-04-10 | |rstudio |2026.01.1+403 Apple Blossom (desktop) | |pandoc |3.6.4 @ /opt/homebrew/bin/ (via rmarkdown) | |quarto |1.7.30 @ /usr/local/bin/quarto | -|FreesearchR |26.4.1.260401 | +|FreesearchR |26.4.2.260410 | -------------------------------------------------------------------------------- @@ -83,7 +83,7 @@ |foreach |1.5.2 |2022-02-02 |CRAN (R 4.5.0) | |foreign |0.8-91 |2026-01-29 |CRAN (R 4.5.2) | |Formula |1.2-5 |2023-02-24 |CRAN (R 4.5.0) | -|FreesearchR |26.4.1 |NA |NA | +|FreesearchR |26.4.2 |NA |NA | |fs |1.6.7 |2026-03-06 |CRAN (R 4.5.2) | |gdtools |0.5.0 |2026-02-09 |CRAN (R 4.5.2) | |generics |0.1.4 |2025-05-09 |CRAN (R 4.5.0) | @@ -147,7 +147,6 @@ |pkgload |1.5.0 |2026-02-03 |CRAN (R 4.5.2) | |plyr |1.8.9 |2023-10-02 |CRAN (R 4.5.0) | |polyclip |1.10-7 |2024-07-23 |CRAN (R 4.5.0) | -|polylabelr |1.0.0 |2026-01-19 |CRAN (R 4.5.2) | |pracma |2.4.6 |2025-10-22 |CRAN (R 4.5.0) | |processx |3.8.6 |2025-02-21 |CRAN (R 4.5.0) | |promises |1.5.0 |2025-11-01 |CRAN (R 4.5.0) | diff --git a/inst/translations/translation_da.csv b/inst/translations/translation_da.csv index 2240bc2c..927131ba 100644 --- a/inst/translations/translation_da.csv +++ b/inst/translations/translation_da.csv @@ -275,7 +275,6 @@ "Select a dataset from your environment or sample dataset from a package.","Vælg et datasæt fra din kørende session eller vælg træningsdata." "Select a sample dataset from a package.","Vælg et træningsdatasæt." "Data ready to be imported!","Data er klar til at blive importeret!" -"Data has %s obs. of %s variables.","Data har %s obs. på %s variabler." "Data successfully imported!","Data successfully imported!" "Click to see data","Klik for at se data" "No data present.","Ingen data tilstede." @@ -320,3 +319,4 @@ "Likert diagram","Likert diagram" "Modify factor","Modify factor" "Create factor/categorical variable from other variables.","Create factor/categorical variable from other variables." +"The data set has %s obs. in %s variables.","The data set has %s obs. in %s variables." diff --git a/inst/translations/translation_sw.csv b/inst/translations/translation_sw.csv index 7866710e..134ec155 100644 --- a/inst/translations/translation_sw.csv +++ b/inst/translations/translation_sw.csv @@ -275,7 +275,6 @@ "Select a dataset from your environment or sample dataset from a package.","Select a dataset from your environment or sample dataset from a package." "Select a sample dataset from a package.","Select a sample dataset from a package." "Data ready to be imported!","Data ready to be imported!" -"Data has %s obs. of %s variables.","Data has %s obs. of %s variables." "Data successfully imported!","Data successfully imported!" "Click to see data","Click to see data" "No data present.","No data present." @@ -320,3 +319,4 @@ "Likert diagram","Likert diagram" "Modify factor","Modify factor" "Create factor/categorical variable from other variables.","Create factor/categorical variable from other variables." +"The data set has %s obs. in %s variables.","The data set has %s obs. in %s variables." diff --git a/man/align_axes.Rd b/man/align_axes.Rd index 2a8ab279..6d3e79e2 100644 --- a/man/align_axes.Rd +++ b/man/align_axes.Rd @@ -4,7 +4,7 @@ \alias{align_axes} \title{Aligns axes between plots} \usage{ -align_axes(..., x.axis = TRUE, y.axis = TRUE) +align_axes(..., x.axis = TRUE, y.axis = TRUE, percentage = FALSE) } \arguments{ \item{...}{ggplot2 objects or list of ggplot2 objects} diff --git a/man/data-plots.Rd b/man/data-plots.Rd index 6da5a230..4222466f 100644 --- a/man/data-plots.Rd +++ b/man/data-plots.Rd @@ -7,6 +7,7 @@ \alias{data_visuals_ui} \alias{data_visuals_server} \alias{create_plot} +\alias{plot_bar} \alias{plot_bar_single} \alias{plot_box} \alias{plot_box_single} @@ -25,6 +26,17 @@ data_visuals_server(id, data, palettes, ...) create_plot(data, type, pri, sec, ter = NULL, color.palette = "viridis", ...) +plot_bar( + data, + pri, + sec = NULL, + ter = NULL, + style = c("stack", "dodge", "fill"), + color.palette = "viridis", + max_level = 30, + ... +) + plot_bar_single( data, pri, @@ -91,6 +103,8 @@ shiny server module ggplot2 object +ggplot list object + ggplot object ggplot2 object @@ -116,6 +130,8 @@ Data correlations evaluation module Wrapper to create plot based on provided type +Title + Single vertical barplot Beautiful box plot(s) @@ -138,6 +154,13 @@ Beautiful violin plot } \examples{ create_plot(mtcars, "plot_violin", "mpg", "cyl") |> attributes() +mtcars |> + dplyr::mutate(cyl = factor(cyl), am = factor(am)) |> + plot_bar(pri = "cyl", sec = "am", style = "fill") + +mtcars |> + dplyr::mutate(dplyr::across(tidyselect::all_of(c("cyl","am","gear")),factor)) |> + plot_bar(pri = "cyl", sec = "gear", ter = "am", style = "stack",color.palette="turbo") mtcars |> dplyr::mutate(cyl = factor(cyl), am = factor(am)) |> plot_bar_single(pri = "cyl", sec = "am", style = "fill") diff --git a/man/wrap_plot_list.Rd b/man/wrap_plot_list.Rd index 2a6e8d62..40cf0ba1 100644 --- a/man/wrap_plot_list.Rd +++ b/man/wrap_plot_list.Rd @@ -12,6 +12,7 @@ wrap_plot_list( guides = "collect", axes = "collect", axis_titles = "collect", + y.axis.percentage = FALSE, ... ) }