mirror of
https://github.com/agdamsbo/FreesearchR.git
synced 2026-06-19 04:27:30 +02:00
Compare commits
62 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
acbed08a0d |
|||
|
e8307d3a2e |
|||
| dbf819c55a | |||
|
5e85902d4b |
|||
|
1793a2650f |
|||
|
bcc4905354 |
|||
|
ab3df0eda6 |
|||
|
5ca751d3ea |
|||
|
f774b90d07 |
|||
|
f2a522dcb6 |
|||
|
d1e0236437 |
|||
|
0d4f51f176 |
|||
|
7f14447627 |
|||
|
41c855a71c |
|||
|
af4e21b836 |
|||
|
b2745f5628 |
|||
|
1e19486af1 |
|||
|
4213487a77 |
|||
|
0d9ad7457e |
|||
|
451f5bf9a8 |
|||
|
dda744a99a |
|||
|
1d0fc4f4ad |
|||
|
de52a56b1f |
|||
|
d397532aed |
|||
|
46c6ed03ae |
|||
|
7b0692fd17 |
|||
|
75f2ae07b7 |
|||
|
fcf422bc4b |
|||
|
c28a3d0a6d |
|||
|
9122ce2663 |
|||
|
18eae4b3a3 |
|||
|
163cbffeaf |
|||
|
ba03109416 |
|||
|
ce0ecef633 |
|||
|
9b4ddafe6f |
|||
|
748a3c3e07 |
|||
|
7408227788 |
|||
|
692776a857 |
|||
|
8961bc6a5d |
|||
|
9a223f4c54 |
|||
|
6c850847b7 |
|||
|
2d062e0ac5 |
|||
|
b0ecce8c54 |
|||
|
cfbee14dcb |
|||
|
c23570ca54 |
|||
|
507982c51b |
|||
|
7394a6753f |
|||
|
9e2ee1e402 |
|||
|
afae978c26 |
|||
|
f0f1e6965a |
|||
|
95e813753f |
|||
|
f928aee110 |
|||
|
342579c36f |
|||
|
a8ff1c8204 |
|||
|
95fc0a4d5f |
|||
|
a73f8b1ba3 |
|||
|
39db24c9be |
|||
|
62aa629ad2 |
|||
|
16fdd3fdef |
|||
|
0090651927 |
|||
|
01b48dccb5 |
|||
|
8935b0b2a4 |
86 changed files with 15463 additions and 8635 deletions
|
|
@ -17,3 +17,5 @@
|
|||
^app*$
|
||||
^page$
|
||||
^demo$
|
||||
^\.positai$
|
||||
^\.claude$
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -6,7 +6,6 @@ dev/
|
|||
.DS_Store
|
||||
.quarto
|
||||
app/rsconnect
|
||||
inst/shiny-examples/casting/functions.R
|
||||
functions.R
|
||||
docs
|
||||
inst/doc
|
||||
|
|
@ -17,3 +16,4 @@ app
|
|||
page
|
||||
demo
|
||||
visuals
|
||||
.positai
|
||||
|
|
|
|||
|
|
@ -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.3.2
|
||||
version: 26.6.1
|
||||
doi: 10.5281/zenodo.14527429
|
||||
identifiers:
|
||||
- type: url
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
Package: FreesearchR
|
||||
Title: Easy data analysis for clinicians
|
||||
Version: 26.3.2
|
||||
Version: 26.6.1
|
||||
Authors@R: c(
|
||||
person("Andreas Gammelgaard", "Damsbo",email="agdamsbo@clin.au.dk", role = c("aut", "cre"),
|
||||
comment = c(ORCID = "0000-0002-7559-1154")),
|
||||
|
|
@ -108,6 +108,7 @@ Collate:
|
|||
'data_plots.R'
|
||||
'datagrid-infos-mod.R'
|
||||
'footer_ui.R'
|
||||
'generate_colors.R'
|
||||
'helpers.R'
|
||||
'hosted_version.R'
|
||||
'html_dependency_freesearchr.R'
|
||||
|
|
@ -117,10 +118,12 @@ Collate:
|
|||
'launch_FreesearchR.R'
|
||||
'missings-module.R'
|
||||
'plot-download-module.R'
|
||||
'plot-helpers.R'
|
||||
'plot_bar.R'
|
||||
'plot_box.R'
|
||||
'plot_euler.R'
|
||||
'plot_hbar.R'
|
||||
'plot_likert.R'
|
||||
'plot_ridge.R'
|
||||
'plot_sankey.R'
|
||||
'plot_scatter.R'
|
||||
|
|
@ -141,5 +144,6 @@ Collate:
|
|||
'update-variables-ext.R'
|
||||
'utils-labels.R'
|
||||
'validation.R'
|
||||
'version_check.R'
|
||||
'visual_summary.R'
|
||||
'wide2long.R'
|
||||
|
|
|
|||
19
NAMESPACE
19
NAMESPACE
|
|
@ -16,13 +16,16 @@ export(append_column)
|
|||
export(append_list)
|
||||
export(apply_labels)
|
||||
export(argsstring2list)
|
||||
export(available_plots)
|
||||
export(baseline_table)
|
||||
export(class_icons)
|
||||
export(clean_common_axis)
|
||||
export(clean_date)
|
||||
export(clean_sep)
|
||||
export(colorSelectInput)
|
||||
export(columnSelectInput)
|
||||
export(compare_missings)
|
||||
export(continuous_colors)
|
||||
export(contrast_text)
|
||||
export(corr_pairs_validate)
|
||||
export(correlation_pairs)
|
||||
|
|
@ -59,8 +62,10 @@ export(factor_new_levels_labels)
|
|||
export(factorize)
|
||||
export(file_export)
|
||||
export(format_writer)
|
||||
export(generate_colors)
|
||||
export(get_data_packages)
|
||||
export(get_fun_options)
|
||||
export(get_input_params)
|
||||
export(get_label)
|
||||
export(get_list_elements)
|
||||
export(get_plot_options)
|
||||
|
|
@ -113,12 +118,14 @@ 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)
|
||||
export(plot_euler)
|
||||
export(plot_euler_single)
|
||||
export(plot_hbars)
|
||||
export(plot_likert)
|
||||
export(plot_ridge)
|
||||
export(plot_sankey)
|
||||
export(plot_sankey_single)
|
||||
|
|
@ -139,6 +146,8 @@ export(remove_nested_list)
|
|||
export(repeated_instruments)
|
||||
export(restore_labels)
|
||||
export(sankey_ready)
|
||||
export(scale_color_generate)
|
||||
export(scale_fill_generate)
|
||||
export(selectInputIcon)
|
||||
export(separate_string)
|
||||
export(set_column_label)
|
||||
|
|
@ -161,6 +170,7 @@ export(update_factor_server)
|
|||
export(update_factor_ui)
|
||||
export(update_variables_server)
|
||||
export(update_variables_ui)
|
||||
export(validate_redcap_filter)
|
||||
export(validation_server)
|
||||
export(validation_ui)
|
||||
export(vectorSelectInput)
|
||||
|
|
@ -174,9 +184,17 @@ export(winbox_update_factor)
|
|||
export(with_labels)
|
||||
export(wrap_plot_list)
|
||||
export(write_quarto)
|
||||
importFrom(RColorBrewer,brewer.pal)
|
||||
importFrom(RColorBrewer,brewer.pal.info)
|
||||
importFrom(classInt,classIntervals)
|
||||
importFrom(data.table,as.data.table)
|
||||
importFrom(data.table,data.table)
|
||||
importFrom(grDevices,colorRampPalette)
|
||||
importFrom(grDevices,hcl.colors)
|
||||
importFrom(grDevices,heat.colors)
|
||||
importFrom(grDevices,rainbow)
|
||||
importFrom(grDevices,terrain.colors)
|
||||
importFrom(grDevices,topo.colors)
|
||||
importFrom(graphics,abline)
|
||||
importFrom(graphics,axis)
|
||||
importFrom(graphics,hist)
|
||||
|
|
@ -239,3 +257,4 @@ importFrom(toastui,renderDatagrid)
|
|||
importFrom(toastui,renderDatagrid2)
|
||||
importFrom(utils,data)
|
||||
importFrom(utils,type.convert)
|
||||
importFrom(viridisLite,viridis)
|
||||
|
|
|
|||
46
NEWS.md
46
NEWS.md
|
|
@ -1,3 +1,49 @@
|
|||
# FreesearchR 26.6.1
|
||||
|
||||
*NEW* The visuals module has been restructured to allow for more advanced inputs, which will be added in the future. Basically a more future proof design allowing for more adjustments, while striving to keep the simplicity. Have fun!
|
||||
|
||||
# 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.
|
||||
|
||||
# FreesearchR 26.3.6
|
||||
|
||||
*FIX* Plot single variable in Likert plot.
|
||||
|
||||
*FIX* Horizontal stacked plot crashed. Fixed!
|
||||
|
||||
# FreesearchR 26.3.5
|
||||
|
||||
*FIX* Labelled categorical variables were not handled correctly importing from REDCap resulting in lost labels. Fixed!
|
||||
|
||||
*CHANGE* Testing in new data I realised, that automatically removing empty levels in categorical variables/factors is not desired. It should be a concious decision to remove levels. This is now possible in the "Modify factor" pop-up.
|
||||
|
||||
*CHANGE* REDCap export now throws an error if no data was exported. The server side filtering prior to export is now validated and feedback is printed. Only valid filter statements are used when exporting data from the REDCap server. This is an advanced use case, but a great way to ensure only the minimum required data is exported from the server.
|
||||
|
||||
*FIX* Applying filters now works also when the data contains text variables.
|
||||
|
||||
*NEW* Initial support for plotting Likert scale survey results. This is expected to be further improved. For based on ggstats::gglikert.
|
||||
|
||||
# FreesearchR 26.3.4
|
||||
|
||||
*NEW* Color select for plotting across all plots for even more option. Ten palettes have been chosen, to provide varied and interpretable options. The selector will always show a preview of four colors.
|
||||
|
||||
*NEW* Added app version check against latest release on GitHub. Only runs if internet connection present. No other polling.
|
||||
|
||||
*NEW* Added a "Missing" level to the Sankey plot function and adjusted the label font size. And fixed support for dichotomous data.
|
||||
|
||||
# FreesearchR 26.3.3
|
||||
|
||||
*NEW* option to pass global settings when running as docker or launching from R. Support for INCLUDE_GLOBALENV, DATA_LIMIT_DEFAULT, DATA_LIMIT_UPPER and DATA_LIMIT_LOWER. Described in the README.
|
||||
|
||||
*FIX* faster data description function.
|
||||
|
||||
Also added a few tests to the package.
|
||||
|
||||
# FreesearchR 26.3.2
|
||||
|
||||
*FIX* Updating factor levels always created new factor.
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
app_version <- function()'26.3.2'
|
||||
app_version <- function()'26.6.1'
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@
|
|||
#' @examples
|
||||
#' mtcars |> baseline_table()
|
||||
#' mtcars |> baseline_table(fun.args = list(by = "gear"))
|
||||
baseline_table <- function(data, fun.args = NULL, fun = gtsummary::tbl_summary, vars = NULL) {
|
||||
baseline_table <- function(data,
|
||||
fun.args = NULL,
|
||||
fun = gtsummary::tbl_summary,
|
||||
vars = NULL) {
|
||||
out <- do.call(fun, c(list(data = data), fun.args))
|
||||
return(out)
|
||||
}
|
||||
|
|
@ -37,7 +40,15 @@ baseline_table <- function(data, fun.args = NULL, fun = gtsummary::tbl_summary,
|
|||
#' mtcars |> create_baseline(by.var = "gear", detail_level = "extended",type = list(gtsummary::all_dichotomous() ~ "categorical"),theme="nejm")
|
||||
#'
|
||||
#' create_baseline(default_parsing(mtcars), by.var = "am", add.p = FALSE, add.overall = FALSE, theme = "lancet")
|
||||
create_baseline <- function(data, ..., by.var, add.p = FALSE, add.diff=FALSE, add.overall = FALSE, theme = c("jama", "lancet", "nejm", "qjecon"), detail_level = c("minimal", "extended")) {
|
||||
create_baseline <- function(data,
|
||||
...,
|
||||
by.var,
|
||||
add.p = FALSE,
|
||||
add.diff = FALSE,
|
||||
add.overall = FALSE,
|
||||
theme = c("jama", "lancet", "nejm", "qjecon"),
|
||||
detail_level = c("minimal", "extended"),
|
||||
drop_empty = FALSE) {
|
||||
theme <- match.arg(theme)
|
||||
|
||||
detail_level <- match.arg(detail_level)
|
||||
|
|
@ -64,31 +75,28 @@ create_baseline <- function(data, ..., by.var, add.p = FALSE, add.diff=FALSE, ad
|
|||
if (!any(hasName(args, c("type", "statistic")))) {
|
||||
if (detail_level == "extended") {
|
||||
args <-
|
||||
modifyList(
|
||||
args,
|
||||
list(
|
||||
type = list(gtsummary::all_continuous() ~ "continuous2",
|
||||
gtsummary::all_dichotomous() ~ "categorical"),
|
||||
statistic = list(gtsummary::all_continuous() ~ c(
|
||||
"{median} ({p25}, {p75})",
|
||||
"{mean} ({sd})",
|
||||
"{min}, {max}"))
|
||||
modifyList(args, list(
|
||||
type = list(
|
||||
gtsummary::all_continuous() ~ "continuous2",
|
||||
gtsummary::all_dichotomous() ~ "categorical"
|
||||
),
|
||||
statistic = list(
|
||||
gtsummary::all_continuous() ~ c("{median} ({p25}, {p75})", "{mean} ({sd})", "{min}, {max}")
|
||||
)
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
parameters <- list(
|
||||
data = data,
|
||||
fun.args = purrr::list_flatten(list(by = by.var, args))
|
||||
)
|
||||
if (isTRUE(drop_empty)) {
|
||||
## Drops empty levels if minimal
|
||||
data <- data |> REDCapCAST::fct_drop()
|
||||
}
|
||||
|
||||
parameters <- list(data = data, fun.args = purrr::list_flatten(list(by = by.var, args)))
|
||||
|
||||
|
||||
# browser()
|
||||
out <- do.call(
|
||||
baseline_table,
|
||||
parameters
|
||||
)
|
||||
out <- do.call(baseline_table, parameters)
|
||||
|
||||
|
||||
if (!is.null(by.var)) {
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -20,30 +20,36 @@
|
|||
#' @importFrom shiny selectizeInput
|
||||
#' @export
|
||||
#'
|
||||
columnSelectInput <- function(
|
||||
inputId,
|
||||
label,
|
||||
data,
|
||||
selected = "",
|
||||
...,
|
||||
col_subset = NULL,
|
||||
placeholder = "",
|
||||
onInitialize,
|
||||
none_label = "No variable selected",
|
||||
maxItems = NULL
|
||||
) {
|
||||
datar <- if (is.reactive(data)) data else reactive(data)
|
||||
col_subsetr <- if (is.reactive(col_subset)) col_subset else reactive(col_subset)
|
||||
columnSelectInput <- function(inputId,
|
||||
label,
|
||||
data,
|
||||
selected = "",
|
||||
...,
|
||||
col_subset = NULL,
|
||||
placeholder = "",
|
||||
onInitialize,
|
||||
none_label = "No variable selected",
|
||||
maxItems = NULL) {
|
||||
datar <- if (is.reactive(data))
|
||||
data
|
||||
else
|
||||
reactive(data)
|
||||
col_subsetr <- if (is.reactive(col_subset))
|
||||
col_subset
|
||||
else
|
||||
reactive(col_subset)
|
||||
|
||||
labels <- Map(function(col) {
|
||||
json <- sprintf(
|
||||
IDEAFilter:::strip_leading_ws('
|
||||
IDEAFilter:::strip_leading_ws(
|
||||
'
|
||||
{
|
||||
"name": "%s",
|
||||
"label": "%s",
|
||||
"dataclass": "%s",
|
||||
"datatype": "%s"
|
||||
}'),
|
||||
}'
|
||||
),
|
||||
col,
|
||||
attr(datar()[[col]], "label") %||% "",
|
||||
IDEAFilter:::get_dataFilter_class(datar()[[col]]),
|
||||
|
|
@ -52,12 +58,25 @@ columnSelectInput <- function(
|
|||
}, col = names(datar()))
|
||||
|
||||
if (!"none" %in% names(datar())) {
|
||||
labels <- c("none" = list(sprintf('\n {\n \"name\": \"none\",\n \"label\": \"%s\",\n \"dataclass\": \"\",\n \"datatype\": \"\"\n }', none_label)), labels)
|
||||
labels <- c("none" = list(
|
||||
sprintf(
|
||||
'\n {\n \"name\": \"none\",\n \"label\": \"%s\",\n \"dataclass\": \"\",\n \"datatype\": \"\"\n }',
|
||||
none_label
|
||||
)
|
||||
), labels)
|
||||
choices <- setNames(names(labels), labels)
|
||||
choices <- choices[match(if (length(col_subsetr()) == 0 || isTRUE(col_subsetr() == "")) names(datar()) else col_subsetr(), choices)]
|
||||
choices <- choices[match(if (length(col_subsetr()) == 0 ||
|
||||
isTRUE(col_subsetr() == ""))
|
||||
names(datar())
|
||||
else
|
||||
col_subsetr(), choices)]
|
||||
} else {
|
||||
choices <- setNames(names(datar()), labels)
|
||||
choices <- choices[match(if (length(col_subsetr()) == 0 || isTRUE(col_subsetr() == "")) choices else col_subsetr(), choices)]
|
||||
choices <- choices[match(if (length(col_subsetr()) == 0 ||
|
||||
isTRUE(col_subsetr() == ""))
|
||||
choices
|
||||
else
|
||||
col_subsetr(), choices)]
|
||||
}
|
||||
|
||||
shiny::selectizeInput(
|
||||
|
|
@ -66,8 +85,9 @@ columnSelectInput <- function(
|
|||
choices = choices,
|
||||
selected = selected,
|
||||
...,
|
||||
options = c(
|
||||
list(render = I("{
|
||||
options = c(list(
|
||||
render = I(
|
||||
"{
|
||||
// format the way that options are rendered
|
||||
option: function(item, escape) {
|
||||
item.data = JSON.parse(item.label);
|
||||
|
|
@ -95,9 +115,10 @@ columnSelectInput <- function(
|
|||
escape(item.data.name) +
|
||||
'</div>';
|
||||
}
|
||||
}")),
|
||||
if (!is.null(maxItems)) list(maxItems = maxItems)
|
||||
)
|
||||
}"
|
||||
)
|
||||
), if (!is.null(maxItems))
|
||||
list(maxItems = maxItems))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -150,7 +171,10 @@ vectorSelectInput <- function(inputId,
|
|||
...,
|
||||
placeholder = "",
|
||||
onInitialize) {
|
||||
datar <- if (shiny::is.reactive(choices)) data else shiny::reactive(choices)
|
||||
datar <- if (shiny::is.reactive(choices))
|
||||
data
|
||||
else
|
||||
shiny::reactive(choices)
|
||||
|
||||
labels <- sprintf(
|
||||
IDEAFilter:::strip_leading_ws('
|
||||
|
|
@ -170,8 +194,9 @@ vectorSelectInput <- function(inputId,
|
|||
choices = choices_new,
|
||||
selected = selected,
|
||||
...,
|
||||
options = c(
|
||||
list(render = I("{
|
||||
options = c(list(
|
||||
render = I(
|
||||
"{
|
||||
// format the way that options are rendered
|
||||
option: function(item, escape) {
|
||||
item.data = JSON.parse(item.label);
|
||||
|
|
@ -190,7 +215,135 @@ vectorSelectInput <- function(inputId,
|
|||
escape(item.data.name) +
|
||||
'</div>';
|
||||
}
|
||||
}"))
|
||||
}"
|
||||
)
|
||||
))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#' A selectizeInput customized for named vectors of color names supported by
|
||||
#' \code{\link{generate_colors}}
|
||||
#'
|
||||
#' @param inputId passed to \code{\link[shiny]{selectizeInput}}
|
||||
#' @param label passed to \code{\link[shiny]{selectizeInput}}
|
||||
#' @param choices A named \code{vector} from which fields should be populated
|
||||
#' @param selected default selection
|
||||
#' @param previews number of preview colors. Default is 4.
|
||||
#' @param ... passed to \code{\link[shiny]{selectizeInput}}
|
||||
#' @param placeholder passed to \code{\link[shiny]{selectizeInput}} options
|
||||
#' @param onInitialize passed to \code{\link[shiny]{selectizeInput}} options
|
||||
#'
|
||||
#' @returns a \code{\link[shiny]{selectizeInput}} dropdown element
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' if (shiny::interactive()) {
|
||||
#'top_palettes <- c(
|
||||
#'"Perceptual (blue-yellow)" = "viridis",
|
||||
#'"Perceptual (fire)" = "plasma",
|
||||
#'"Colour-blind friendly" = "Okabe-Ito",
|
||||
#'"Qualitative (bold)" = "Dark 2",
|
||||
#'"Qualitative (paired)" = "Paired",
|
||||
#'"Sequential (blues)" = "Blues",
|
||||
#'"Diverging (red-blue)" = "RdBu",
|
||||
#'"Tableau style" = "Tableau 10",
|
||||
#'"Pastel" = "Pastel 1",
|
||||
#'"Rainbow" = "rainbow"
|
||||
#')
|
||||
#' shinyApp(
|
||||
#' ui = fluidPage(
|
||||
#' titlePanel("Color Palette Select Test"),
|
||||
#' colorSelectInput(
|
||||
#' inputId = "palette",
|
||||
#' label = "Color palette",
|
||||
#' choices = top_palettes,
|
||||
#' selected = "viridis"
|
||||
#' ),
|
||||
#' verbatimTextOutput("selected")
|
||||
#' ),
|
||||
#' server = function(input, output, session) {
|
||||
#' output$selected <- renderPrint(input$palette)
|
||||
#' }
|
||||
#' )
|
||||
#' }
|
||||
colorSelectInput <- function(inputId,
|
||||
label,
|
||||
choices,
|
||||
selected = NULL,
|
||||
previews = 4,
|
||||
...,
|
||||
placeholder = "") {
|
||||
vals <- if (shiny::is.reactive(choices)) {
|
||||
choices()
|
||||
} else{
|
||||
choices
|
||||
}
|
||||
|
||||
swatch_html <- function(palette_name) {
|
||||
colors <- tryCatch(
|
||||
suppressMessages(generate_colors(previews, palette_name)),
|
||||
error = function(e)
|
||||
rep("#cccccc", 3)
|
||||
)
|
||||
# Strip alpha channel to ensure valid 6-digit CSS hex
|
||||
colors <- substr(colors, 1, 7)
|
||||
paste0(
|
||||
sprintf(
|
||||
"<span style='display:inline-block;width:12px;height:12px;background:%s;border-radius:2px;margin-right:1px;'></span>",
|
||||
colors
|
||||
),
|
||||
collapse = ""
|
||||
)
|
||||
}
|
||||
|
||||
labels <- sprintf(
|
||||
'{"name": "%s", "label": "%s", "swatch": "%s"}',
|
||||
vals,
|
||||
names(vals) %||% "",
|
||||
vapply(vals, swatch_html, character(1))
|
||||
)
|
||||
|
||||
choices_new <- stats::setNames(vals, labels)
|
||||
|
||||
if (is.null(selected) || selected == "") {
|
||||
selected <- vals[[1]]
|
||||
}
|
||||
|
||||
shiny::selectizeInput(
|
||||
inputId = inputId,
|
||||
label = label,
|
||||
choices = choices_new,
|
||||
selected = selected,
|
||||
...,
|
||||
options = list(
|
||||
render = I(
|
||||
"{
|
||||
option: function(item, escape) {
|
||||
item.data = JSON.parse(item.label);
|
||||
return '<div style=\"padding:3px 12px\">' +
|
||||
'<div><strong>' + escape(item.data.name) + '</strong></div>' +
|
||||
(item.data.label != '' ? '<div><small>' + escape(item.data.label) + '</small></div>' : '') +
|
||||
'<div style=\"margin-top:4px\">' + item.data.swatch + '</div>' +
|
||||
'</div>';
|
||||
},
|
||||
item: function(item, escape) {
|
||||
item.data = JSON.parse(item.label);
|
||||
return '<div style=\"display:flex;align-items:center;gap:6px\">' +
|
||||
'<span>' + escape(item.data.name) + '</span>' +
|
||||
item.data.swatch +
|
||||
'</div>';
|
||||
}
|
||||
}"
|
||||
),
|
||||
onInitialize = I(
|
||||
"function() {
|
||||
var self = this;
|
||||
self.$control_input.prop('readonly', true);
|
||||
self.$control_input.css('cursor', 'default');
|
||||
self.$control.css('cursor', 'pointer');
|
||||
}"
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
@ -378,7 +378,7 @@ cut_variable_server <- function(id, data_r = reactive(NULL)) {
|
|||
rlang::exec(cut_var, !!!parameters)
|
||||
},
|
||||
error = function(err) {
|
||||
showNotification(paste("We encountered the following error creating the new factor:", err), type = "err")
|
||||
showNotification(paste("We encountered the following error creating the new factor:", err), type = "error")
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ add_sparkline <- function(grid, column = "vals", color.main = "#2a8484", color.s
|
|||
type <- "line"
|
||||
ds <- data.frame(x = NA, y = NA)
|
||||
horizontal <- FALSE
|
||||
} else if (identical(data_cl, "factor")) {
|
||||
} else if ("factor" %in% data_cl) {
|
||||
type <- "column"
|
||||
s <- summary(data)
|
||||
ds <- data.frame(x = names(s), y = s)
|
||||
|
|
@ -309,21 +309,29 @@ class_icons <- function(x) {
|
|||
lapply(x,class_icons)
|
||||
} else {
|
||||
if (identical(x, "numeric")) {
|
||||
shiny::icon("calculator")
|
||||
phosphoricons::ph("calculator")
|
||||
# shiny::icon("calculator")
|
||||
} else if (identical(x, "factor")) {
|
||||
shiny::icon("chart-simple")
|
||||
phosphoricons::ph("chart-bar")
|
||||
# shiny::icon("chart-simple")
|
||||
} else if (identical(x, "integer")) {
|
||||
shiny::icon("arrow-down-1-9")
|
||||
phosphoricons::ph("list-numbers")
|
||||
# shiny::icon("arrow-down-1-9")
|
||||
} else if (identical(x, "character")) {
|
||||
shiny::icon("arrow-down-a-z")
|
||||
phosphoricons::ph("text-aa")
|
||||
# shiny::icon("arrow-down-a-z")
|
||||
} else if (identical(x, "logical")) {
|
||||
shiny::icon("toggle-off")
|
||||
phosphoricons::ph("toggle-left")
|
||||
# shiny::icon("toggle-off")
|
||||
} else if (any(c("Date", "POSIXt") %in% x)) {
|
||||
shiny::icon("calendar-days")
|
||||
phosphoricons::ph("calendar")
|
||||
# shiny::icon("calendar-days")
|
||||
} else if (any("POSIXct", "hms") %in% x) {
|
||||
shiny::icon("clock")
|
||||
phosphoricons::ph("clock")
|
||||
# shiny::icon("clock")
|
||||
} else {
|
||||
shiny::icon("table")
|
||||
phosphoricons::ph("calendar")
|
||||
# shiny::icon("table")
|
||||
}}
|
||||
}
|
||||
|
||||
|
|
@ -342,21 +350,29 @@ type_icons <- function(x) {
|
|||
lapply(x,class_icons)
|
||||
} else {
|
||||
if (identical(x, "continuous")) {
|
||||
shiny::icon("calculator")
|
||||
phosphoricons::ph("calculator")
|
||||
# shiny::icon("calculator")
|
||||
} else if (identical(x, "categorical")) {
|
||||
shiny::icon("chart-simple")
|
||||
phosphoricons::ph("chart-bar")
|
||||
# shiny::icon("chart-simple")
|
||||
} else if (identical(x, "ordinal")) {
|
||||
shiny::icon("arrow-down-1-9")
|
||||
phosphoricons::ph("list-numbers")
|
||||
# shiny::icon("arrow-down-1-9")
|
||||
} else if (identical(x, "text")) {
|
||||
shiny::icon("arrow-down-a-z")
|
||||
phosphoricons::ph("text-aa")
|
||||
# shiny::icon("arrow-down-a-z")
|
||||
} else if (identical(x, "dichotomous")) {
|
||||
shiny::icon("toggle-off")
|
||||
phosphoricons::ph("toggle-left")
|
||||
# shiny::icon("toggle-off")
|
||||
} else if (identical(x,"datetime")) {
|
||||
shiny::icon("calendar-days")
|
||||
phosphoricons::ph("calendar")
|
||||
# shiny::icon("calendar-days")
|
||||
} else if (identical(x,"id")) {
|
||||
shiny::icon("id-card")
|
||||
phosphoricons::ph("identification-badge")
|
||||
# shiny::icon("id-card")
|
||||
} else {
|
||||
shiny::icon("table")
|
||||
phosphoricons::ph("table")
|
||||
# shiny::icon("table")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
909
R/data_plots.R
909
R/data_plots.R
File diff suppressed because it is too large
Load diff
259
R/generate_colors.R
Normal file
259
R/generate_colors.R
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
#' Generate N Colors from a Specified Color Palette
|
||||
#'
|
||||
#' A flexible wrapper around multiple color palette libraries, returning N
|
||||
#' colors as a character vector of hex codes. Supports palettes from
|
||||
#' \pkg{viridisLite}, base R \pkg{grDevices}, and \pkg{RColorBrewer}.
|
||||
#'
|
||||
#' @param n \code{integer}. Number of colors to generate. Must be a positive
|
||||
#' integer.
|
||||
#' @param palette \code{character(1)}. Name of the color palette to use.
|
||||
#' Case-insensitive. Supported options:
|
||||
#' \describe{
|
||||
#' \item{\strong{viridisLite}}{`"viridis"`, `"magma"`, `"plasma"`,
|
||||
#' `"inferno"`, `"cividis"`, `"mako"`, `"rocket"`, `"turbo"`}
|
||||
#' \item{\strong{grDevices}}{`"hcl"`, `"rainbow"`, `"heat"`,
|
||||
#' `"terrain"`, `"topo"`}
|
||||
#' \item{\strong{RColorBrewer}}{Any palette name from
|
||||
#' \code{RColorBrewer::brewer.pal.info}, e.g. `"Set1"`, `"Blues"`,
|
||||
#' `"Dark2"`. If \code{n} exceeds the palette maximum, colors are
|
||||
#' interpolated via \code{\link[grDevices]{colorRampPalette}}.}
|
||||
#' }
|
||||
#' @param ... Additional arguments passed to the underlying palette function.
|
||||
#' For example, \code{alpha}, \code{direction}, \code{begin}, \code{end}
|
||||
#' are forwarded to \code{\link[viridisLite]{viridis}}; \code{palette} is
|
||||
#' forwarded to \code{\link[grDevices]{hcl.colors}}.
|
||||
#'
|
||||
#' @return A \code{character} vector of length \code{n} containing hex color
|
||||
#' codes (e.g. \code{"#440154FF"}).
|
||||
#'
|
||||
#' @examples
|
||||
#' # viridisLite palettes
|
||||
#' generate_colors(5, "viridis")
|
||||
#' generate_colors(5, "plasma")
|
||||
#' generate_colors(5, "viridis", alpha = 0.8, direction = -1)
|
||||
#'
|
||||
#' # Base R grDevices
|
||||
#' generate_colors(5, "rainbow")
|
||||
#' generate_colors(8, "hcl", palette = "Dark 3")
|
||||
#'
|
||||
#' # RColorBrewer
|
||||
#' generate_colors(5, "Set1")
|
||||
#' generate_colors(5, "Blues")
|
||||
#' generate_colors(12, "Set1") # interpolates beyond palette max of 9
|
||||
#'
|
||||
#' # Drop-in replacement for viridisLite::viridis()
|
||||
#' # generate_colors(n = length(levels(data_orig[[pri]])), palette = "viridis")
|
||||
#'
|
||||
#' @seealso
|
||||
#' \code{\link[viridisLite]{viridis}},
|
||||
#' \code{\link[grDevices]{hcl.colors}},
|
||||
#' \code{\link[RColorBrewer]{brewer.pal}}
|
||||
#'
|
||||
#' @importFrom viridisLite viridis
|
||||
#' @importFrom grDevices hcl.colors rainbow heat.colors terrain.colors
|
||||
#' topo.colors colorRampPalette
|
||||
#' @importFrom RColorBrewer brewer.pal brewer.pal.info
|
||||
#'
|
||||
#' @export
|
||||
generate_colors <- function(n, palette = "viridis", ...) {
|
||||
|
||||
# --- Input validation -------------------------------------------------------
|
||||
if (!is.numeric(n) || length(n) != 1 || n < 1 || n %% 1 != 0) {
|
||||
stop("`n` must be a single positive integer.")
|
||||
}
|
||||
if (!is.function(palette) && (!is.character(palette) || length(palette) != 1)) {
|
||||
stop("`palette` must be a single character string or a function.")
|
||||
}
|
||||
|
||||
# --- Function passthrough ---------------------------------------------------
|
||||
if (is.function(palette)) {
|
||||
return(palette(n, ...))
|
||||
}
|
||||
|
||||
# --- Named palette dispatch -------------------------------------------------
|
||||
palette_lower <- tolower(palette)
|
||||
|
||||
viridis_palettes <- c("viridis", "magma", "plasma", "inferno",
|
||||
"cividis", "mako", "rocket", "turbo")
|
||||
|
||||
if (palette_lower %in% viridis_palettes) {
|
||||
viridisLite::viridis(n = n, option = palette_lower, ...)
|
||||
|
||||
} else if (palette_lower == "hcl") {
|
||||
grDevices::hcl.colors(n = n, ...)
|
||||
|
||||
} else if (palette_lower == "rainbow") {
|
||||
grDevices::rainbow(n = n, ...)
|
||||
|
||||
} else if (palette_lower == "heat") {
|
||||
grDevices::heat.colors(n = n, ...)
|
||||
|
||||
} else if (palette_lower == "terrain") {
|
||||
grDevices::terrain.colors(n = n, ...)
|
||||
|
||||
} else if (palette_lower == "topo") {
|
||||
grDevices::topo.colors(n = n, ...)
|
||||
|
||||
} else {
|
||||
# Case-insensitive RColorBrewer lookup
|
||||
brewer_names <- rownames(RColorBrewer::brewer.pal.info)
|
||||
brewer_match <- brewer_names[match(palette_lower, tolower(brewer_names))]
|
||||
|
||||
if (!is.na(brewer_match)) {
|
||||
max_n <- RColorBrewer::brewer.pal.info[brewer_match, "maxcolors"]
|
||||
fetch_n <- max(min(n, max_n), 3L)
|
||||
base_colors <- RColorBrewer::brewer.pal(n = fetch_n, name = brewer_match)
|
||||
grDevices::colorRampPalette(base_colors)(n)
|
||||
|
||||
} else {
|
||||
# Case-insensitive grDevices palette.pals() lookup
|
||||
pal_names <- grDevices::palette.pals()
|
||||
pal_match <- pal_names[match(palette_lower, tolower(pal_names))]
|
||||
|
||||
if (!is.na(pal_match)) {
|
||||
grDevices::colorRampPalette(grDevices::palette.colors(palette = pal_match))(n)
|
||||
|
||||
} else if (palette %in% grDevices::hcl.pals()) {
|
||||
# Named HCL palettes (e.g. "Rocket", "Plasma") — distinct from viridisLite
|
||||
grDevices::hcl.colors(n = n, palette = palette, ...)
|
||||
|
||||
} else {
|
||||
warning(
|
||||
"Unknown palette: '", palette, "'. Falling back to viridis.\n",
|
||||
"Available options:\n",
|
||||
" viridisLite : viridis, magma, plasma, inferno, cividis, mako, rocket, turbo\n",
|
||||
" grDevices : hcl, rainbow, heat, terrain, topo\n",
|
||||
" grDevices HCL: use grDevices::hcl.pals() to see all options\n",
|
||||
" grDevices : use grDevices::palette.pals() to see all options\n",
|
||||
" RColorBrewer : use RColorBrewer::brewer.pal.info to see all options"
|
||||
)
|
||||
viridisLite::viridis(n = n, option = "viridis")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#' Create a Continuous Color Function from a Palette
|
||||
#'
|
||||
#' Wraps \code{\link{generate_colors}} into a function that accepts a value
|
||||
#' between 0 and 1 and returns the corresponding color. Useful for mapping
|
||||
#' continuous variables to colors.
|
||||
#'
|
||||
#' @param palette Passed directly to [generate_colors()]. Either a palette
|
||||
#' name string or a function.
|
||||
#' @param n \code{integer}. Resolution of the underlying color ramp — higher
|
||||
#' values give smoother gradients. Defaults to 256.
|
||||
#' @param ... Additional arguments passed to [generate_colors()].
|
||||
#'
|
||||
#' @return A function that takes a numeric vector of values in \code{[0, 1]}
|
||||
#' and returns a character vector of hex colors.
|
||||
#'
|
||||
#' @examples
|
||||
#' pal <- continuous_colors("viridis")
|
||||
#' pal(0) # first color
|
||||
#' pal(1) # last color
|
||||
#' pal(0.5) # midpoint
|
||||
#'
|
||||
#' # Map a continuous variable to colors
|
||||
#' values <- seq(0, 1, length.out = 10)
|
||||
#' pal(values)
|
||||
#'
|
||||
#' # Works with any palette generate_colors() accepts
|
||||
#' pal <- continuous_colors("plasma", direction = -1)
|
||||
#' pal <- continuous_colors(\(n) hcl.colors(n, palette = "Blue-Red"))
|
||||
#'
|
||||
#' @seealso [generate_colors()]
|
||||
#' @export
|
||||
continuous_colors <- function(palette = "viridis", n = 256, ...) {
|
||||
colors <- generate_colors(n, palette, ...)
|
||||
ramp <- grDevices::colorRamp(colors)
|
||||
|
||||
function(x) {
|
||||
if (any(x < 0 |
|
||||
x > 1, na.rm = TRUE))
|
||||
stop("Values must be in [0, 1].")
|
||||
rgb_vals <- ramp(x)
|
||||
grDevices::rgb(rgb_vals[, 1], rgb_vals[, 2], rgb_vals[, 3], maxColorValue = 255)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#' Discrete and Continuous Fill Scale Using generate_colors
|
||||
#'
|
||||
#' Drop-in replacement for [viridis::scale_fill_viridis()] that works with
|
||||
#' any palette supported by [generate_colors()].
|
||||
#'
|
||||
#' @param palette Passed to [generate_colors()]. Either a palette name string
|
||||
#' or a function.
|
||||
#' @param discrete \code{logical}. If \code{TRUE} (default), a discrete scale
|
||||
#' is returned. If \code{FALSE}, a continuous scale is returned.
|
||||
#' @param ... Additional arguments passed to [ggplot2::scale_fill_manual()]
|
||||
#' (discrete) or [ggplot2::scale_fill_gradientn()] (continuous).
|
||||
#'
|
||||
#' @examples
|
||||
#' library(ggplot2)
|
||||
#'
|
||||
#' # Discrete
|
||||
#' ggplot(mtcars, aes(x = wt, y = mpg, fill = factor(cyl))) +
|
||||
#' geom_col() +
|
||||
#' scale_fill_generate(palette = "Set1")
|
||||
#'
|
||||
#' # Continuous
|
||||
#' ggplot(mtcars, aes(x = wt, y = mpg, fill = mpg)) +
|
||||
#' geom_point(shape = 21, size = 3) +
|
||||
#' scale_fill_generate(palette = "viridis", discrete = FALSE)
|
||||
#'
|
||||
#' @seealso [scale_color_generate()], [generate_colors()], [continuous_colors()]
|
||||
#' @export
|
||||
scale_fill_generate <- function(palette = "viridis",
|
||||
discrete = TRUE,
|
||||
...) {
|
||||
if (discrete) {
|
||||
ggplot2::discrete_scale(
|
||||
aesthetics = "fill",
|
||||
palette = function(n)
|
||||
generate_colors(n, palette),
|
||||
...
|
||||
)
|
||||
} else {
|
||||
ggplot2::scale_fill_gradientn(colors = continuous_colors(palette)(seq(0, 1, length.out = 256)), ...)
|
||||
}
|
||||
}
|
||||
|
||||
#' @rdname scale_fill_generate
|
||||
#' @examples
|
||||
#' ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
|
||||
#' geom_point() +
|
||||
#' scale_color_generate(palette = "Set1")
|
||||
#' @export
|
||||
scale_color_generate <- function(palette = "viridis",
|
||||
discrete = TRUE,
|
||||
...) {
|
||||
if (discrete) {
|
||||
ggplot2::discrete_scale(
|
||||
aesthetics = "colour",
|
||||
palette = function(n)
|
||||
generate_colors(n, palette),
|
||||
...
|
||||
)
|
||||
} else {
|
||||
ggplot2::scale_color_gradientn(colors = continuous_colors(palette)(seq(0, 1, length.out = 256)), ...)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
color_choices <- function() {
|
||||
c(
|
||||
"Perceptual (blue-yellow)" = "viridis",
|
||||
"Perceptual (fire)" = "plasma",
|
||||
"Colour-blind friendly" = "Okabe-Ito",
|
||||
"Diverging (red-yellow-green)"= "RdYlGn",
|
||||
"Diverging (red-blue)" = "RdBu",
|
||||
"Sequential (blues)" = "Blues",
|
||||
"Qualitative (paired)" = "Paired",
|
||||
"Qualitative (bold)" = "Dark 2",
|
||||
"Rainbow" = "Spectral",
|
||||
"Generic" = "Set1"
|
||||
)
|
||||
}
|
||||
117
R/helpers.R
117
R/helpers.R
|
|
@ -219,20 +219,23 @@ file_export <- function(data,
|
|||
#' head(5) |>
|
||||
#' str()
|
||||
default_parsing <- function(data) {
|
||||
name_labels <- lapply(data, \(.x) REDCapCAST::get_attr(.x, attr = "label"))
|
||||
# name_labels <- lapply(data, \(.x) REDCapCAST::get_attr(.x, attr = "label"))
|
||||
# browser()
|
||||
out <- data |>
|
||||
setNames(make.names(names(data), unique = TRUE)) |>
|
||||
## Temporary step to avoid nested list and crashing
|
||||
remove_nested_list() |>
|
||||
REDCapCAST::parse_data() |>
|
||||
REDCapCAST::as_factor() |>
|
||||
REDCapCAST::numchar2fct(numeric.threshold = 8,
|
||||
character.throshold = 10) |>
|
||||
REDCapCAST::as_logical() |>
|
||||
REDCapCAST::fct_drop()
|
||||
|
||||
set_column_label(out, setNames(name_labels, names(out)), overwrite = FALSE)
|
||||
with_labels(data,{
|
||||
data |>
|
||||
setNames(make.names(names(data), unique = TRUE)) |>
|
||||
## Temporary step to avoid nested list and crashing
|
||||
remove_nested_list() |>
|
||||
REDCapCAST::parse_data() |>
|
||||
REDCapCAST::as_factor() |>
|
||||
REDCapCAST::numchar2fct(numeric.threshold = 8,
|
||||
character.throshold = 10) |>
|
||||
REDCapCAST::as_logical() #|>
|
||||
# REDCapCAST::fct_drop()
|
||||
})
|
||||
# out <-
|
||||
#
|
||||
# set_column_label(out, setNames(name_labels, names(out)), overwrite = FALSE)
|
||||
|
||||
# purrr::map2(
|
||||
# out,
|
||||
|
|
@ -356,33 +359,28 @@ missing_fraction <- function(data) {
|
|||
#' sample(c(1:8, NA), 20, TRUE)
|
||||
#' ) |> data_description()
|
||||
data_description <- function(data, data_text = "Data") {
|
||||
data <- if (shiny::is.reactive(data))
|
||||
data()
|
||||
else
|
||||
data
|
||||
# Resolve reactive once
|
||||
if (shiny::is.reactive(data)) data <- data()
|
||||
|
||||
# Early return if null
|
||||
if (is.null(data)) return(i18n$t("No data present."))
|
||||
|
||||
n <- nrow(data)
|
||||
|
||||
# Early return if empty
|
||||
if (n == 0L) return(i18n$t("No data present."))
|
||||
|
||||
n_var <- ncol(data)
|
||||
n_complete <- sum(complete.cases(data))
|
||||
|
||||
# Faster complete.cases alternative using rowSums on NA matrix
|
||||
n_complete <- n - sum(rowSums(is.na(data)) > 0L)
|
||||
p_complete <- signif(100 * n_complete / n, 3)
|
||||
|
||||
if (is.null(data)) {
|
||||
i18n$t("No data present.")
|
||||
} else {
|
||||
glue::glue(
|
||||
i18n$t(
|
||||
"{data_text} has {n} observations and {n_var} variables, with {n_complete} ({p_complete} %) complete cases."
|
||||
)
|
||||
glue::glue(
|
||||
i18n$t(
|
||||
"{data_text} has {n} observations and {n_var} variables, with {n_complete} ({p_complete} %) complete cases."
|
||||
)
|
||||
}
|
||||
# sprintf(
|
||||
# "%s has %s observations and %s variables, with %s (%s%%) complete cases.",
|
||||
# data_text,
|
||||
# n,
|
||||
# n_var,
|
||||
# n_complete,
|
||||
# p_complete
|
||||
# )
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -842,3 +840,54 @@ data_types <- function() {
|
|||
"Any other class")
|
||||
)
|
||||
}
|
||||
|
||||
non_character_cols <- function(df) {
|
||||
if (shiny::is.reactive(df)) df <- df()
|
||||
df[, !sapply(df, is.character), drop = FALSE]
|
||||
}
|
||||
|
||||
apply_idea_filter <- function(filtered_reactive, df_target, env = parent.frame()) {
|
||||
# If this ever brakes, the solution will have to be to modify the original filter function
|
||||
if (shiny::is.reactive(df_target)) df_target <- df_target()
|
||||
|
||||
result <- if (shiny::is.reactive(filtered_reactive)) filtered_reactive() else filtered_reactive
|
||||
filter_code <- attr(result, "code")
|
||||
|
||||
if (is.null(filter_code)) return(df_target)
|
||||
|
||||
deparsed <- paste(deparse(filter_code), collapse = "")
|
||||
|
||||
if (is.symbol(filter_code) || !grepl("filter(", deparsed, fixed = TRUE)) {
|
||||
return(df_target)
|
||||
}
|
||||
|
||||
extract_filters <- function(code) {
|
||||
filters <- list()
|
||||
while (!is.symbol(code) && deparse(code[[1]]) == "%>%") {
|
||||
rhs <- code[[3]]
|
||||
if (deparse(rhs[[1]]) == "filter") {
|
||||
filters <- c(list(rhs), filters)
|
||||
}
|
||||
code <- code[[2]]
|
||||
}
|
||||
if (!is.symbol(code) && deparse(code[[1]]) == "filter") {
|
||||
filters <- c(list(code), filters)
|
||||
}
|
||||
filters
|
||||
}
|
||||
|
||||
tryCatch({
|
||||
out <- df_target
|
||||
for (f in extract_filters(filter_code)) {
|
||||
args <- lapply(rlang::call_args(f), function(arg) {
|
||||
rlang::new_quosure(arg, env = env)
|
||||
})
|
||||
out <- dplyr::filter(out, !!!args)
|
||||
}
|
||||
out
|
||||
},
|
||||
error = function(e) {
|
||||
warning("Could not apply filter: ", conditionMessage(e))
|
||||
df_target
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
hosted_version <- function()'v26.3.2-260311'
|
||||
hosted_version <- function()'v26.6.1'
|
||||
|
|
|
|||
|
|
@ -353,7 +353,7 @@ import_file_server <- function(id,
|
|||
# showNotification(warn, type = "warning")
|
||||
# },
|
||||
error = function(err) {
|
||||
showNotification(err, type = "err")
|
||||
showNotification(err, type = "error")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -370,7 +370,7 @@ import_file_server <- function(id,
|
|||
minBodyHeight = 250
|
||||
)
|
||||
}, error = function(err) {
|
||||
showNotification(err, type = "err")
|
||||
showNotification(err, type = "error")
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -485,7 +485,7 @@ import_xls <- function(file, sheet, skip, na.strings) {
|
|||
# showNotification(paste0(warn), type = "warning")
|
||||
# },
|
||||
error = function(err) {
|
||||
showNotification(paste0(err), type = "err")
|
||||
showNotification(paste0(err), type = "error")
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -513,7 +513,7 @@ import_ods <- function(file, sheet, skip, na.strings) {
|
|||
# showNotification(paste0(warn), type = "warning")
|
||||
# },
|
||||
error = function(err) {
|
||||
showNotification(paste0(err), type = "err")
|
||||
?showNotification(paste0(err), type = "error")
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -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)
|
||||
),
|
||||
|
|
|
|||
|
|
@ -37,20 +37,6 @@ landing_page_ui <- function(i18n) {
|
|||
div(
|
||||
class = "container my-5",
|
||||
|
||||
# Introduction text
|
||||
# div(
|
||||
# class = "row mb-5",
|
||||
# div(
|
||||
# class = "col-12 text-center",
|
||||
# p(
|
||||
# class = "lead",
|
||||
# i18n$t("Start with FreesearchR for basic data evaluation and analysis."),
|
||||
# i18n$t("When you need more advanced tools, you'll be better prepared to use R directly."),
|
||||
# style = "font-size: 1.2rem; color: #555;"
|
||||
# )
|
||||
# )
|
||||
# ),
|
||||
|
||||
# Core Features Section
|
||||
h2(i18n$t("Core Features"), class = "text-center mb-4",
|
||||
style = "color: #1E4A8F; font-weight: 600;"),
|
||||
|
|
@ -68,7 +54,8 @@ landing_page_ui <- function(i18n) {
|
|||
class = "card-body text-center p-4",
|
||||
div(
|
||||
style = "font-size: 3rem; color: #1E4A8F; margin-bottom: 15px;",
|
||||
fa("file-import")
|
||||
phosphoricons::ph("folder-simple-plus", weight = "bold")
|
||||
# fa("file-import")
|
||||
),
|
||||
h4(i18n$t("Import Data"), class = "card-title", style = "color: #2D2D42; font-weight: 600;"),
|
||||
p(
|
||||
|
|
@ -89,7 +76,8 @@ landing_page_ui <- function(i18n) {
|
|||
class = "card-body text-center p-4",
|
||||
div(
|
||||
style = "font-size: 3rem; color: #1E4A8F; margin-bottom: 15px;",
|
||||
fa("pen-to-square")
|
||||
phosphoricons::ph("note-pencil", weight = "bold")
|
||||
# fa("pen-to-square")
|
||||
),
|
||||
h4(i18n$t("Data Management"), class = "card-title", style = "color: #2D2D42; font-weight: 600;"),
|
||||
p(
|
||||
|
|
@ -110,7 +98,8 @@ landing_page_ui <- function(i18n) {
|
|||
class = "card-body text-center p-4",
|
||||
div(
|
||||
style = "font-size: 3rem; color: #1E4A8F; margin-bottom: 15px;",
|
||||
fa("magnifying-glass-chart")
|
||||
phosphoricons::ph("magnifying-glass", weight = "bold")
|
||||
# fa("magnifying-glass-chart")
|
||||
),
|
||||
h4(i18n$t("Descriptive Statistics"), class = "card-title", style = "color: #2D2D42; font-weight: 600;"),
|
||||
p(
|
||||
|
|
@ -135,7 +124,7 @@ landing_page_ui <- function(i18n) {
|
|||
style = "border-left: 4px solid #8A4FFF;",
|
||||
div(
|
||||
class = "card-body",
|
||||
h5(fa("chart-line"), " ", i18n$t("Data Visualization"), class = "card-title", style = "color: #2D2D42;"),
|
||||
h5(phosphoricons::ph("chart-line", weight = "bold"), " ", i18n$t("Data Visualization"), class = "card-title", style = "color: #2D2D42;"),
|
||||
p(class = "card-text small", i18n$t("Create simple, clean plots for quick insights and overview"))
|
||||
)
|
||||
)
|
||||
|
|
@ -147,7 +136,7 @@ landing_page_ui <- function(i18n) {
|
|||
style = "border-left: 4px solid #8A4FFF;",
|
||||
div(
|
||||
class = "card-body",
|
||||
h5(fa("calculator"), " ", i18n$t("Regression Models"), class = "card-title", style = "color: #2D2D42;"),
|
||||
h5(phosphoricons::ph("calculator", weight = "bold"), " ", i18n$t("Regression Models"), class = "card-title", style = "color: #2D2D42;"),
|
||||
p(class = "card-text small", i18n$t("Build simple regression models for advanced analysis"))
|
||||
)
|
||||
)
|
||||
|
|
@ -164,7 +153,7 @@ landing_page_ui <- function(i18n) {
|
|||
style = "background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); border: none;",
|
||||
div(
|
||||
class = "card-body p-4",
|
||||
h4(fa("download"), " ", i18n$t("Export & Learn"), class = "text-center mb-3", style = "color: #1E4A8F;"),
|
||||
h4(phosphoricons::ph("book-bookmark", weight = "bold"), " ", i18n$t("Export & Learn"), class = "text-center mb-3", style = "color: #1E4A8F;"),
|
||||
div(
|
||||
class = "row text-center",
|
||||
div(
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#' @param data_limit_default default data set observations limit
|
||||
#' @param data_limit_upper data set observations upper limit
|
||||
#' @param data_limit_lower data set observations lower limit
|
||||
#' @param check_app_version always attempt to check app version against latest
|
||||
#' release on GitHub. Default is FALSE
|
||||
#' @param ... passed on to `shiny::runApp()`
|
||||
#'
|
||||
#' @returns shiny app
|
||||
|
|
@ -18,16 +20,18 @@
|
|||
#' data(mtcars)
|
||||
#' launch_FreesearchR(launch.browser = TRUE)
|
||||
#' }
|
||||
launch_FreesearchR <- function(inlcude_globalenv = TRUE,
|
||||
launch_FreesearchR <- function(include_globalenv = TRUE,
|
||||
data_limit_default = 1000,
|
||||
data_limit_upper = 100000,
|
||||
data_limit_lower = 1,
|
||||
check_app_version = FALSE,
|
||||
...) {
|
||||
global_freesearchR <- list(
|
||||
include_globalenv = include_globalenv,
|
||||
data_limit_default = data_limit_default,
|
||||
data_limit_upper = data_limit_upper,
|
||||
data_limit_lower = data_limit_lower
|
||||
Sys.setenv(
|
||||
INCLUDE_GLOBALENV = include_globalenv,
|
||||
DATA_LIMIT_DEFAULT = data_limit_default,
|
||||
DATA_LIMIT_UPPER = data_limit_upper,
|
||||
DATA_LIMIT_LOWER = data_limit_lower,
|
||||
CHECK_APP_VERSION = check_app_version
|
||||
)
|
||||
|
||||
appDir <- system.file("apps", "FreesearchR", package = "FreesearchR")
|
||||
|
|
@ -39,3 +43,120 @@ launch_FreesearchR <- function(inlcude_globalenv = TRUE,
|
|||
a <- shiny::runApp(appDir = paste0(appDir, "/app.R"), ...)
|
||||
return(invisible(a))
|
||||
}
|
||||
|
||||
|
||||
## Helper to set env variables
|
||||
get_config <- function(var_name, default = NULL) {
|
||||
val <- Sys.getenv(var_name, unset = NA_character_)
|
||||
|
||||
# Only use env var if it is explicitly set and non-empty
|
||||
if (!is.na(val) && nzchar(trimws(val))) {
|
||||
if (is.logical(default)) return(to_logical(val))
|
||||
if (is.numeric(default)) return(as.numeric(val))
|
||||
return(val)
|
||||
}
|
||||
|
||||
if (!is.null(default)) {
|
||||
return(default)
|
||||
}
|
||||
|
||||
stop(paste("Required config variable not set:", var_name))
|
||||
}
|
||||
|
||||
to_logical <- function(x) {
|
||||
result <- switch(tolower(trimws(as.character(x))),
|
||||
"true" = , "1" = , "yes" = TRUE,
|
||||
"false" = , "0" = , "no" = FALSE,
|
||||
NA
|
||||
)
|
||||
if (is.na(result)) stop(paste("Cannot coerce to logical:", x))
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
## File loader - based on the module, uses hard coded default values
|
||||
load_file <- function(path) {
|
||||
read_fns <- list(
|
||||
ods = "import_ods",
|
||||
dta = "import_dta",
|
||||
csv = "import_delim",
|
||||
tsv = "import_delim",
|
||||
txt = "import_delim",
|
||||
xls = "import_xls",
|
||||
xlsx = "import_xls",
|
||||
rds = "import_rds"
|
||||
)
|
||||
|
||||
ext <- tolower(tools::file_ext(path))
|
||||
|
||||
if (!ext %in% names(read_fns)) {
|
||||
message("Unsupported file type, skipping: ", basename(path), " (.", ext, ")")
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
read_fn <- read_fns[[ext]]
|
||||
|
||||
parameters <- list(
|
||||
file = path,
|
||||
sheet = 1,
|
||||
skip = 0,
|
||||
dec = ".",
|
||||
encoding = "unknown"
|
||||
)
|
||||
|
||||
# Trim parameters to only those accepted by the target function
|
||||
parameters <- parameters[which(names(parameters) %in% rlang::fn_fmls_names(get(read_fn)))]
|
||||
|
||||
result <- tryCatch(
|
||||
rlang::exec(read_fn, !!!parameters),
|
||||
error = function(e) {
|
||||
# Fall back to rio::import
|
||||
message("Primary loader failed for ", basename(path), ", trying rio::import")
|
||||
tryCatch(
|
||||
rio::import(path),
|
||||
error = function(e2) {
|
||||
message("Failed to load ", basename(path), ": ", e2$message)
|
||||
NULL
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
if (!is.null(result) && NROW(result) < 1) {
|
||||
message("File loaded but contains no rows, skipping: ", basename(path))
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
|
||||
load_folder <- function(folder = "/app/data", envir = .GlobalEnv) {
|
||||
if (is.null(folder) || !dir.exists(folder)) {
|
||||
message("No data folder found, skipping load")
|
||||
return(invisible(NULL))
|
||||
}
|
||||
|
||||
files <- list.files(folder, full.names = TRUE)
|
||||
if (length(files) == 0) {
|
||||
message("Data folder is empty, skipping load")
|
||||
return(invisible(NULL))
|
||||
}
|
||||
|
||||
loaded <- vapply(files, function(file) {
|
||||
result <- load_file(file)
|
||||
if (is.null(result))
|
||||
return(FALSE)
|
||||
name <- tools::file_path_sans_ext(basename(file))
|
||||
assign(name, default_parsing(result), envir = envir)
|
||||
TRUE
|
||||
}, logical(1))
|
||||
|
||||
message(sprintf(
|
||||
"Loaded %d/%d files from %s",
|
||||
sum(loaded),
|
||||
length(files),
|
||||
folder
|
||||
))
|
||||
invisible(loaded)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,8 @@ data_missings_ui <- function(id, ...) {
|
|||
bslib::accordion_panel(
|
||||
value = "acc_pan_mis",
|
||||
title = "Settings",
|
||||
icon = bsicons::bs_icon("gear"),
|
||||
icon = phosphoricons::ph("gear"),
|
||||
# icon = bsicons::bs_icon("gear"),
|
||||
shiny::conditionalPanel(
|
||||
condition = "output.missings == true",
|
||||
shiny::uiOutput(ns("missings_method")),
|
||||
|
|
@ -36,14 +37,16 @@ data_missings_ui <- function(id, ...) {
|
|||
inputId = ns("act_miss"),
|
||||
label = i18n$t("Evaluate"),
|
||||
width = "100%",
|
||||
icon = shiny::icon("calculator"),
|
||||
icon = phosphoricons::ph("calculator",weight = "bold"),
|
||||
# icon = shiny::icon("calculator"),
|
||||
disabled = TRUE
|
||||
)
|
||||
),
|
||||
do.call(bslib::accordion_panel, c(
|
||||
list(
|
||||
title = "Download",
|
||||
icon = bsicons::bs_icon("file-earmark-arrow-down")
|
||||
icon = phosphoricons::ph("download-simple")
|
||||
# icon = bsicons::bs_icon("file-earmark-arrow-down")
|
||||
),
|
||||
table_download_ui(id = ns("tbl_dwn"), title = NULL)
|
||||
))
|
||||
|
|
@ -172,7 +175,7 @@ data_missings_server <- function(id, data, max_level = 20, ...) {
|
|||
out <- do.call(compare_missings, modifyList(parameters, list(data = df_tbl)))
|
||||
})
|
||||
}, error = function(err) {
|
||||
showNotification(paste0("Error: ", err), type = "err")
|
||||
showNotification(paste0("Error: ", err), type = "error")
|
||||
})
|
||||
|
||||
if (is.null(input$missings_var) ||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ plot_download_ui <- regression_ui <- function(id, ...) {
|
|||
shiny::downloadButton(
|
||||
outputId = ns("download_plot"),
|
||||
label = "Download plot",
|
||||
icon = shiny::icon("download")
|
||||
icon = phosphoricons::ph("arrow-fat-down")
|
||||
# icon = shiny::icon("download")
|
||||
)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
878
R/plot-helpers.R
Normal file
878
R/plot-helpers.R
Normal file
|
|
@ -0,0 +1,878 @@
|
|||
#' Implemented functions
|
||||
#'
|
||||
#' @description
|
||||
#' Library of supported functions. The list name and "descr" element should be
|
||||
#' unique for each element on list.
|
||||
#'
|
||||
#' - fun: the plotting function
|
||||
#'
|
||||
#' - fun.args: default parameters for the plotting function
|
||||
#'
|
||||
#' - descr: Plot description
|
||||
#'
|
||||
#' - note: Short note/description of the function for displaying in ui and docs
|
||||
#'
|
||||
#' - primary.type: Primary variable data type (see [data_type])
|
||||
#'
|
||||
#' - base: holds a list of parameters for plot input fields generation
|
||||
#' Secondary and tertiary variable input fields are mandatory.
|
||||
#'
|
||||
#'
|
||||
#' @returns list
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' available_plots() |> str()
|
||||
available_plots <- function() {
|
||||
list(
|
||||
plot_bar_rel = list(
|
||||
fun = "plot_bar",
|
||||
fun.args = list(style = "fill"),
|
||||
descr = i18n$t("Stacked relative barplot"),
|
||||
note = i18n$t(
|
||||
"Create relative stacked barplots to show the distribution of categorical levels"
|
||||
),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
allow_none = FALSE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Additional variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_bar_abs = list(
|
||||
fun = "plot_bar",
|
||||
fun.args = list(style = "dodge"),
|
||||
descr = i18n$t("Side-by-side barplot"),
|
||||
note = i18n$t(
|
||||
"Create side-by-side barplot to show the distribution of categorical levels"
|
||||
),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
allow_none = TRUE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Secondary variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_hbars = list(
|
||||
fun = "plot_hbars",
|
||||
descr = i18n$t("Stacked horizontal bars"),
|
||||
note = i18n$t(
|
||||
"A classical way of visualising the distribution of an ordinal scale like the modified Ranking Scale and known as Grotta bars"
|
||||
),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
allow_none = TRUE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Secondary variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "reverse",
|
||||
type = "select_input",
|
||||
label = i18n$t("Reverse colors"),
|
||||
choices = c(yes = TRUE, no = FALSE)
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_violin = list(
|
||||
fun = "plot_violin",
|
||||
descr = i18n$t("Violin plot"),
|
||||
note = i18n$t(
|
||||
"A modern alternative to the classic boxplot to visualise data distribution"
|
||||
),
|
||||
primary.type = c("datatime", "continuous"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
allow_none = TRUE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Secondary variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_sankey = list(
|
||||
fun = "plot_sankey",
|
||||
descr = i18n$t("Sankey plot"),
|
||||
note = i18n$t("A way of visualising change between groups"),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
allow_none = FALSE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Secondary variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_scatter = list(
|
||||
fun = "plot_scatter",
|
||||
descr = i18n$t("Scatter plot"),
|
||||
note = i18n$t("A classic way of showing the association between to variables"),
|
||||
primary.type = c("datatime", "continuous"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("datatime", "continuous", "categorical"),
|
||||
allow_none = FALSE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Secondary variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_box = list(
|
||||
fun = "plot_box",
|
||||
descr = i18n$t("Box plot"),
|
||||
note = i18n$t("A classic way to plot data distribution by groups"),
|
||||
primary.type = c("datatime", "continuous"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
allow_none = TRUE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Secondary variable"),
|
||||
multiple = FALSE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_euler = list(
|
||||
fun = "plot_euler",
|
||||
descr = i18n$t("Euler diagram"),
|
||||
note = i18n$t(
|
||||
"Generate area-proportional Euler diagrams to display set relationships"
|
||||
),
|
||||
primary.type = c("dichotomous"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous"),
|
||||
allow_none = FALSE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Secondary variable"),
|
||||
multiple = TRUE,
|
||||
maxItems = 4
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
),
|
||||
plot_likert = list(
|
||||
fun = "plot_likert",
|
||||
descr = i18n$t("Likert diagram"),
|
||||
note = i18n$t("Plot survey results"),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
### Input definitions ###
|
||||
base = list(
|
||||
list(
|
||||
id = "secondary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
allow_none = TRUE,
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Additional variables"),
|
||||
multiple = TRUE
|
||||
),
|
||||
list(
|
||||
id = "tertiary",
|
||||
type = "select_variables",
|
||||
var_types = c("dichotomous", "categorical"),
|
||||
# inputId = "sec",
|
||||
label = i18n$t("Grouping variable"),
|
||||
multiple = FALSE
|
||||
)
|
||||
),
|
||||
advanced = list()
|
||||
#########
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
# Helper function to create input elements dynamically
|
||||
create_input_element <- function(params, ns, input_id) {
|
||||
# Add the namespaced inputId to the arguments
|
||||
params$inputId <- ns(input_id)
|
||||
|
||||
# Map input types to Shiny functions
|
||||
input_function <- switch(
|
||||
params$type,
|
||||
"numeric_input" = shiny::numericInput,
|
||||
"select_input" = shiny::selectInput,
|
||||
"checkbox_input" = shiny::checkboxInput,
|
||||
"slider_input" = shiny::sliderInput,
|
||||
"text_input" = shiny::textInput,
|
||||
"select_variables" = selectPlotVariables
|
||||
)
|
||||
|
||||
params$type <- NULL
|
||||
params$id <- NULL
|
||||
|
||||
|
||||
# Call the function with all arguments
|
||||
do.call(input_function, params)
|
||||
}
|
||||
|
||||
#' Wrapper for columnSelectInput
|
||||
#'
|
||||
selectPlotVariables <- function(data,
|
||||
exclude = NULL,
|
||||
allow_none = TRUE,
|
||||
var_types,
|
||||
...) {
|
||||
datar <- if (is.reactive(data)) {
|
||||
data
|
||||
} else {
|
||||
reactive(data)
|
||||
}
|
||||
|
||||
cols <- all_but(colnames(subset_types(datar(), var_types)), exclude)
|
||||
|
||||
if (isTRUE(allow_none)) {
|
||||
cols <- c("none", cols)
|
||||
}
|
||||
|
||||
params <- list(...)
|
||||
|
||||
params$none_label <- i18n$t("No variable")
|
||||
params$col_subset <- cols
|
||||
|
||||
rlang::exec(columnSelectInput, !!!append_list(datar(), params, "data"))
|
||||
}
|
||||
|
||||
|
||||
|
||||
#' Select all from vector but
|
||||
#'
|
||||
#' @param data vector
|
||||
#' @param ... exclude
|
||||
#'
|
||||
#' @returns vector
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' all_but(1:10, c(2, 3), 11, 5)
|
||||
all_but <- function(data, ...) {
|
||||
data[!data %in% c(...)]
|
||||
}
|
||||
|
||||
#' Easily subset by data type function
|
||||
#'
|
||||
#' @param data data
|
||||
#' @param types desired types
|
||||
#' @param type.fun function to get type. Default is outcome_type
|
||||
#'
|
||||
#' @returns vector
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' default_parsing(mtcars) |> subset_types("ordinal")
|
||||
#' default_parsing(mtcars) |> subset_types(c("dichotomous", "categorical"))
|
||||
#' #' default_parsing(mtcars) |> subset_types("factor",class)
|
||||
subset_types <- function(data, types, type.fun = data_type) {
|
||||
data[sapply(data, type.fun) %in% types]
|
||||
}
|
||||
|
||||
|
||||
#' Implemented functions
|
||||
#'
|
||||
#' @description
|
||||
#' Library of supported functions. The list name and "descr" element should be
|
||||
#' unique for each element on list.
|
||||
#'
|
||||
#' - descr: Plot description
|
||||
#'
|
||||
#' - primary.type: Primary variable data type (continuous, dichotomous or ordinal)
|
||||
#'
|
||||
#' - secondary.type: Secondary variable data type (continuous, dichotomous or ordinal)
|
||||
#'
|
||||
#' - secondary.extra: "none" or NULL to have option to choose none.
|
||||
#'
|
||||
#' - tertiary.type: Tertiary variable data type (continuous, dichotomous or ordinal)
|
||||
#'
|
||||
#'
|
||||
#' @returns list
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' supported_plots() |> str()
|
||||
supported_plots <- function() {
|
||||
list(
|
||||
plot_bar_rel = list(
|
||||
fun = "plot_bar",
|
||||
fun.args = list(style = "fill"),
|
||||
descr = i18n$t("Stacked relative barplot"),
|
||||
note = i18n$t(
|
||||
"Create relative stacked barplots to show the distribution of categorical levels"
|
||||
),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
secondary.type = c("dichotomous", "categorical"),
|
||||
secondary.multi = FALSE,
|
||||
tertiary.type = c("dichotomous", "categorical"),
|
||||
secondary.extra = NULL
|
||||
),
|
||||
plot_bar_abs = list(
|
||||
fun = "plot_bar",
|
||||
fun.args = list(style = "dodge"),
|
||||
descr = i18n$t("Side-by-side barplot"),
|
||||
note = i18n$t(
|
||||
"Create side-by-side barplot to show the distribution of categorical levels"
|
||||
),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
secondary.type = c("dichotomous", "categorical"),
|
||||
secondary.multi = FALSE,
|
||||
tertiary.type = c("dichotomous", "categorical"),
|
||||
secondary.extra = "none"
|
||||
),
|
||||
plot_hbars = list(
|
||||
fun = "plot_hbars",
|
||||
descr = i18n$t("Stacked horizontal bars"),
|
||||
note = i18n$t(
|
||||
"A classical way of visualising the distribution of an ordinal scale like the modified Ranking Scale and known as Grotta bars"
|
||||
),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
secondary.type = c("dichotomous", "categorical"),
|
||||
secondary.multi = FALSE,
|
||||
tertiary.type = c("dichotomous", "categorical"),
|
||||
secondary.extra = "none"
|
||||
),
|
||||
plot_violin = list(
|
||||
fun = "plot_violin",
|
||||
descr = i18n$t("Violin plot"),
|
||||
note = i18n$t(
|
||||
"A modern alternative to the classic boxplot to visualise data distribution"
|
||||
),
|
||||
primary.type = c("datatime", "continuous"),
|
||||
secondary.type = c("dichotomous", "categorical"),
|
||||
secondary.multi = FALSE,
|
||||
secondary.extra = "none",
|
||||
tertiary.type = c("dichotomous", "categorical")
|
||||
),
|
||||
# plot_ridge = list(
|
||||
# descr = "Ridge plot",
|
||||
# note = "An alternative option to visualise data distribution",
|
||||
# primary.type = "continuous",
|
||||
# secondary.type = c("dichotomous" ,"categorical"),
|
||||
# tertiary.type = c("dichotomous" ,"categorical"),
|
||||
# secondary.extra = NULL
|
||||
# ),
|
||||
plot_sankey = list(
|
||||
fun = "plot_sankey",
|
||||
descr = i18n$t("Sankey plot"),
|
||||
note = i18n$t("A way of visualising change between groups"),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
secondary.type = c("dichotomous", "categorical"),
|
||||
secondary.multi = FALSE,
|
||||
secondary.extra = NULL,
|
||||
tertiary.type = c("dichotomous", "categorical")
|
||||
),
|
||||
plot_scatter = list(
|
||||
fun = "plot_scatter",
|
||||
descr = i18n$t("Scatter plot"),
|
||||
note = i18n$t("A classic way of showing the association between to variables"),
|
||||
primary.type = c("datatime", "continuous"),
|
||||
secondary.type = c("datatime", "continuous", "categorical"),
|
||||
secondary.multi = FALSE,
|
||||
tertiary.type = c("dichotomous", "categorical"),
|
||||
secondary.extra = NULL
|
||||
),
|
||||
plot_box = list(
|
||||
fun = "plot_box",
|
||||
descr = i18n$t("Box plot"),
|
||||
note = i18n$t("A classic way to plot data distribution by groups"),
|
||||
primary.type = c("datatime", "continuous"),
|
||||
secondary.type = c("dichotomous", "categorical"),
|
||||
secondary.multi = FALSE,
|
||||
tertiary.type = c("dichotomous", "categorical"),
|
||||
secondary.extra = "none"
|
||||
),
|
||||
plot_euler = list(
|
||||
fun = "plot_euler",
|
||||
descr = i18n$t("Euler diagram"),
|
||||
note = i18n$t(
|
||||
"Generate area-proportional Euler diagrams to display set relationships"
|
||||
),
|
||||
primary.type = c("dichotomous"),
|
||||
secondary.type = c("dichotomous"),
|
||||
secondary.multi = TRUE,
|
||||
secondary.max = 4,
|
||||
tertiary.type = c("dichotomous"),
|
||||
secondary.extra = NULL
|
||||
),
|
||||
plot_likert = list(
|
||||
fun = "plot_likert",
|
||||
descr = i18n$t("Likert diagram"),
|
||||
note = i18n$t("Plot survey results"),
|
||||
primary.type = c("dichotomous", "categorical"),
|
||||
secondary.type = c("dichotomous", "categorical"),
|
||||
secondary.multi = TRUE,
|
||||
secondary.extra = NULL,
|
||||
tertiary.type = c("dichotomous", "categorical"),
|
||||
secondary.extra = NULL
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#' Get possible regression models
|
||||
#'
|
||||
#' @param data data
|
||||
#'
|
||||
#' @returns character vector
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' mtcars |>
|
||||
#' default_parsing() |>
|
||||
#' dplyr::pull("cyl") |>
|
||||
#' possible_plots()
|
||||
#'
|
||||
#' mtcars |>
|
||||
#' default_parsing() |>
|
||||
#' dplyr::select("mpg") |>
|
||||
#' possible_plots()
|
||||
possible_plots <- function(data, source_list = supported_plots()) {
|
||||
# browser()
|
||||
# data <- if (is.reactive(data)) data() else data
|
||||
if (is.data.frame(data)) {
|
||||
data <- data[[1]]
|
||||
}
|
||||
|
||||
type <- data_type(data)
|
||||
|
||||
if (type == "unknown") {
|
||||
out <- type
|
||||
} else {
|
||||
out <- source_list |>
|
||||
lapply(\(.x) {
|
||||
if (type %in% .x$primary.type) {
|
||||
.x$descr
|
||||
}
|
||||
}) |>
|
||||
unlist()
|
||||
}
|
||||
unname(out)
|
||||
}
|
||||
|
||||
#' Get the function options based on the selected function description
|
||||
#'
|
||||
#' @param data vector
|
||||
#'
|
||||
#' @returns list
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' ls <- mtcars |>
|
||||
#' default_parsing() |>
|
||||
#' dplyr::pull(mpg) |>
|
||||
#' possible_plots() |>
|
||||
#' (\(.x){
|
||||
#' .x[[1]]
|
||||
#' })() |>
|
||||
#' get_plot_options()
|
||||
get_plot_options <- function(data) {
|
||||
descrs <- supported_plots() |>
|
||||
lapply(\(.x) {
|
||||
.x$descr
|
||||
}) |>
|
||||
unlist()
|
||||
supported_plots() |>
|
||||
(\(.x) {
|
||||
.x[match(data, descrs)]
|
||||
})()
|
||||
}
|
||||
|
||||
#' Get the function parameters based on the selected function description
|
||||
#'
|
||||
#' @param data vector
|
||||
#'
|
||||
#' @returns list
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' ls <- mtcars |>
|
||||
#' default_parsing() |>
|
||||
#' dplyr::pull(mpg) |>
|
||||
#' possible_plots() |>
|
||||
#' (\(.x){
|
||||
#' .x[[1]]
|
||||
#' })() |>
|
||||
#' get_input_params()
|
||||
get_input_params <- function(data) {
|
||||
descr <- available_plots() |>
|
||||
lapply(\(.x) {
|
||||
.x$descr
|
||||
}) |>
|
||||
unlist()
|
||||
available_plots() |>
|
||||
(\(.x) {
|
||||
.x[match(data, descr)]
|
||||
})()
|
||||
}
|
||||
|
||||
|
||||
#' Wrapper to create plot based on provided type
|
||||
#'
|
||||
#' @param data data.frame
|
||||
#' @param pri primary variable
|
||||
#' @param sec secondary variable
|
||||
#' @param ter tertiary variable
|
||||
#' @param type plot type (derived from possible_plots() and matches custom function)
|
||||
#' @param color.palette choose color palette. See \code{\link{plot_colors}} for support.
|
||||
#' @param ... ignored for now
|
||||
#'
|
||||
#' @name data-plots
|
||||
#'
|
||||
#' @returns ggplot2 object
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' create_plot(mtcars, "plot_violin", "mpg", "cyl") |> attributes()
|
||||
create_plot <- function(data,
|
||||
type,
|
||||
pri,
|
||||
sec,
|
||||
ter = NULL,
|
||||
color.palette = "viridis",
|
||||
...) {
|
||||
if (!is.null(sec)) {
|
||||
if (!any(sec %in% names(data))) {
|
||||
sec <- NULL
|
||||
}
|
||||
}
|
||||
|
||||
if (!is.null(ter)) {
|
||||
if (!ter %in% names(data)) {
|
||||
ter <- NULL
|
||||
}
|
||||
}
|
||||
|
||||
parameters <- list(
|
||||
pri = pri,
|
||||
sec = sec,
|
||||
ter = ter,
|
||||
color.palette = color.palette,
|
||||
...
|
||||
)
|
||||
|
||||
out <- do.call(type, modifyList(parameters, list(data = data)))
|
||||
|
||||
code <- rlang::call2(type, !!!parameters, .ns = "FreesearchR")
|
||||
|
||||
attr(out, "code") <- code
|
||||
out
|
||||
}
|
||||
|
||||
#' Print label, and if missing print variable name for plots
|
||||
#'
|
||||
#' @param data vector or data frame
|
||||
#' @param var variable name. Optional.
|
||||
#'
|
||||
#' @returns character string
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' mtcars |> get_label(var = "mpg")
|
||||
#' mtcars |> get_label()
|
||||
#' mtcars$mpg |> get_label()
|
||||
#' gtsummary::trial |> get_label(var = "trt")
|
||||
#' gtsummary::trial$trt |> get_label()
|
||||
#' 1:10 |> get_label()
|
||||
get_label <- function(data, var = NULL) {
|
||||
# data <- if (is.reactive(data)) data() else data
|
||||
if (!is.null(var) & is.data.frame(data)) {
|
||||
data <- data[[var]]
|
||||
}
|
||||
out <- REDCapCAST::get_attr(data = data, attr = "label")
|
||||
if (is.na(out)) {
|
||||
if (is.null(var)) {
|
||||
out <- deparse(substitute(data))
|
||||
} else {
|
||||
if (is.symbol(var)) {
|
||||
out <- gsub('\"', "", deparse(substitute(var)))
|
||||
} else {
|
||||
out <- var
|
||||
}
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
|
||||
#' Line breaking at given number of characters for nicely plotting labels
|
||||
#'
|
||||
#' @param data string
|
||||
#' @param lineLength maximum line length
|
||||
#' @param fixed flag to force split at exactly the value given in lineLength.
|
||||
#' Default is FALSE, only splitting at spaces.
|
||||
#'
|
||||
#' @returns character string
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' "Lorem ipsum... you know the routine" |> line_break()
|
||||
#' paste(sample(letters[1:10], 100, TRUE), collapse = "") |> line_break(force = TRUE)
|
||||
line_break <- function(data,
|
||||
lineLength = 20,
|
||||
force = FALSE) {
|
||||
if (isTRUE(force)) {
|
||||
## This eats some letters when splitting a sentence... ??
|
||||
gsub(paste0("(.{1,", lineLength, "})(\\s|[[:alnum:]])"),
|
||||
"\\1\n",
|
||||
data)
|
||||
} else {
|
||||
paste(strwrap(data, lineLength), collapse = "\n")
|
||||
}
|
||||
## https://stackoverflow.com/a/29847221
|
||||
}
|
||||
|
||||
|
||||
#' Wrapping
|
||||
#'
|
||||
#' @param data list of ggplot2 objects
|
||||
#' @param tag_levels passed to patchwork::plot_annotation if given. Default is NULL
|
||||
#' @param title panel title
|
||||
#' @param guides passed to patchwork::wrap_plots()
|
||||
#' @param axes passed to patchwork::wrap_plots()
|
||||
#' @param axis_titles passed to patchwork::wrap_plots()
|
||||
#' @param ... passed to patchwork::wrap_plots()
|
||||
#'
|
||||
#' @returns list of ggplot2 objects
|
||||
#' @export
|
||||
#'
|
||||
wrap_plot_list <- function(data,
|
||||
tag_levels = NULL,
|
||||
title = NULL,
|
||||
axis.font.family = NULL,
|
||||
guides = "collect",
|
||||
axes = "collect",
|
||||
axis_titles = "collect",
|
||||
y.axis.percentage = FALSE,
|
||||
...) {
|
||||
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
|
||||
}
|
||||
})() |>
|
||||
align_axes(percentage = y.axis.percentage) |>
|
||||
patchwork::wrap_plots(guides = guides,
|
||||
axes = axes,
|
||||
axis_titles = axis_titles,
|
||||
...)
|
||||
if (!is.null(tag_levels)) {
|
||||
out <- out + patchwork::plot_annotation(tag_levels = tag_levels)
|
||||
}
|
||||
if (!is.null(title)) {
|
||||
out <- out +
|
||||
patchwork::plot_annotation(
|
||||
title = title,
|
||||
theme = ggplot2::theme(plot.title = ggplot2::element_text(size = 25))
|
||||
)
|
||||
}
|
||||
} else {
|
||||
out <- data[[1]]
|
||||
}
|
||||
} else {
|
||||
cli::cli_abort("Can only wrap lists of {.cls ggplot} objects")
|
||||
}
|
||||
|
||||
if (!is.null(axis.font.family)) {
|
||||
if (inherits(x = out, what = "patchwork")) {
|
||||
out <- out &
|
||||
ggplot2::theme(axis.text = ggplot2::element_text(family = axis.font.family))
|
||||
} else {
|
||||
out <- out +
|
||||
ggplot2::theme(axis.text = ggplot2::element_text(family = axis.font.family))
|
||||
}
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
|
||||
#' Aligns axes between plots
|
||||
#'
|
||||
#' @param ... ggplot2 objects or list of ggplot2 objects
|
||||
#'
|
||||
#' @returns list of ggplot2 objects
|
||||
#' @export
|
||||
#'
|
||||
align_axes <- function(...,
|
||||
x.axis = TRUE,
|
||||
y.axis = TRUE,
|
||||
percentage = FALSE) {
|
||||
# https://stackoverflow.com/questions/62818776/get-axis-limits-from-ggplot-object
|
||||
# https://github.com/thomasp85/patchwork/blob/main/R/plot_multipage.R#L150
|
||||
if (ggplot2::is_ggplot(..1)) {
|
||||
## Assumes list of ggplots
|
||||
p <- list(...)
|
||||
} else if (is.list(..1)) {
|
||||
## Assumes list with list of ggplots
|
||||
p <- ..1
|
||||
} else {
|
||||
cli::cli_abort("Can only align {.cls ggplot} objects or a list of them")
|
||||
}
|
||||
|
||||
yr <- clean_common_axis(p, "y")
|
||||
|
||||
xr <- clean_common_axis(p, "x")
|
||||
|
||||
suppressWarnings({
|
||||
p_out <- purrr::map(p, \(.x) {
|
||||
out <- .x
|
||||
if (isTRUE(x.axis)) {
|
||||
out <- out + ggplot2::xlim(xr)
|
||||
}
|
||||
if (isTRUE(y.axis)) {
|
||||
out <- out + ggplot2::ylim(yr)
|
||||
}
|
||||
out
|
||||
})
|
||||
})
|
||||
|
||||
if (isTRUE(percentage)) {
|
||||
lapply(p_out, \(.x) {
|
||||
.x +
|
||||
ggplot2::scale_y_continuous(labels = scales::percent)
|
||||
})
|
||||
} else {
|
||||
p_out
|
||||
}
|
||||
}
|
||||
|
||||
#' 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 {
|
||||
as.character(.x)
|
||||
}
|
||||
})() |>
|
||||
unique()
|
||||
}
|
||||
112
R/plot_bar.R
112
R/plot_bar.R
|
|
@ -1,4 +1,29 @@
|
|||
plot_bar <- function(data, pri, sec, ter = NULL, style = c("stack", "dodge", "fill"), 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)) {
|
||||
|
|
@ -7,17 +32,21 @@ 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,
|
||||
sec = sec,
|
||||
style = style,
|
||||
max_level = max_level
|
||||
max_level = max_level,
|
||||
color.palette = color.palette,
|
||||
...
|
||||
)
|
||||
})
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -38,8 +67,13 @@ 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")
|
||||
plot_bar_single <- function(data, pri, sec = NULL, style = c("stack", "dodge", "fill"), max_level = 30) {
|
||||
#' 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,
|
||||
color.palette = "viridis") {
|
||||
style <- match.arg(style)
|
||||
|
||||
if (identical(sec, "none")) {
|
||||
|
|
@ -48,35 +82,12 @@ 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) {
|
||||
# browser()
|
||||
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)
|
||||
# if (is.null(sec)){
|
||||
# p_data <- sort_by(
|
||||
# p_data,
|
||||
# p_data[["Freq"]],
|
||||
# decreasing=TRUE) |>
|
||||
# head(max_level)
|
||||
# } else {
|
||||
# split(p_data,p_data[[sec]]) |>
|
||||
# lapply(\(.x){
|
||||
# # browser()
|
||||
# sort_by(
|
||||
# .x,
|
||||
# .x[["Freq"]],
|
||||
# decreasing=TRUE) |>
|
||||
# head(max_level)
|
||||
# }) |> dplyr::bind_rows()
|
||||
# }
|
||||
}
|
||||
|
||||
## Shortens long level names
|
||||
|
|
@ -88,38 +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) +
|
||||
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")
|
||||
}
|
||||
|
|
|
|||
14
R/plot_box.R
14
R/plot_box.R
|
|
@ -20,7 +20,7 @@
|
|||
#' mtcars |>
|
||||
#' default_parsing() |>
|
||||
#' plot_box(pri = "mpg", sec = "cyl", ter = "gear",axis.font.family="mono")
|
||||
plot_box <- function(data, pri, sec, ter = NULL,...) {
|
||||
plot_box <- function(data, pri, sec, ter = NULL,color.palette="viridis",...) {
|
||||
if (!is.null(ter)) {
|
||||
ds <- split(data, data[ter])
|
||||
} else {
|
||||
|
|
@ -31,11 +31,12 @@ plot_box <- function(data, pri, sec, ter = NULL,...) {
|
|||
plot_box_single(
|
||||
data = .ds,
|
||||
pri = pri,
|
||||
sec = sec
|
||||
sec = sec,
|
||||
color.palette=color.palette, ...
|
||||
)
|
||||
})
|
||||
|
||||
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)}")))
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -48,9 +49,10 @@ plot_box <- function(data, pri, sec, ter = NULL,...) {
|
|||
#'
|
||||
#' @examples
|
||||
#' mtcars |> plot_box_single("mpg")
|
||||
#' mtcars |> plot_box_single("mpg","cyl")
|
||||
#' mtcars |> plot_box_single("mpg","cyl",color.palette="Blues")
|
||||
#' stRoke::trial |> plot_box_single("age","active",color.palette="Blues")
|
||||
#' gtsummary::trial |> plot_box_single("age","trt")
|
||||
plot_box_single <- function(data, pri, sec=NULL, seed = 2103) {
|
||||
plot_box_single <- function(data, pri, sec=NULL, seed = 2103,color.palette="viridis") {
|
||||
set.seed(seed)
|
||||
|
||||
if (is.null(sec)) {
|
||||
|
|
@ -68,7 +70,7 @@ plot_box_single <- function(data, pri, sec=NULL, seed = 2103) {
|
|||
ggplot2::xlab(get_label(data,pri))+
|
||||
ggplot2::ylab(get_label(data,sec)) +
|
||||
ggplot2::coord_flip() +
|
||||
viridis::scale_fill_viridis(discrete = discrete, option = "D") +
|
||||
scale_fill_generate(discrete = discrete,palette = color.palette) +
|
||||
# ggplot2::theme_void() +
|
||||
ggplot2::theme_bw(base_size = 24) +
|
||||
ggplot2::theme(
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ ggeulerr <- function(
|
|||
#' plot_euler("mfi_cut", "mdi_cut")
|
||||
#' stRoke::trial |>
|
||||
#' plot_euler(pri="male", sec=c("hypertension"))
|
||||
plot_euler <- function(data, pri, sec, ter = NULL, seed = 2103) {
|
||||
plot_euler <- function(data, pri, sec, ter = NULL, seed = 2103,color.palette="viridis") {
|
||||
set.seed(seed = seed)
|
||||
if (!is.null(ter)) {
|
||||
ds <- split(data, data[ter])
|
||||
|
|
@ -112,7 +112,7 @@ plot_euler <- function(data, pri, sec, ter = NULL, seed = 2103) {
|
|||
out <- lapply(ds, \(.x){
|
||||
.x[c(pri, sec)] |>
|
||||
na.omit() |>
|
||||
plot_euler_single()
|
||||
plot_euler_single(color.palette=color.palette)
|
||||
})
|
||||
|
||||
wrap_plot_list(out, title = glue::glue(i18n$t("Grouped by {get_label(data,ter)}")))
|
||||
|
|
@ -130,16 +130,12 @@ plot_euler <- function(data, pri, sec, ter = NULL, seed = 2103) {
|
|||
#' C = sample(c(TRUE, FALSE, FALSE, FALSE), 50, TRUE),
|
||||
#' D = sample(c(TRUE, FALSE, FALSE, FALSE), 50, TRUE)
|
||||
#' ) |> plot_euler_single()
|
||||
#' mtcars[c("vs", "am")] |> plot_euler_single()
|
||||
plot_euler_single <- function(data) {
|
||||
# if (any("categorical" %in% data_type(data))){
|
||||
# shape <- "ellipse"
|
||||
# } else {
|
||||
# shape <- "circle"
|
||||
# }
|
||||
#' mtcars[c("vs", "am")] |> plot_euler_single("magma")
|
||||
plot_euler_single <- function(data,color.palette="viridis", ...) {
|
||||
|
||||
data |>
|
||||
ggeulerr(shape = "circle") +
|
||||
scale_fill_generate(palette=color.palette) +
|
||||
ggplot2::theme_void() +
|
||||
ggplot2::theme(
|
||||
legend.position = "none",
|
||||
|
|
|
|||
|
|
@ -8,11 +8,23 @@
|
|||
#' @examples
|
||||
#' mtcars |> plot_hbars(pri = "carb", sec = "cyl")
|
||||
#' mtcars |> plot_hbars(pri = "carb", sec = "cyl", ter="am")
|
||||
#' mtcars |> plot_hbars(pri = "carb", sec = NULL)
|
||||
plot_hbars <- function(data, pri, sec, ter = NULL) {
|
||||
out <- vertical_stacked_bars(data = data, score = pri, group = sec, strata = ter)
|
||||
|
||||
out
|
||||
#' mtcars |> plot_hbars(pri = "carb", sec = NULL,color.palette="Blues")
|
||||
#' mtcars |> plot_hbars(pri = "carb", sec = NULL,color.palette="Magma")
|
||||
#' mtcars |> plot_hbars(pri = "carb", sec = "am",color.palette="Viridis")
|
||||
plot_hbars <- function(data,
|
||||
pri,
|
||||
sec,
|
||||
ter = NULL,
|
||||
color.palette = "viridis",
|
||||
...) {
|
||||
vertical_stacked_bars(
|
||||
data = data,
|
||||
score = pri,
|
||||
group = sec,
|
||||
strata = ter,
|
||||
color.palette = color.palette,
|
||||
...
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -31,11 +43,13 @@ vertical_stacked_bars <- function(data,
|
|||
score = "full_score",
|
||||
group = "pase_0_q",
|
||||
strata = NULL,
|
||||
t.size = 10,
|
||||
t.size = 8,
|
||||
l.color = "black",
|
||||
l.size = .5,
|
||||
draw.lines = TRUE,
|
||||
label.str="{n}\n{round(100 * p,0)}%") {
|
||||
label.str = "{n}\n{round(100 * p,0)}%",
|
||||
color.palette = "viridis",
|
||||
reverse = TRUE) {
|
||||
if (is.null(group)) {
|
||||
df.table <- data[c(score, group, strata)] |>
|
||||
dplyr::mutate("All" = 1) |>
|
||||
|
|
@ -60,15 +74,19 @@ vertical_stacked_bars <- function(data,
|
|||
returnData = TRUE
|
||||
)
|
||||
|
||||
colors <- viridisLite::viridis(nrow(df.table))
|
||||
contrast_cut <-
|
||||
sum(contrast_text(colors, threshold = .3) == "white")
|
||||
colors <- generate_colors(n = nrow(df.table), palette = color.palette)
|
||||
## Colors are reversed by default as that usually gives the best result
|
||||
if (isTRUE(reverse) | reverse=="TRUE") {
|
||||
colors <- rev(colors)
|
||||
}
|
||||
|
||||
score_label <- data |> get_label(var = score)
|
||||
group_label <- data |> get_label(var = group)
|
||||
|
||||
# browser()
|
||||
|
||||
p |>
|
||||
(\(.x){
|
||||
(\(.x) {
|
||||
.x$plot +
|
||||
ggplot2::geom_text(
|
||||
data = .x$rectData[which(.x$rectData$n >
|
||||
|
|
@ -78,20 +96,17 @@ vertical_stacked_bars <- function(data,
|
|||
ggplot2::aes(
|
||||
x = group,
|
||||
y = p_prev + 0.49 * p,
|
||||
color = as.numeric(score) > contrast_cut,
|
||||
color = contrast_text(colors[as.numeric(score)], threshold = .3),
|
||||
# label = paste0(sprintf("%2.0f", 100 * p),"%"),
|
||||
# label = sprintf("%2.0f", 100 * p)
|
||||
label = glue::glue(label.str)
|
||||
)
|
||||
) +
|
||||
ggplot2::labs(fill = score_label) +
|
||||
ggplot2::scale_fill_manual(values = rev(colors)) +
|
||||
ggplot2::theme(
|
||||
legend.position = "bottom",
|
||||
axis.title = ggplot2::element_text(),
|
||||
) +
|
||||
ggplot2::scale_fill_manual(values = colors) +
|
||||
ggplot2::theme(legend.position = "bottom",
|
||||
axis.title = ggplot2::element_text(),) +
|
||||
ggplot2::xlab(group_label) +
|
||||
ggplot2::ylab(NULL)
|
||||
# viridis::scale_fill_viridis(discrete = TRUE, direction = -1, option = "D")
|
||||
})()
|
||||
}
|
||||
|
|
|
|||
57
R/plot_likert.R
Normal file
57
R/plot_likert.R
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#' Nice horizontal bar plot centred on the central category
|
||||
#'
|
||||
#' @returns ggplot2 object
|
||||
#' @export
|
||||
#'
|
||||
#' @name data-plots
|
||||
#'
|
||||
#' @examples
|
||||
#' mtcars |> plot_likert(pri = "carb", sec = "cyl")
|
||||
#' mtcars |> plot_likert(pri = "carb", sec = "cyl", ter="am")
|
||||
#' mtcars |> plot_likert(pri = "cyl",color.palette="Blues")
|
||||
#' mtcars |> plot_likert(pri = "carb", sec = NULL,color.palette="Magma")
|
||||
#' mtcars |> plot_likert(pri = "carb", sec = c("cyl","am"),color.palette="Viridis")
|
||||
plot_likert <- function(data,
|
||||
pri,
|
||||
sec = NULL,
|
||||
ter = NULL,
|
||||
color.palette = "viridis",
|
||||
...) {
|
||||
if (!is.null(ter)) {
|
||||
ds <- split(data, data[ter])
|
||||
} else {
|
||||
ds <- list(data)
|
||||
}
|
||||
out <- lapply(ds, \(.x) {
|
||||
plot_likert_single(
|
||||
data = .x,
|
||||
include = tidyselect::any_of(c(pri, sec)),
|
||||
color.palette = color.palette
|
||||
)
|
||||
})
|
||||
|
||||
wrap_plot_list(out, title = glue::glue(i18n$t("Grouped by {get_label(data,ter)}")))
|
||||
}
|
||||
|
||||
|
||||
plot_likert_single <- function(data,
|
||||
include = dplyr::everything(),
|
||||
color.palette = "viridis") {
|
||||
data |>
|
||||
dplyr::as_tibble() |>
|
||||
ggstats::gglikert(include = include) +
|
||||
scale_fill_generate(palette = color.palette) +
|
||||
ggplot2::theme(
|
||||
# legend.position = "none",
|
||||
# panel.grid.major = element_blank(),
|
||||
# panel.grid.minor = element_blank(),
|
||||
# axis.text.y = ggplot2::element_blank(),
|
||||
# axis.title.y = ggplot2::element_blank(),
|
||||
text = ggplot2::element_text(size = 12)
|
||||
# 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()
|
||||
)
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
#' default_parsing() |>
|
||||
#' plot_ridge(x = "mpg", y = "cyl")
|
||||
#' mtcars |> plot_ridge(x = "mpg", y = "cyl", z = "gear")
|
||||
plot_ridge <- function(data, x, y, z = NULL, ...) {
|
||||
plot_ridge <- function(data, x, y, z = NULL, color.palette="viridis", ...) {
|
||||
if (!is.null(z)) {
|
||||
ds <- split(data, data[z])
|
||||
} else {
|
||||
|
|
@ -21,6 +21,7 @@ plot_ridge <- function(data, x, y, z = NULL, ...) {
|
|||
ggplot2::ggplot(.ds, ggplot2::aes(x = !!dplyr::sym(x), y = !!dplyr::sym(y), fill = !!dplyr::sym(y))) +
|
||||
ggridges::geom_density_ridges() +
|
||||
ggridges::theme_ridges() +
|
||||
scale_fill_generate(palette=color.palette) +
|
||||
ggplot2::theme(legend.position = "none") |> rempsyc:::theme_apa()
|
||||
})
|
||||
|
||||
|
|
|
|||
176
R/plot_sankey.R
176
R/plot_sankey.R
|
|
@ -19,7 +19,7 @@ sankey_ready <- function(data, pri, sec, numbers = "count", ...) {
|
|||
## TODO: Ensure ordering x and y
|
||||
|
||||
## Ensure all are factors
|
||||
data[c(pri, sec)] <- data[c(pri, sec)] |>
|
||||
data <- data[c(pri, sec)] |>
|
||||
dplyr::mutate(dplyr::across(!dplyr::where(is.factor), forcats::as_factor))
|
||||
|
||||
out <- dplyr::count(data, !!dplyr::sym(pri), !!dplyr::sym(sec), .drop = FALSE)
|
||||
|
|
@ -33,15 +33,17 @@ sankey_ready <- function(data, pri, sec, numbers = "count", ...) {
|
|||
dplyr::ungroup()
|
||||
|
||||
if (numbers == "count") {
|
||||
out <- out |> dplyr::mutate(
|
||||
lx = factor(paste0(!!dplyr::sym(pri), "\n(n=", gx.sum, ")")),
|
||||
ly = factor(paste0(!!dplyr::sym(sec), "\n(n=", gy.sum, ")"))
|
||||
)
|
||||
out <- out |> dplyr::mutate(lx = factor(paste0(
|
||||
!!dplyr::sym(pri), "\n(n=", gx.sum, ")"
|
||||
)), ly = factor(paste0(
|
||||
!!dplyr::sym(sec), "\n(n=", gy.sum, ")"
|
||||
)))
|
||||
} else if (numbers == "percentage") {
|
||||
out <- out |> dplyr::mutate(
|
||||
lx = factor(paste0(!!dplyr::sym(pri), "\n(", round((gx.sum / sum(n)) * 100, 1), "%)")),
|
||||
ly = factor(paste0(!!dplyr::sym(sec), "\n(", round((gy.sum / sum(n)) * 100, 1), "%)"))
|
||||
)
|
||||
out <- out |> dplyr::mutate(lx = factor(paste0(
|
||||
!!dplyr::sym(pri), "\n(", round((gx.sum / sum(n)) * 100, 1), "%)"
|
||||
)), ly = factor(paste0(
|
||||
!!dplyr::sym(sec), "\n(", round((gy.sum / sum(n)) * 100, 1), "%)"
|
||||
)))
|
||||
}
|
||||
|
||||
if (is.factor(data[[pri]])) {
|
||||
|
|
@ -82,21 +84,44 @@ str_remove_last <- function(data, pattern = "\n") {
|
|||
#' ## Dont know why...
|
||||
#' mtcars |>
|
||||
#' default_parsing() |>
|
||||
#' plot_sankey("cyl", "gear", "vs", color.group = "pri")
|
||||
plot_sankey <- function(data, pri, sec, ter = NULL, color.group = "pri", colors = NULL,missing.level="Missing") {
|
||||
#' plot_sankey("cyl", "gear", "vs", color.group = "pri",color.palette="inferno")
|
||||
plot_sankey <- function(data,
|
||||
pri,
|
||||
sec,
|
||||
ter = NULL,
|
||||
color.group = "pri",
|
||||
colors = NULL,
|
||||
color.palette = "viridis",
|
||||
default.color = "#2986cc",
|
||||
box.color = "#1E4B66",
|
||||
na.color = "grey80",
|
||||
missing.level = "Missing",
|
||||
...) {
|
||||
if (!is.null(ter)) {
|
||||
ds <- split(data, data[ter])
|
||||
} else {
|
||||
ds <- list(data)
|
||||
}
|
||||
|
||||
out <- lapply(ds, \(.ds){
|
||||
plot_sankey_single(.ds, pri = pri, sec = sec, color.group = color.group, colors = colors,missing.level=missing.level)
|
||||
# browser()
|
||||
|
||||
out <- lapply(ds, \(.ds) {
|
||||
plot_sankey_single(
|
||||
.ds,
|
||||
pri = pri,
|
||||
sec = sec,
|
||||
color.palette = color.palette,
|
||||
color.group = color.group,
|
||||
colors = colors,
|
||||
missing.level = missing.level
|
||||
)
|
||||
})
|
||||
|
||||
patchwork::wrap_plots(out)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#' Beautiful sankey plot
|
||||
#'
|
||||
#' @param color.group set group to colour by. "x" or "y".
|
||||
|
|
@ -123,41 +148,58 @@ plot_sankey <- function(data, pri, sec, ter = NULL, color.group = "pri", colors
|
|||
#' stRoke::trial |>
|
||||
#' default_parsing() |>
|
||||
#' plot_sankey_single("diabetes", "hypertension")
|
||||
plot_sankey_single <- function(data, pri, sec, color.group = c("pri", "sec"), colors = NULL,missing.level="Missing", ...) {
|
||||
#'
|
||||
#'
|
||||
#' # stRoke::trial |> plot_sankey_single("mrs_1", "mrs_6", color.palette="magma")
|
||||
#' # stRoke::trial |> plot_sankey_single("active", "male")
|
||||
#' # stRoke::trial |> plot_sankey_single("diabetes", "active", color.group="sec")
|
||||
#' # stRoke::trial |> plot_sankey_single("active", "diabetes", color.group="sec", color.palette="topo")
|
||||
plot_sankey_single <- function(data,
|
||||
pri,
|
||||
sec,
|
||||
color.group = c("pri", "sec"),
|
||||
color.palette = "viridis",
|
||||
colors=NULL,
|
||||
missing.level = "Missing",
|
||||
default.color = "#2986cc",
|
||||
box.color = "#1E4B66",
|
||||
na.color = "grey80",
|
||||
...) {
|
||||
color.group <- match.arg(color.group)
|
||||
|
||||
# browser()
|
||||
data_orig <- data
|
||||
data[c(pri, sec)] <- data[c(pri, sec)] |>
|
||||
dplyr::mutate(
|
||||
# dplyr::across(dplyr::where(is.logical), as.factor),
|
||||
dplyr::across(dplyr::where(is.factor), forcats::fct_drop)#,
|
||||
# dplyr::across(dplyr::where(is.factor), \(.x){forcats::fct_na_value_to_level(.x,missing.level)})
|
||||
)
|
||||
|
||||
data[c(pri, sec)] <- with_labels(data,{
|
||||
data[c(pri, sec)] |>
|
||||
to_clean_levels() |>
|
||||
missing_to_text_levels(missing.text=missing.level)
|
||||
})
|
||||
|
||||
data <- data |> sankey_ready(pri = pri, sec = sec, ...)
|
||||
## Aggregate data
|
||||
data_aggr <- data |> sankey_ready(pri = pri, sec = sec, ...)
|
||||
|
||||
na.color <- "#2986cc"
|
||||
box.color <- "#1E4B66"
|
||||
default.color = default.color
|
||||
box.color = box.color
|
||||
na.color = na.color
|
||||
|
||||
if (is.null(colors)) {
|
||||
if (color.group == "sec") {
|
||||
main.colors <- viridisLite::viridis(n = length(levels(data_orig[[sec]])))
|
||||
## Only keep colors for included levels
|
||||
main.colors <- main.colors[match(levels(data[[sec]]), levels(data_orig[[sec]]))]
|
||||
main.colors <- color_levels_gen(data_orig[[sec]],palette=color.palette)
|
||||
|
||||
secondary.colors <- rep(na.color, length(levels(data[[pri]])))
|
||||
label.colors <- Reduce(c, lapply(list(secondary.colors, rev(main.colors)), contrast_text))
|
||||
secondary.colors <- rep(default.color, length(levels(data[[pri]])))
|
||||
label.colors <- Reduce(c, lapply(list(
|
||||
secondary.colors, rev(main.colors)
|
||||
), contrast_text))
|
||||
} else {
|
||||
main.colors <- viridisLite::viridis(n = length(levels(data_orig[[pri]])))
|
||||
## Only keep colors for included levels
|
||||
main.colors <- main.colors[match(levels(data[[pri]]), levels(data_orig[[pri]]))]
|
||||
main.colors <- color_levels_gen(data_orig[[pri]],palette=color.palette)
|
||||
|
||||
secondary.colors <- rep(na.color, length(levels(data[[sec]])))
|
||||
label.colors <- Reduce(c, lapply(list(rev(main.colors), secondary.colors), contrast_text))
|
||||
secondary.colors <- rep(default.color, length(levels(data[[sec]])))
|
||||
label.colors <- Reduce(c, lapply(list(
|
||||
rev(main.colors), secondary.colors
|
||||
), contrast_text))
|
||||
}
|
||||
colors <- c(na.color, main.colors, secondary.colors)
|
||||
colors <- c(default.color, main.colors, secondary.colors)
|
||||
colors[is.na(colors)] <- na.color
|
||||
} else {
|
||||
label.colors <- contrast_text(colors)
|
||||
}
|
||||
|
|
@ -166,7 +208,7 @@ plot_sankey_single <- function(data, pri, sec, color.group = c("pri", "sec"), co
|
|||
sapply(line_break) |>
|
||||
unname()
|
||||
|
||||
p <- ggplot2::ggplot(data, ggplot2::aes(y = n, axis1 = lx, axis2 = ly))
|
||||
p <- ggplot2::ggplot(data_aggr, ggplot2::aes(y = n, axis1 = lx, axis2 = ly))
|
||||
|
||||
if (color.group == "sec") {
|
||||
p <- p +
|
||||
|
|
@ -181,9 +223,8 @@ plot_sankey_single <- function(data, pri, sec, color.group = c("pri", "sec"), co
|
|||
knot.pos = 0.4,
|
||||
curve_type = "sigmoid"
|
||||
) + ggalluvial::geom_stratum(ggplot2::aes(fill = !!dplyr::sym(sec)),
|
||||
size = 2,
|
||||
width = 1 / 3.4
|
||||
)
|
||||
size = 2,
|
||||
width = 1 / 3.4)
|
||||
} else {
|
||||
p <- p +
|
||||
ggalluvial::geom_alluvium(
|
||||
|
|
@ -196,9 +237,8 @@ plot_sankey_single <- function(data, pri, sec, color.group = c("pri", "sec"), co
|
|||
knot.pos = 0.4,
|
||||
curve_type = "sigmoid"
|
||||
) + ggalluvial::geom_stratum(ggplot2::aes(fill = !!dplyr::sym(pri)),
|
||||
size = 2,
|
||||
width = 1 / 3.4
|
||||
)
|
||||
size = 2,
|
||||
width = 1 / 3.4)
|
||||
}
|
||||
|
||||
## Will fail to use stat="stratum" if library is not loaded.
|
||||
|
|
@ -208,13 +248,10 @@ plot_sankey_single <- function(data, pri, sec, color.group = c("pri", "sec"), co
|
|||
stat = "stratum",
|
||||
ggplot2::aes(label = after_stat(stratum)),
|
||||
colour = label.colors,
|
||||
size = 8,
|
||||
size = 6,
|
||||
lineheight = 1
|
||||
) +
|
||||
ggplot2::scale_x_continuous(
|
||||
breaks = 1:2,
|
||||
labels = group_labels
|
||||
) +
|
||||
ggplot2::scale_x_continuous(breaks = 1:2, labels = group_labels) +
|
||||
ggplot2::scale_fill_manual(values = colors[-1], na.value = colors[1]) +
|
||||
# ggplot2::scale_color_manual(values = main.colors) +
|
||||
ggplot2::theme_void() +
|
||||
|
|
@ -232,3 +269,48 @@ plot_sankey_single <- function(data, pri, sec, color.group = c("pri", "sec"), co
|
|||
panel.border = ggplot2::element_blank()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
# stRoke::trial["male"] |> to_clean_levels()
|
||||
to_clean_levels <- function(data,missing.text="Missing"){
|
||||
if (is.data.frame(data)){
|
||||
data |>
|
||||
lapply(all_levels_clean) |>
|
||||
dplyr::bind_cols()
|
||||
} else {
|
||||
data |>
|
||||
all_levels_clean()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
# stRoke::trial["mrs_1"] |> missing_to_text_levels()
|
||||
missing_to_text_levels <- function(data,missing.text="Missing"){
|
||||
data |>
|
||||
dplyr::mutate(
|
||||
dplyr::across(dplyr::where(is.factor), \(.x) {
|
||||
if (anyNA(.x)) forcats::fct_na_value_to_level(.x, missing.text) else .x
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
all_levels_clean <- function(data){
|
||||
data |>
|
||||
(\(.x){
|
||||
if (is.logical(.x)) as.factor(.x) else .x
|
||||
})() |>
|
||||
(\(.x){
|
||||
if (is.factor(.x)) forcats::fct_drop(.x) else .x
|
||||
})()
|
||||
}
|
||||
|
||||
# stRoke::trial$mrs_1 |> color_levels_gen()
|
||||
color_levels_gen <- function(data,na.color="grey80",palette="viridis"){
|
||||
out <- generate_colors(n = length(levels(to_clean_levels(data))),palette = palette)
|
||||
if (anyNA(data)){
|
||||
out <- c(out,na.color)
|
||||
}
|
||||
out
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
#'
|
||||
#' @examples
|
||||
#' mtcars |> plot_scatter(pri = "mpg", sec = "wt")
|
||||
plot_scatter <- function(data, pri, sec, ter = NULL) {
|
||||
#' mtcars |> plot_scatter(pri = "mpg", sec = "wt",ter="carb")
|
||||
plot_scatter <- function(data, pri, sec, ter = NULL, color.palette="viridis", ...) {
|
||||
if (is.null(ter)) {
|
||||
rempsyc::nice_scatter(
|
||||
data = data,
|
||||
|
|
@ -24,6 +25,7 @@ plot_scatter <- function(data, pri, sec, ter = NULL) {
|
|||
group = ter,
|
||||
xtitle = get_label(data, var = sec),
|
||||
ytitle = get_label(data, var = pri)
|
||||
)
|
||||
)+
|
||||
scale_color_generate(palette=color.palette)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#' Beatiful violin plot
|
||||
#' Beautiful violin plot
|
||||
#'
|
||||
#' @returns ggplot2 object
|
||||
#' @export
|
||||
|
|
@ -6,8 +6,9 @@
|
|||
#' @name data-plots
|
||||
#'
|
||||
#' @examples
|
||||
#' mtcars |> plot_violin(pri = "mpg", sec = "cyl", ter = "gear")
|
||||
plot_violin <- function(data, pri, sec, ter = NULL) {
|
||||
#' mtcars |> plot_violin(pri = "mpg", sec = "cyl")
|
||||
#' mtcars |> plot_violin(pri = "mpg", sec = "cyl", ter = "gear", color.palette="Blues")
|
||||
plot_violin <- function(data, pri, sec, ter = NULL, color.palette="viridis", ...) {
|
||||
if (!is.null(ter)) {
|
||||
ds <- split(data, data[ter])
|
||||
} else {
|
||||
|
|
@ -22,8 +23,10 @@ plot_violin <- function(data, pri, sec, ter = NULL) {
|
|||
group = sec,
|
||||
response = pri,
|
||||
xtitle = get_label(data, var = sec),
|
||||
ytitle = get_label(data, var = pri)
|
||||
)
|
||||
ytitle = get_label(data, var = pri),
|
||||
...
|
||||
)+
|
||||
scale_fill_generate(palette=color.palette)
|
||||
})
|
||||
|
||||
wrap_plot_list(out, title = glue::glue(i18n$t("Grouped by {get_label(data,ter)}")))
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -57,7 +57,8 @@ regression_ui <- function(id, ...) {
|
|||
bslib::accordion_panel(
|
||||
value = "acc_pan_reg",
|
||||
title = i18n$t("Regression"),
|
||||
icon = bsicons::bs_icon("calculator"),
|
||||
icon = phosphoricons::ph("calculator"),
|
||||
# icon = bsicons::bs_icon("calculator"),
|
||||
shiny::uiOutput(outputId = ns("outcome_var")),
|
||||
# shiny::selectInput(
|
||||
# inputId = "design",
|
||||
|
|
@ -91,7 +92,8 @@ regression_ui <- function(id, ...) {
|
|||
bslib::input_task_button(
|
||||
id = ns("load"),
|
||||
label = i18n$t("Analyse"),
|
||||
icon = bsicons::bs_icon("pencil"),
|
||||
icon = phosphoricons::ph("math-operations"),
|
||||
# icon = bsicons::bs_icon("pencil"),
|
||||
label_busy = i18n$t("Working..."),
|
||||
icon_busy = fontawesome::fa_i("arrows-rotate",
|
||||
class = "fa-spin",
|
||||
|
|
@ -136,7 +138,8 @@ regression_ui <- function(id, ...) {
|
|||
list(
|
||||
value = "acc_pan_coef_plot",
|
||||
title = "Coefficients plot",
|
||||
icon = bsicons::bs_icon("bar-chart-steps"),
|
||||
icon = phosphoricons::ph("chart-bar-horizontal"),
|
||||
# icon = bsicons::bs_icon("bar-chart-steps"),
|
||||
shiny::tags$br(),
|
||||
shiny::uiOutput(outputId = ns("plot_model"))
|
||||
),
|
||||
|
|
@ -179,7 +182,8 @@ regression_ui <- function(id, ...) {
|
|||
shiny::downloadButton(
|
||||
outputId = ns("download_plot"),
|
||||
label = i18n$t("Download plot"),
|
||||
icon = shiny::icon("download")
|
||||
icon = phosphoricons::ph("arrow-fat-down")
|
||||
# icon = shiny::icon("download")
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
@ -200,7 +204,8 @@ regression_ui <- function(id, ...) {
|
|||
bslib::accordion_panel(
|
||||
value = "acc_pan_checks",
|
||||
title = "Checks",
|
||||
icon = bsicons::bs_icon("clipboard-check"),
|
||||
icon = phosphoricons::ph("checks"),
|
||||
# icon = bsicons::bs_icon("clipboard-check"),
|
||||
shiny::uiOutput(outputId = ns("plot_checks"))
|
||||
)
|
||||
)
|
||||
|
|
@ -416,7 +421,7 @@ regression_server <- function(id,
|
|||
rv$list$regression$models <- model_lists
|
||||
},
|
||||
error = function(err) {
|
||||
showNotification(paste(i18n$t("Creating regression models failed with the following error:"), err), type = "err")
|
||||
showNotification(paste(i18n$t("Creating regression models failed with the following error:"), err), type = "error")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -481,7 +486,7 @@ regression_server <- function(id,
|
|||
showNotification(paste0(warn), type = "warning")
|
||||
},
|
||||
error = function(err) {
|
||||
showNotification(paste(i18n$t("Creating a regression table failed with the following error:"), err), type = "err")
|
||||
showNotification(paste(i18n$t("Creating a regression table failed with the following error:"), err), type = "error")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -559,7 +564,7 @@ regression_server <- function(id,
|
|||
gg_theme_shiny()
|
||||
},
|
||||
error = function(err) {
|
||||
showNotification(paste0(err), type = "err")
|
||||
showNotification(paste0(err), type = "error")
|
||||
}
|
||||
)
|
||||
})
|
||||
|
|
@ -619,7 +624,7 @@ regression_server <- function(id,
|
|||
# showNotification(paste0(warn), type = "warning")
|
||||
# },
|
||||
error = function(err) {
|
||||
showNotification(paste(i18n$t("Running model assumptions checks failed with the following error:"), err), type = "err")
|
||||
showNotification(paste(i18n$t("Running model assumptions checks failed with the following error:"), err), type = "error")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
@ -690,7 +695,7 @@ regression_server <- function(id,
|
|||
out <- patchwork::wrap_plots(ls, ncol = if (length(ls) == 1) 1 else 2)
|
||||
},
|
||||
error = function(err) {
|
||||
showNotification(err, type = "err")
|
||||
showNotification(err, type = "error")
|
||||
}
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
BIN
R/sysdata.rda
BIN
R/sysdata.rda
Binary file not shown.
|
|
@ -37,7 +37,8 @@ table_download_server <- function(id, data, file_name = "table", ...) {
|
|||
shiny::downloadButton(
|
||||
outputId = ns("act_table"),
|
||||
label = i18n$t("Download table"),
|
||||
icon = shiny::icon("download")
|
||||
icon = phosphoricons::ph("arrow-fat-down")
|
||||
# icon = shiny::icon("download")
|
||||
)
|
||||
} else {
|
||||
# Return NULL to show nothing
|
||||
|
|
|
|||
|
|
@ -15,7 +15,8 @@ ui_elements <- function(selection) {
|
|||
"home" = bslib::nav_panel(
|
||||
title = "FreesearchR",
|
||||
# title = shiny::div(htmltools::img(src="FreesearchR-logo-white-nobg-h80.png")),
|
||||
icon = shiny::icon("house"),
|
||||
icon = phosphoricons::ph("house", weight = "bold"),
|
||||
# icon = shiny::icon("house"),
|
||||
shiny::fluidRow(
|
||||
# "The browser language is",
|
||||
# textOutput("your_lang"),
|
||||
|
|
@ -25,6 +26,7 @@ ui_elements <- function(selection) {
|
|||
## Default just output "NULL"
|
||||
## This could probably be achieved more legantly, but this works.
|
||||
dev_banner(),
|
||||
version_banner,
|
||||
landing_page_ui(i18n = i18n),
|
||||
# shiny::column(width = 2),
|
||||
# shiny::column(
|
||||
|
|
@ -44,7 +46,8 @@ ui_elements <- function(selection) {
|
|||
##############################################################################
|
||||
"import" = bslib::nav_panel(
|
||||
title = i18n$t("Get started"),
|
||||
icon = shiny::icon("play"),
|
||||
icon = phosphoricons::ph("play", weight = "bold"),
|
||||
# icon = shiny::icon("play"),
|
||||
value = "nav_import",
|
||||
shiny::fluidRow(
|
||||
shiny::column(width = 2),
|
||||
|
|
@ -83,9 +86,9 @@ ui_elements <- function(selection) {
|
|||
layout_params = "dropdown",
|
||||
# title = "Choose a datafile to upload",
|
||||
file_extensions = c(".csv", ".tsv", ".txt", ".xls", ".xlsx", ".rds", ".ods", ".dta"),
|
||||
limit_default = global_freesearchR$data_limit_default,
|
||||
limit_lower = global_freesearchR$data_limit_lower,
|
||||
limit_upper = global_freesearchR$data_limit_upper
|
||||
limit_default = DATA_LIMIT_DEFAULT,
|
||||
limit_lower = DATA_LIMIT_LOWER,
|
||||
limit_upper = DATA_LIMIT_UPPER
|
||||
|
||||
)
|
||||
),
|
||||
|
|
@ -107,7 +110,7 @@ ui_elements <- function(selection) {
|
|||
id = "env",
|
||||
title = NULL,
|
||||
packages = c("NHANES", "stRoke", "datasets", "MASS"),
|
||||
globalenv = global_freesearchR$include_globalenv
|
||||
globalenv = isTruthy(INCLUDE_GLOBALENV)
|
||||
)
|
||||
),
|
||||
# shiny::conditionalPanel(
|
||||
|
|
@ -121,7 +124,8 @@ ui_elements <- function(selection) {
|
|||
inputId = "modal_initial_view",
|
||||
label = i18n$t("Quick overview"),
|
||||
width = "100%",
|
||||
icon = shiny::icon("binoculars"),
|
||||
icon = phosphoricons::ph("binoculars",weight = "bold"),
|
||||
# icon = shiny::icon("binoculars"),
|
||||
disabled = FALSE
|
||||
),
|
||||
shiny::br(),
|
||||
|
|
@ -165,7 +169,8 @@ ui_elements <- function(selection) {
|
|||
inputId = "act_start",
|
||||
label = i18n$t("Let's begin!"),
|
||||
width = "100%",
|
||||
icon = shiny::icon("play"),
|
||||
icon = phosphoricons::ph("play",weight = "bold"),
|
||||
# icon = shiny::icon("play"),
|
||||
disabled = TRUE
|
||||
),
|
||||
shiny::br(),
|
||||
|
|
@ -184,11 +189,13 @@ ui_elements <- function(selection) {
|
|||
##############################################################################
|
||||
"prepare" = bslib::nav_menu(
|
||||
title = i18n$t("Prepare"),
|
||||
icon = shiny::icon("pen-to-square"),
|
||||
icon = phosphoricons::ph("note-pencil", weight = "bold"),
|
||||
# icon = shiny::icon("pen-to-square"),
|
||||
value = "nav_prepare",
|
||||
bslib::nav_panel(
|
||||
title = i18n$t("Overview and filter"),
|
||||
icon = shiny::icon("eye"),
|
||||
icon = phosphoricons::ph("eye"),
|
||||
# icon = shiny::icon("eye"),
|
||||
value = "nav_prepare_overview",
|
||||
tags$h3(i18n$t("Overview and filtering")),
|
||||
fluidRow(
|
||||
|
|
@ -240,7 +247,7 @@ ui_elements <- function(selection) {
|
|||
"Read more on how ",
|
||||
tags$a(
|
||||
"data types",
|
||||
href = "https://agdamsbo.github.io/FreesearchR/articles/data-types.html",
|
||||
href = "https://freesearchr.github.io/FreesearchR-knowledge/app/data_types.html",
|
||||
target = "_blank",
|
||||
rel = "noopener noreferrer"
|
||||
),
|
||||
|
|
@ -263,7 +270,8 @@ ui_elements <- function(selection) {
|
|||
),
|
||||
bslib::nav_panel(
|
||||
title = i18n$t("Edit and create data"),
|
||||
icon = shiny::icon("file-pen"),
|
||||
icon = phosphoricons::ph("pencil-line"),
|
||||
# icon = shiny::icon("file-pen"),
|
||||
tags$h3(i18n$t("Subset, rename and convert variables")),
|
||||
fluidRow(shiny::column(
|
||||
width = 9, shiny::tags$p(
|
||||
|
|
@ -292,13 +300,13 @@ ui_elements <- function(selection) {
|
|||
width = 3,
|
||||
shiny::actionButton(
|
||||
inputId = "modal_update",
|
||||
label = i18n$t("Modify factor levels"),
|
||||
label = i18n$t("Modify factor"),
|
||||
width = "100%"
|
||||
),
|
||||
shiny::tags$br(),
|
||||
shiny::helpText(
|
||||
i18n$t("Reorder or rename the levels of factor/categorical variables.")
|
||||
),
|
||||
shiny::helpText(i18n$t(
|
||||
"Modify the levels of factor/categorical variables."
|
||||
)),
|
||||
shiny::tags$br(),
|
||||
shiny::tags$br()
|
||||
),
|
||||
|
|
@ -311,9 +319,7 @@ ui_elements <- function(selection) {
|
|||
),
|
||||
shiny::tags$br(),
|
||||
shiny::helpText(
|
||||
i18n$t(
|
||||
"Create factor/categorical variable from a continous variable (number/date/time)."
|
||||
)
|
||||
i18n$t("Create factor/categorical variable from other variables.")
|
||||
),
|
||||
shiny::tags$br(),
|
||||
shiny::tags$br()
|
||||
|
|
@ -390,14 +396,16 @@ ui_elements <- function(selection) {
|
|||
"describe" =
|
||||
bslib::nav_menu(
|
||||
title = i18n$t("Evaluate"),
|
||||
icon = shiny::icon("magnifying-glass-chart"),
|
||||
icon = phosphoricons::ph("magnifying-glass", weight = "bold"),
|
||||
# icon = shiny::icon("magnifying-glass-chart"),
|
||||
value = "nav_describe",
|
||||
# id = "navdescribe",
|
||||
# bslib::navset_bar(
|
||||
# title = "",
|
||||
bslib::nav_panel(
|
||||
title = i18n$t("Characteristics"),
|
||||
icon = bsicons::bs_icon("table"),
|
||||
icon = phosphoricons::ph("table"),
|
||||
# icon = bsicons::bs_icon("table"),
|
||||
bslib::layout_sidebar(
|
||||
sidebar = bslib::sidebar(
|
||||
shiny::uiOutput(outputId = "data_info_nochar", inline = TRUE),
|
||||
|
|
@ -409,7 +417,8 @@ ui_elements <- function(selection) {
|
|||
open = TRUE,
|
||||
value = "acc_pan_chars",
|
||||
title = "Settings",
|
||||
icon = bsicons::bs_icon("table"),
|
||||
icon = phosphoricons::ph("table"),
|
||||
# icon = bsicons::bs_icon("table"),
|
||||
# vectorSelectInput(
|
||||
# inputId = "baseline_theme",
|
||||
# selected = "none",
|
||||
|
|
@ -451,7 +460,8 @@ ui_elements <- function(selection) {
|
|||
inputId = "act_eval",
|
||||
label = i18n$t("Evaluate"),
|
||||
width = "100%",
|
||||
icon = shiny::icon("calculator"),
|
||||
icon = phosphoricons::ph("calculator",weight = "bold"),
|
||||
# icon = shiny::icon("calculator"),
|
||||
disabled = TRUE
|
||||
),
|
||||
shiny::helpText(i18n$t(
|
||||
|
|
@ -465,7 +475,8 @@ ui_elements <- function(selection) {
|
|||
),
|
||||
bslib::nav_panel(
|
||||
title = i18n$t("Correlations"),
|
||||
icon = bsicons::bs_icon("bounding-box"),
|
||||
icon = phosphoricons::ph("graph"),
|
||||
# icon = bsicons::bs_icon("bounding-box"),
|
||||
bslib::layout_sidebar(
|
||||
sidebar = bslib::sidebar(
|
||||
# shiny::uiOutput(outputId = "data_info_nochar", inline = TRUE),
|
||||
|
|
@ -506,7 +517,8 @@ ui_elements <- function(selection) {
|
|||
do.call(bslib::nav_panel, c(
|
||||
list(
|
||||
title = i18n$t("Missings"),
|
||||
icon = bsicons::bs_icon("x-circle")
|
||||
icon = phosphoricons::ph("placeholder")
|
||||
# icon = bsicons::bs_icon("x-circle")
|
||||
),
|
||||
data_missings_ui(id = "missingness", validation_ui("validation_mcar"))
|
||||
))
|
||||
|
|
@ -521,7 +533,8 @@ ui_elements <- function(selection) {
|
|||
c(
|
||||
list(
|
||||
title = i18n$t("Visuals"),
|
||||
icon = shiny::icon("chart-line"),
|
||||
icon = phosphoricons::ph("chart-line", weight = "bold"),
|
||||
# icon = shiny::icon("chart-line"),
|
||||
value = "nav_visuals"
|
||||
),
|
||||
data_visuals_ui("visuals")
|
||||
|
|
@ -542,7 +555,8 @@ ui_elements <- function(selection) {
|
|||
"analyze" =
|
||||
bslib::nav_panel(
|
||||
title = i18n$t("Regression"),
|
||||
icon = shiny::icon("calculator"),
|
||||
icon = phosphoricons::ph("calculator", weight = "bold"),
|
||||
# icon = shiny::icon("calculator"),
|
||||
value = "nav_analyses",
|
||||
do.call(bslib::navset_card_tab, regression_ui("regression"))
|
||||
),
|
||||
|
|
@ -554,7 +568,8 @@ ui_elements <- function(selection) {
|
|||
"download" =
|
||||
bslib::nav_panel(
|
||||
title = i18n$t("Download"),
|
||||
icon = shiny::icon("download"),
|
||||
icon = phosphoricons::ph("download-simple", weight = "bold"),
|
||||
# icon = shiny::icon("download"),
|
||||
value = "nav_download",
|
||||
shiny::fluidRow(
|
||||
shiny::column(width = 2),
|
||||
|
|
@ -590,7 +605,8 @@ ui_elements <- function(selection) {
|
|||
shiny::downloadButton(
|
||||
outputId = "report",
|
||||
label = "Download report",
|
||||
icon = shiny::icon("download")
|
||||
icon = phosphoricons::ph("arrow-fat-down")
|
||||
# icon = shiny::icon("download")
|
||||
),
|
||||
shiny::br()
|
||||
# shiny::helpText("If choosing to output to MS Word, please note, that when opening the document, two errors will pop-up. Choose to repair and choose not to update references. The issue is being worked on. You can always choose LibreOffice instead."),
|
||||
|
|
@ -620,7 +636,8 @@ ui_elements <- function(selection) {
|
|||
shiny::downloadButton(
|
||||
outputId = "data_modified",
|
||||
label = "Download data",
|
||||
icon = shiny::icon("download")
|
||||
icon = phosphoricons::ph("arrow-fat-down")
|
||||
# icon = shiny::icon("download")
|
||||
)
|
||||
)
|
||||
),
|
||||
|
|
@ -677,7 +694,7 @@ ui_elements <- function(selection) {
|
|||
"docs" = bslib::nav_item(
|
||||
# shiny::img(shiny::icon("book")),
|
||||
shiny::tags$a(
|
||||
href = "https://agdamsbo.github.io/FreesearchR/",
|
||||
href = "https://freesearchr.github.io/FreesearchR-knowledge/",
|
||||
"Docs",
|
||||
shiny::icon("arrow-up-right-from-square"),
|
||||
target = "_blank",
|
||||
|
|
|
|||
|
|
@ -29,22 +29,33 @@ update_factor_ui <- function(id) {
|
|||
),
|
||||
fluidRow(
|
||||
column(
|
||||
width = 6,
|
||||
width = 3,
|
||||
shinyWidgets::virtualSelectInput(
|
||||
inputId = ns("variable"),
|
||||
label = i18n$t("Factor variable to reorder:"),
|
||||
label = i18n$t("Choose variable:"),
|
||||
choices = NULL,
|
||||
width = "100%",
|
||||
zIndex = 50
|
||||
)
|
||||
),
|
||||
column(
|
||||
width = 3,
|
||||
class = "d-flex align-items-end",
|
||||
actionButton(
|
||||
disabled = TRUE,
|
||||
inputId = ns("drop_levels"),
|
||||
label = tagList(phosphoricons::ph("trash",weight = "bold"), i18n$t("Drop empty")),
|
||||
class = "btn-outline-primary mb-3",
|
||||
width = "100%"
|
||||
)
|
||||
),
|
||||
column(
|
||||
width = 3,
|
||||
class = "d-flex align-items-end",
|
||||
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",
|
||||
|
|
@ -57,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",
|
||||
|
|
@ -70,7 +81,9 @@ update_factor_ui <- function(id) {
|
|||
class = "float-end",
|
||||
shinyWidgets::prettyCheckbox(
|
||||
inputId = ns("new_var"),
|
||||
label = i18n$t("Create a new variable; otherwise replaces (Updating labels always creates new variable)"),
|
||||
label = i18n$t(
|
||||
"Create a new variable; otherwise replaces (Updating labels always creates new variable)"
|
||||
),
|
||||
value = FALSE,
|
||||
status = "primary",
|
||||
outline = TRUE,
|
||||
|
|
@ -79,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"
|
||||
|
|
@ -125,6 +138,20 @@ update_factor_server <- function(id, data_r = reactive(NULL)) {
|
|||
rv$data_grid <- grid
|
||||
})
|
||||
|
||||
observeEvent(rv$data_grid, {
|
||||
variable <- req(input$variable)
|
||||
if (isTRUE(has_empty_levels(rv$data[[variable]]))) {
|
||||
# browser()
|
||||
updateActionButton(inputId = "drop_levels", disabled = FALSE)
|
||||
} else {
|
||||
updateActionButton(inputId = "drop_levels", disabled = TRUE)
|
||||
}
|
||||
})
|
||||
|
||||
observeEvent(input$drop_levels, {
|
||||
rv$data_grid <- rv$data_grid[!rv$data_grid$Freq==0,]
|
||||
})
|
||||
|
||||
observeEvent(input$sort_levels, {
|
||||
if (input$sort_levels %% 2 == 1) {
|
||||
decreasing <- FALSE
|
||||
|
|
@ -208,7 +235,7 @@ update_factor_server <- function(id, data_r = reactive(NULL)) {
|
|||
)
|
||||
|
||||
data <- tryCatch({
|
||||
with_labels(data,{
|
||||
with_labels(data, {
|
||||
rlang::exec(factor_new_levels_labels,
|
||||
!!!modifyList(parameters, val = list(data = data)))
|
||||
})
|
||||
|
|
@ -218,7 +245,7 @@ update_factor_server <- function(id, data_r = reactive(NULL)) {
|
|||
"We encountered the following error creating the new factor:",
|
||||
err
|
||||
),
|
||||
type = "err")
|
||||
type = "error")
|
||||
})
|
||||
|
||||
# browser()
|
||||
|
|
@ -370,3 +397,12 @@ unique_names <- function(new, existing = character()) {
|
|||
|
||||
new_names[-seq_along(existing)]
|
||||
}
|
||||
|
||||
|
||||
has_empty_levels <- function(x) {
|
||||
if (is.factor(x)) {
|
||||
any(!levels(x) %in% x)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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%"
|
||||
|
|
|
|||
|
|
@ -65,33 +65,6 @@ validation_server <- function(id,
|
|||
|
||||
data_r <- if (shiny::is.reactive(data)) data else shiny::reactive(data)
|
||||
|
||||
# observeEvent(data_r(), {
|
||||
# to_validate <- data()
|
||||
# valid_dims <- check_data(to_validate, n_row = n_row, n_col = n_col)
|
||||
#
|
||||
# if (all(c(valid_dims$nrows, valid_dims$ncols))) {
|
||||
# valid_status <- "OK"
|
||||
# } else {
|
||||
# valid_status <- "Failed"
|
||||
# }
|
||||
#
|
||||
# valid_results <- lapply(
|
||||
# X = c("nrows", "ncols"),
|
||||
# FUN = function(x) {
|
||||
# if (is.null(valid_dims[[x]]))
|
||||
# return(NULL)
|
||||
# label <- switch(
|
||||
# x,
|
||||
# "nrows" = n_row_label,
|
||||
# "ncols" = n_col_label
|
||||
# )
|
||||
# list(
|
||||
# status = ifelse(valid_dims[[x]], "OK", "Failed"),
|
||||
# label = paste0("<b>", label, "</b>")
|
||||
# )
|
||||
# }
|
||||
# )
|
||||
|
||||
shiny::observeEvent(
|
||||
data_r(),
|
||||
{
|
||||
|
|
|
|||
325
R/version_check.R
Normal file
325
R/version_check.R
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
# version_check.R
|
||||
#
|
||||
# Runs a one-time version check at app startup and returns a ready-made
|
||||
# shinyWidgets::alert() UI element that can be placed directly in the UI
|
||||
# definition -- no server(), no renderUI(), no uiOutput() required.
|
||||
#
|
||||
# Because the check runs outside server(), it executes once when the app
|
||||
# process starts, so the banner is present immediately on first render with
|
||||
# no loading delay.
|
||||
#
|
||||
# Version detection uses two strategies, tried in order:
|
||||
# 1. utils::packageVersion() -- works when the package is installed locally.
|
||||
# 2. app_version argument -- explicit fallback for environments where the
|
||||
# package is not installed (e.g. shinyapps.io). Pass the result of your
|
||||
# app_version() function here.
|
||||
#
|
||||
# Quick start:
|
||||
#
|
||||
# # global.R (or top of app.R, before ui / server)
|
||||
# source("version_check.R")
|
||||
# version_banner <- check_app_version(
|
||||
# github_user = "your-github-username",
|
||||
# github_repo = "your-repo-name",
|
||||
# app_version = app_version() # fallback for shinyapps.io
|
||||
# )
|
||||
#
|
||||
# # ui.R -- drop the result anywhere in the UI tree
|
||||
# fluidPage(
|
||||
# version_banner,
|
||||
# ...
|
||||
# )
|
||||
#
|
||||
# # Verbose / debug mode -- always show the banner:
|
||||
# version_banner <- check_app_version(
|
||||
# github_user = "your-github-username",
|
||||
# github_repo = "your-repo-name",
|
||||
# app_version = app_version(),
|
||||
# verbose = TRUE
|
||||
# )
|
||||
|
||||
|
||||
# -- Internal helpers ----------------------------------------------------------
|
||||
|
||||
#' Check internet connectivity
|
||||
#'
|
||||
#' @return Logical; TRUE if an internet connection is available.
|
||||
.has_internet <- function() {
|
||||
tryCatch({
|
||||
con <- url("https://api.github.com", open = "r")
|
||||
close(con)
|
||||
TRUE
|
||||
}, error = function(e) FALSE)
|
||||
}
|
||||
|
||||
|
||||
#' Fetch the latest release version from a GitHub repository
|
||||
#'
|
||||
#' @param github_user GitHub username or organisation.
|
||||
#' @param github_repo Repository name.
|
||||
#'
|
||||
#' @return A character string with the version tag (e.g. "1.2.0"), or NULL on
|
||||
#' failure.
|
||||
.get_latest_github_version <- function(github_user, github_repo) {
|
||||
api_url <- sprintf(
|
||||
"https://api.github.com/repos/%s/%s/releases/latest",
|
||||
github_user,
|
||||
github_repo
|
||||
)
|
||||
|
||||
tryCatch({
|
||||
response <- readLines(url(api_url), warn = FALSE)
|
||||
json_text <- paste(response, collapse = "")
|
||||
|
||||
tag <- regmatches(
|
||||
json_text,
|
||||
regexpr('"tag_name"\\s*:\\s*"([^"]+)"', json_text)
|
||||
)
|
||||
|
||||
if (length(tag) == 0 || nchar(tag) == 0) return(NULL)
|
||||
|
||||
# Strip a leading "v" if present (e.g. "v1.2.0" -> "1.2.0")
|
||||
sub('^"tag_name"\\s*:\\s*"v?([^"]+)"$', "\\1", tag)
|
||||
}, error = function(e) NULL)
|
||||
}
|
||||
|
||||
|
||||
#' Resolve the current app version
|
||||
#'
|
||||
#' Tries two strategies in order:
|
||||
#' \enumerate{
|
||||
#' \item \code{utils::packageVersion(package_name)} -- works when the package
|
||||
#' is installed locally (development, local \code{runApp()}).
|
||||
#' \item \code{app_version} argument -- an explicit version string supplied by
|
||||
#' the caller, e.g. from an \code{app_version()} function bundled with the
|
||||
#' app. Used on shinyapps.io where the package is not installed.
|
||||
#' }
|
||||
#'
|
||||
#' @param package_name Name of the package / repository.
|
||||
#' @param app_version Optional fallback version string.
|
||||
#'
|
||||
#' @return A character string with the version (e.g. "1.1.0"), or NULL if
|
||||
#' neither strategy succeeds.
|
||||
.resolve_app_version <- function(package_name, app_version = NULL) {
|
||||
|
||||
# Strategy 1: installed package
|
||||
v <- tryCatch(
|
||||
as.character(utils::packageVersion(package_name)),
|
||||
error = function(e) NULL
|
||||
)
|
||||
if (!is.null(v)) {
|
||||
message("[version_check] Version source: installed package")
|
||||
return(v)
|
||||
}
|
||||
|
||||
# Strategy 2: explicit fallback supplied by the caller
|
||||
if (!is.null(app_version)) {
|
||||
message("[version_check] Version source: app_version() fallback")
|
||||
return(as.character(app_version))
|
||||
}
|
||||
|
||||
NULL
|
||||
}
|
||||
|
||||
|
||||
#' Build a shinyWidgets::alert() UI element for the version banner
|
||||
#'
|
||||
#' @param current Current installed version string.
|
||||
#' @param latest Latest GitHub release version string, or NULL when
|
||||
#' the check could not complete (e.g. no internet).
|
||||
#' @param update_available Logical; whether latest > current.
|
||||
#' @param github_user GitHub username / organisation.
|
||||
#' @param github_repo Repository name.
|
||||
#'
|
||||
#' @return A \code{shinyWidgets::alert()} UI element.
|
||||
.build_version_alert <- function(current,
|
||||
latest,
|
||||
update_available,
|
||||
github_user,
|
||||
github_repo) {
|
||||
|
||||
repo_url <- sprintf(
|
||||
"https://github.com/%s/%s/releases/latest",
|
||||
github_user,
|
||||
github_repo
|
||||
)
|
||||
|
||||
if (is.null(latest)) {
|
||||
# Version check could not complete (no internet or API failure)
|
||||
return(
|
||||
shinyWidgets::alert(
|
||||
tags$b("Version check failed. "),
|
||||
sprintf(
|
||||
"Running version %s. Could not reach GitHub to check for updates.",
|
||||
current
|
||||
),
|
||||
status = "warning",
|
||||
dismissible = TRUE
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
if (update_available) {
|
||||
shinyWidgets::alert(
|
||||
tags$b("Update available! "),
|
||||
sprintf(
|
||||
"You are running version %s. Version %s is available on GitHub.",
|
||||
current, latest
|
||||
),
|
||||
" ",
|
||||
tags$a(href = repo_url, target = "_blank", "View release"),
|
||||
status = "warning",
|
||||
dismissible = TRUE
|
||||
)
|
||||
} else {
|
||||
# Up to date -- only shown in verbose mode
|
||||
shinyWidgets::alert(
|
||||
tags$b("Up to date. "),
|
||||
sprintf(
|
||||
"You are running version %s, which matches the latest release (%s).",
|
||||
current, latest
|
||||
),
|
||||
status = "success",
|
||||
dismissible = TRUE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# -- Public API ----------------------------------------------------------------
|
||||
|
||||
#' Run a startup version check and return a banner UI element
|
||||
#'
|
||||
#' Call this \strong{outside} \code{server()} -- typically in
|
||||
#' \code{global.R} or at the top of \code{app.R} -- and embed the returned
|
||||
#' value directly in your UI definition. Because the check runs at startup
|
||||
#' the banner is present on first render with no loading delay, and no
|
||||
#' \code{uiOutput()} / \code{renderUI()} wiring is needed.
|
||||
#'
|
||||
#' \strong{Normal mode} (\code{verbose = FALSE}): returns a banner only when
|
||||
#' a newer version is available or when the check fails. Returns \code{NULL}
|
||||
#' when the app is up to date (Shiny silently ignores \code{NULL} in the UI).
|
||||
#'
|
||||
#' \strong{Verbose / debug mode} (\code{verbose = TRUE}): always returns a
|
||||
#' banner -- including a success banner when up to date -- so you can confirm
|
||||
#' the check ran and inspect both version strings during development.
|
||||
#'
|
||||
#' @param github_user GitHub username or organisation that owns the repository.
|
||||
#' @param github_repo Repository name. Also used as the package name for
|
||||
#' \code{utils::packageVersion()}.
|
||||
#' @param app_version Optional fallback version string for environments where
|
||||
#' the package is not installed (e.g. shinyapps.io). Pass the result of your
|
||||
#' \code{app_version()} function here. Ignored when \code{packageVersion()}
|
||||
#' succeeds.
|
||||
#' @param verbose Logical; if \code{TRUE} a banner is always returned.
|
||||
#' Defaults to \code{FALSE}.
|
||||
#'
|
||||
#' @return A \code{shinyWidgets::alert()} UI element, or \code{NULL} when there
|
||||
#' is nothing to show (up to date in non-verbose mode).
|
||||
#'
|
||||
#' @examples
|
||||
#' \dontrun{
|
||||
#' # global.R or top of app.R
|
||||
#' source("version_check.R")
|
||||
#' version_banner <- check_app_version(
|
||||
#' github_user = "my-org",
|
||||
#' github_repo = "my-shiny-app",
|
||||
#' app_version = app_version() # fallback for shinyapps.io
|
||||
#' )
|
||||
#'
|
||||
#' # ui.R
|
||||
#' fluidPage(
|
||||
#' version_banner,
|
||||
#' # ... rest of UI
|
||||
#' )
|
||||
#'
|
||||
#' # Verbose mode for development
|
||||
#' version_banner <- check_app_version(
|
||||
#' github_user = "my-org",
|
||||
#' github_repo = "my-shiny-app",
|
||||
#' app_version = app_version(),
|
||||
#' verbose = TRUE
|
||||
#' )
|
||||
#' }
|
||||
check_app_version <- function(github_user,
|
||||
github_repo,
|
||||
app_version = NULL,
|
||||
verbose = FALSE) {
|
||||
|
||||
# -- 1. Resolve current version ----------------------------------------------
|
||||
local_version <- .resolve_app_version(github_repo, app_version)
|
||||
if (is.null(local_version)) {
|
||||
message(sprintf(
|
||||
"[version_check] Could not determine version for '%s' (package not installed and no app_version() fallback supplied).",
|
||||
github_repo
|
||||
))
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
message(sprintf("[version_check] Current version: %s", local_version))
|
||||
|
||||
# -- 2. Internet check -------------------------------------------------------
|
||||
if (!.has_internet()) {
|
||||
message("[version_check] No internet connection detected -- skipping.")
|
||||
|
||||
if (verbose) {
|
||||
return(.build_version_alert(
|
||||
current = local_version,
|
||||
latest = NULL,
|
||||
update_available = FALSE,
|
||||
github_user = github_user,
|
||||
github_repo = github_repo
|
||||
))
|
||||
}
|
||||
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
# -- 3. Fetch latest GitHub release ------------------------------------------
|
||||
latest_version <- .get_latest_github_version(github_user, github_repo)
|
||||
if (is.null(latest_version)) {
|
||||
message("[version_check] Could not retrieve latest version from GitHub.")
|
||||
|
||||
if (verbose) {
|
||||
return(.build_version_alert(
|
||||
current = local_version,
|
||||
latest = NULL,
|
||||
update_available = FALSE,
|
||||
github_user = github_user,
|
||||
github_repo = github_repo
|
||||
))
|
||||
}
|
||||
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
message(sprintf("[version_check] Latest GitHub release: %s", latest_version))
|
||||
|
||||
# -- 4. Compare versions -----------------------------------------------------
|
||||
update_available <- numeric_version(latest_version) > numeric_version(local_version)
|
||||
|
||||
if (update_available) {
|
||||
message(sprintf(
|
||||
"[version_check] Update available: %s -> %s",
|
||||
local_version, latest_version
|
||||
))
|
||||
} else {
|
||||
message(sprintf("[version_check] App is up to date (%s).", local_version))
|
||||
}
|
||||
|
||||
# -- 5. Return banner --------------------------------------------------------
|
||||
# An update was found -> always return a warning banner
|
||||
# Up to date + verbose -> return a success banner
|
||||
# Up to date + not verbose -> return NULL (Shiny ignores NULL in the UI)
|
||||
if (update_available || verbose) {
|
||||
.build_version_alert(
|
||||
current = local_version,
|
||||
latest = latest_version,
|
||||
update_available = update_available,
|
||||
github_user = github_user,
|
||||
github_repo = github_repo
|
||||
)
|
||||
} else {
|
||||
NULL
|
||||
}
|
||||
}
|
||||
87
README.md
87
README.md
|
|
@ -1,10 +1,9 @@
|
|||
# FreesearchR <a href="https://agdamsbo.github.io/FreesearchR/"><img src="man/figures/logo.png" align="right" height="70" alt="FreesearchR website" /></a>
|
||||
# FreesearchR <a href="https://agdamsbo.github.io/FreesearchR/"><img src="man/figures/logo.png" alt="FreesearchR website" align="right" height="70"/></a>
|
||||
|
||||
<!-- badges: start -->
|
||||
[](https://lifecycle.r-lib.org/articles/stages.html#experimental)
|
||||
[](https://doi.org/10.5281/zenodo.14527429)
|
||||
[](https://github.com/agdamsbo/FreesearchR/actions/workflows/rhub.yaml)
|
||||
[](https://agdamsbo.shinyapps.io/FreesearchR/)
|
||||
|
||||
[](https://lifecycle.r-lib.org/articles/stages.html#experimental) [](https://doi.org/10.5281/zenodo.14527429) [](https://github.com/agdamsbo/FreesearchR/actions/workflows/rhub.yaml) [](https://agdamsbo.shinyapps.io/FreesearchR/)
|
||||
|
||||
<!-- badges: end -->
|
||||
|
||||
The [***FreesearchR***](https://app.freesearchr.org) is a simple, clinical health data exploration and analysis tool to democratise clinical research by assisting any researcher to easily evaluate and analyse data and export publication ready results.
|
||||
|
|
@ -19,51 +18,77 @@ All feedback is welcome and can be shared as a GitHub issue. Any suggestions on
|
|||
|
||||
This app has the following simple goals:
|
||||
|
||||
1. help the health clinician getting an overview of data in quality improvement projects and clinical research
|
||||
1. help the health clinician getting an overview of data in quality improvement projects and clinical research
|
||||
|
||||
1. help learners get a good start analysing data and coding in *R*
|
||||
2. help learners get a good start analysing data and coding in *R*
|
||||
|
||||
1. ease quick data overview and basic visualisations for any clinical researcher
|
||||
3. ease quick data overview and basic visualisations for any clinical researcher
|
||||
|
||||
## Run locally on your own machine
|
||||
Here’s a polished and restructured version of your README section for clarity, conciseness, and user-friendliness:
|
||||
|
||||
The ***FreesearchR*** app can also run on your own machine with no data transmitted anywhere. Blow are the available options.
|
||||
## Run Locally on Your Own Machine
|
||||
|
||||
### Run from R (or RStduio)
|
||||
The **FreesearchR** app can be run locally on your machine, ensuring no data is transmitted externally. Below are the available options for setup and configuration.
|
||||
|
||||
Working with data in R, FreesearchR is a quick and easy tool to get overview and perform the first explorative analyses to get you going.
|
||||
### Configuration & Data Loading
|
||||
|
||||
Any data available in the your R session will be available to the FreesearchR app. Just follow the below steps to get going:
|
||||
The app can be configured either by passing a named list to `run_app()` or by setting environment variables in a **Docker Compose** file. The following variables control data access and display behavior. If no values are provided, the app will use the defaults listed below.
|
||||
|
||||
1. **Requirement:** You need to have [*R* installed](https://www.r-project.org/) and possibly an editor like [RStudio](https://posit.co/download/rstudio-desktop/).
|
||||
**Configuration Variables**
|
||||
|
||||
1. Then open the *R* console and copy/paste the following code, that will install the `{devtools}` package and then the `{FreesearchR}` *R*-package with its dependencies:
|
||||
| Variable | Description | Default |
|
||||
|--------------|--------------------------------------------|--------------|
|
||||
| `INCLUDE_GLOBALENV` | Load datasets already present in the global R environment into the app | `FALSE` |
|
||||
| `DATA_LIMIT_DEFAULT` | Default number of observations for previewing or working with a dataset | `10,000` |
|
||||
| `DATA_LIMIT_UPPER` | Maximum number of observations a user can set for the upper limit. If set to 0, no uppper limit is applied. | `100,000` |
|
||||
| `DATA_LIMIT_LOWER` | Minimum number of observations a user can set for the lower limit | `1` |
|
||||
| `CHECK_APP_VERSION` | Always print version check results. Checks app version against latest release on GitHub. | `FALSE` |
|
||||
|
||||
```
|
||||
require("devtools")
|
||||
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)
|
||||
launch_FreesearchR()
|
||||
```
|
||||
### Run from R (or RStudio)
|
||||
|
||||
### Running with docker compose
|
||||
If you're working with data in R, **FreesearchR** is a quick and easy tool for exploratory analysis.
|
||||
|
||||
For advanced users, wanting to deploy the FreesearchR app to run anywhere, a docker image is available.
|
||||
1. **Requirement:** Ensure you have [R](https://www.r-project.org/) installed, and optionally an editor like [RStudio](https://posit.co/download/rstudio-desktop/).
|
||||
|
||||
Below is the minimal `docker_compose.yml` file:
|
||||
2. Open the **R console** and run the following code to install the `{FreesearchR}` package and launch the app:
|
||||
|
||||
```
|
||||
``` r
|
||||
if (!require("devtools")) install.packages("devtools")
|
||||
devtools::install_github("agdamsbo/FreesearchR")
|
||||
library(FreesearchR)
|
||||
# Load sample data (e.g., mtcars) to make it available in the app
|
||||
data(mtcars)
|
||||
launch_FreesearchR(INCLUDE_GLOBALENV=TRUE,CHECK_APP_VERSION=TRUE)
|
||||
```
|
||||
|
||||
All the variables specified above can also be passed to the app on launch from R. Set DATA_LIMIT_UPPER=0 to remove upper data limit. This limit is set to protect the online app version from choking and crashing on large data sets.
|
||||
|
||||
### Running with Docker Compose
|
||||
|
||||
For advanced users, you can deploy **FreesearchR** using Docker. A data folder can be mounted to `/app/data` to automatically load supported file types (`.csv`, `.tsv`, `.txt`, `.xls`, `.xlsx`, `.ods`, `.dta`, `.rds`) at startup.
|
||||
|
||||
To mount a local data folder, add a `volumes` entry to your `docker-compose.yml` file:
|
||||
|
||||
``` yaml
|
||||
services:
|
||||
freesearchr:
|
||||
image: ghcr.io/agdamsbo/freesearchr:latest
|
||||
ports:
|
||||
shiny:
|
||||
image: ghcr.io/agdamsbo/freesearchr:latest
|
||||
volumes:
|
||||
- ./data:/app/data:ro
|
||||
environment:
|
||||
- INCLUDE_GLOBALENV=FALSE
|
||||
- DATA_LIMIT_DEFAULT=10000
|
||||
- DATA_LIMIT_UPPER=100000
|
||||
- DATA_LIMIT_LOWER=1
|
||||
ports:
|
||||
- '3838:3838'
|
||||
restart: on-failure
|
||||
```
|
||||
|
||||
- The `:ro` flag mounts the folder as **read-only**, preventing the app from modifying your original data files.
|
||||
|
||||
- If no volume is mounted, the app will start without any preloaded datasets.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
Please note that the ***FreesearchR*** project is published 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.
|
||||
|
|
|
|||
95
SESSION.md
95
SESSION.md
|
|
@ -1,21 +1,21 @@
|
|||
--------------------------------------------------------------------------------
|
||||
-------------------------------- R environment ---------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
|setting |value |
|
||||
|:-----------|:------------------------------------------|
|
||||
|version |R version 4.5.2 (2025-10-31) |
|
||||
|os |macOS Tahoe 26.3 |
|
||||
|system |aarch64, darwin20 |
|
||||
|ui |RStudio |
|
||||
|language |(EN) |
|
||||
|collate |en_US.UTF-8 |
|
||||
|ctype |en_US.UTF-8 |
|
||||
|tz |Europe/Copenhagen |
|
||||
|date |2026-03-11 |
|
||||
|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.3.2.260311 |
|
||||
|setting |value |
|
||||
|:-----------|:--------------------------------------------------------------------------------------------------|
|
||||
|version |R version 4.5.2 (2025-10-31) |
|
||||
|os |macOS Tahoe 26.5 |
|
||||
|system |aarch64, darwin20 |
|
||||
|ui |RStudio |
|
||||
|language |(EN) |
|
||||
|collate |en_US.UTF-8 |
|
||||
|ctype |en_US.UTF-8 |
|
||||
|tz |Europe/Copenhagen |
|
||||
|date |2026-06-01 |
|
||||
|rstudio |2026.04.0+526 Globemaster Allium (desktop) |
|
||||
|pandoc |3.8.3 @ /Applications/RStudio.app/Contents/Resources/app/quarto/bin/tools/aarch64/ (via rmarkdown) |
|
||||
|quarto |1.9.37 @ /usr/local/bin/quarto |
|
||||
|FreesearchR |26.6.1.260601 |
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
|
@ -34,7 +34,7 @@
|
|||
|bit |4.6.0 |2025-03-06 |CRAN (R 4.5.0) |
|
||||
|bit64 |4.6.0-1 |2025-01-16 |CRAN (R 4.5.0) |
|
||||
|bitops |1.0-9 |2024-10-03 |CRAN (R 4.5.0) |
|
||||
|boot |1.3-32 |2025-08-29 |CRAN (R 4.5.2) |
|
||||
|boot |1.3-32 |2025-08-29 |CRAN (R 4.5.0) |
|
||||
|brio |1.1.5 |2024-04-24 |CRAN (R 4.5.0) |
|
||||
|broom |1.0.12 |2026-01-27 |CRAN (R 4.5.2) |
|
||||
|broom.helpers |1.22.0 |2025-09-17 |CRAN (R 4.5.0) |
|
||||
|
|
@ -48,16 +48,14 @@
|
|||
|cellranger |1.1.0 |2016-07-27 |CRAN (R 4.5.0) |
|
||||
|cffr |1.2.1 |2026-01-12 |CRAN (R 4.5.2) |
|
||||
|checkmate |2.3.4 |2026-02-03 |CRAN (R 4.5.2) |
|
||||
|class |7.3-23 |2025-01-01 |CRAN (R 4.5.2) |
|
||||
|class |7.3-23 |2025-01-01 |CRAN (R 4.5.0) |
|
||||
|classInt |0.4-11 |2025-01-08 |CRAN (R 4.5.0) |
|
||||
|cli |3.6.5 |2025-04-23 |CRAN (R 4.5.0) |
|
||||
|cluster |2.1.8.2 |2026-02-05 |CRAN (R 4.5.2) |
|
||||
|codetools |0.2-20 |2024-03-31 |CRAN (R 4.5.2) |
|
||||
|codetools |0.2-20 |2024-03-31 |CRAN (R 4.5.0) |
|
||||
|colorspace |2.1-2 |2025-09-22 |CRAN (R 4.5.0) |
|
||||
|commonmark |2.0.0 |2025-07-07 |CRAN (R 4.5.0) |
|
||||
|crayon |1.5.3 |2024-06-20 |CRAN (R 4.5.0) |
|
||||
|credentials |2.0.3 |2025-09-12 |CRAN (R 4.5.0) |
|
||||
|curl |7.0.0 |2025-08-19 |CRAN (R 4.5.0) |
|
||||
|data.table |1.18.2.1 |2026-01-27 |CRAN (R 4.5.2) |
|
||||
|datamods |1.5.3 |2024-10-02 |CRAN (R 4.5.0) |
|
||||
|datawizard |1.3.0 |2025-10-11 |CRAN (R 4.5.0) |
|
||||
|
|
@ -87,22 +85,19 @@
|
|||
|fontquiver |0.2.1 |2017-02-01 |CRAN (R 4.5.0) |
|
||||
|forcats |1.0.1 |2025-09-25 |CRAN (R 4.5.0) |
|
||||
|foreach |1.5.2 |2022-02-02 |CRAN (R 4.5.0) |
|
||||
|foreign |0.8-90 |2025-03-31 |CRAN (R 4.5.2) |
|
||||
|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.3.2 |NA |NA |
|
||||
|fs |1.6.6 |2025-04-12 |CRAN (R 4.5.0) |
|
||||
|FreesearchR |26.6.1 |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) |
|
||||
|gert |2.3.1 |2026-01-11 |CRAN (R 4.5.2) |
|
||||
|ggalluvial |0.12.5 |2023-02-22 |CRAN (R 4.5.0) |
|
||||
|ggalluvial |0.12.6 |2026-02-22 |CRAN (R 4.5.2) |
|
||||
|ggcorrplot |0.1.4.1 |2023-09-05 |CRAN (R 4.5.0) |
|
||||
|ggforce |0.5.0 |2025-06-18 |CRAN (R 4.5.0) |
|
||||
|ggplot2 |4.0.2 |2026-02-03 |CRAN (R 4.5.2) |
|
||||
|ggridges |0.5.7 |2025-08-27 |CRAN (R 4.5.0) |
|
||||
|ggstats |0.12.0 |2025-12-22 |CRAN (R 4.5.2) |
|
||||
|gh |1.5.0 |2025-05-26 |CRAN (R 4.5.0) |
|
||||
|gitcreds |0.1.2 |2022-09-08 |CRAN (R 4.5.0) |
|
||||
|glue |1.8.0 |2024-09-30 |CRAN (R 4.5.0) |
|
||||
|ggstats |0.13.0 |2026-03-06 |CRAN (R 4.5.2) |
|
||||
|glue |1.8.0 |2024-09-30 |CRAN (R 4.5.2) |
|
||||
|gridExtra |2.3 |2017-09-09 |CRAN (R 4.5.0) |
|
||||
|gt |1.3.0 |2026-01-22 |CRAN (R 4.5.2) |
|
||||
|gtable |0.3.6 |2024-10-25 |CRAN (R 4.5.0) |
|
||||
|
|
@ -115,38 +110,36 @@
|
|||
|htmltools |0.5.9 |2025-12-04 |CRAN (R 4.5.2) |
|
||||
|htmlwidgets |1.6.4 |2023-12-06 |CRAN (R 4.5.0) |
|
||||
|httpuv |1.6.16 |2025-04-16 |CRAN (R 4.5.0) |
|
||||
|httr2 |1.2.2 |2025-12-08 |CRAN (R 4.5.2) |
|
||||
|IDEAFilter |0.2.1 |2025-07-29 |CRAN (R 4.5.0) |
|
||||
|insight |1.4.6 |2026-02-04 |CRAN (R 4.5.2) |
|
||||
|iterators |1.0.14 |2022-02-05 |CRAN (R 4.5.0) |
|
||||
|jquerylib |0.1.4 |2021-04-26 |CRAN (R 4.5.0) |
|
||||
|jsonlite |2.0.0 |2025-03-27 |CRAN (R 4.5.0) |
|
||||
|jsonvalidate |1.5.0 |2025-02-07 |CRAN (R 4.5.0) |
|
||||
|KernSmooth |2.23-26 |2025-01-01 |CRAN (R 4.5.2) |
|
||||
|KernSmooth |2.23-26 |2025-01-01 |CRAN (R 4.5.0) |
|
||||
|keyring |1.4.1 |2025-06-15 |CRAN (R 4.5.0) |
|
||||
|knitr |1.51 |2025-12-20 |CRAN (R 4.5.2) |
|
||||
|later |1.4.6 |2026-02-13 |CRAN (R 4.5.2) |
|
||||
|labeling |0.4.3 |2023-08-29 |CRAN (R 4.5.0) |
|
||||
|later |1.4.8 |2026-03-05 |CRAN (R 4.5.2) |
|
||||
|lattice |0.22-7 |2025-04-02 |CRAN (R 4.5.2) |
|
||||
|lifecycle |1.0.5 |2026-01-08 |CRAN (R 4.5.2) |
|
||||
|litedown |0.9 |2025-12-18 |CRAN (R 4.5.2) |
|
||||
|lme4 |1.1-38 |2025-12-02 |CRAN (R 4.5.2) |
|
||||
|lme4 |2.0-1 |2026-03-05 |CRAN (R 4.5.2) |
|
||||
|lubridate |1.9.5 |2026-02-04 |CRAN (R 4.5.2) |
|
||||
|magrittr |2.0.4 |2025-09-12 |CRAN (R 4.5.0) |
|
||||
|markdown |2.0 |2025-03-23 |CRAN (R 4.5.0) |
|
||||
|MASS |7.3-65 |2025-02-28 |CRAN (R 4.5.0) |
|
||||
|Matrix |1.7-4 |2025-08-28 |CRAN (R 4.5.2) |
|
||||
|Matrix |1.7-4 |2025-08-28 |CRAN (R 4.5.0) |
|
||||
|memoise |2.0.1 |2021-11-26 |CRAN (R 4.5.0) |
|
||||
|mgcv |1.9-4 |2025-11-07 |CRAN (R 4.5.0) |
|
||||
|mime |0.13 |2025-03-17 |CRAN (R 4.5.0) |
|
||||
|minqa |1.2.8 |2024-08-17 |CRAN (R 4.5.0) |
|
||||
|mvtnorm |1.3-3 |2025-01-10 |CRAN (R 4.5.0) |
|
||||
|mvtnorm |1.3-2 |2024-11-04 |CRAN (R 4.5.2) |
|
||||
|NHANES |2.1.0 |2015-07-02 |CRAN (R 4.5.0) |
|
||||
|nlme |3.1-168 |2025-03-31 |CRAN (R 4.5.2) |
|
||||
|nlme |3.1-168 |2025-03-31 |CRAN (R 4.5.0) |
|
||||
|nloptr |2.2.1 |2025-03-17 |CRAN (R 4.5.0) |
|
||||
|nnet |7.3-20 |2025-01-01 |CRAN (R 4.5.2) |
|
||||
|nnet |7.3-20 |2025-01-01 |CRAN (R 4.5.0) |
|
||||
|officer |0.7.3 |2026-01-16 |CRAN (R 4.5.2) |
|
||||
|opdisDownsampling |1.0.1 |2024-04-15 |CRAN (R 4.5.0) |
|
||||
|openssl |2.3.4 |2025-09-30 |CRAN (R 4.5.0) |
|
||||
|openxlsx2 |1.23.1 |2026-01-19 |CRAN (R 4.5.2) |
|
||||
|openssl |2.3.5 |2026-02-26 |CRAN (R 4.5.2) |
|
||||
|openxlsx2 |1.25 |2026-03-07 |CRAN (R 4.5.2) |
|
||||
|otel |0.2.0 |2025-08-29 |CRAN (R 4.5.0) |
|
||||
|pak |0.9.2 |2025-12-22 |CRAN (R 4.5.2) |
|
||||
|parameters |0.28.3 |2025-11-25 |CRAN (R 4.5.2) |
|
||||
|
|
@ -160,6 +153,7 @@
|
|||
|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) |
|
||||
|
|
@ -170,9 +164,8 @@
|
|||
|qqplotr |0.0.7 |2025-09-05 |CRAN (R 4.5.0) |
|
||||
|quarto |1.5.1 |2025-09-04 |CRAN (R 4.5.0) |
|
||||
|R6 |2.6.1 |2025-02-15 |CRAN (R 4.5.0) |
|
||||
|ragg |1.5.0 |2025-09-02 |CRAN (R 4.5.0) |
|
||||
|ragg |1.5.1 |2026-03-06 |CRAN (R 4.5.2) |
|
||||
|rankinPlot |1.1.0 |2023-01-30 |CRAN (R 4.5.0) |
|
||||
|rappdirs |0.3.4 |2026-01-17 |CRAN (R 4.5.2) |
|
||||
|rbibutils |2.4.1 |2026-01-21 |CRAN (R 4.5.2) |
|
||||
|RColorBrewer |1.1-3 |2022-04-03 |CRAN (R 4.5.0) |
|
||||
|Rcpp |1.1.1 |2026-01-10 |CRAN (R 4.5.2) |
|
||||
|
|
@ -187,14 +180,14 @@
|
|||
|reformulas |0.4.4 |2026-02-02 |CRAN (R 4.5.2) |
|
||||
|remotes |2.5.0 |2024-03-17 |CRAN (R 4.5.0) |
|
||||
|rempsyc |0.2.0 |2025-09-15 |CRAN (R 4.5.0) |
|
||||
|renv |1.1.7 |2026-01-27 |CRAN (R 4.5.2) |
|
||||
|renv |1.1.8 |2026-03-05 |CRAN (R 4.5.2) |
|
||||
|reshape2 |1.4.5 |2025-11-12 |CRAN (R 4.5.0) |
|
||||
|rio |1.2.4 |2025-09-26 |CRAN (R 4.5.0) |
|
||||
|rlang |1.1.7 |2026-01-09 |CRAN (R 4.5.2) |
|
||||
|rmarkdown |2.30 |2025-09-28 |CRAN (R 4.5.0) |
|
||||
|robustbase |0.99-7 |2026-02-05 |CRAN (R 4.5.2) |
|
||||
|roxygen2 |7.3.3 |2025-09-03 |CRAN (R 4.5.0) |
|
||||
|rpart |4.1.24 |2025-01-07 |CRAN (R 4.5.2) |
|
||||
|rpart |4.1.24 |2025-01-07 |CRAN (R 4.5.0) |
|
||||
|rprojroot |2.1.1 |2025-08-26 |CRAN (R 4.5.0) |
|
||||
|rsconnect |1.7.0 |2025-12-06 |CRAN (R 4.5.2) |
|
||||
|rstudioapi |0.18.0 |2026-01-16 |CRAN (R 4.5.2) |
|
||||
|
|
@ -209,15 +202,14 @@
|
|||
|shinybusy |0.3.3 |2024-03-09 |CRAN (R 4.5.0) |
|
||||
|shinyjs |2.1.1 |2026-01-15 |CRAN (R 4.5.2) |
|
||||
|shinyTime |1.0.3 |2022-08-19 |CRAN (R 4.5.0) |
|
||||
|shinyWidgets |0.9.0 |2025-02-21 |CRAN (R 4.5.0) |
|
||||
|shinyWidgets |0.9.1 |2026-03-09 |CRAN (R 4.5.2) |
|
||||
|smd |0.8.0 |2025-02-12 |CRAN (R 4.5.0) |
|
||||
|stringi |1.8.7 |2025-03-27 |CRAN (R 4.5.0) |
|
||||
|stringr |1.6.0 |2025-11-04 |CRAN (R 4.5.0) |
|
||||
|stRoke |25.9.2 |2025-09-30 |CRAN (R 4.5.0) |
|
||||
|sys |3.4.3 |2024-10-04 |CRAN (R 4.5.0) |
|
||||
|systemfonts |1.3.1 |2025-10-01 |CRAN (R 4.5.0) |
|
||||
|systemfonts |1.3.2 |2026-03-05 |CRAN (R 4.5.2) |
|
||||
|testthat |3.3.2 |2026-01-11 |CRAN (R 4.5.2) |
|
||||
|textshaping |1.0.4 |2025-10-10 |CRAN (R 4.5.0) |
|
||||
|textshaping |1.0.5 |2026-03-06 |CRAN (R 4.5.2) |
|
||||
|thematic |0.1.8 |2025-09-29 |CRAN (R 4.5.0) |
|
||||
|tibble |3.3.1 |2026-01-11 |CRAN (R 4.5.2) |
|
||||
|tidyr |1.3.2 |2025-12-19 |CRAN (R 4.5.2) |
|
||||
|
|
@ -229,7 +221,6 @@
|
|||
|tzdb |0.5.0 |2025-03-15 |CRAN (R 4.5.0) |
|
||||
|usethis |3.2.1 |2025-09-06 |CRAN (R 4.5.0) |
|
||||
|uuid |1.2-2 |2026-01-23 |CRAN (R 4.5.2) |
|
||||
|V8 |8.0.1 |2025-10-10 |CRAN (R 4.5.0) |
|
||||
|vctrs |0.7.1 |2026-01-23 |CRAN (R 4.5.2) |
|
||||
|viridis |0.6.5 |2024-01-29 |CRAN (R 4.5.0) |
|
||||
|viridisLite |0.4.3 |2026-02-04 |CRAN (R 4.5.2) |
|
||||
|
|
@ -238,7 +229,7 @@
|
|||
|writexl |1.5.4 |2025-04-15 |CRAN (R 4.5.0) |
|
||||
|xfun |0.56 |2026-01-18 |CRAN (R 4.5.2) |
|
||||
|xml2 |1.5.2 |2026-01-17 |CRAN (R 4.5.2) |
|
||||
|xtable |1.8-4 |2019-04-21 |CRAN (R 4.5.0) |
|
||||
|xtable |1.8-8 |2026-02-22 |CRAN (R 4.5.2) |
|
||||
|yaml |2.3.12 |2025-12-10 |CRAN (R 4.5.2) |
|
||||
|yesno |0.1.3 |2024-07-26 |CRAN (R 4.5.0) |
|
||||
|zip |2.3.3 |2025-05-13 |CRAN (R 4.5.0) |
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
FROM rocker/tidyverse:4.5.2
|
||||
RUN apt-get update -y && apt-get install -y cmake make libcurl4-openssl-dev libicu-dev libssl-dev pandoc zlib1g-dev libsecret-1-dev libxml2-dev libx11-dev libcairo2-dev libfontconfig1-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev libjpeg-dev libpng-dev libtiff-dev libwebp-dev libfftw3-dev && rm -rf /var/lib/apt/lists/*
|
||||
RUN apt-get update -y && apt-get install -y cmake make libcurl4-openssl-dev libicu-dev libuv1-dev libssl-dev pandoc zlib1g-dev libsecret-1-dev libxml2-dev libx11-dev libcairo2-dev libfontconfig1-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev libjpeg-dev libpng-dev libtiff-dev libwebp-dev libfftw3-dev && rm -rf /var/lib/apt/lists/*
|
||||
RUN mkdir -p /usr/local/lib/R/etc/ /usr/lib/R/etc/
|
||||
RUN echo "options(renv.config.pak.enabled = FALSE, repos = c(CRAN = 'https://cran.rstudio.com/'), download.file.method = 'libcurl', Ncpus = 4)" | tee /usr/local/lib/R/etc/Rprofile.site | tee /usr/lib/R/etc/Rprofile.site
|
||||
RUN R -e 'install.packages("remotes")'
|
||||
RUN R -e 'remotes::install_version("renv", version = "1.1.7")'
|
||||
RUN R -e 'remotes::install_version("renv", version = "1.1.8")'
|
||||
COPY renv.lock renv.lock
|
||||
RUN --mount=type=cache,id=renv-cache,target=/root/.cache/R/renv R -e 'renv::restore()'
|
||||
WORKDIR /srv/shiny-server/
|
||||
|
|
|
|||
4584
app_docker/app.R
4584
app_docker/app.R
File diff suppressed because it is too large
Load diff
|
|
@ -2761,7 +2761,7 @@
|
|||
},
|
||||
"effectsize": {
|
||||
"Package": "effectsize",
|
||||
"Version": "1.0.1",
|
||||
"Version": "1.0.2",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Indices of Effect Size",
|
||||
|
|
@ -2775,11 +2775,11 @@
|
|||
"R (>= 4.0)"
|
||||
],
|
||||
"Imports": [
|
||||
"bayestestR (>= 0.16.0)",
|
||||
"insight (>= 1.3.0)",
|
||||
"parameters (>= 0.26.0)",
|
||||
"performance (>= 0.14.0)",
|
||||
"datawizard (>= 1.1.0)",
|
||||
"bayestestR (>= 0.17.0)",
|
||||
"insight (>= 1.4.5)",
|
||||
"parameters (>= 0.28.3)",
|
||||
"performance (>= 0.15.3)",
|
||||
"datawizard (>= 1.3.0)",
|
||||
"stats",
|
||||
"utils"
|
||||
],
|
||||
|
|
@ -2809,7 +2809,7 @@
|
|||
"VignetteBuilder": "knitr",
|
||||
"Encoding": "UTF-8",
|
||||
"Language": "en-US",
|
||||
"RoxygenNote": "7.3.2",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"Config/testthat/edition": "3",
|
||||
"Config/testthat/parallel": "true",
|
||||
"Config/Needs/website": "rstudio/bslib, r-lib/pkgdown, easystats/easystatstemplate",
|
||||
|
|
@ -3405,10 +3405,10 @@
|
|||
},
|
||||
"foreign": {
|
||||
"Package": "foreign",
|
||||
"Version": "0.8-90",
|
||||
"Version": "0.8-91",
|
||||
"Source": "Repository",
|
||||
"Priority": "recommended",
|
||||
"Date": "2025-03-31",
|
||||
"Date": "2026-01-29",
|
||||
"Title": "Read Data Stored by 'Minitab', 'S', 'SAS', 'SPSS', 'Stata', 'Systat', 'Weka', 'dBase', ...",
|
||||
"Depends": [
|
||||
"R (>= 4.0.0)"
|
||||
|
|
@ -3429,22 +3429,22 @@
|
|||
"MailingList": "R-help@r-project.org",
|
||||
"URL": "https://svn.r-project.org/R-packages/trunk/foreign/",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "R Core Team [aut, cph, cre] (02zz1nj61), Roger Bivand [ctb, cph], Vincent J. Carey [ctb, cph], Saikat DebRoy [ctb, cph], Stephen Eglen [ctb, cph], Rajarshi Guha [ctb, cph], Swetlana Herbrandt [ctb], Nicholas Lewin-Koh [ctb, cph], Mark Myatt [ctb, cph], Michael Nelson [ctb], Ben Pfaff [ctb], Brian Quistorff [ctb], Frank Warmerdam [ctb, cph], Stephen Weigand [ctb, cph], Free Software Foundation, Inc. [cph]",
|
||||
"Author": "R Core Team [aut, cph, cre] (ROR: <https://ror.org/02zz1nj61>), Roger Bivand [ctb, cph], Vincent J. Carey [ctb, cph], Saikat DebRoy [ctb, cph], Stephen Eglen [ctb, cph], Rajarshi Guha [ctb, cph], Swetlana Herbrandt [ctb], Nicholas Lewin-Koh [ctb, cph], Mark Myatt [ctb, cph], Michael Nelson [ctb], Ben Pfaff [ctb], Brian Quistorff [ctb], Frank Warmerdam [ctb, cph], Stephen Weigand [ctb, cph], Free Software Foundation, Inc. [cph]",
|
||||
"Maintainer": "R Core Team <R-core@R-project.org>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
"fs": {
|
||||
"Package": "fs",
|
||||
"Version": "1.6.6",
|
||||
"Version": "1.6.7",
|
||||
"Source": "Repository",
|
||||
"Title": "Cross-Platform File System Operations Based on 'libuv'",
|
||||
"Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"libuv project contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Joyent, Inc. and other Node contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )",
|
||||
"Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Gábor\", \"Csárdi\", role = \"aut\"), person(\"Jeroen\", \"Ooms\", , \"jeroenooms@gmail.com\", role = \"cre\"), person(\"libuv project contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Joyent, Inc. and other Node contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )",
|
||||
"Description": "A cross-platform interface to file system operations, built on top of the 'libuv' C library.",
|
||||
"License": "MIT + file LICENSE",
|
||||
"URL": "https://fs.r-lib.org, https://github.com/r-lib/fs",
|
||||
"BugReports": "https://github.com/r-lib/fs/issues",
|
||||
"Depends": [
|
||||
"R (>= 3.6)"
|
||||
"R (>= 4.1)"
|
||||
],
|
||||
"Imports": [
|
||||
"methods"
|
||||
|
|
@ -3465,14 +3465,15 @@
|
|||
"ByteCompile": "true",
|
||||
"Config/Needs/website": "tidyverse/tidytemplate",
|
||||
"Config/testthat/edition": "3",
|
||||
"Config/usethis/last-upkeep": "2025-04-23",
|
||||
"Copyright": "file COPYRIGHTS",
|
||||
"Encoding": "UTF-8",
|
||||
"Language": "en-US",
|
||||
"RoxygenNote": "7.2.3",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"SystemRequirements": "GNU make",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "Jim Hester [aut], Hadley Wickham [aut], Gábor Csárdi [aut, cre], libuv project contributors [cph] (libuv library), Joyent, Inc. and other Node contributors [cph] (libuv library), Posit Software, PBC [cph, fnd]",
|
||||
"Maintainer": "Gábor Csárdi <csardi.gabor@gmail.com>",
|
||||
"Author": "Jim Hester [aut], Hadley Wickham [aut], Gábor Csárdi [aut], Jeroen Ooms [cre], libuv project contributors [cph] (libuv library), Joyent, Inc. and other Node contributors [cph] (libuv library), Posit Software, PBC [cph, fnd] (ROR: <https://ror.org/03wc8by49>)",
|
||||
"Maintainer": "Jeroen Ooms <jeroenooms@gmail.com>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
"gap": {
|
||||
|
|
@ -3642,7 +3643,7 @@
|
|||
},
|
||||
"ggalluvial": {
|
||||
"Package": "ggalluvial",
|
||||
"Version": "0.12.5",
|
||||
"Version": "0.12.6",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Alluvial Plots in 'ggplot2'",
|
||||
|
|
@ -3889,7 +3890,7 @@
|
|||
},
|
||||
"ggstats": {
|
||||
"Package": "ggstats",
|
||||
"Version": "0.12.0",
|
||||
"Version": "0.13.0",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Extension to 'ggplot2' for Plotting Stats",
|
||||
|
|
@ -4288,7 +4289,7 @@
|
|||
},
|
||||
"highr": {
|
||||
"Package": "highr",
|
||||
"Version": "0.11",
|
||||
"Version": "0.12",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Syntax Highlighting for R Source Code",
|
||||
|
|
@ -4310,9 +4311,9 @@
|
|||
"BugReports": "https://github.com/yihui/highr/issues",
|
||||
"VignetteBuilder": "knitr",
|
||||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.1",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"NeedsCompilation": "no",
|
||||
"Author": "Yihui Xie [aut, cre] (<https://orcid.org/0000-0003-0645-5666>), Yixuan Qiu [aut], Christopher Gandrud [ctb], Qiang Li [ctb]",
|
||||
"Author": "Yihui Xie [aut, cre] (ORCID: <https://orcid.org/0000-0003-0645-5666>), Yixuan Qiu [aut], Christopher Gandrud [ctb], Qiang Li [ctb]",
|
||||
"Maintainer": "Yihui Xie <xie@yihui.name>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
|
|
@ -5041,7 +5042,7 @@
|
|||
},
|
||||
"later": {
|
||||
"Package": "later",
|
||||
"Version": "1.4.6",
|
||||
"Version": "1.4.8",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Utilities for Scheduling Functions to Execute Later with Event Loops",
|
||||
|
|
@ -5217,72 +5218,74 @@
|
|||
},
|
||||
"lme4": {
|
||||
"Package": "lme4",
|
||||
"Version": "1.1-38",
|
||||
"Version": "2.0-1",
|
||||
"Source": "Repository",
|
||||
"Title": "Linear Mixed-Effects Models using 'Eigen' and S4",
|
||||
"Authors@R": "c( person(\"Douglas\",\"Bates\", role=\"aut\", comment=c(ORCID=\"0000-0001-8316-9503\")), person(\"Martin\",\"Maechler\", role=\"aut\", comment=c(ORCID=\"0000-0002-8685-9910\")), person(\"Ben\",\"Bolker\",email=\"bbolker+lme4@gmail.com\", role=c(\"aut\",\"cre\"), comment=c(ORCID=\"0000-0002-2127-0443\")), person(\"Steven\",\"Walker\",role=\"aut\", comment=c(ORCID=\"0000-0002-4394-9078\")), person(\"Rune Haubo Bojesen\",\"Christensen\", role=\"ctb\", comment=c(ORCID=\"0000-0002-4494-3399\")), person(\"Henrik\",\"Singmann\", role=\"ctb\", comment=c(ORCID=\"0000-0002-4842-3657\")), person(\"Bin\", \"Dai\", role=\"ctb\"), person(\"Fabian\", \"Scheipl\", role=\"ctb\", comment=c(ORCID=\"0000-0001-8172-3603\")), person(\"Gabor\", \"Grothendieck\", role=\"ctb\"), person(\"Peter\", \"Green\", role=\"ctb\", comment=c(ORCID=\"0000-0002-0238-9852\")), person(\"John\", \"Fox\", role=\"ctb\"), person(\"Alexander\", \"Bauer\", role=\"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role=c(\"ctb\",\"cph\"), comment=c(ORCID=\"0000-0002-9101-3362\", \"shared copyright on simulate.formula\")), person(\"Emi\", \"Tanaka\", role = \"ctb\", comment = c(ORCID=\"0000-0002-1455-259X\")), person(\"Mikael\", \"Jagan\", role = \"ctb\", comment = c(ORCID=\"0000-0002-3542-2938\")), person(\"Ross D.\", \"Boylan\", email=\"ross.boylan@ucsf.edu\", role=(\"ctb\"), comment = c(ORCID=\"0009-0003-4123-8090\")), person(\"Anna\", \"Ly\", role = \"ctb\", comment = c(ORCID = \"0000-0002-0210-0342\")) )",
|
||||
"Description": "Fit linear and generalized linear mixed-effects models. The models and their components are represented using S4 classes and methods. The core computational algorithms are implemented using the 'Eigen' C++ library for numerical linear algebra and 'RcppEigen' \"glue\".",
|
||||
"Authors@R": "c(person(\"Douglas\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Martin\", \"Maechler\", role = \"aut\", comment = c(ORCID = \"0000-0002-8685-9910\")), person(\"Ben\", \"Bolker\", role = c(\"cre\", \"aut\"), email = \"bbolker+lme4@gmail.com\", comment = c(ORCID = \"0000-0002-2127-0443\")), person(\"Steven\", \"Walker\", role = \"aut\", comment = c(ORCID = \"0000-0002-4394-9078\")), person(\"Rune Haubo Bojesen\", \"Christensen\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4494-3399\")), person(\"Henrik\", \"Singmann\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4842-3657\")), person(\"Bin\", \"Dai\", role = \"ctb\"), person(\"Fabian\", \"Scheipl\", role = \"ctb\", comment = c(ORCID = \"0000-0001-8172-3603\")), person(\"Gabor\", \"Grothendieck\", role = \"ctb\"), person(\"Peter\", \"Green\", role = \"ctb\", comment = c(ORCID = \"0000-0002-0238-9852\")), person(\"John\", \"Fox\", role = \"ctb\"), person(\"Alexander\", \"Bauer\", role = \"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role = c(\"ctb\", \"cph\"), comment = c(ORCID = \"0000-0002-9101-3362\", \"shared copyright on simulate.formula\")), person(\"Emi\", \"Tanaka\", role = \"ctb\", comment = c(ORCID = \"0000-0002-1455-259X\")), person(\"Mikael\", \"Jagan\", role = \"aut\", comment = c(ORCID = \"0000-0002-3542-2938\")), person(\"Ross D.\", \"Boylan\", role = \"ctb\", comment = c(ORCID = \"0009-0003-4123-8090\")), person(\"Anna\", \"Ly\", role = \"aut\", comment = c(ORCID = \"0000-0002-0210-0342\")))",
|
||||
"Description": "Fit linear and generalized linear mixed-effects models. The models and their components are represented using S4 classes and methods. The core computational algorithms are implemented using the 'Eigen' C++ library for numerical linear algebra and 'RcppEigen' \"glue\".",
|
||||
"Depends": [
|
||||
"R (>= 3.6.0)",
|
||||
"R (>= 3.6)",
|
||||
"Matrix",
|
||||
"methods",
|
||||
"stats"
|
||||
],
|
||||
"LinkingTo": [
|
||||
"Matrix (>= 1.5-0)",
|
||||
"Rcpp (>= 0.10.5)",
|
||||
"RcppEigen (>= 0.3.3.9.4)",
|
||||
"Matrix (>= 1.5-0)"
|
||||
"RcppEigen (>= 0.3.3.9.4)"
|
||||
],
|
||||
"Imports": [
|
||||
"MASS",
|
||||
"Rdpack",
|
||||
"boot",
|
||||
"graphics",
|
||||
"grid",
|
||||
"splines",
|
||||
"utils",
|
||||
"parallel",
|
||||
"MASS",
|
||||
"lattice",
|
||||
"boot",
|
||||
"nlme (>= 3.1-123)",
|
||||
"minqa (>= 1.1.15)",
|
||||
"nlme (>= 3.1-123)",
|
||||
"nloptr (>= 1.0.4)",
|
||||
"reformulas (>= 0.3.0)",
|
||||
"parallel",
|
||||
"reformulas (>= 0.4.3.1)",
|
||||
"rlang",
|
||||
"Rdpack"
|
||||
"splines",
|
||||
"utils"
|
||||
],
|
||||
"RdMacros": "Rdpack",
|
||||
"Suggests": [
|
||||
"knitr",
|
||||
"rmarkdown",
|
||||
"MEMSS",
|
||||
"testthat (>= 0.8.1)",
|
||||
"ggplot2",
|
||||
"mlmRev",
|
||||
"optimx (>= 2013.8.6)",
|
||||
"gamm4",
|
||||
"pbkrtest",
|
||||
"HSAUR3",
|
||||
"numDeriv",
|
||||
"MEMSS",
|
||||
"car",
|
||||
"dfoptim",
|
||||
"gamm4",
|
||||
"ggplot2",
|
||||
"glmmTMB",
|
||||
"knitr",
|
||||
"merDeriv",
|
||||
"mgcv",
|
||||
"statmod",
|
||||
"mlmRev",
|
||||
"numDeriv",
|
||||
"optimx (>= 2013.8.6)",
|
||||
"pbkrtest",
|
||||
"rmarkdown",
|
||||
"rr2",
|
||||
"semEff",
|
||||
"tibble",
|
||||
"merDeriv"
|
||||
"statmod",
|
||||
"testthat (>= 0.8.1)",
|
||||
"tibble"
|
||||
],
|
||||
"Enhances": [
|
||||
"DHARMa",
|
||||
"performance"
|
||||
],
|
||||
"RdMacros": "Rdpack",
|
||||
"VignetteBuilder": "knitr",
|
||||
"LazyData": "yes",
|
||||
"License": "GPL (>= 2)",
|
||||
"URL": "https://github.com/lme4/lme4/",
|
||||
"BugReports": "https://github.com/lme4/lme4/issues",
|
||||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "Douglas Bates [aut] (ORCID: <https://orcid.org/0000-0001-8316-9503>), Martin Maechler [aut] (ORCID: <https://orcid.org/0000-0002-8685-9910>), Ben Bolker [aut, cre] (ORCID: <https://orcid.org/0000-0002-2127-0443>), Steven Walker [aut] (ORCID: <https://orcid.org/0000-0002-4394-9078>), Rune Haubo Bojesen Christensen [ctb] (ORCID: <https://orcid.org/0000-0002-4494-3399>), Henrik Singmann [ctb] (ORCID: <https://orcid.org/0000-0002-4842-3657>), Bin Dai [ctb], Fabian Scheipl [ctb] (ORCID: <https://orcid.org/0000-0001-8172-3603>), Gabor Grothendieck [ctb], Peter Green [ctb] (ORCID: <https://orcid.org/0000-0002-0238-9852>), John Fox [ctb], Alexander Bauer [ctb], Pavel N. Krivitsky [ctb, cph] (ORCID: <https://orcid.org/0000-0002-9101-3362>, shared copyright on simulate.formula), Emi Tanaka [ctb] (ORCID: <https://orcid.org/0000-0002-1455-259X>), Mikael Jagan [ctb] (ORCID: <https://orcid.org/0000-0002-3542-2938>), Ross D. Boylan [ctb] (ORCID: <https://orcid.org/0009-0003-4123-8090>), Anna Ly [ctb] (ORCID: <https://orcid.org/0000-0002-0210-0342>)",
|
||||
"Author": "Douglas Bates [aut] (ORCID: <https://orcid.org/0000-0001-8316-9503>), Martin Maechler [aut] (ORCID: <https://orcid.org/0000-0002-8685-9910>), Ben Bolker [cre, aut] (ORCID: <https://orcid.org/0000-0002-2127-0443>), Steven Walker [aut] (ORCID: <https://orcid.org/0000-0002-4394-9078>), Rune Haubo Bojesen Christensen [ctb] (ORCID: <https://orcid.org/0000-0002-4494-3399>), Henrik Singmann [ctb] (ORCID: <https://orcid.org/0000-0002-4842-3657>), Bin Dai [ctb], Fabian Scheipl [ctb] (ORCID: <https://orcid.org/0000-0001-8172-3603>), Gabor Grothendieck [ctb], Peter Green [ctb] (ORCID: <https://orcid.org/0000-0002-0238-9852>), John Fox [ctb], Alexander Bauer [ctb], Pavel N. Krivitsky [ctb, cph] (ORCID: <https://orcid.org/0000-0002-9101-3362>, shared copyright on simulate.formula), Emi Tanaka [ctb] (ORCID: <https://orcid.org/0000-0002-1455-259X>), Mikael Jagan [aut] (ORCID: <https://orcid.org/0000-0002-3542-2938>), Ross D. Boylan [ctb] (ORCID: <https://orcid.org/0009-0003-4123-8090>), Anna Ly [aut] (ORCID: <https://orcid.org/0000-0002-0210-0342>)",
|
||||
"Maintainer": "Ben Bolker <bbolker+lme4@gmail.com>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
|
|
@ -5459,14 +5462,14 @@
|
|||
},
|
||||
"mgcv": {
|
||||
"Package": "mgcv",
|
||||
"Version": "1.9-3",
|
||||
"Version": "1.9-4",
|
||||
"Source": "Repository",
|
||||
"Authors@R": "person(given = \"Simon\", family = \"Wood\", role = c(\"aut\", \"cre\"), email = \"simon.wood@r-project.org\")",
|
||||
"Title": "Mixed GAM Computation Vehicle with Automatic Smoothness Estimation",
|
||||
"Description": "Generalized additive (mixed) models, some of their extensions and other generalized ridge regression with multiple smoothing parameter estimation by (Restricted) Marginal Likelihood, Generalized Cross Validation and similar, or using iterated nested Laplace approximation for fully Bayesian inference. See Wood (2017) <doi:10.1201/9781315370279> for an overview. Includes a gam() function, a wide variety of smoothers, 'JAGS' support and distributions beyond the exponential family.",
|
||||
"Description": "Generalized additive (mixed) models, some of their extensions and other generalized ridge regression with multiple smoothing parameter estimation by (Restricted) Marginal Likelihood, Cross Validation and similar, or using iterated nested Laplace approximation for fully Bayesian inference. See Wood (2025) <doi:10.1146/annurev-statistics-112723-034249> for an overview. Includes a gam() function, a wide variety of smoothers, 'JAGS' support and distributions beyond the exponential family.",
|
||||
"Priority": "recommended",
|
||||
"Depends": [
|
||||
"R (>= 3.6.0)",
|
||||
"R (>= 4.4.0)",
|
||||
"nlme (>= 3.1-64)"
|
||||
],
|
||||
"Imports": [
|
||||
|
|
@ -5672,10 +5675,10 @@
|
|||
},
|
||||
"mvtnorm": {
|
||||
"Package": "mvtnorm",
|
||||
"Version": "1.3-3",
|
||||
"Version": "1.3-2",
|
||||
"Source": "Repository",
|
||||
"Title": "Multivariate Normal and t Distributions",
|
||||
"Date": "2025-01-09",
|
||||
"Date": "2024-11-04",
|
||||
"Authors@R": "c(person(\"Alan\", \"Genz\", role = \"aut\"), person(\"Frank\", \"Bretz\", role = \"aut\"), person(\"Tetsuhisa\", \"Miwa\", role = \"aut\"), person(\"Xuefei\", \"Mi\", role = \"aut\"), person(\"Friedrich\", \"Leisch\", role = \"ctb\"), person(\"Fabian\", \"Scheipl\", role = \"ctb\"), person(\"Bjoern\", \"Bornkamp\", role = \"ctb\", comment = c(ORCID = \"0000-0002-6294-8185\")), person(\"Martin\", \"Maechler\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8685-9910\")), person(\"Torsten\", \"Hothorn\", role = c(\"aut\", \"cre\"), email = \"Torsten.Hothorn@R-project.org\", comment = c(ORCID = \"0000-0001-8301-0471\")))",
|
||||
"Description": "Computes multivariate normal and t probabilities, quantiles, random deviates, and densities. Log-likelihoods for multivariate Gaussian models and Gaussian copulae parameterised by Cholesky factors of covariance or precision matrices are implemented for interval-censored and exact data, or a mix thereof. Score functions for these log-likelihoods are available. A class representing multiple lower triangular matrices and corresponding methods are part of this package.",
|
||||
"Imports": [
|
||||
|
|
@ -5882,7 +5885,7 @@
|
|||
},
|
||||
"openssl": {
|
||||
"Package": "openssl",
|
||||
"Version": "2.3.4",
|
||||
"Version": "2.3.5",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Toolkit for Encryption, Signatures and Certificates Based on OpenSSL",
|
||||
|
|
@ -5915,7 +5918,7 @@
|
|||
},
|
||||
"openxlsx2": {
|
||||
"Package": "openxlsx2",
|
||||
"Version": "1.23.1",
|
||||
"Version": "1.25",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Read, Write and Edit 'xlsx' Files",
|
||||
|
|
@ -5942,10 +5945,10 @@
|
|||
"ggplot2",
|
||||
"knitr",
|
||||
"mschart (>= 0.4)",
|
||||
"openssl",
|
||||
"rmarkdown",
|
||||
"rvg",
|
||||
"testthat (>= 3.0.0)",
|
||||
"waldo",
|
||||
"zip"
|
||||
],
|
||||
"VignetteBuilder": "knitr",
|
||||
|
|
@ -7089,7 +7092,7 @@
|
|||
},
|
||||
"ragg": {
|
||||
"Package": "ragg",
|
||||
"Version": "1.5.0",
|
||||
"Version": "1.5.1",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Graphic Devices Based on AGG",
|
||||
|
|
@ -7118,7 +7121,7 @@
|
|||
"Config/testthat/edition": "3",
|
||||
"Config/usethis/last-upkeep": "2025-04-25",
|
||||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.2",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"SystemRequirements": "freetype2, libpng, libtiff, libjpeg, libwebp, libwebpmux",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "Thomas Lin Pedersen [cre, aut] (ORCID: <https://orcid.org/0000-0002-5147-4711>), Maxim Shemanarev [aut, cph] (Author of AGG), Tony Juricic [ctb, cph] (Contributor to AGG), Milan Marusinec [ctb, cph] (Contributor to AGG), Spencer Garrett [ctb] (Contributor to AGG), Posit Software, PBC [cph, fnd] (ROR: <https://ror.org/03wc8by49>)",
|
||||
|
|
@ -7541,7 +7544,7 @@
|
|||
},
|
||||
"renv": {
|
||||
"Package": "renv",
|
||||
"Version": "1.1.7",
|
||||
"Version": "1.1.8",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Project Environments",
|
||||
|
|
@ -7585,11 +7588,11 @@
|
|||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"VignetteBuilder": "knitr",
|
||||
"NeedsCompilation": "yes",
|
||||
"Config/Needs/website": "tidyverse/tidytemplate",
|
||||
"Config/testthat/edition": "3",
|
||||
"Config/testthat/parallel": "true",
|
||||
"Config/testthat/start-first": "bioconductor,python,install,restore,snapshot,retrieve,remotes",
|
||||
"NeedsCompilation": "no",
|
||||
"Author": "Kevin Ushey [aut, cre] (ORCID: <https://orcid.org/0000-0003-2880-7407>), Hadley Wickham [aut] (ORCID: <https://orcid.org/0000-0003-4757-117X>), Posit Software, PBC [cph, fnd]",
|
||||
"Maintainer": "Kevin Ushey <kevin@rstudio.com>",
|
||||
"Repository": "CRAN"
|
||||
|
|
@ -8317,7 +8320,7 @@
|
|||
},
|
||||
"shinyWidgets": {
|
||||
"Package": "shinyWidgets",
|
||||
"Version": "0.9.0",
|
||||
"Version": "0.9.1",
|
||||
"Source": "Repository",
|
||||
"Title": "Custom Inputs Widgets for Shiny",
|
||||
"Authors@R": "c( person(\"Victor\", \"Perrier\", email = \"victor.perrier@dreamrs.fr\", role = c(\"aut\", \"cre\", \"cph\")), person(\"Fanny\", \"Meyer\", role = \"aut\"), person(\"David\", \"Granjon\", role = \"aut\"), person(\"Ian\", \"Fellows\", role = \"ctb\", comment = \"Methods for mutating vertical tabs & updateMultiInput\"), person(\"Wil\", \"Davis\", role = \"ctb\", comment = \"numericRangeInput function\"), person(\"Spencer\", \"Matthews\", role = \"ctb\", comment = \"autoNumeric methods\"), person(family = \"JavaScript and CSS libraries authors\", role = c(\"ctb\", \"cph\"), comment = \"All authors are listed in LICENSE.md\") )",
|
||||
|
|
@ -8327,7 +8330,7 @@
|
|||
"License": "GPL-3",
|
||||
"Encoding": "UTF-8",
|
||||
"LazyData": "true",
|
||||
"RoxygenNote": "7.3.2",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"Depends": [
|
||||
"R (>= 3.1.0)"
|
||||
],
|
||||
|
|
@ -8624,7 +8627,7 @@
|
|||
},
|
||||
"systemfonts": {
|
||||
"Package": "systemfonts",
|
||||
"Version": "1.3.1",
|
||||
"Version": "1.3.2",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "System Native Font Finding",
|
||||
|
|
@ -8672,7 +8675,7 @@
|
|||
},
|
||||
"textshaping": {
|
||||
"Package": "textshaping",
|
||||
"Version": "1.0.4",
|
||||
"Version": "1.0.5",
|
||||
"Source": "Repository",
|
||||
"Title": "Bindings to the 'HarfBuzz' and 'Fribidi' Libraries for Text Shaping",
|
||||
"Authors@R": "c( person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )",
|
||||
|
|
@ -9513,21 +9516,23 @@
|
|||
},
|
||||
"xtable": {
|
||||
"Package": "xtable",
|
||||
"Version": "1.8-4",
|
||||
"Version": "1.8-8",
|
||||
"Source": "Repository",
|
||||
"Date": "2019-04-08",
|
||||
"Date": "2026-02-20",
|
||||
"Title": "Export Tables to LaTeX or HTML",
|
||||
"Authors@R": "c(person(\"David B.\", \"Dahl\", role=\"aut\"), person(\"David\", \"Scott\", role=c(\"aut\",\"cre\"), email=\"d.scott@auckland.ac.nz\"), person(\"Charles\", \"Roosen\", role=\"aut\"), person(\"Arni\", \"Magnusson\", role=\"aut\"), person(\"Jonathan\", \"Swinton\", role=\"aut\"), person(\"Ajay\", \"Shah\", role=\"ctb\"), person(\"Arne\", \"Henningsen\", role=\"ctb\"), person(\"Benno\", \"Puetz\", role=\"ctb\"), person(\"Bernhard\", \"Pfaff\", role=\"ctb\"), person(\"Claudio\", \"Agostinelli\", role=\"ctb\"), person(\"Claudius\", \"Loehnert\", role=\"ctb\"), person(\"David\", \"Mitchell\", role=\"ctb\"), person(\"David\", \"Whiting\", role=\"ctb\"), person(\"Fernando da\", \"Rosa\", role=\"ctb\"), person(\"Guido\", \"Gay\", role=\"ctb\"), person(\"Guido\", \"Schulz\", role=\"ctb\"), person(\"Ian\", \"Fellows\", role=\"ctb\"), person(\"Jeff\", \"Laake\", role=\"ctb\"), person(\"John\", \"Walker\", role=\"ctb\"), person(\"Jun\", \"Yan\", role=\"ctb\"), person(\"Liviu\", \"Andronic\", role=\"ctb\"), person(\"Markus\", \"Loecher\", role=\"ctb\"), person(\"Martin\", \"Gubri\", role=\"ctb\"), person(\"Matthieu\", \"Stigler\", role=\"ctb\"), person(\"Robert\", \"Castelo\", role=\"ctb\"), person(\"Seth\", \"Falcon\", role=\"ctb\"), person(\"Stefan\", \"Edwards\", role=\"ctb\"), person(\"Sven\", \"Garbade\", role=\"ctb\"), person(\"Uwe\", \"Ligges\", role=\"ctb\"))",
|
||||
"Maintainer": "David Scott <d.scott@auckland.ac.nz>",
|
||||
"Imports": [
|
||||
"stats",
|
||||
"utils"
|
||||
"utils",
|
||||
"methods"
|
||||
],
|
||||
"Suggests": [
|
||||
"knitr",
|
||||
"plm",
|
||||
"zoo",
|
||||
"survival"
|
||||
"survival",
|
||||
"glue",
|
||||
"tinytex"
|
||||
],
|
||||
"VignetteBuilder": "knitr",
|
||||
"Description": "Coerce data to LaTeX and HTML tables.",
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
"en","da"
|
||||
"Hello","Hej"
|
||||
"Get started","Kom i gang"
|
||||
"File upload","Upload fil"
|
||||
"REDCap server export","Eksport fra REDCap server"
|
||||
"Local or sample data","Lokal eller testdata"
|
||||
"Please be mindfull handling sensitive data","Pas godt på og overvej nøje hvordan du håndterer personfølsomme data"
|
||||
"Quick overview","Hurtigt overblik"
|
||||
"Select variables for final import","Vælg variabler til den endelige import"
|
||||
|
|
@ -58,7 +55,6 @@
|
|||
"Imported data","Importeret data"
|
||||
"www/intro.md","www/intro.md"
|
||||
"Choose your data","Vælg dine data"
|
||||
"Factor variable to reorder:","Kategoriske variabel der skal ændres:"
|
||||
"Sort by levels","Sorter efter niveauer"
|
||||
"Sort by count","Sorter efter antal"
|
||||
"Update factor variable","Updater faktor-variabel"
|
||||
|
|
@ -92,9 +88,7 @@
|
|||
"No variables have a correlation measure above the threshold.","Ingen variabler er korrelerede over den angivne tærskelværdi."
|
||||
"and","og"
|
||||
"from each pair","fra hvert par"
|
||||
"Only non-text variables are available for plotting. Go the ""Data"" to reclass data to plot.","Kun variabler, der ikke er klassificerede som tekst er tilgængelige. Gå til fanen ""Forbered"" for at ændre klassifikationer."
|
||||
"Plot","Tegn"
|
||||
"Adjust settings, then press ""Plot"".","Juster indstillingerne og tryk så ""Tegn""."
|
||||
"Plot height (mm)","Højde af grafik (mm)"
|
||||
"Plot width (mm)","Bredde af grafik (mm)"
|
||||
"File format","File format"
|
||||
|
|
@ -102,18 +96,11 @@
|
|||
"Select variable","Vælg variabel"
|
||||
"Response variable","Svarvariable"
|
||||
"Plot type","Type af grafik"
|
||||
"Please select","Vælg"
|
||||
"Additional variables","Yderligere variabler"
|
||||
"Secondary variable","Sekundær variabel"
|
||||
"No variable","Ingen variabel"
|
||||
"Grouping variable","Variabel til gruppering"
|
||||
"No stratification","Ingen stratificering"
|
||||
"Drawing the plot. Hold tight for a moment..","Tegner grafikken. Spænd selen.."
|
||||
"#Plotting\n","#Tegner\n"
|
||||
"Stacked horizontal bars","Stablede horisontale søjler"
|
||||
"A classical way of visualising the distribution of an ordinal scale like the modified Ranking Scale and known as Grotta bars","En klassisk visualisering af fordelingen af observationer på en ordinal kategorisk skala. Typisk brugt til modified Rankin Scale og kendes også som 'Grotta bars'"
|
||||
"Violin plot","Violin-diagram"
|
||||
"A modern alternative to the classic boxplot to visualise data distribution","Moderne alternativ til den klassiske box-plot og velegnet til at visualisere fordelingen af observationer"
|
||||
"Sankey plot","Sankey-diagram"
|
||||
"A way of visualising change between groups","Visualiserer ændring mellem grupper for samme type observationer"
|
||||
"Scatter plot","Punkt-diagram"
|
||||
|
|
@ -121,7 +108,6 @@
|
|||
"Box plot","Kasse-diagram"
|
||||
"A classic way to plot data distribution by groups","Klassik måde at visualisere fordeling"
|
||||
"Euler diagram","Eulerdiagram"
|
||||
"Generate area-proportional Euler diagrams to display set relationships","Generer proportionelt Euler-diagram for at vise forhold mellem forskellige kategoriske observationer"
|
||||
"Documentation","Dokumentation"
|
||||
"Data is only stored for analyses and deleted when the app is closed.","Data opbevares alene til brug i analyser og slettes så snart appen lukkes."
|
||||
"Feedback","Feedback"
|
||||
|
|
@ -132,7 +118,6 @@
|
|||
"Coefficients plot","Koefficientgraf"
|
||||
"Checks","Test af model"
|
||||
"Browse observations","Gennemse observationer"
|
||||
"Settings","Indstillinger"
|
||||
"The following error occured on determining correlations:","Følgende fejl opstod i forbindelse med korrelationsanalysen:"
|
||||
"No missing observations","Ingen manglende observationer"
|
||||
"There is a total of {p_miss} % missing observations.","Der er i alt {p_miss} % manglende observationer."
|
||||
|
|
@ -145,15 +130,7 @@
|
|||
"Missings","Manglende observationer"
|
||||
"Class","Klasse"
|
||||
"Observations","Observationer"
|
||||
"Data classes and missing observations","Dataklasser og manglende observationer"
|
||||
"Sure you want to reset data? This cannot be undone.","Er du sikker på at du vil gendanne data? Det kan ikke fortrydes."
|
||||
"Cancel","Afbryd"
|
||||
"Confirm","Bekræft"
|
||||
"The filtered data","Filtreret data"
|
||||
"Create new factor","Ny kategorisk variabel"
|
||||
"Create new variables","Opret nye variabler"
|
||||
"Select data types to include","Vælg datatyper, der skal inkluderes"
|
||||
"Uploaded data overview","Overblik over uploaded data"
|
||||
"Specify covariables","Angiv kovariabler"
|
||||
"If none are selected, all are included.","Hvis ingen er valgt inkluderes alle."
|
||||
"Analyse","Analysér"
|
||||
|
|
@ -161,20 +138,15 @@
|
|||
"Press 'Analyse' to create the regression model and after changing parameters.","Tryk 'Analysér' for at danne regressionsmodel og for at opdatere hvis parametre ændres."
|
||||
"Show p-value","Vis p-værdi"
|
||||
"Model checks","Model-test"
|
||||
"Please confirm data reset!","Bekræft gendannelse af data!"
|
||||
"Import data from REDCap","Importér data fra REDCap"
|
||||
"REDCap server","REDCap-server"
|
||||
"Web address","Serveradresse"
|
||||
"Format should be either 'https://redcap.your.institution/' or 'https://your.institution/redcap/'","Adressen skal være som 'https://redcap.your.institution/' eller 'https://your.institution/redcap/'"
|
||||
"API token","API-nøgle"
|
||||
"The token is a string of 32 numbers and letters.","En API-nøgle består af ialt 32 tal og bogstaver."
|
||||
"Connect","Forbind"
|
||||
"Data import parameters","Data import parameters"
|
||||
"Select fields/variables to import and click the funnel to apply optional filters","Vælg variabler, der skal importeres og tryk på tragten for at anvende valgfrie filtre"
|
||||
"Import","Import"
|
||||
"Click to see data dictionary","Tryk for at se metadata (Data Dictionary)"
|
||||
"Connected to server!","Forbindelse til serveren oprettet!"
|
||||
"The {data_rv$info$project_title} project is loaded.","{data_rv$info$project_title}-projektet er forbundet."
|
||||
"Data dictionary","Data dictionary"
|
||||
"Preview:","Forsmag:"
|
||||
"Imported data set","Importeret datasæt"
|
||||
|
|
@ -182,8 +154,6 @@
|
|||
"Specify the data format","Specificér dataformatet"
|
||||
"Fill missing values?","Skal manglende observationer udfyldes?"
|
||||
"Requested data was retrieved!","Det udvalgte data blev hentet!"
|
||||
"Data retrieved, but it looks like only the ID was retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data er hentet, men det ser ud til kun at indeholde ID-variablen. Du skal kontakte din REDCap-administrator og sikre dig at du har adgang til faktisk at hente de udvalgte data."
|
||||
"Data retrieved, but it looks like not all requested fields were retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data er hentet, men det ser ud til kun at indeholde nogle af de udvalgte variabler. Du skal kontakte din REDCap-administrator og sikre dig at du har adgang til faktisk at hente de udvalgte data."
|
||||
"Click to see the imported data","Tryk for at se de importerede data"
|
||||
"Regression table","Regressionstabel"
|
||||
"Import a dataset from an environment","Importer et datasæt fra et kodemiljø"
|
||||
|
|
@ -210,18 +180,7 @@
|
|||
"Multivariable regression model checks","Tests af multivariabel regressionsmodel"
|
||||
"Grouped by {get_label(data,ter)}","Grupperet efter {get_label(data,ter)}"
|
||||
"Option to perform statistical comparisons between strata in baseline table.","Mulighed for at udføre statistiske tests mellem strata i oversigtstabellen."
|
||||
"The data includes {n_col} variables. Please limit to 100.","Data indeholder {n_col} variabler. Begræns venligst til 100."
|
||||
"Data import","Data import"
|
||||
"Data import formatting","Formatering af data ved import"
|
||||
"Data modifications","Ændringer af data"
|
||||
"Variables filter","Variables filter"
|
||||
"Data filter","Data filter"
|
||||
"Data characteristics table","Oversigtstabel"
|
||||
"The dataset without text variables","Datasættet uden variabler formateret som tekst"
|
||||
"Creating the table. Hold on for a moment..","Opretter tabellen. Vent et øjeblik.."
|
||||
"Generating the report. Hold on for a moment..","Opretter rapporten. Vent et øjeblik.."
|
||||
"We encountered the following error showing missingness:","Under analysen af manglende observationer opstod følgende fejl:"
|
||||
"We encountered the following error browsing your data:","I forsøget på at vise en dataoversigt opstod følgende fejl:"
|
||||
"Choose a name for the column to be created or modified, then enter an expression before clicking on the button below to create the variable, or cancel to exit without saving anything.","Vælg et navn til den nye variabel, skriv din formel og tryk så på knappen for at gemme variablen, eller annuler for at lukke uden at gemme."
|
||||
"Please fill in web address and API token, then press 'Connect'.","Udfyld serveradresse og API-nøgle, og tryk så 'Fobind'."
|
||||
"Other","Other"
|
||||
|
|
@ -254,16 +213,10 @@
|
|||
"Browse data preview","Forhåndsvisning af resultat"
|
||||
"Split character string","Opdel tegnstreng"
|
||||
"Split text","Opdel tekst"
|
||||
"Split a character string by a common delimiter","Opdel en tekstkolonne med en fælles afgrænser"
|
||||
"Apply split","Anvend opdeling"
|
||||
"Stacked relative barplot","Stablet relativt søjlediagram"
|
||||
"Create relative stacked barplots to show the distribution of categorical levels","Opret relative stablede søjlediagrammer for at vise fordelingen af kategoriske niveauer"
|
||||
"Side-by-side barplot","Side om side barplot"
|
||||
"Create side-by-side barplot to show the distribution of categorical levels","Opret et side-om-side søjlediagram for at vise fordelingen af kategoriske niveauer"
|
||||
"Select table theme","Vælg tema"
|
||||
"Level of detail","Detaljeniveau"
|
||||
"Minimal","Minimal"
|
||||
"Extensive","Stor"
|
||||
"Letters","Bogstaver"
|
||||
"Words","Ord"
|
||||
"Shorten to first letters","Afkort til første bogstaver"
|
||||
|
|
@ -301,7 +254,6 @@
|
|||
"FreesearchR is available in multiple languages. To help with translations, please contact us at info@freesearchr.org","FreesearchR er tilgængelig på flere sprog. For at få hjælp med oversættelser, kontakt os venligst på info@freesearchr.org"
|
||||
"Home","Hjem"
|
||||
"Start with FreesearchR for basic data evaluation and analysis.","Start med FreesearchR til grundlæggende dataevaluering og -analyse."
|
||||
"When you need more advanced tools, you'll be better prepared to use R directly.","Når du har brug for mere avancerede værktøjer, vil du være bedre forberedt på at bruge R direkte."
|
||||
"(Read more)","(Læs mere)"
|
||||
"Run the FreesearchR app locally when working with sensitive data.","Kør FreesearchR-appen lokalt, når du arbejder med følsomme data."
|
||||
"Load data from spreadsheets, REDCap servers, or try with sample data. Multiple sources supported for maximum flexibility.","Indlæs data fra regneark, REDCap-servere, eller prøv med eksempeldata. Flere kilder understøttes for maksimal fleksibilitet."
|
||||
|
|
@ -312,19 +264,63 @@
|
|||
"When you need more advanced tools, you'll be prepared to use R directly.","Når du har brug for mere avancerede værktøjer, vil du være forberedt på at bruge R direkte."
|
||||
"The app contains a selelct number of features and will guide you through key analyses.","Appen indeholder udvalgte funktioner, og guider dig gennem de vigtigste analyser."
|
||||
"Sort by Levels","Sorter efter niveauer"
|
||||
"Reorder factor levels","Omarranger niveauer"
|
||||
"Modify factor levels","Ændr kategoriske niveauer"
|
||||
"Reorder or rename the levels of factor/categorical variables.","Ændr navn eller rækkefølge på kategorisk variabel."
|
||||
"Maximum number of observations:","Maximale antal observationer:"
|
||||
"setting to 0 includes all","angiv 0 for at inkludere alle"
|
||||
"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."
|
||||
"You have provided a complete dataset with no missing values.","Data er uden manglende observationer."
|
||||
"Start by loading data.","Start med at vælge data."
|
||||
"Sample data","Træningsdata"
|
||||
"Create a new variable; otherwise replaces (Updating labels always creates new variable)","Create a new variable; otherwise replaces (Updating labels always creates new variable)"
|
||||
"Data classes and missing observations","Data classes and missing observations"
|
||||
"We encountered the following error showing missingness:","We encountered the following error showing missingness:"
|
||||
"Please confirm data reset!","Please confirm data reset!"
|
||||
"Sure you want to reset data? This cannot be undone.","Sure you want to reset data? This cannot be undone."
|
||||
"Confirm","Confirm"
|
||||
"The filtered data","The filtered data"
|
||||
"Reorder factor levels","Reorder factor levels"
|
||||
"Split a character string by a common delimiter","Split a character string by a common delimiter"
|
||||
"Create new variables","Create new variables"
|
||||
"Select data types to include","Select data types to include"
|
||||
"Uploaded data overview","Uploaded data overview"
|
||||
"We encountered the following error browsing your data:","We encountered the following error browsing your data:"
|
||||
"Data import","Data import"
|
||||
"Data import formatting","Data import formatting"
|
||||
"Data modifications","Data modifications"
|
||||
"Variables filter","Variables filter"
|
||||
"Data filter","Data filter"
|
||||
"Data characteristics table","Data characteristics table"
|
||||
"Level of detail","Level of detail"
|
||||
"Minimal","Minimal"
|
||||
"Extensive","Extensive"
|
||||
"The dataset without text variables","The dataset without text variables"
|
||||
"The data includes {n_col} variables. Please limit to 100.","The data includes {n_col} variables. Please limit to 100."
|
||||
"Creating the table. Hold on for a moment..","Creating the table. Hold on for a moment.."
|
||||
"File upload","File upload"
|
||||
"REDCap server export","REDCap server export"
|
||||
"Local or sample data","Local or sample data"
|
||||
"Sample data","Sample data"
|
||||
"Settings","Settings"
|
||||
"Create new factor","Create new factor"
|
||||
"Optional filter logic (e.g., [gender] = 'female')","Optional filter logic (e.g., [gender] = 'female')"
|
||||
"Drop empty","Drop empty"
|
||||
"Choose variable:","Choose variable:"
|
||||
"An empty data set was imported. Please review data filter.","An empty data set was imported. Please review data filter."
|
||||
"An error was encountered exporting data. Please review data filter.","An error was encountered exporting data. Please review data filter."
|
||||
"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."
|
||||
"Adjust plot input and settings below, then press ""Plot"".","Adjust plot input and settings below, then press ""Plot""."
|
||||
"Define plot","Define plot"
|
||||
"Choose color palette","Choose color palette"
|
||||
"Additional variable","Additional variable"
|
||||
"Grouping variable","Grouping variable"
|
||||
"Secondary variable","Secondary variable"
|
||||
"Reverse colors","Reverse colors"
|
||||
"Plot survey results","Plot survey results"
|
||||
"Additional variables","Additional variables"
|
||||
"Other variables","Other variables"
|
||||
"Select variables and plot type,\nthen click 'Plot' to generate visualization","Select variables and plot type,\nthen click 'Plot' to generate visualization"
|
||||
|
|
|
|||
|
|
|
@ -1,9 +1,6 @@
|
|||
"en","sw"
|
||||
"Hello","Habari"
|
||||
"Get started","Tuanze!"
|
||||
"File upload","Upakiaji wa faili"
|
||||
"REDCap server export","Usafirishaji wa seva ya REDCap"
|
||||
"Local or sample data","Data ya ndani au ya sampuli"
|
||||
"Please be mindfull handling sensitive data","Tafadhali kuwa mwangalifu kushughulikia data nyeti"
|
||||
"Quick overview","Muhtasari wa haraka"
|
||||
"Select variables for final import","Chagua vigezo vya kuingiza mwisho"
|
||||
|
|
@ -58,7 +55,6 @@
|
|||
"Imported data","Data iliyoingizwa"
|
||||
"www/intro.md","www/intro.md"
|
||||
"Choose your data","Chagua data yako"
|
||||
"Factor variable to reorder:","Kigezo cha vipengele ili kupanga upya:"
|
||||
"Sort by levels","Panga kwa viwango"
|
||||
"Sort by count","Panga kwa hesabu"
|
||||
"Update factor variable","Sasisha kigezo cha kipengele"
|
||||
|
|
@ -92,9 +88,7 @@
|
|||
"No variables have a correlation measure above the threshold.","Hakuna vigezo vyenye kipimo cha uhusiano kilicho juu ya kizingiti."
|
||||
"and","na"
|
||||
"from each pair","kutoka kwa kila jozi"
|
||||
"Only non-text variables are available for plotting. Go the ""Data"" to reclass data to plot.","Vigezo visivyo vya maandishi pekee ndivyo vinavyopatikana kwa ajili ya kupanga. Nenda kwenye ""Data"" ili kupanga upya data ili kupanga."
|
||||
"Plot","Kipande cha habari"
|
||||
"Adjust settings, then press ""Plot"".","Rekebisha mipangilio, kisha bonyeza ""Plot""."
|
||||
"Plot height (mm)","Urefu wa kiwanja (mm)"
|
||||
"Plot width (mm)","Upana wa kiwanja (mm)"
|
||||
"File format","Umbizo la faili"
|
||||
|
|
@ -102,18 +96,11 @@
|
|||
"Select variable","Chagua kigezo"
|
||||
"Response variable","Kigezo cha majibu"
|
||||
"Plot type","Aina ya kiwanja"
|
||||
"Please select","Tafadhali chagua"
|
||||
"Additional variables","Vigezo vya ziada"
|
||||
"Secondary variable","Kigezo cha pili"
|
||||
"No variable","Hakuna kigezo"
|
||||
"Grouping variable","Kigezo cha kuweka katika makundi"
|
||||
"No stratification","Hakuna matabaka"
|
||||
"Drawing the plot. Hold tight for a moment..","Kuchora njama. Shikilia kwa muda.."
|
||||
"#Plotting\n","#Upangaji\n"
|
||||
"Stacked horizontal bars","Pau za mlalo zilizopangwa kwa mpangilio"
|
||||
"A classical way of visualising the distribution of an ordinal scale like the modified Ranking Scale and known as Grotta bars","Njia ya kitamaduni ya kuibua usambazaji wa mizani ya kawaida kama vile Mizani ya Nafasi iliyorekebishwa na inayojulikana kama baa za Grotta"
|
||||
"Violin plot","Hadithi ya violin"
|
||||
"A modern alternative to the classic boxplot to visualise data distribution","Njia mbadala ya kisasa ya mpangilio wa kisanduku wa kawaida ili kuibua usambazaji wa data"
|
||||
"Sankey plot","Njama ya Sankey"
|
||||
"A way of visualising change between groups","Njia ya kuibua mabadiliko kati ya vikundi"
|
||||
"Scatter plot","Njama ya kutawanya"
|
||||
|
|
@ -121,7 +108,6 @@
|
|||
"Box plot","Kipande cha sanduku"
|
||||
"A classic way to plot data distribution by groups","Njia ya kawaida ya kupanga usambazaji wa data kwa vikundi"
|
||||
"Euler diagram","Mchoro wa Euler"
|
||||
"Generate area-proportional Euler diagrams to display set relationships","Tengeneza michoro ya Euler inayolingana na eneo ili kuonyesha uhusiano uliowekwa"
|
||||
"Documentation","Nyaraka"
|
||||
"Data is only stored for analyses and deleted when the app is closed.","Data huhifadhiwa kwa ajili ya uchambuzi na kufutwa tu wakati programu imefungwa."
|
||||
"Feedback","Maoni"
|
||||
|
|
@ -132,7 +118,6 @@
|
|||
"Coefficients plot","Mchoro wa viambato"
|
||||
"Checks","Hundi"
|
||||
"Browse observations","Vinjari uchunguzi"
|
||||
"Settings","Mipangilio"
|
||||
"The following error occured on determining correlations:","Hitilafu ifuatayo ilitokea katika kubaini uhusiano:"
|
||||
"No missing observations","Hakuna uchunguzi unaokosekana"
|
||||
"There is a total of {p_miss} % missing observations.","Kuna jumla ya uchunguzi wa {p_miss}% unaokosekana."
|
||||
|
|
@ -145,15 +130,7 @@
|
|||
"Missings","Hazipo"
|
||||
"Class","Darasa"
|
||||
"Observations","Uchunguzi"
|
||||
"Data classes and missing observations","Madarasa ya data na uchunguzi unaokosekana"
|
||||
"Sure you want to reset data? This cannot be undone.","Una uhakika unataka kuweka upya data? Hii haiwezi kutenduliwa."
|
||||
"Cancel","Ghairi"
|
||||
"Confirm","Thibitisha"
|
||||
"The filtered data","Data iliyochujwa"
|
||||
"Create new factor","Unda kipengele kipya"
|
||||
"Create new variables","Unda vigezo vipya"
|
||||
"Select data types to include","Chagua aina za data za kujumuisha"
|
||||
"Uploaded data overview","Muhtasari wa data iliyopakiwa"
|
||||
"Specify covariables","Bainisha vigeu vinavyoweza kuunganishwa"
|
||||
"If none are selected, all are included.","Ikiwa hakuna aliyechaguliwa, wote wamejumuishwa."
|
||||
"Analyse","Changanua"
|
||||
|
|
@ -161,20 +138,15 @@
|
|||
"Press 'Analyse' to create the regression model and after changing parameters.","Bonyeza 'Changanua' ili kuunda modeli ya urejeshaji na baada ya kubadilisha vigezo."
|
||||
"Show p-value","Onyesha thamani ya p"
|
||||
"Model checks","Ukaguzi wa modeli"
|
||||
"Please confirm data reset!","Tafadhali thibitisha urejeshaji wa data!"
|
||||
"Import data from REDCap","Ingiza data kutoka REDCap"
|
||||
"REDCap server","Seva ya REDCap"
|
||||
"Web address","Anwani ya wavuti"
|
||||
"Format should be either 'https://redcap.your.institution/' or 'https://your.institution/redcap/'","Muundo unapaswa kuwa 'https://redcap.your.institution/' au 'https://your.institution/redcap/'"
|
||||
"API token","Tokeni ya API"
|
||||
"The token is a string of 32 numbers and letters.","Tokeni ni mfuatano wa nambari na herufi 32."
|
||||
"Connect","Unganisha"
|
||||
"Data import parameters","Vigezo vya kuingiza data"
|
||||
"Select fields/variables to import and click the funnel to apply optional filters","Chagua sehemu/vigezo vya kuingiza na ubofye faneli ili kutumia vichujio vya hiari"
|
||||
"Import","Ingiza"
|
||||
"Click to see data dictionary","Bofya ili kuona kamusi ya data"
|
||||
"Connected to server!","Imeunganishwa na seva!"
|
||||
"The {data_rv$info$project_title} project is loaded.","Mradi wa {data_rv$info$project_title} umepakiwa."
|
||||
"Data dictionary","Kamusi ya data"
|
||||
"Preview:","Hakikisho:"
|
||||
"Imported data set","Seti ya data iliyoingizwa"
|
||||
|
|
@ -182,8 +154,6 @@
|
|||
"Specify the data format","Bainisha umbizo la data"
|
||||
"Fill missing values?","Jaza thamani zinazokosekana?"
|
||||
"Requested data was retrieved!","Data iliyoombwa ilipatikana!"
|
||||
"Data retrieved, but it looks like only the ID was retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data imerejeshwa, lakini inaonekana ni kitambulisho pekee kilichorejeshwa kutoka kwa seva. Tafadhali wasiliana na msimamizi wako wa REDCap kama una ruhusa zinazohitajika kwa ufikiaji wa data."
|
||||
"Data retrieved, but it looks like not all requested fields were retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data imerejeshwa, lakini inaonekana kama si sehemu zote zilizoombwa zilizorejeshwa kutoka kwa seva. Tafadhali wasiliana na msimamizi wako wa REDCap kama una ruhusa zinazohitajika kwa ufikiaji wa data."
|
||||
"Click to see the imported data","Bofya ili kuona data iliyoingizwa"
|
||||
"Regression table","Jedwali la urejeshaji"
|
||||
"Import a dataset from an environment","Ingiza seti ya data kutoka kwa mazingira"
|
||||
|
|
@ -210,18 +180,7 @@
|
|||
"Multivariable regression model checks","Ukaguzi wa modeli ya urejeshaji unaoweza kubadilika-badilika"
|
||||
"Grouped by {get_label(data,ter)}","Imepangwa kwa makundi kulingana na {get_label(data,ter)}"
|
||||
"Option to perform statistical comparisons between strata in baseline table.","Chaguo la kufanya ulinganisho wa takwimu kati ya tabaka katika jedwali la msingi."
|
||||
"The data includes {n_col} variables. Please limit to 100.","Data inajumuisha vigezo vya {n_col}. Tafadhali punguza hadi 100."
|
||||
"Data import","Uingizaji wa data"
|
||||
"Data import formatting","Uumbizaji wa kuingiza data"
|
||||
"Data modifications","Marekebisho ya data"
|
||||
"Variables filter","Kichujio cha vigeugeu"
|
||||
"Data filter","Kichujio cha data"
|
||||
"Data characteristics table","Jedwali la sifa za data"
|
||||
"The dataset without text variables","Seti ya data bila vigeu vya maandishi"
|
||||
"Creating the table. Hold on for a moment..","Kutengeneza meza. Subiri kwa muda.."
|
||||
"Generating the report. Hold on for a moment..","Inazalisha ripoti. Subiri kidogo.."
|
||||
"We encountered the following error showing missingness:","Tulikutana na hitilafu ifuatayo inayoonyesha ukosefu:"
|
||||
"We encountered the following error browsing your data:","Tulipata hitilafu ifuatayo wakati wa kuvinjari data yako:"
|
||||
"Choose a name for the column to be created or modified, then enter an expression before clicking on the button below to create the variable, or cancel to exit without saving anything.","Chagua jina la safu wima itakayoundwa au kurekebishwa, kisha ingiza usemi kabla ya kubofya kitufe kilicho hapa chini ili kuunda kigezo, au ghairi ili kutoka bila kuhifadhi chochote."
|
||||
"Other","Nyingine"
|
||||
"Hour of the day","Saa ya siku"
|
||||
|
|
@ -249,7 +208,6 @@
|
|||
"Split string to multiple observations (rows) in the same column. Also ads id and instance columns","Gawanya mfuatano katika uchunguzi mwingi (safu) katika safu wima moja. Pia vitambulisho vya matangazo na safu wima za mfano"
|
||||
"Split character string","Gawanya mfuatano wa herufi"
|
||||
"Split text","Gawanya maandishi"
|
||||
"Split a character string by a common delimiter","Gawanya mfuatano wa herufi kwa kitenganishi cha kawaida"
|
||||
"Select delimiter","Chagua kidhibiti"
|
||||
"Browse data preview","Vinjari hakikisho la data"
|
||||
"Original data","Data asili"
|
||||
|
|
@ -257,13 +215,8 @@
|
|||
"No character variables with accepted delimiters detected.","Hakuna vigezo vya herufi vilivyo na vidhibiti vinavyokubalika vilivyogunduliwa."
|
||||
"Apply split","Tumia mgawanyiko"
|
||||
"Stacked relative barplot","Kipande cha baruni kilichopangwa kwa mirundiko"
|
||||
"Create relative stacked barplots to show the distribution of categorical levels","Unda viwanja vya baruni vilivyopangwa ili kuonyesha usambazaji wa viwango vya kategoria"
|
||||
"Side-by-side barplot","Kipande cha baruni cha kando kwa kando"
|
||||
"Create side-by-side barplot to show the distribution of categorical levels","Unda mpangilio wa barufa kando ili kuonyesha usambazaji wa viwango vya kategoria"
|
||||
"Select table theme","Chagua mandhari ya jedwali"
|
||||
"Level of detail","Kiwango cha maelezo"
|
||||
"Minimal","Kidogo"
|
||||
"Extensive","Kina"
|
||||
"Letters","Barua"
|
||||
"Words","Maneno"
|
||||
"Shorten to first letters","Fupisha herufi za kwanza"
|
||||
|
|
@ -301,7 +254,6 @@
|
|||
"FreesearchR is available in multiple languages. To help with translations, please contact us at info@freesearchr.org","FreesearchR inapatikana katika lugha nyingi. Ili kukusaidia na tafsiri, tafadhali wasiliana nasi kwa info@freesearchr.org."
|
||||
"Home","Nyumbani"
|
||||
"Start with FreesearchR for basic data evaluation and analysis.","Anza na FreesearchR kwa tathmini na uchambuzi wa data ya msingi."
|
||||
"When you need more advanced tools, you'll be better prepared to use R directly.","Unapohitaji zana za hali ya juu zaidi, utakuwa tayari zaidi kutumia R moja kwa moja."
|
||||
"(Read more)","(Soma zaidi)"
|
||||
"Run the FreesearchR app locally when working with sensitive data.","Endesha programu ya FreesearchR ndani ya eneo lako unapofanya kazi na data nyeti."
|
||||
"Load data from spreadsheets, REDCap servers, or try with sample data. Multiple sources supported for maximum flexibility.","Pakia data kutoka kwa lahajedwali, seva za REDCap, au jaribu na data ya sampuli. Vyanzo vingi vinaungwa mkono kwa unyumbufu wa hali ya juu."
|
||||
|
|
@ -312,19 +264,63 @@
|
|||
"When you need more advanced tools, you'll be prepared to use R directly.","Unapohitaji zana za hali ya juu zaidi, utakuwa tayari kutumia R moja kwa moja."
|
||||
"The app contains a selelct number of features and will guide you through key analyses.","The app contains a selelct number of features and will guide you through key analyses."
|
||||
"Sort by Levels","Sort by Levels"
|
||||
"Reorder factor levels","Reorder factor levels"
|
||||
"Modify factor levels","Modify factor levels"
|
||||
"Reorder or rename the levels of factor/categorical variables.","Reorder or rename the levels of factor/categorical variables."
|
||||
"Maximum number of observations:","Maximum number of observations:"
|
||||
"setting to 0 includes all","setting to 0 includes all"
|
||||
"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."
|
||||
"You have provided a complete dataset with no missing values.","You have provided a complete dataset with no missing values."
|
||||
"Start by loading data.","Start by loading data."
|
||||
"Data classes and missing observations","Data classes and missing observations"
|
||||
"We encountered the following error showing missingness:","We encountered the following error showing missingness:"
|
||||
"Please confirm data reset!","Please confirm data reset!"
|
||||
"Sure you want to reset data? This cannot be undone.","Sure you want to reset data? This cannot be undone."
|
||||
"Confirm","Confirm"
|
||||
"The filtered data","The filtered data"
|
||||
"Reorder factor levels","Reorder factor levels"
|
||||
"Split a character string by a common delimiter","Split a character string by a common delimiter"
|
||||
"Create new variables","Create new variables"
|
||||
"Select data types to include","Select data types to include"
|
||||
"Uploaded data overview","Uploaded data overview"
|
||||
"We encountered the following error browsing your data:","We encountered the following error browsing your data:"
|
||||
"Data import","Data import"
|
||||
"Data import formatting","Data import formatting"
|
||||
"Data modifications","Data modifications"
|
||||
"Variables filter","Variables filter"
|
||||
"Data filter","Data filter"
|
||||
"Data characteristics table","Data characteristics table"
|
||||
"Level of detail","Level of detail"
|
||||
"Minimal","Minimal"
|
||||
"Extensive","Extensive"
|
||||
"The dataset without text variables","The dataset without text variables"
|
||||
"The data includes {n_col} variables. Please limit to 100.","The data includes {n_col} variables. Please limit to 100."
|
||||
"Creating the table. Hold on for a moment..","Creating the table. Hold on for a moment.."
|
||||
"File upload","File upload"
|
||||
"REDCap server export","REDCap server export"
|
||||
"Local or sample data","Local or sample data"
|
||||
"Sample data","Sample data"
|
||||
"Create a new variable; otherwise replaces (Updating labels always creates new variable)","Create a new variable; otherwise replaces (Updating labels always creates new variable)"
|
||||
"Settings","Settings"
|
||||
"Create new factor","Create new factor"
|
||||
"Optional filter logic (e.g., [gender] = 'female')","Optional filter logic (e.g., [gender] = 'female')"
|
||||
"Drop empty","Drop empty"
|
||||
"Choose variable:","Choose variable:"
|
||||
"An empty data set was imported. Please review data filter.","An empty data set was imported. Please review data filter."
|
||||
"An error was encountered exporting data. Please review data filter.","An error was encountered exporting data. Please review data filter."
|
||||
"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."
|
||||
"Adjust plot input and settings below, then press ""Plot"".","Adjust plot input and settings below, then press ""Plot""."
|
||||
"Define plot","Define plot"
|
||||
"Choose color palette","Choose color palette"
|
||||
"Additional variable","Additional variable"
|
||||
"Grouping variable","Grouping variable"
|
||||
"Secondary variable","Secondary variable"
|
||||
"Reverse colors","Reverse colors"
|
||||
"Plot survey results","Plot survey results"
|
||||
"Additional variables","Additional variables"
|
||||
"Other variables","Other variables"
|
||||
"Select variables and plot type,\nthen click 'Plot' to generate visualization","Select variables and plot type,\nthen click 'Plot' to generate visualization"
|
||||
|
|
|
|||
|
|
|
@ -22,7 +22,7 @@ visuals_demo_app <- function() {
|
|||
)
|
||||
)
|
||||
server <- function(input, output, session) {
|
||||
pl <- data_visuals_server("visuals", data = shiny::reactive(default_parsing(mtcars)))
|
||||
pl <- data_visuals_server("visuals", data = shiny::reactive(default_parsing(mtcars)),palettes = color_choices())
|
||||
}
|
||||
shiny::shinyApp(ui, server)
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +1,6 @@
|
|||
"en","da"
|
||||
"Hello","Hej"
|
||||
"Get started","Kom i gang"
|
||||
"File upload","Upload fil"
|
||||
"REDCap server export","Eksport fra REDCap server"
|
||||
"Local or sample data","Lokal eller testdata"
|
||||
"Please be mindfull handling sensitive data","Pas godt på og overvej nøje hvordan du håndterer personfølsomme data"
|
||||
"Quick overview","Hurtigt overblik"
|
||||
"Select variables for final import","Vælg variabler til den endelige import"
|
||||
|
|
@ -58,7 +55,6 @@
|
|||
"Imported data","Importeret data"
|
||||
"www/intro.md","www/intro.md"
|
||||
"Choose your data","Vælg dine data"
|
||||
"Factor variable to reorder:","Kategoriske variabel der skal ændres:"
|
||||
"Sort by levels","Sorter efter niveauer"
|
||||
"Sort by count","Sorter efter antal"
|
||||
"Update factor variable","Updater faktor-variabel"
|
||||
|
|
@ -92,9 +88,7 @@
|
|||
"No variables have a correlation measure above the threshold.","Ingen variabler er korrelerede over den angivne tærskelværdi."
|
||||
"and","og"
|
||||
"from each pair","fra hvert par"
|
||||
"Only non-text variables are available for plotting. Go the ""Data"" to reclass data to plot.","Kun variabler, der ikke er klassificerede som tekst er tilgængelige. Gå til fanen ""Forbered"" for at ændre klassifikationer."
|
||||
"Plot","Tegn"
|
||||
"Adjust settings, then press ""Plot"".","Juster indstillingerne og tryk så ""Tegn""."
|
||||
"Plot height (mm)","Højde af grafik (mm)"
|
||||
"Plot width (mm)","Bredde af grafik (mm)"
|
||||
"File format","File format"
|
||||
|
|
@ -102,18 +96,11 @@
|
|||
"Select variable","Vælg variabel"
|
||||
"Response variable","Svarvariable"
|
||||
"Plot type","Type af grafik"
|
||||
"Please select","Vælg"
|
||||
"Additional variables","Yderligere variabler"
|
||||
"Secondary variable","Sekundær variabel"
|
||||
"No variable","Ingen variabel"
|
||||
"Grouping variable","Variabel til gruppering"
|
||||
"No stratification","Ingen stratificering"
|
||||
"Drawing the plot. Hold tight for a moment..","Tegner grafikken. Spænd selen.."
|
||||
"#Plotting\n","#Tegner\n"
|
||||
"Stacked horizontal bars","Stablede horisontale søjler"
|
||||
"A classical way of visualising the distribution of an ordinal scale like the modified Ranking Scale and known as Grotta bars","En klassisk visualisering af fordelingen af observationer på en ordinal kategorisk skala. Typisk brugt til modified Rankin Scale og kendes også som 'Grotta bars'"
|
||||
"Violin plot","Violin-diagram"
|
||||
"A modern alternative to the classic boxplot to visualise data distribution","Moderne alternativ til den klassiske box-plot og velegnet til at visualisere fordelingen af observationer"
|
||||
"Sankey plot","Sankey-diagram"
|
||||
"A way of visualising change between groups","Visualiserer ændring mellem grupper for samme type observationer"
|
||||
"Scatter plot","Punkt-diagram"
|
||||
|
|
@ -121,7 +108,6 @@
|
|||
"Box plot","Kasse-diagram"
|
||||
"A classic way to plot data distribution by groups","Klassik måde at visualisere fordeling"
|
||||
"Euler diagram","Eulerdiagram"
|
||||
"Generate area-proportional Euler diagrams to display set relationships","Generer proportionelt Euler-diagram for at vise forhold mellem forskellige kategoriske observationer"
|
||||
"Documentation","Dokumentation"
|
||||
"Data is only stored for analyses and deleted when the app is closed.","Data opbevares alene til brug i analyser og slettes så snart appen lukkes."
|
||||
"Feedback","Feedback"
|
||||
|
|
@ -132,7 +118,6 @@
|
|||
"Coefficients plot","Koefficientgraf"
|
||||
"Checks","Test af model"
|
||||
"Browse observations","Gennemse observationer"
|
||||
"Settings","Indstillinger"
|
||||
"The following error occured on determining correlations:","Følgende fejl opstod i forbindelse med korrelationsanalysen:"
|
||||
"No missing observations","Ingen manglende observationer"
|
||||
"There is a total of {p_miss} % missing observations.","Der er i alt {p_miss} % manglende observationer."
|
||||
|
|
@ -145,15 +130,7 @@
|
|||
"Missings","Manglende observationer"
|
||||
"Class","Klasse"
|
||||
"Observations","Observationer"
|
||||
"Data classes and missing observations","Dataklasser og manglende observationer"
|
||||
"Sure you want to reset data? This cannot be undone.","Er du sikker på at du vil gendanne data? Det kan ikke fortrydes."
|
||||
"Cancel","Afbryd"
|
||||
"Confirm","Bekræft"
|
||||
"The filtered data","Filtreret data"
|
||||
"Create new factor","Ny kategorisk variabel"
|
||||
"Create new variables","Opret nye variabler"
|
||||
"Select data types to include","Vælg datatyper, der skal inkluderes"
|
||||
"Uploaded data overview","Overblik over uploaded data"
|
||||
"Specify covariables","Angiv kovariabler"
|
||||
"If none are selected, all are included.","Hvis ingen er valgt inkluderes alle."
|
||||
"Analyse","Analysér"
|
||||
|
|
@ -161,20 +138,15 @@
|
|||
"Press 'Analyse' to create the regression model and after changing parameters.","Tryk 'Analysér' for at danne regressionsmodel og for at opdatere hvis parametre ændres."
|
||||
"Show p-value","Vis p-værdi"
|
||||
"Model checks","Model-test"
|
||||
"Please confirm data reset!","Bekræft gendannelse af data!"
|
||||
"Import data from REDCap","Importér data fra REDCap"
|
||||
"REDCap server","REDCap-server"
|
||||
"Web address","Serveradresse"
|
||||
"Format should be either 'https://redcap.your.institution/' or 'https://your.institution/redcap/'","Adressen skal være som 'https://redcap.your.institution/' eller 'https://your.institution/redcap/'"
|
||||
"API token","API-nøgle"
|
||||
"The token is a string of 32 numbers and letters.","En API-nøgle består af ialt 32 tal og bogstaver."
|
||||
"Connect","Forbind"
|
||||
"Data import parameters","Data import parameters"
|
||||
"Select fields/variables to import and click the funnel to apply optional filters","Vælg variabler, der skal importeres og tryk på tragten for at anvende valgfrie filtre"
|
||||
"Import","Import"
|
||||
"Click to see data dictionary","Tryk for at se metadata (Data Dictionary)"
|
||||
"Connected to server!","Forbindelse til serveren oprettet!"
|
||||
"The {data_rv$info$project_title} project is loaded.","{data_rv$info$project_title}-projektet er forbundet."
|
||||
"Data dictionary","Data dictionary"
|
||||
"Preview:","Forsmag:"
|
||||
"Imported data set","Importeret datasæt"
|
||||
|
|
@ -182,8 +154,6 @@
|
|||
"Specify the data format","Specificér dataformatet"
|
||||
"Fill missing values?","Skal manglende observationer udfyldes?"
|
||||
"Requested data was retrieved!","Det udvalgte data blev hentet!"
|
||||
"Data retrieved, but it looks like only the ID was retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data er hentet, men det ser ud til kun at indeholde ID-variablen. Du skal kontakte din REDCap-administrator og sikre dig at du har adgang til faktisk at hente de udvalgte data."
|
||||
"Data retrieved, but it looks like not all requested fields were retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data er hentet, men det ser ud til kun at indeholde nogle af de udvalgte variabler. Du skal kontakte din REDCap-administrator og sikre dig at du har adgang til faktisk at hente de udvalgte data."
|
||||
"Click to see the imported data","Tryk for at se de importerede data"
|
||||
"Regression table","Regressionstabel"
|
||||
"Import a dataset from an environment","Importer et datasæt fra et kodemiljø"
|
||||
|
|
@ -210,18 +180,7 @@
|
|||
"Multivariable regression model checks","Tests af multivariabel regressionsmodel"
|
||||
"Grouped by {get_label(data,ter)}","Grupperet efter {get_label(data,ter)}"
|
||||
"Option to perform statistical comparisons between strata in baseline table.","Mulighed for at udføre statistiske tests mellem strata i oversigtstabellen."
|
||||
"The data includes {n_col} variables. Please limit to 100.","Data indeholder {n_col} variabler. Begræns venligst til 100."
|
||||
"Data import","Data import"
|
||||
"Data import formatting","Formatering af data ved import"
|
||||
"Data modifications","Ændringer af data"
|
||||
"Variables filter","Variables filter"
|
||||
"Data filter","Data filter"
|
||||
"Data characteristics table","Oversigtstabel"
|
||||
"The dataset without text variables","Datasættet uden variabler formateret som tekst"
|
||||
"Creating the table. Hold on for a moment..","Opretter tabellen. Vent et øjeblik.."
|
||||
"Generating the report. Hold on for a moment..","Opretter rapporten. Vent et øjeblik.."
|
||||
"We encountered the following error showing missingness:","Under analysen af manglende observationer opstod følgende fejl:"
|
||||
"We encountered the following error browsing your data:","I forsøget på at vise en dataoversigt opstod følgende fejl:"
|
||||
"Choose a name for the column to be created or modified, then enter an expression before clicking on the button below to create the variable, or cancel to exit without saving anything.","Vælg et navn til den nye variabel, skriv din formel og tryk så på knappen for at gemme variablen, eller annuler for at lukke uden at gemme."
|
||||
"Please fill in web address and API token, then press 'Connect'.","Udfyld serveradresse og API-nøgle, og tryk så 'Fobind'."
|
||||
"Other","Other"
|
||||
|
|
@ -254,16 +213,10 @@
|
|||
"Browse data preview","Forhåndsvisning af resultat"
|
||||
"Split character string","Opdel tegnstreng"
|
||||
"Split text","Opdel tekst"
|
||||
"Split a character string by a common delimiter","Opdel en tekstkolonne med en fælles afgrænser"
|
||||
"Apply split","Anvend opdeling"
|
||||
"Stacked relative barplot","Stablet relativt søjlediagram"
|
||||
"Create relative stacked barplots to show the distribution of categorical levels","Opret relative stablede søjlediagrammer for at vise fordelingen af kategoriske niveauer"
|
||||
"Side-by-side barplot","Side om side barplot"
|
||||
"Create side-by-side barplot to show the distribution of categorical levels","Opret et side-om-side søjlediagram for at vise fordelingen af kategoriske niveauer"
|
||||
"Select table theme","Vælg tema"
|
||||
"Level of detail","Detaljeniveau"
|
||||
"Minimal","Minimal"
|
||||
"Extensive","Stor"
|
||||
"Letters","Bogstaver"
|
||||
"Words","Ord"
|
||||
"Shorten to first letters","Afkort til første bogstaver"
|
||||
|
|
@ -301,7 +254,6 @@
|
|||
"FreesearchR is available in multiple languages. To help with translations, please contact us at info@freesearchr.org","FreesearchR er tilgængelig på flere sprog. For at få hjælp med oversættelser, kontakt os venligst på info@freesearchr.org"
|
||||
"Home","Hjem"
|
||||
"Start with FreesearchR for basic data evaluation and analysis.","Start med FreesearchR til grundlæggende dataevaluering og -analyse."
|
||||
"When you need more advanced tools, you'll be better prepared to use R directly.","Når du har brug for mere avancerede værktøjer, vil du være bedre forberedt på at bruge R direkte."
|
||||
"(Read more)","(Læs mere)"
|
||||
"Run the FreesearchR app locally when working with sensitive data.","Kør FreesearchR-appen lokalt, når du arbejder med følsomme data."
|
||||
"Load data from spreadsheets, REDCap servers, or try with sample data. Multiple sources supported for maximum flexibility.","Indlæs data fra regneark, REDCap-servere, eller prøv med eksempeldata. Flere kilder understøttes for maksimal fleksibilitet."
|
||||
|
|
@ -312,19 +264,63 @@
|
|||
"When you need more advanced tools, you'll be prepared to use R directly.","Når du har brug for mere avancerede værktøjer, vil du være forberedt på at bruge R direkte."
|
||||
"The app contains a selelct number of features and will guide you through key analyses.","Appen indeholder udvalgte funktioner, og guider dig gennem de vigtigste analyser."
|
||||
"Sort by Levels","Sorter efter niveauer"
|
||||
"Reorder factor levels","Omarranger niveauer"
|
||||
"Modify factor levels","Ændr kategoriske niveauer"
|
||||
"Reorder or rename the levels of factor/categorical variables.","Ændr navn eller rækkefølge på kategorisk variabel."
|
||||
"Maximum number of observations:","Maximale antal observationer:"
|
||||
"setting to 0 includes all","angiv 0 for at inkludere alle"
|
||||
"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."
|
||||
"You have provided a complete dataset with no missing values.","Data er uden manglende observationer."
|
||||
"Start by loading data.","Start med at vælge data."
|
||||
"Sample data","Træningsdata"
|
||||
"Create a new variable; otherwise replaces (Updating labels always creates new variable)","Create a new variable; otherwise replaces (Updating labels always creates new variable)"
|
||||
"Data classes and missing observations","Data classes and missing observations"
|
||||
"We encountered the following error showing missingness:","We encountered the following error showing missingness:"
|
||||
"Please confirm data reset!","Please confirm data reset!"
|
||||
"Sure you want to reset data? This cannot be undone.","Sure you want to reset data? This cannot be undone."
|
||||
"Confirm","Confirm"
|
||||
"The filtered data","The filtered data"
|
||||
"Reorder factor levels","Reorder factor levels"
|
||||
"Split a character string by a common delimiter","Split a character string by a common delimiter"
|
||||
"Create new variables","Create new variables"
|
||||
"Select data types to include","Select data types to include"
|
||||
"Uploaded data overview","Uploaded data overview"
|
||||
"We encountered the following error browsing your data:","We encountered the following error browsing your data:"
|
||||
"Data import","Data import"
|
||||
"Data import formatting","Data import formatting"
|
||||
"Data modifications","Data modifications"
|
||||
"Variables filter","Variables filter"
|
||||
"Data filter","Data filter"
|
||||
"Data characteristics table","Data characteristics table"
|
||||
"Level of detail","Level of detail"
|
||||
"Minimal","Minimal"
|
||||
"Extensive","Extensive"
|
||||
"The dataset without text variables","The dataset without text variables"
|
||||
"The data includes {n_col} variables. Please limit to 100.","The data includes {n_col} variables. Please limit to 100."
|
||||
"Creating the table. Hold on for a moment..","Creating the table. Hold on for a moment.."
|
||||
"File upload","File upload"
|
||||
"REDCap server export","REDCap server export"
|
||||
"Local or sample data","Local or sample data"
|
||||
"Sample data","Sample data"
|
||||
"Settings","Settings"
|
||||
"Create new factor","Create new factor"
|
||||
"Optional filter logic (e.g., [gender] = 'female')","Optional filter logic (e.g., [gender] = 'female')"
|
||||
"Drop empty","Drop empty"
|
||||
"Choose variable:","Choose variable:"
|
||||
"An empty data set was imported. Please review data filter.","An empty data set was imported. Please review data filter."
|
||||
"An error was encountered exporting data. Please review data filter.","An error was encountered exporting data. Please review data filter."
|
||||
"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."
|
||||
"Adjust plot input and settings below, then press ""Plot"".","Adjust plot input and settings below, then press ""Plot""."
|
||||
"Define plot","Define plot"
|
||||
"Choose color palette","Choose color palette"
|
||||
"Additional variable","Additional variable"
|
||||
"Grouping variable","Grouping variable"
|
||||
"Secondary variable","Secondary variable"
|
||||
"Reverse colors","Reverse colors"
|
||||
"Plot survey results","Plot survey results"
|
||||
"Additional variables","Additional variables"
|
||||
"Other variables","Other variables"
|
||||
"Select variables and plot type,\nthen click 'Plot' to generate visualization","Select variables and plot type,\nthen click 'Plot' to generate visualization"
|
||||
|
|
|
|||
|
|
|
@ -1,9 +1,6 @@
|
|||
"en","sw"
|
||||
"Hello","Habari"
|
||||
"Get started","Tuanze!"
|
||||
"File upload","Upakiaji wa faili"
|
||||
"REDCap server export","Usafirishaji wa seva ya REDCap"
|
||||
"Local or sample data","Data ya ndani au ya sampuli"
|
||||
"Please be mindfull handling sensitive data","Tafadhali kuwa mwangalifu kushughulikia data nyeti"
|
||||
"Quick overview","Muhtasari wa haraka"
|
||||
"Select variables for final import","Chagua vigezo vya kuingiza mwisho"
|
||||
|
|
@ -58,7 +55,6 @@
|
|||
"Imported data","Data iliyoingizwa"
|
||||
"www/intro.md","www/intro.md"
|
||||
"Choose your data","Chagua data yako"
|
||||
"Factor variable to reorder:","Kigezo cha vipengele ili kupanga upya:"
|
||||
"Sort by levels","Panga kwa viwango"
|
||||
"Sort by count","Panga kwa hesabu"
|
||||
"Update factor variable","Sasisha kigezo cha kipengele"
|
||||
|
|
@ -92,9 +88,7 @@
|
|||
"No variables have a correlation measure above the threshold.","Hakuna vigezo vyenye kipimo cha uhusiano kilicho juu ya kizingiti."
|
||||
"and","na"
|
||||
"from each pair","kutoka kwa kila jozi"
|
||||
"Only non-text variables are available for plotting. Go the ""Data"" to reclass data to plot.","Vigezo visivyo vya maandishi pekee ndivyo vinavyopatikana kwa ajili ya kupanga. Nenda kwenye ""Data"" ili kupanga upya data ili kupanga."
|
||||
"Plot","Kipande cha habari"
|
||||
"Adjust settings, then press ""Plot"".","Rekebisha mipangilio, kisha bonyeza ""Plot""."
|
||||
"Plot height (mm)","Urefu wa kiwanja (mm)"
|
||||
"Plot width (mm)","Upana wa kiwanja (mm)"
|
||||
"File format","Umbizo la faili"
|
||||
|
|
@ -102,18 +96,11 @@
|
|||
"Select variable","Chagua kigezo"
|
||||
"Response variable","Kigezo cha majibu"
|
||||
"Plot type","Aina ya kiwanja"
|
||||
"Please select","Tafadhali chagua"
|
||||
"Additional variables","Vigezo vya ziada"
|
||||
"Secondary variable","Kigezo cha pili"
|
||||
"No variable","Hakuna kigezo"
|
||||
"Grouping variable","Kigezo cha kuweka katika makundi"
|
||||
"No stratification","Hakuna matabaka"
|
||||
"Drawing the plot. Hold tight for a moment..","Kuchora njama. Shikilia kwa muda.."
|
||||
"#Plotting\n","#Upangaji\n"
|
||||
"Stacked horizontal bars","Pau za mlalo zilizopangwa kwa mpangilio"
|
||||
"A classical way of visualising the distribution of an ordinal scale like the modified Ranking Scale and known as Grotta bars","Njia ya kitamaduni ya kuibua usambazaji wa mizani ya kawaida kama vile Mizani ya Nafasi iliyorekebishwa na inayojulikana kama baa za Grotta"
|
||||
"Violin plot","Hadithi ya violin"
|
||||
"A modern alternative to the classic boxplot to visualise data distribution","Njia mbadala ya kisasa ya mpangilio wa kisanduku wa kawaida ili kuibua usambazaji wa data"
|
||||
"Sankey plot","Njama ya Sankey"
|
||||
"A way of visualising change between groups","Njia ya kuibua mabadiliko kati ya vikundi"
|
||||
"Scatter plot","Njama ya kutawanya"
|
||||
|
|
@ -121,7 +108,6 @@
|
|||
"Box plot","Kipande cha sanduku"
|
||||
"A classic way to plot data distribution by groups","Njia ya kawaida ya kupanga usambazaji wa data kwa vikundi"
|
||||
"Euler diagram","Mchoro wa Euler"
|
||||
"Generate area-proportional Euler diagrams to display set relationships","Tengeneza michoro ya Euler inayolingana na eneo ili kuonyesha uhusiano uliowekwa"
|
||||
"Documentation","Nyaraka"
|
||||
"Data is only stored for analyses and deleted when the app is closed.","Data huhifadhiwa kwa ajili ya uchambuzi na kufutwa tu wakati programu imefungwa."
|
||||
"Feedback","Maoni"
|
||||
|
|
@ -132,7 +118,6 @@
|
|||
"Coefficients plot","Mchoro wa viambato"
|
||||
"Checks","Hundi"
|
||||
"Browse observations","Vinjari uchunguzi"
|
||||
"Settings","Mipangilio"
|
||||
"The following error occured on determining correlations:","Hitilafu ifuatayo ilitokea katika kubaini uhusiano:"
|
||||
"No missing observations","Hakuna uchunguzi unaokosekana"
|
||||
"There is a total of {p_miss} % missing observations.","Kuna jumla ya uchunguzi wa {p_miss}% unaokosekana."
|
||||
|
|
@ -145,15 +130,7 @@
|
|||
"Missings","Hazipo"
|
||||
"Class","Darasa"
|
||||
"Observations","Uchunguzi"
|
||||
"Data classes and missing observations","Madarasa ya data na uchunguzi unaokosekana"
|
||||
"Sure you want to reset data? This cannot be undone.","Una uhakika unataka kuweka upya data? Hii haiwezi kutenduliwa."
|
||||
"Cancel","Ghairi"
|
||||
"Confirm","Thibitisha"
|
||||
"The filtered data","Data iliyochujwa"
|
||||
"Create new factor","Unda kipengele kipya"
|
||||
"Create new variables","Unda vigezo vipya"
|
||||
"Select data types to include","Chagua aina za data za kujumuisha"
|
||||
"Uploaded data overview","Muhtasari wa data iliyopakiwa"
|
||||
"Specify covariables","Bainisha vigeu vinavyoweza kuunganishwa"
|
||||
"If none are selected, all are included.","Ikiwa hakuna aliyechaguliwa, wote wamejumuishwa."
|
||||
"Analyse","Changanua"
|
||||
|
|
@ -161,20 +138,15 @@
|
|||
"Press 'Analyse' to create the regression model and after changing parameters.","Bonyeza 'Changanua' ili kuunda modeli ya urejeshaji na baada ya kubadilisha vigezo."
|
||||
"Show p-value","Onyesha thamani ya p"
|
||||
"Model checks","Ukaguzi wa modeli"
|
||||
"Please confirm data reset!","Tafadhali thibitisha urejeshaji wa data!"
|
||||
"Import data from REDCap","Ingiza data kutoka REDCap"
|
||||
"REDCap server","Seva ya REDCap"
|
||||
"Web address","Anwani ya wavuti"
|
||||
"Format should be either 'https://redcap.your.institution/' or 'https://your.institution/redcap/'","Muundo unapaswa kuwa 'https://redcap.your.institution/' au 'https://your.institution/redcap/'"
|
||||
"API token","Tokeni ya API"
|
||||
"The token is a string of 32 numbers and letters.","Tokeni ni mfuatano wa nambari na herufi 32."
|
||||
"Connect","Unganisha"
|
||||
"Data import parameters","Vigezo vya kuingiza data"
|
||||
"Select fields/variables to import and click the funnel to apply optional filters","Chagua sehemu/vigezo vya kuingiza na ubofye faneli ili kutumia vichujio vya hiari"
|
||||
"Import","Ingiza"
|
||||
"Click to see data dictionary","Bofya ili kuona kamusi ya data"
|
||||
"Connected to server!","Imeunganishwa na seva!"
|
||||
"The {data_rv$info$project_title} project is loaded.","Mradi wa {data_rv$info$project_title} umepakiwa."
|
||||
"Data dictionary","Kamusi ya data"
|
||||
"Preview:","Hakikisho:"
|
||||
"Imported data set","Seti ya data iliyoingizwa"
|
||||
|
|
@ -182,8 +154,6 @@
|
|||
"Specify the data format","Bainisha umbizo la data"
|
||||
"Fill missing values?","Jaza thamani zinazokosekana?"
|
||||
"Requested data was retrieved!","Data iliyoombwa ilipatikana!"
|
||||
"Data retrieved, but it looks like only the ID was retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data imerejeshwa, lakini inaonekana ni kitambulisho pekee kilichorejeshwa kutoka kwa seva. Tafadhali wasiliana na msimamizi wako wa REDCap kama una ruhusa zinazohitajika kwa ufikiaji wa data."
|
||||
"Data retrieved, but it looks like not all requested fields were retrieved from the server. Please check with your REDCap administrator that you have required permissions for data access.","Data imerejeshwa, lakini inaonekana kama si sehemu zote zilizoombwa zilizorejeshwa kutoka kwa seva. Tafadhali wasiliana na msimamizi wako wa REDCap kama una ruhusa zinazohitajika kwa ufikiaji wa data."
|
||||
"Click to see the imported data","Bofya ili kuona data iliyoingizwa"
|
||||
"Regression table","Jedwali la urejeshaji"
|
||||
"Import a dataset from an environment","Ingiza seti ya data kutoka kwa mazingira"
|
||||
|
|
@ -210,18 +180,7 @@
|
|||
"Multivariable regression model checks","Ukaguzi wa modeli ya urejeshaji unaoweza kubadilika-badilika"
|
||||
"Grouped by {get_label(data,ter)}","Imepangwa kwa makundi kulingana na {get_label(data,ter)}"
|
||||
"Option to perform statistical comparisons between strata in baseline table.","Chaguo la kufanya ulinganisho wa takwimu kati ya tabaka katika jedwali la msingi."
|
||||
"The data includes {n_col} variables. Please limit to 100.","Data inajumuisha vigezo vya {n_col}. Tafadhali punguza hadi 100."
|
||||
"Data import","Uingizaji wa data"
|
||||
"Data import formatting","Uumbizaji wa kuingiza data"
|
||||
"Data modifications","Marekebisho ya data"
|
||||
"Variables filter","Kichujio cha vigeugeu"
|
||||
"Data filter","Kichujio cha data"
|
||||
"Data characteristics table","Jedwali la sifa za data"
|
||||
"The dataset without text variables","Seti ya data bila vigeu vya maandishi"
|
||||
"Creating the table. Hold on for a moment..","Kutengeneza meza. Subiri kwa muda.."
|
||||
"Generating the report. Hold on for a moment..","Inazalisha ripoti. Subiri kidogo.."
|
||||
"We encountered the following error showing missingness:","Tulikutana na hitilafu ifuatayo inayoonyesha ukosefu:"
|
||||
"We encountered the following error browsing your data:","Tulipata hitilafu ifuatayo wakati wa kuvinjari data yako:"
|
||||
"Choose a name for the column to be created or modified, then enter an expression before clicking on the button below to create the variable, or cancel to exit without saving anything.","Chagua jina la safu wima itakayoundwa au kurekebishwa, kisha ingiza usemi kabla ya kubofya kitufe kilicho hapa chini ili kuunda kigezo, au ghairi ili kutoka bila kuhifadhi chochote."
|
||||
"Other","Nyingine"
|
||||
"Hour of the day","Saa ya siku"
|
||||
|
|
@ -249,7 +208,6 @@
|
|||
"Split string to multiple observations (rows) in the same column. Also ads id and instance columns","Gawanya mfuatano katika uchunguzi mwingi (safu) katika safu wima moja. Pia vitambulisho vya matangazo na safu wima za mfano"
|
||||
"Split character string","Gawanya mfuatano wa herufi"
|
||||
"Split text","Gawanya maandishi"
|
||||
"Split a character string by a common delimiter","Gawanya mfuatano wa herufi kwa kitenganishi cha kawaida"
|
||||
"Select delimiter","Chagua kidhibiti"
|
||||
"Browse data preview","Vinjari hakikisho la data"
|
||||
"Original data","Data asili"
|
||||
|
|
@ -257,13 +215,8 @@
|
|||
"No character variables with accepted delimiters detected.","Hakuna vigezo vya herufi vilivyo na vidhibiti vinavyokubalika vilivyogunduliwa."
|
||||
"Apply split","Tumia mgawanyiko"
|
||||
"Stacked relative barplot","Kipande cha baruni kilichopangwa kwa mirundiko"
|
||||
"Create relative stacked barplots to show the distribution of categorical levels","Unda viwanja vya baruni vilivyopangwa ili kuonyesha usambazaji wa viwango vya kategoria"
|
||||
"Side-by-side barplot","Kipande cha baruni cha kando kwa kando"
|
||||
"Create side-by-side barplot to show the distribution of categorical levels","Unda mpangilio wa barufa kando ili kuonyesha usambazaji wa viwango vya kategoria"
|
||||
"Select table theme","Chagua mandhari ya jedwali"
|
||||
"Level of detail","Kiwango cha maelezo"
|
||||
"Minimal","Kidogo"
|
||||
"Extensive","Kina"
|
||||
"Letters","Barua"
|
||||
"Words","Maneno"
|
||||
"Shorten to first letters","Fupisha herufi za kwanza"
|
||||
|
|
@ -301,7 +254,6 @@
|
|||
"FreesearchR is available in multiple languages. To help with translations, please contact us at info@freesearchr.org","FreesearchR inapatikana katika lugha nyingi. Ili kukusaidia na tafsiri, tafadhali wasiliana nasi kwa info@freesearchr.org."
|
||||
"Home","Nyumbani"
|
||||
"Start with FreesearchR for basic data evaluation and analysis.","Anza na FreesearchR kwa tathmini na uchambuzi wa data ya msingi."
|
||||
"When you need more advanced tools, you'll be better prepared to use R directly.","Unapohitaji zana za hali ya juu zaidi, utakuwa tayari zaidi kutumia R moja kwa moja."
|
||||
"(Read more)","(Soma zaidi)"
|
||||
"Run the FreesearchR app locally when working with sensitive data.","Endesha programu ya FreesearchR ndani ya eneo lako unapofanya kazi na data nyeti."
|
||||
"Load data from spreadsheets, REDCap servers, or try with sample data. Multiple sources supported for maximum flexibility.","Pakia data kutoka kwa lahajedwali, seva za REDCap, au jaribu na data ya sampuli. Vyanzo vingi vinaungwa mkono kwa unyumbufu wa hali ya juu."
|
||||
|
|
@ -312,19 +264,63 @@
|
|||
"When you need more advanced tools, you'll be prepared to use R directly.","Unapohitaji zana za hali ya juu zaidi, utakuwa tayari kutumia R moja kwa moja."
|
||||
"The app contains a selelct number of features and will guide you through key analyses.","The app contains a selelct number of features and will guide you through key analyses."
|
||||
"Sort by Levels","Sort by Levels"
|
||||
"Reorder factor levels","Reorder factor levels"
|
||||
"Modify factor levels","Modify factor levels"
|
||||
"Reorder or rename the levels of factor/categorical variables.","Reorder or rename the levels of factor/categorical variables."
|
||||
"Maximum number of observations:","Maximum number of observations:"
|
||||
"setting to 0 includes all","setting to 0 includes all"
|
||||
"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."
|
||||
"You have provided a complete dataset with no missing values.","You have provided a complete dataset with no missing values."
|
||||
"Start by loading data.","Start by loading data."
|
||||
"Data classes and missing observations","Data classes and missing observations"
|
||||
"We encountered the following error showing missingness:","We encountered the following error showing missingness:"
|
||||
"Please confirm data reset!","Please confirm data reset!"
|
||||
"Sure you want to reset data? This cannot be undone.","Sure you want to reset data? This cannot be undone."
|
||||
"Confirm","Confirm"
|
||||
"The filtered data","The filtered data"
|
||||
"Reorder factor levels","Reorder factor levels"
|
||||
"Split a character string by a common delimiter","Split a character string by a common delimiter"
|
||||
"Create new variables","Create new variables"
|
||||
"Select data types to include","Select data types to include"
|
||||
"Uploaded data overview","Uploaded data overview"
|
||||
"We encountered the following error browsing your data:","We encountered the following error browsing your data:"
|
||||
"Data import","Data import"
|
||||
"Data import formatting","Data import formatting"
|
||||
"Data modifications","Data modifications"
|
||||
"Variables filter","Variables filter"
|
||||
"Data filter","Data filter"
|
||||
"Data characteristics table","Data characteristics table"
|
||||
"Level of detail","Level of detail"
|
||||
"Minimal","Minimal"
|
||||
"Extensive","Extensive"
|
||||
"The dataset without text variables","The dataset without text variables"
|
||||
"The data includes {n_col} variables. Please limit to 100.","The data includes {n_col} variables. Please limit to 100."
|
||||
"Creating the table. Hold on for a moment..","Creating the table. Hold on for a moment.."
|
||||
"File upload","File upload"
|
||||
"REDCap server export","REDCap server export"
|
||||
"Local or sample data","Local or sample data"
|
||||
"Sample data","Sample data"
|
||||
"Create a new variable; otherwise replaces (Updating labels always creates new variable)","Create a new variable; otherwise replaces (Updating labels always creates new variable)"
|
||||
"Settings","Settings"
|
||||
"Create new factor","Create new factor"
|
||||
"Optional filter logic (e.g., [gender] = 'female')","Optional filter logic (e.g., [gender] = 'female')"
|
||||
"Drop empty","Drop empty"
|
||||
"Choose variable:","Choose variable:"
|
||||
"An empty data set was imported. Please review data filter.","An empty data set was imported. Please review data filter."
|
||||
"An error was encountered exporting data. Please review data filter.","An error was encountered exporting data. Please review data filter."
|
||||
"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."
|
||||
"Adjust plot input and settings below, then press ""Plot"".","Adjust plot input and settings below, then press ""Plot""."
|
||||
"Define plot","Define plot"
|
||||
"Choose color palette","Choose color palette"
|
||||
"Additional variable","Additional variable"
|
||||
"Grouping variable","Grouping variable"
|
||||
"Secondary variable","Secondary variable"
|
||||
"Reverse colors","Reverse colors"
|
||||
"Plot survey results","Plot survey results"
|
||||
"Additional variables","Additional variables"
|
||||
"Other variables","Other variables"
|
||||
"Select variables and plot type,\nthen click 'Plot' to generate visualization","Select variables and plot type,\nthen click 'Plot' to generate visualization"
|
||||
|
|
|
|||
|
|
|
@ -1,10 +1,10 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{align_axes}
|
||||
\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}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{all_but}
|
||||
\alias{all_but}
|
||||
\title{Select all from vector but}
|
||||
|
|
|
|||
27
man/available_plots.Rd
Normal file
27
man/available_plots.Rd
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{available_plots}
|
||||
\alias{available_plots}
|
||||
\title{Implemented functions}
|
||||
\usage{
|
||||
available_plots()
|
||||
}
|
||||
\value{
|
||||
list
|
||||
}
|
||||
\description{
|
||||
Library of supported functions. The list name and "descr" element should be
|
||||
unique for each element on list.
|
||||
\itemize{
|
||||
\item fun: the plotting function
|
||||
\item fun.args: default parameters for the plotting function
|
||||
\item descr: Plot description
|
||||
\item note: Short note/description of the function for displaying in ui and docs
|
||||
\item primary.type: Primary variable data type (see \link{data_type})
|
||||
\item base: holds a list of parameters for plot input fields generation
|
||||
Secondary and tertiary variable input fields are mandatory.
|
||||
}
|
||||
}
|
||||
\examples{
|
||||
available_plots() |> str()
|
||||
}
|
||||
72
man/check_app_version.Rd
Normal file
72
man/check_app_version.Rd
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/version_check.R
|
||||
\name{check_app_version}
|
||||
\alias{check_app_version}
|
||||
\title{Run a startup version check and return a banner UI element}
|
||||
\usage{
|
||||
check_app_version(
|
||||
github_user,
|
||||
github_repo,
|
||||
app_version = NULL,
|
||||
verbose = FALSE
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
\item{github_user}{GitHub username or organisation that owns the repository.}
|
||||
|
||||
\item{github_repo}{Repository name. Also used as the package name for
|
||||
\code{utils::packageVersion()}.}
|
||||
|
||||
\item{app_version}{Optional fallback version string for environments where
|
||||
the package is not installed (e.g. shinyapps.io). Pass the result of your
|
||||
\code{app_version()} function here. Ignored when \code{packageVersion()}
|
||||
succeeds.}
|
||||
|
||||
\item{verbose}{Logical; if \code{TRUE} a banner is always returned.
|
||||
Defaults to \code{FALSE}.}
|
||||
}
|
||||
\value{
|
||||
A \code{shinyWidgets::alert()} UI element, or \code{NULL} when there
|
||||
is nothing to show (up to date in non-verbose mode).
|
||||
}
|
||||
\description{
|
||||
Call this \strong{outside} \code{server()} -- typically in
|
||||
\code{global.R} or at the top of \code{app.R} -- and embed the returned
|
||||
value directly in your UI definition. Because the check runs at startup
|
||||
the banner is present on first render with no loading delay, and no
|
||||
\code{uiOutput()} / \code{renderUI()} wiring is needed.
|
||||
}
|
||||
\details{
|
||||
\strong{Normal mode} (\code{verbose = FALSE}): returns a banner only when
|
||||
a newer version is available or when the check fails. Returns \code{NULL}
|
||||
when the app is up to date (Shiny silently ignores \code{NULL} in the UI).
|
||||
|
||||
\strong{Verbose / debug mode} (\code{verbose = TRUE}): always returns a
|
||||
banner -- including a success banner when up to date -- so you can confirm
|
||||
the check ran and inspect both version strings during development.
|
||||
}
|
||||
\examples{
|
||||
\dontrun{
|
||||
# global.R or top of app.R
|
||||
source("version_check.R")
|
||||
version_banner <- check_app_version(
|
||||
github_user = "my-org",
|
||||
github_repo = "my-shiny-app",
|
||||
app_version = app_version() # fallback for shinyapps.io
|
||||
)
|
||||
|
||||
# ui.R
|
||||
fluidPage(
|
||||
version_banner,
|
||||
# ... rest of UI
|
||||
)
|
||||
|
||||
# Verbose mode for development
|
||||
version_banner <- check_app_version(
|
||||
github_user = "my-org",
|
||||
github_repo = "my-shiny-app",
|
||||
app_version = app_version(),
|
||||
verbose = TRUE
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{clean_common_axis}
|
||||
\alias{clean_common_axis}
|
||||
\title{Extract and clean axis ranges}
|
||||
|
|
|
|||
72
man/colorSelectInput.Rd
Normal file
72
man/colorSelectInput.Rd
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/custom_SelectInput.R
|
||||
\name{colorSelectInput}
|
||||
\alias{colorSelectInput}
|
||||
\title{A selectizeInput customized for named vectors of color names supported by
|
||||
\code{\link{generate_colors}}}
|
||||
\usage{
|
||||
colorSelectInput(
|
||||
inputId,
|
||||
label,
|
||||
choices,
|
||||
selected = NULL,
|
||||
previews = 4,
|
||||
...,
|
||||
placeholder = ""
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
\item{inputId}{passed to \code{\link[shiny]{selectizeInput}}}
|
||||
|
||||
\item{label}{passed to \code{\link[shiny]{selectizeInput}}}
|
||||
|
||||
\item{choices}{A named \code{vector} from which fields should be populated}
|
||||
|
||||
\item{selected}{default selection}
|
||||
|
||||
\item{previews}{number of preview colors. Default is 4.}
|
||||
|
||||
\item{...}{passed to \code{\link[shiny]{selectizeInput}}}
|
||||
|
||||
\item{placeholder}{passed to \code{\link[shiny]{selectizeInput}} options}
|
||||
|
||||
\item{onInitialize}{passed to \code{\link[shiny]{selectizeInput}} options}
|
||||
}
|
||||
\value{
|
||||
a \code{\link[shiny]{selectizeInput}} dropdown element
|
||||
}
|
||||
\description{
|
||||
A selectizeInput customized for named vectors of color names supported by
|
||||
\code{\link{generate_colors}}
|
||||
}
|
||||
\examples{
|
||||
if (shiny::interactive()) {
|
||||
top_palettes <- c(
|
||||
"Perceptual (blue-yellow)" = "viridis",
|
||||
"Perceptual (fire)" = "plasma",
|
||||
"Colour-blind friendly" = "Okabe-Ito",
|
||||
"Qualitative (bold)" = "Dark 2",
|
||||
"Qualitative (paired)" = "Paired",
|
||||
"Sequential (blues)" = "Blues",
|
||||
"Diverging (red-blue)" = "RdBu",
|
||||
"Tableau style" = "Tableau 10",
|
||||
"Pastel" = "Pastel 1",
|
||||
"Rainbow" = "rainbow"
|
||||
)
|
||||
shinyApp(
|
||||
ui = fluidPage(
|
||||
titlePanel("Color Palette Select Test"),
|
||||
colorSelectInput(
|
||||
inputId = "palette",
|
||||
label = "Color palette",
|
||||
choices = top_palettes,
|
||||
selected = "viridis"
|
||||
),
|
||||
verbatimTextOutput("selected")
|
||||
),
|
||||
server = function(input, output, session) {
|
||||
output$selected <- renderPrint(input$palette)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
44
man/continuous_colors.Rd
Normal file
44
man/continuous_colors.Rd
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/generate_colors.R
|
||||
\name{continuous_colors}
|
||||
\alias{continuous_colors}
|
||||
\title{Create a Continuous Color Function from a Palette}
|
||||
\usage{
|
||||
continuous_colors(palette = "viridis", n = 256, ...)
|
||||
}
|
||||
\arguments{
|
||||
\item{palette}{Passed directly to \code{\link[=generate_colors]{generate_colors()}}. Either a palette
|
||||
name string or a function.}
|
||||
|
||||
\item{n}{\code{integer}. Resolution of the underlying color ramp — higher
|
||||
values give smoother gradients. Defaults to 256.}
|
||||
|
||||
\item{...}{Additional arguments passed to \code{\link[=generate_colors]{generate_colors()}}.}
|
||||
}
|
||||
\value{
|
||||
A function that takes a numeric vector of values in \code{[0, 1]}
|
||||
and returns a character vector of hex colors.
|
||||
}
|
||||
\description{
|
||||
Wraps \code{\link{generate_colors}} into a function that accepts a value
|
||||
between 0 and 1 and returns the corresponding color. Useful for mapping
|
||||
continuous variables to colors.
|
||||
}
|
||||
\examples{
|
||||
pal <- continuous_colors("viridis")
|
||||
pal(0) # first color
|
||||
pal(1) # last color
|
||||
pal(0.5) # midpoint
|
||||
|
||||
# Map a continuous variable to colors
|
||||
values <- seq(0, 1, length.out = 10)
|
||||
pal(values)
|
||||
|
||||
# Works with any palette generate_colors() accepts
|
||||
pal <- continuous_colors("plasma", direction = -1)
|
||||
pal <- continuous_colors(\(n) hcl.colors(n, palette = "Blue-Red"))
|
||||
|
||||
}
|
||||
\seealso{
|
||||
\code{\link[=generate_colors]{generate_colors()}}
|
||||
}
|
||||
|
|
@ -12,7 +12,8 @@ create_baseline(
|
|||
add.diff = FALSE,
|
||||
add.overall = FALSE,
|
||||
theme = c("jama", "lancet", "nejm", "qjecon"),
|
||||
detail_level = c("minimal", "extended")
|
||||
detail_level = c("minimal", "extended"),
|
||||
drop_empty = FALSE
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R, R/plot_bar.R, R/plot_box.R,
|
||||
% R/plot_hbar.R, R/plot_ridge.R, R/plot_sankey.R, R/plot_scatter.R,
|
||||
% R/plot_violin.R
|
||||
% Please edit documentation in R/data_plots.R, R/plot-helpers.R, R/plot_bar.R,
|
||||
% R/plot_box.R, R/plot_hbar.R, R/plot_likert.R, R/plot_ridge.R,
|
||||
% R/plot_sankey.R, R/plot_scatter.R, R/plot_violin.R
|
||||
\name{data-plots}
|
||||
\alias{data-plots}
|
||||
\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}
|
||||
\alias{plot_hbars}
|
||||
\alias{plot_likert}
|
||||
\alias{plot_ridge}
|
||||
\alias{sankey_ready}
|
||||
\alias{plot_sankey}
|
||||
|
|
@ -20,25 +22,39 @@
|
|||
\usage{
|
||||
data_visuals_ui(id, tab_title = "Plots", ...)
|
||||
|
||||
data_visuals_server(id, data, ...)
|
||||
data_visuals_server(id, data, palettes = color_choices(), ...)
|
||||
|
||||
create_plot(data, type, pri, sec, ter = NULL, ...)
|
||||
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,
|
||||
sec = NULL,
|
||||
style = c("stack", "dodge", "fill"),
|
||||
max_level = 30
|
||||
max_level = 30,
|
||||
color.palette = "viridis"
|
||||
)
|
||||
|
||||
plot_box(data, pri, sec, ter = NULL, ...)
|
||||
plot_box(data, pri, sec, ter = NULL, color.palette = "viridis", ...)
|
||||
|
||||
plot_box_single(data, pri, sec = NULL, seed = 2103)
|
||||
plot_box_single(data, pri, sec = NULL, seed = 2103, color.palette = "viridis")
|
||||
|
||||
plot_hbars(data, pri, sec, ter = NULL)
|
||||
plot_hbars(data, pri, sec, ter = NULL, color.palette = "viridis", ...)
|
||||
|
||||
plot_ridge(data, x, y, z = NULL, ...)
|
||||
plot_likert(data, pri, sec = NULL, ter = NULL, color.palette = "viridis", ...)
|
||||
|
||||
plot_ridge(data, x, y, z = NULL, color.palette = "viridis", ...)
|
||||
|
||||
sankey_ready(data, pri, sec, numbers = "count", ...)
|
||||
|
||||
|
|
@ -49,12 +65,17 @@ plot_sankey(
|
|||
ter = NULL,
|
||||
color.group = "pri",
|
||||
colors = NULL,
|
||||
missing.level = "Missing"
|
||||
color.palette = "viridis",
|
||||
default.color = "#2986cc",
|
||||
box.color = "#1E4B66",
|
||||
na.color = "grey80",
|
||||
missing.level = "Missing",
|
||||
...
|
||||
)
|
||||
|
||||
plot_scatter(data, pri, sec, ter = NULL)
|
||||
plot_scatter(data, pri, sec, ter = NULL, color.palette = "viridis", ...)
|
||||
|
||||
plot_violin(data, pri, sec, ter = NULL)
|
||||
plot_violin(data, pri, sec, ter = NULL, color.palette = "viridis", ...)
|
||||
}
|
||||
\arguments{
|
||||
\item{id}{Module id. (Use 'ns("id")')}
|
||||
|
|
@ -71,6 +92,8 @@ plot_violin(data, pri, sec, ter = NULL)
|
|||
|
||||
\item{ter}{tertiary variable}
|
||||
|
||||
\item{color.palette}{choose color palette. See \code{\link{plot_colors}} for support.}
|
||||
|
||||
\item{style}{barplot style passed to geom_bar position argument.
|
||||
One of c("stack", "dodge", "fill")}
|
||||
}
|
||||
|
|
@ -81,6 +104,8 @@ shiny server module
|
|||
|
||||
ggplot2 object
|
||||
|
||||
ggplot list object
|
||||
|
||||
ggplot object
|
||||
|
||||
ggplot2 object
|
||||
|
|
@ -91,6 +116,8 @@ ggplot2 object
|
|||
|
||||
ggplot2 object
|
||||
|
||||
ggplot2 object
|
||||
|
||||
data.frame
|
||||
|
||||
ggplot2 object
|
||||
|
|
@ -104,6 +131,8 @@ Data correlations evaluation module
|
|||
|
||||
Wrapper to create plot based on provided type
|
||||
|
||||
Title
|
||||
|
||||
Single vertical barplot
|
||||
|
||||
Beautiful box plot(s)
|
||||
|
|
@ -112,6 +141,8 @@ Create nice box-plots
|
|||
|
||||
Nice horizontal stacked bars (Grotta bars)
|
||||
|
||||
Nice horizontal bar plot centred on the central category
|
||||
|
||||
Plot nice ridge plot
|
||||
|
||||
Readying data for sankey plot
|
||||
|
|
@ -120,17 +151,24 @@ Beautiful sankey plot with option to split by a tertiary group
|
|||
|
||||
Beautiful violin plot
|
||||
|
||||
Beatiful violin plot
|
||||
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")
|
||||
|
||||
mtcars |>
|
||||
dplyr::mutate(cyl = factor(cyl), am = factor(am)) |>
|
||||
plot_bar_single(pri = "cyl", style = "stack")
|
||||
plot_bar_single(pri = "cyl", style = "stack",color.palette="turbo")
|
||||
mtcars |> plot_box(pri = "mpg", sec = "gear")
|
||||
mtcars |> plot_box(pri = "mpg", sec="cyl")
|
||||
mtcars |>
|
||||
|
|
@ -140,11 +178,19 @@ mtcars |>
|
|||
default_parsing() |>
|
||||
plot_box(pri = "mpg", sec = "cyl", ter = "gear",axis.font.family="mono")
|
||||
mtcars |> plot_box_single("mpg")
|
||||
mtcars |> plot_box_single("mpg","cyl")
|
||||
mtcars |> plot_box_single("mpg","cyl",color.palette="Blues")
|
||||
stRoke::trial |> plot_box_single("age","active",color.palette="Blues")
|
||||
gtsummary::trial |> plot_box_single("age","trt")
|
||||
mtcars |> plot_hbars(pri = "carb", sec = "cyl")
|
||||
mtcars |> plot_hbars(pri = "carb", sec = "cyl", ter="am")
|
||||
mtcars |> plot_hbars(pri = "carb", sec = NULL)
|
||||
mtcars |> plot_hbars(pri = "carb", sec = NULL,color.palette="Blues")
|
||||
mtcars |> plot_hbars(pri = "carb", sec = NULL,color.palette="Magma")
|
||||
mtcars |> plot_hbars(pri = "carb", sec = "am",color.palette="Viridis")
|
||||
mtcars |> plot_likert(pri = "carb", sec = "cyl")
|
||||
mtcars |> plot_likert(pri = "carb", sec = "cyl", ter="am")
|
||||
mtcars |> plot_likert(pri = "cyl",color.palette="Blues")
|
||||
mtcars |> plot_likert(pri = "carb", sec = NULL,color.palette="Magma")
|
||||
mtcars |> plot_likert(pri = "carb", sec = c("cyl","am"),color.palette="Viridis")
|
||||
mtcars |>
|
||||
default_parsing() |>
|
||||
plot_ridge(x = "mpg", y = "cyl")
|
||||
|
|
@ -169,7 +215,9 @@ mtcars |>
|
|||
## Dont know why...
|
||||
mtcars |>
|
||||
default_parsing() |>
|
||||
plot_sankey("cyl", "gear", "vs", color.group = "pri")
|
||||
plot_sankey("cyl", "gear", "vs", color.group = "pri",color.palette="inferno")
|
||||
mtcars |> plot_scatter(pri = "mpg", sec = "wt")
|
||||
mtcars |> plot_violin(pri = "mpg", sec = "cyl", ter = "gear")
|
||||
mtcars |> plot_scatter(pri = "mpg", sec = "wt",ter="carb")
|
||||
mtcars |> plot_violin(pri = "mpg", sec = "cyl")
|
||||
mtcars |> plot_violin(pri = "mpg", sec = "cyl", ter = "gear", color.palette="Blues")
|
||||
}
|
||||
|
|
|
|||
32
man/dot-build_version_alert.Rd
Normal file
32
man/dot-build_version_alert.Rd
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/version_check.R
|
||||
\name{.build_version_alert}
|
||||
\alias{.build_version_alert}
|
||||
\title{Build a shinyWidgets::alert() UI element for the version banner}
|
||||
\usage{
|
||||
.build_version_alert(
|
||||
current,
|
||||
latest,
|
||||
update_available,
|
||||
github_user,
|
||||
github_repo
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
\item{current}{Current installed version string.}
|
||||
|
||||
\item{latest}{Latest GitHub release version string, or NULL when
|
||||
the check could not complete (e.g. no internet).}
|
||||
|
||||
\item{update_available}{Logical; whether latest > current.}
|
||||
|
||||
\item{github_user}{GitHub username / organisation.}
|
||||
|
||||
\item{github_repo}{Repository name.}
|
||||
}
|
||||
\value{
|
||||
A \code{shinyWidgets::alert()} UI element.
|
||||
}
|
||||
\description{
|
||||
Build a shinyWidgets::alert() UI element for the version banner
|
||||
}
|
||||
20
man/dot-get_latest_github_version.Rd
Normal file
20
man/dot-get_latest_github_version.Rd
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/version_check.R
|
||||
\name{.get_latest_github_version}
|
||||
\alias{.get_latest_github_version}
|
||||
\title{Fetch the latest release version from a GitHub repository}
|
||||
\usage{
|
||||
.get_latest_github_version(github_user, github_repo)
|
||||
}
|
||||
\arguments{
|
||||
\item{github_user}{GitHub username or organisation.}
|
||||
|
||||
\item{github_repo}{Repository name.}
|
||||
}
|
||||
\value{
|
||||
A character string with the version tag (e.g. "1.2.0"), or NULL on
|
||||
failure.
|
||||
}
|
||||
\description{
|
||||
Fetch the latest release version from a GitHub repository
|
||||
}
|
||||
14
man/dot-has_internet.Rd
Normal file
14
man/dot-has_internet.Rd
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/version_check.R
|
||||
\name{.has_internet}
|
||||
\alias{.has_internet}
|
||||
\title{Check internet connectivity}
|
||||
\usage{
|
||||
.has_internet()
|
||||
}
|
||||
\value{
|
||||
Logical; TRUE if an internet connection is available.
|
||||
}
|
||||
\description{
|
||||
Check internet connectivity
|
||||
}
|
||||
27
man/dot-resolve_app_version.Rd
Normal file
27
man/dot-resolve_app_version.Rd
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/version_check.R
|
||||
\name{.resolve_app_version}
|
||||
\alias{.resolve_app_version}
|
||||
\title{Resolve the current app version}
|
||||
\usage{
|
||||
.resolve_app_version(package_name, app_version = NULL)
|
||||
}
|
||||
\arguments{
|
||||
\item{package_name}{Name of the package / repository.}
|
||||
|
||||
\item{app_version}{Optional fallback version string.}
|
||||
}
|
||||
\value{
|
||||
A character string with the version (e.g. "1.1.0"), or NULL if
|
||||
neither strategy succeeds.
|
||||
}
|
||||
\description{
|
||||
Tries two strategies in order:
|
||||
\enumerate{
|
||||
\item \code{utils::packageVersion(package_name)} -- works when the package
|
||||
is installed locally (development, local \code{runApp()}).
|
||||
\item \code{app_version} argument -- an explicit version string supplied by
|
||||
the caller, e.g. from an \code{app_version()} function bundled with the
|
||||
app. Used on shinyapps.io where the package is not installed.
|
||||
}
|
||||
}
|
||||
63
man/generate_colors.Rd
Normal file
63
man/generate_colors.Rd
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/generate_colors.R
|
||||
\name{generate_colors}
|
||||
\alias{generate_colors}
|
||||
\title{Generate N Colors from a Specified Color Palette}
|
||||
\usage{
|
||||
generate_colors(n, palette = "viridis", ...)
|
||||
}
|
||||
\arguments{
|
||||
\item{n}{\code{integer}. Number of colors to generate. Must be a positive
|
||||
integer.}
|
||||
|
||||
\item{palette}{\code{character(1)}. Name of the color palette to use.
|
||||
Case-insensitive. Supported options:
|
||||
\describe{
|
||||
\item{\strong{viridisLite}}{\code{"viridis"}, \code{"magma"}, \code{"plasma"},
|
||||
\code{"inferno"}, \code{"cividis"}, \code{"mako"}, \code{"rocket"}, \code{"turbo"}}
|
||||
\item{\strong{grDevices}}{\code{"hcl"}, \code{"rainbow"}, \code{"heat"},
|
||||
\code{"terrain"}, \code{"topo"}}
|
||||
\item{\strong{RColorBrewer}}{Any palette name from
|
||||
\code{RColorBrewer::brewer.pal.info}, e.g. \code{"Set1"}, \code{"Blues"},
|
||||
\code{"Dark2"}. If \code{n} exceeds the palette maximum, colors are
|
||||
interpolated via \code{\link[grDevices]{colorRampPalette}}.}
|
||||
}}
|
||||
|
||||
\item{...}{Additional arguments passed to the underlying palette function.
|
||||
For example, \code{alpha}, \code{direction}, \code{begin}, \code{end}
|
||||
are forwarded to \code{\link[viridisLite]{viridis}}; \code{palette} is
|
||||
forwarded to \code{\link[grDevices]{hcl.colors}}.}
|
||||
}
|
||||
\value{
|
||||
A \code{character} vector of length \code{n} containing hex color
|
||||
codes (e.g. \code{"#440154FF"}).
|
||||
}
|
||||
\description{
|
||||
A flexible wrapper around multiple color palette libraries, returning N
|
||||
colors as a character vector of hex codes. Supports palettes from
|
||||
\pkg{viridisLite}, base R \pkg{grDevices}, and \pkg{RColorBrewer}.
|
||||
}
|
||||
\examples{
|
||||
# viridisLite palettes
|
||||
generate_colors(5, "viridis")
|
||||
generate_colors(5, "plasma")
|
||||
generate_colors(5, "viridis", alpha = 0.8, direction = -1)
|
||||
|
||||
# Base R grDevices
|
||||
generate_colors(5, "rainbow")
|
||||
generate_colors(8, "hcl", palette = "Dark 3")
|
||||
|
||||
# RColorBrewer
|
||||
generate_colors(5, "Set1")
|
||||
generate_colors(5, "Blues")
|
||||
generate_colors(12, "Set1") # interpolates beyond palette max of 9
|
||||
|
||||
# Drop-in replacement for viridisLite::viridis()
|
||||
# generate_colors(n = length(levels(data_orig[[pri]])), palette = "viridis")
|
||||
|
||||
}
|
||||
\seealso{
|
||||
\code{\link[viridisLite]{viridis}},
|
||||
\code{\link[grDevices]{hcl.colors}},
|
||||
\code{\link[RColorBrewer]{brewer.pal}}
|
||||
}
|
||||
27
man/get_input_params.Rd
Normal file
27
man/get_input_params.Rd
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{get_input_params}
|
||||
\alias{get_input_params}
|
||||
\title{Get the function parameters based on the selected function description}
|
||||
\usage{
|
||||
get_input_params(data)
|
||||
}
|
||||
\arguments{
|
||||
\item{data}{vector}
|
||||
}
|
||||
\value{
|
||||
list
|
||||
}
|
||||
\description{
|
||||
Get the function parameters based on the selected function description
|
||||
}
|
||||
\examples{
|
||||
ls <- mtcars |>
|
||||
default_parsing() |>
|
||||
dplyr::pull(mpg) |>
|
||||
possible_plots() |>
|
||||
(\(.x){
|
||||
.x[[1]]
|
||||
})() |>
|
||||
get_input_params()
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{get_label}
|
||||
\alias{get_label}
|
||||
\title{Print label, and if missing print variable name for plots}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{get_plot_options}
|
||||
\alias{get_plot_options}
|
||||
\title{Get the function options based on the selected function description}
|
||||
|
|
|
|||
|
|
@ -5,24 +5,28 @@
|
|||
\title{Easily launch the FreesearchR app}
|
||||
\usage{
|
||||
launch_FreesearchR(
|
||||
inlcude_globalenv = TRUE,
|
||||
include_globalenv = TRUE,
|
||||
data_limit_default = 1000,
|
||||
data_limit_upper = 1e+05,
|
||||
data_limit_lower = 1,
|
||||
check_app_version = FALSE,
|
||||
...
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
\item{include_globalenv}{flag to include global env (local data) as option
|
||||
when loading data}
|
||||
|
||||
\item{data_limit_default}{default data set observations limit}
|
||||
|
||||
\item{data_limit_upper}{data set observations upper limit}
|
||||
|
||||
\item{data_limit_lower}{data set observations lower limit}
|
||||
|
||||
\item{...}{passed on to \code{shiny::runApp()}}
|
||||
\item{check_app_version}{always attempt to check app version against latest
|
||||
release on GitHub. Default is FALSE}
|
||||
|
||||
\item{include_globalenv}{flag to include global env (local data) as option
|
||||
when loading data}
|
||||
\item{...}{passed on to \code{shiny::runApp()}}
|
||||
}
|
||||
\value{
|
||||
shiny app
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{line_break}
|
||||
\alias{line_break}
|
||||
\title{Line breaking at given number of characters for nicely plotting labels}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
\alias{plot_euler}
|
||||
\title{Easily plot euler diagrams}
|
||||
\usage{
|
||||
plot_euler(data, pri, sec, ter = NULL, seed = 2103)
|
||||
plot_euler(data, pri, sec, ter = NULL, seed = 2103, color.palette = "viridis")
|
||||
}
|
||||
\arguments{
|
||||
\item{data}{data}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
\alias{plot_euler_single}
|
||||
\title{Easily plot single euler diagrams}
|
||||
\usage{
|
||||
plot_euler_single(data)
|
||||
plot_euler_single(data, color.palette = "viridis", ...)
|
||||
}
|
||||
\value{
|
||||
ggplot2 object
|
||||
|
|
@ -19,5 +19,5 @@ data.frame(
|
|||
C = sample(c(TRUE, FALSE, FALSE, FALSE), 50, TRUE),
|
||||
D = sample(c(TRUE, FALSE, FALSE, FALSE), 50, TRUE)
|
||||
) |> plot_euler_single()
|
||||
mtcars[c("vs", "am")] |> plot_euler_single()
|
||||
mtcars[c("vs", "am")] |> plot_euler_single("magma")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,8 +9,12 @@ plot_sankey_single(
|
|||
pri,
|
||||
sec,
|
||||
color.group = c("pri", "sec"),
|
||||
color.palette = "viridis",
|
||||
colors = NULL,
|
||||
missing.level = "Missing",
|
||||
default.color = "#2986cc",
|
||||
box.color = "#1E4B66",
|
||||
na.color = "grey80",
|
||||
...
|
||||
)
|
||||
}
|
||||
|
|
@ -44,4 +48,10 @@ mtcars |>
|
|||
stRoke::trial |>
|
||||
default_parsing() |>
|
||||
plot_sankey_single("diabetes", "hypertension")
|
||||
|
||||
|
||||
# stRoke::trial |> plot_sankey_single("mrs_1", "mrs_6", color.palette="magma")
|
||||
# stRoke::trial |> plot_sankey_single("active", "male")
|
||||
# stRoke::trial |> plot_sankey_single("diabetes", "active", color.group="sec")
|
||||
# stRoke::trial |> plot_sankey_single("active", "diabetes", color.group="sec", color.palette="topo")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{possible_plots}
|
||||
\alias{possible_plots}
|
||||
\title{Get possible regression models}
|
||||
\usage{
|
||||
possible_plots(data)
|
||||
possible_plots(data, source_list = supported_plots())
|
||||
}
|
||||
\arguments{
|
||||
\item{data}{data}
|
||||
|
|
|
|||
45
man/scale_fill_generate.Rd
Normal file
45
man/scale_fill_generate.Rd
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/generate_colors.R
|
||||
\name{scale_fill_generate}
|
||||
\alias{scale_fill_generate}
|
||||
\alias{scale_color_generate}
|
||||
\title{Discrete and Continuous Fill Scale Using generate_colors}
|
||||
\usage{
|
||||
scale_fill_generate(palette = "viridis", discrete = TRUE, ...)
|
||||
|
||||
scale_color_generate(palette = "viridis", discrete = TRUE, ...)
|
||||
}
|
||||
\arguments{
|
||||
\item{palette}{Passed to \code{\link[=generate_colors]{generate_colors()}}. Either a palette name string
|
||||
or a function.}
|
||||
|
||||
\item{discrete}{\code{logical}. If \code{TRUE} (default), a discrete scale
|
||||
is returned. If \code{FALSE}, a continuous scale is returned.}
|
||||
|
||||
\item{...}{Additional arguments passed to \code{\link[ggplot2:scale_manual]{ggplot2::scale_fill_manual()}}
|
||||
(discrete) or \code{\link[ggplot2:scale_gradient]{ggplot2::scale_fill_gradientn()}} (continuous).}
|
||||
}
|
||||
\description{
|
||||
Drop-in replacement for \code{\link[viridis:scale_viridis]{viridis::scale_fill_viridis()}} that works with
|
||||
any palette supported by \code{\link[=generate_colors]{generate_colors()}}.
|
||||
}
|
||||
\examples{
|
||||
library(ggplot2)
|
||||
|
||||
# Discrete
|
||||
ggplot(mtcars, aes(x = wt, y = mpg, fill = factor(cyl))) +
|
||||
geom_col() +
|
||||
scale_fill_generate(palette = "Set1")
|
||||
|
||||
# Continuous
|
||||
ggplot(mtcars, aes(x = wt, y = mpg, fill = mpg)) +
|
||||
geom_point(shape = 21, size = 3) +
|
||||
scale_fill_generate(palette = "viridis", discrete = FALSE)
|
||||
|
||||
ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) +
|
||||
geom_point() +
|
||||
scale_color_generate(palette = "Set1")
|
||||
}
|
||||
\seealso{
|
||||
\code{\link[=scale_color_generate]{scale_color_generate()}}, \code{\link[=generate_colors]{generate_colors()}}, \code{\link[=continuous_colors]{continuous_colors()}}
|
||||
}
|
||||
11
man/selectPlotVariables.Rd
Normal file
11
man/selectPlotVariables.Rd
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{selectPlotVariables}
|
||||
\alias{selectPlotVariables}
|
||||
\title{Wrapper for columnSelectInput}
|
||||
\usage{
|
||||
selectPlotVariables(data, exclude = NULL, allow_none = TRUE, var_types, ...)
|
||||
}
|
||||
\description{
|
||||
Wrapper for columnSelectInput
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{subset_types}
|
||||
\alias{subset_types}
|
||||
\title{Easily subset by data type function}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{supported_plots}
|
||||
\alias{supported_plots}
|
||||
\title{Implemented functions}
|
||||
|
|
|
|||
72
man/validate_redcap_filter.Rd
Normal file
72
man/validate_redcap_filter.Rd
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/redcap_read_shiny_module.R
|
||||
\name{validate_redcap_filter}
|
||||
\alias{validate_redcap_filter}
|
||||
\title{Validate a REDCap server-side filter string against a data dictionary}
|
||||
\usage{
|
||||
validate_redcap_filter(filter, dictionary)
|
||||
}
|
||||
\arguments{
|
||||
\item{filter}{A single character string containing the filter expression,
|
||||
e.g. \code{"[age] > 18"} or \code{"[cohabitation] = '1' AND [age] > 18"}.}
|
||||
|
||||
\item{dictionary}{A data frame representing the REDCap data dictionary in
|
||||
API export format, as returned by e.g. \code{REDCapCAST::get_redcap_metadata()}.
|
||||
Must contain at least the columns \code{field_name} and \code{field_type}.
|
||||
The columns \code{text_validation_type_or_show_slider_number} and
|
||||
\code{select_choices_or_calculations} are used when present for stricter
|
||||
type and choice validation.}
|
||||
}
|
||||
\value{
|
||||
A named list with two elements:
|
||||
\describe{
|
||||
\item{\code{valid}}{Logical. \code{TRUE} if the filter passes all checks.}
|
||||
\item{\code{message}}{Character. \code{"Filter is valid."} on success, or
|
||||
a newline-separated string of error messages describing every problem
|
||||
found.}
|
||||
}
|
||||
}
|
||||
\description{
|
||||
Checks that a REDCap filter expression is syntactically correct and
|
||||
consistent with the field types defined in the project data dictionary.
|
||||
Plain text without field references is always rejected. Multi-clause
|
||||
filters joined by \code{AND} or \code{OR} are supported.
|
||||
}
|
||||
\details{
|
||||
Validation rules by field type:
|
||||
\describe{
|
||||
\item{\code{calc}}{Numeric fields. Value must be an unquoted number.
|
||||
All comparison operators (\code{=}, \code{!=}, \code{<}, \code{>},
|
||||
\code{<=}, \code{>=}) are accepted.}
|
||||
\item{\code{text} with date validation}{Fields with validation type
|
||||
\code{date_ymd}, \code{date_dmy}, \code{datetime_*}, etc. Value must be
|
||||
a quoted date/datetime string in \code{'YYYY-MM-DD'} format. All
|
||||
comparison operators are accepted.}
|
||||
\item{\code{text} with time validation}{Fields with validation type
|
||||
\code{time_hh_mm_ss} or \code{time_mm_ss}. Value must be a quoted time
|
||||
string, e.g. \code{'14:30:00'}. All comparison operators are accepted.}
|
||||
\item{\code{radio} / \code{dropdown}}{Categorical fields. Value must be a
|
||||
quoted choice code (e.g. \code{'1'}) that exists in the field's choice
|
||||
list. Only \code{=} and \code{!=} are accepted.}
|
||||
\item{\code{text} (plain)}{Free-text fields. Value must be a quoted string.
|
||||
Only \code{=} and \code{!=} are accepted.}
|
||||
}
|
||||
}
|
||||
\examples{
|
||||
\dontrun{
|
||||
dict <- REDCapCAST::get_redcap_metadata(
|
||||
uri = "https://redcap.example.com/api/",
|
||||
token = Sys.getenv("REDCAP_TOKEN")
|
||||
)
|
||||
|
||||
validate_redcap_filter("[age] > 18", dict)
|
||||
#> list(valid = TRUE, message = "Filter is valid.")
|
||||
|
||||
validate_redcap_filter("only plain text", dict)
|
||||
#> list(valid = FALSE, message = "Filter must contain at least one field ...")
|
||||
|
||||
validate_redcap_filter("[cohabitation] = '1' AND [age] > 18", dict)
|
||||
#> list(valid = TRUE, message = "Filter is valid.")
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -9,11 +9,13 @@ vertical_stacked_bars(
|
|||
score = "full_score",
|
||||
group = "pase_0_q",
|
||||
strata = NULL,
|
||||
t.size = 10,
|
||||
t.size = 8,
|
||||
l.color = "black",
|
||||
l.size = 0.5,
|
||||
draw.lines = TRUE,
|
||||
label.str = "{n}\\n{round(100 * p,0)}\%"
|
||||
label.str = "{n}\\n{round(100 * p,0)}\%",
|
||||
color.palette = "viridis",
|
||||
reverse = TRUE
|
||||
)
|
||||
}
|
||||
\arguments{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/data_plots.R
|
||||
% Please edit documentation in R/plot-helpers.R
|
||||
\name{wrap_plot_list}
|
||||
\alias{wrap_plot_list}
|
||||
\title{Wrapping}
|
||||
|
|
@ -12,6 +12,7 @@ wrap_plot_list(
|
|||
guides = "collect",
|
||||
axes = "collect",
|
||||
axis_titles = "collect",
|
||||
y.axis.percentage = FALSE,
|
||||
...
|
||||
)
|
||||
}
|
||||
|
|
|
|||
149
renv.lock
149
renv.lock
|
|
@ -2761,7 +2761,7 @@
|
|||
},
|
||||
"effectsize": {
|
||||
"Package": "effectsize",
|
||||
"Version": "1.0.1",
|
||||
"Version": "1.0.2",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Indices of Effect Size",
|
||||
|
|
@ -2775,11 +2775,11 @@
|
|||
"R (>= 4.0)"
|
||||
],
|
||||
"Imports": [
|
||||
"bayestestR (>= 0.16.0)",
|
||||
"insight (>= 1.3.0)",
|
||||
"parameters (>= 0.26.0)",
|
||||
"performance (>= 0.14.0)",
|
||||
"datawizard (>= 1.1.0)",
|
||||
"bayestestR (>= 0.17.0)",
|
||||
"insight (>= 1.4.5)",
|
||||
"parameters (>= 0.28.3)",
|
||||
"performance (>= 0.15.3)",
|
||||
"datawizard (>= 1.3.0)",
|
||||
"stats",
|
||||
"utils"
|
||||
],
|
||||
|
|
@ -2809,7 +2809,7 @@
|
|||
"VignetteBuilder": "knitr",
|
||||
"Encoding": "UTF-8",
|
||||
"Language": "en-US",
|
||||
"RoxygenNote": "7.3.2",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"Config/testthat/edition": "3",
|
||||
"Config/testthat/parallel": "true",
|
||||
"Config/Needs/website": "rstudio/bslib, r-lib/pkgdown, easystats/easystatstemplate",
|
||||
|
|
@ -3405,10 +3405,10 @@
|
|||
},
|
||||
"foreign": {
|
||||
"Package": "foreign",
|
||||
"Version": "0.8-90",
|
||||
"Version": "0.8-91",
|
||||
"Source": "Repository",
|
||||
"Priority": "recommended",
|
||||
"Date": "2025-03-31",
|
||||
"Date": "2026-01-29",
|
||||
"Title": "Read Data Stored by 'Minitab', 'S', 'SAS', 'SPSS', 'Stata', 'Systat', 'Weka', 'dBase', ...",
|
||||
"Depends": [
|
||||
"R (>= 4.0.0)"
|
||||
|
|
@ -3429,22 +3429,22 @@
|
|||
"MailingList": "R-help@r-project.org",
|
||||
"URL": "https://svn.r-project.org/R-packages/trunk/foreign/",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "R Core Team [aut, cph, cre] (02zz1nj61), Roger Bivand [ctb, cph], Vincent J. Carey [ctb, cph], Saikat DebRoy [ctb, cph], Stephen Eglen [ctb, cph], Rajarshi Guha [ctb, cph], Swetlana Herbrandt [ctb], Nicholas Lewin-Koh [ctb, cph], Mark Myatt [ctb, cph], Michael Nelson [ctb], Ben Pfaff [ctb], Brian Quistorff [ctb], Frank Warmerdam [ctb, cph], Stephen Weigand [ctb, cph], Free Software Foundation, Inc. [cph]",
|
||||
"Author": "R Core Team [aut, cph, cre] (ROR: <https://ror.org/02zz1nj61>), Roger Bivand [ctb, cph], Vincent J. Carey [ctb, cph], Saikat DebRoy [ctb, cph], Stephen Eglen [ctb, cph], Rajarshi Guha [ctb, cph], Swetlana Herbrandt [ctb], Nicholas Lewin-Koh [ctb, cph], Mark Myatt [ctb, cph], Michael Nelson [ctb], Ben Pfaff [ctb], Brian Quistorff [ctb], Frank Warmerdam [ctb, cph], Stephen Weigand [ctb, cph], Free Software Foundation, Inc. [cph]",
|
||||
"Maintainer": "R Core Team <R-core@R-project.org>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
"fs": {
|
||||
"Package": "fs",
|
||||
"Version": "1.6.6",
|
||||
"Version": "1.6.7",
|
||||
"Source": "Repository",
|
||||
"Title": "Cross-Platform File System Operations Based on 'libuv'",
|
||||
"Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"libuv project contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Joyent, Inc. and other Node contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )",
|
||||
"Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Gábor\", \"Csárdi\", role = \"aut\"), person(\"Jeroen\", \"Ooms\", , \"jeroenooms@gmail.com\", role = \"cre\"), person(\"libuv project contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Joyent, Inc. and other Node contributors\", role = \"cph\", comment = \"libuv library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )",
|
||||
"Description": "A cross-platform interface to file system operations, built on top of the 'libuv' C library.",
|
||||
"License": "MIT + file LICENSE",
|
||||
"URL": "https://fs.r-lib.org, https://github.com/r-lib/fs",
|
||||
"BugReports": "https://github.com/r-lib/fs/issues",
|
||||
"Depends": [
|
||||
"R (>= 3.6)"
|
||||
"R (>= 4.1)"
|
||||
],
|
||||
"Imports": [
|
||||
"methods"
|
||||
|
|
@ -3465,14 +3465,15 @@
|
|||
"ByteCompile": "true",
|
||||
"Config/Needs/website": "tidyverse/tidytemplate",
|
||||
"Config/testthat/edition": "3",
|
||||
"Config/usethis/last-upkeep": "2025-04-23",
|
||||
"Copyright": "file COPYRIGHTS",
|
||||
"Encoding": "UTF-8",
|
||||
"Language": "en-US",
|
||||
"RoxygenNote": "7.2.3",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"SystemRequirements": "GNU make",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "Jim Hester [aut], Hadley Wickham [aut], Gábor Csárdi [aut, cre], libuv project contributors [cph] (libuv library), Joyent, Inc. and other Node contributors [cph] (libuv library), Posit Software, PBC [cph, fnd]",
|
||||
"Maintainer": "Gábor Csárdi <csardi.gabor@gmail.com>",
|
||||
"Author": "Jim Hester [aut], Hadley Wickham [aut], Gábor Csárdi [aut], Jeroen Ooms [cre], libuv project contributors [cph] (libuv library), Joyent, Inc. and other Node contributors [cph] (libuv library), Posit Software, PBC [cph, fnd] (ROR: <https://ror.org/03wc8by49>)",
|
||||
"Maintainer": "Jeroen Ooms <jeroenooms@gmail.com>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
"gap": {
|
||||
|
|
@ -3642,7 +3643,7 @@
|
|||
},
|
||||
"ggalluvial": {
|
||||
"Package": "ggalluvial",
|
||||
"Version": "0.12.5",
|
||||
"Version": "0.12.6",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Alluvial Plots in 'ggplot2'",
|
||||
|
|
@ -3889,7 +3890,7 @@
|
|||
},
|
||||
"ggstats": {
|
||||
"Package": "ggstats",
|
||||
"Version": "0.12.0",
|
||||
"Version": "0.13.0",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Extension to 'ggplot2' for Plotting Stats",
|
||||
|
|
@ -4288,7 +4289,7 @@
|
|||
},
|
||||
"highr": {
|
||||
"Package": "highr",
|
||||
"Version": "0.11",
|
||||
"Version": "0.12",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Syntax Highlighting for R Source Code",
|
||||
|
|
@ -4310,9 +4311,9 @@
|
|||
"BugReports": "https://github.com/yihui/highr/issues",
|
||||
"VignetteBuilder": "knitr",
|
||||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.1",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"NeedsCompilation": "no",
|
||||
"Author": "Yihui Xie [aut, cre] (<https://orcid.org/0000-0003-0645-5666>), Yixuan Qiu [aut], Christopher Gandrud [ctb], Qiang Li [ctb]",
|
||||
"Author": "Yihui Xie [aut, cre] (ORCID: <https://orcid.org/0000-0003-0645-5666>), Yixuan Qiu [aut], Christopher Gandrud [ctb], Qiang Li [ctb]",
|
||||
"Maintainer": "Yihui Xie <xie@yihui.name>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
|
|
@ -5041,7 +5042,7 @@
|
|||
},
|
||||
"later": {
|
||||
"Package": "later",
|
||||
"Version": "1.4.6",
|
||||
"Version": "1.4.8",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Utilities for Scheduling Functions to Execute Later with Event Loops",
|
||||
|
|
@ -5217,72 +5218,74 @@
|
|||
},
|
||||
"lme4": {
|
||||
"Package": "lme4",
|
||||
"Version": "1.1-38",
|
||||
"Version": "2.0-1",
|
||||
"Source": "Repository",
|
||||
"Title": "Linear Mixed-Effects Models using 'Eigen' and S4",
|
||||
"Authors@R": "c( person(\"Douglas\",\"Bates\", role=\"aut\", comment=c(ORCID=\"0000-0001-8316-9503\")), person(\"Martin\",\"Maechler\", role=\"aut\", comment=c(ORCID=\"0000-0002-8685-9910\")), person(\"Ben\",\"Bolker\",email=\"bbolker+lme4@gmail.com\", role=c(\"aut\",\"cre\"), comment=c(ORCID=\"0000-0002-2127-0443\")), person(\"Steven\",\"Walker\",role=\"aut\", comment=c(ORCID=\"0000-0002-4394-9078\")), person(\"Rune Haubo Bojesen\",\"Christensen\", role=\"ctb\", comment=c(ORCID=\"0000-0002-4494-3399\")), person(\"Henrik\",\"Singmann\", role=\"ctb\", comment=c(ORCID=\"0000-0002-4842-3657\")), person(\"Bin\", \"Dai\", role=\"ctb\"), person(\"Fabian\", \"Scheipl\", role=\"ctb\", comment=c(ORCID=\"0000-0001-8172-3603\")), person(\"Gabor\", \"Grothendieck\", role=\"ctb\"), person(\"Peter\", \"Green\", role=\"ctb\", comment=c(ORCID=\"0000-0002-0238-9852\")), person(\"John\", \"Fox\", role=\"ctb\"), person(\"Alexander\", \"Bauer\", role=\"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role=c(\"ctb\",\"cph\"), comment=c(ORCID=\"0000-0002-9101-3362\", \"shared copyright on simulate.formula\")), person(\"Emi\", \"Tanaka\", role = \"ctb\", comment = c(ORCID=\"0000-0002-1455-259X\")), person(\"Mikael\", \"Jagan\", role = \"ctb\", comment = c(ORCID=\"0000-0002-3542-2938\")), person(\"Ross D.\", \"Boylan\", email=\"ross.boylan@ucsf.edu\", role=(\"ctb\"), comment = c(ORCID=\"0009-0003-4123-8090\")), person(\"Anna\", \"Ly\", role = \"ctb\", comment = c(ORCID = \"0000-0002-0210-0342\")) )",
|
||||
"Description": "Fit linear and generalized linear mixed-effects models. The models and their components are represented using S4 classes and methods. The core computational algorithms are implemented using the 'Eigen' C++ library for numerical linear algebra and 'RcppEigen' \"glue\".",
|
||||
"Authors@R": "c(person(\"Douglas\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Martin\", \"Maechler\", role = \"aut\", comment = c(ORCID = \"0000-0002-8685-9910\")), person(\"Ben\", \"Bolker\", role = c(\"cre\", \"aut\"), email = \"bbolker+lme4@gmail.com\", comment = c(ORCID = \"0000-0002-2127-0443\")), person(\"Steven\", \"Walker\", role = \"aut\", comment = c(ORCID = \"0000-0002-4394-9078\")), person(\"Rune Haubo Bojesen\", \"Christensen\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4494-3399\")), person(\"Henrik\", \"Singmann\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4842-3657\")), person(\"Bin\", \"Dai\", role = \"ctb\"), person(\"Fabian\", \"Scheipl\", role = \"ctb\", comment = c(ORCID = \"0000-0001-8172-3603\")), person(\"Gabor\", \"Grothendieck\", role = \"ctb\"), person(\"Peter\", \"Green\", role = \"ctb\", comment = c(ORCID = \"0000-0002-0238-9852\")), person(\"John\", \"Fox\", role = \"ctb\"), person(\"Alexander\", \"Bauer\", role = \"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role = c(\"ctb\", \"cph\"), comment = c(ORCID = \"0000-0002-9101-3362\", \"shared copyright on simulate.formula\")), person(\"Emi\", \"Tanaka\", role = \"ctb\", comment = c(ORCID = \"0000-0002-1455-259X\")), person(\"Mikael\", \"Jagan\", role = \"aut\", comment = c(ORCID = \"0000-0002-3542-2938\")), person(\"Ross D.\", \"Boylan\", role = \"ctb\", comment = c(ORCID = \"0009-0003-4123-8090\")), person(\"Anna\", \"Ly\", role = \"aut\", comment = c(ORCID = \"0000-0002-0210-0342\")))",
|
||||
"Description": "Fit linear and generalized linear mixed-effects models. The models and their components are represented using S4 classes and methods. The core computational algorithms are implemented using the 'Eigen' C++ library for numerical linear algebra and 'RcppEigen' \"glue\".",
|
||||
"Depends": [
|
||||
"R (>= 3.6.0)",
|
||||
"R (>= 3.6)",
|
||||
"Matrix",
|
||||
"methods",
|
||||
"stats"
|
||||
],
|
||||
"LinkingTo": [
|
||||
"Matrix (>= 1.5-0)",
|
||||
"Rcpp (>= 0.10.5)",
|
||||
"RcppEigen (>= 0.3.3.9.4)",
|
||||
"Matrix (>= 1.5-0)"
|
||||
"RcppEigen (>= 0.3.3.9.4)"
|
||||
],
|
||||
"Imports": [
|
||||
"MASS",
|
||||
"Rdpack",
|
||||
"boot",
|
||||
"graphics",
|
||||
"grid",
|
||||
"splines",
|
||||
"utils",
|
||||
"parallel",
|
||||
"MASS",
|
||||
"lattice",
|
||||
"boot",
|
||||
"nlme (>= 3.1-123)",
|
||||
"minqa (>= 1.1.15)",
|
||||
"nlme (>= 3.1-123)",
|
||||
"nloptr (>= 1.0.4)",
|
||||
"reformulas (>= 0.3.0)",
|
||||
"parallel",
|
||||
"reformulas (>= 0.4.3.1)",
|
||||
"rlang",
|
||||
"Rdpack"
|
||||
"splines",
|
||||
"utils"
|
||||
],
|
||||
"RdMacros": "Rdpack",
|
||||
"Suggests": [
|
||||
"knitr",
|
||||
"rmarkdown",
|
||||
"MEMSS",
|
||||
"testthat (>= 0.8.1)",
|
||||
"ggplot2",
|
||||
"mlmRev",
|
||||
"optimx (>= 2013.8.6)",
|
||||
"gamm4",
|
||||
"pbkrtest",
|
||||
"HSAUR3",
|
||||
"numDeriv",
|
||||
"MEMSS",
|
||||
"car",
|
||||
"dfoptim",
|
||||
"gamm4",
|
||||
"ggplot2",
|
||||
"glmmTMB",
|
||||
"knitr",
|
||||
"merDeriv",
|
||||
"mgcv",
|
||||
"statmod",
|
||||
"mlmRev",
|
||||
"numDeriv",
|
||||
"optimx (>= 2013.8.6)",
|
||||
"pbkrtest",
|
||||
"rmarkdown",
|
||||
"rr2",
|
||||
"semEff",
|
||||
"tibble",
|
||||
"merDeriv"
|
||||
"statmod",
|
||||
"testthat (>= 0.8.1)",
|
||||
"tibble"
|
||||
],
|
||||
"Enhances": [
|
||||
"DHARMa",
|
||||
"performance"
|
||||
],
|
||||
"RdMacros": "Rdpack",
|
||||
"VignetteBuilder": "knitr",
|
||||
"LazyData": "yes",
|
||||
"License": "GPL (>= 2)",
|
||||
"URL": "https://github.com/lme4/lme4/",
|
||||
"BugReports": "https://github.com/lme4/lme4/issues",
|
||||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "Douglas Bates [aut] (ORCID: <https://orcid.org/0000-0001-8316-9503>), Martin Maechler [aut] (ORCID: <https://orcid.org/0000-0002-8685-9910>), Ben Bolker [aut, cre] (ORCID: <https://orcid.org/0000-0002-2127-0443>), Steven Walker [aut] (ORCID: <https://orcid.org/0000-0002-4394-9078>), Rune Haubo Bojesen Christensen [ctb] (ORCID: <https://orcid.org/0000-0002-4494-3399>), Henrik Singmann [ctb] (ORCID: <https://orcid.org/0000-0002-4842-3657>), Bin Dai [ctb], Fabian Scheipl [ctb] (ORCID: <https://orcid.org/0000-0001-8172-3603>), Gabor Grothendieck [ctb], Peter Green [ctb] (ORCID: <https://orcid.org/0000-0002-0238-9852>), John Fox [ctb], Alexander Bauer [ctb], Pavel N. Krivitsky [ctb, cph] (ORCID: <https://orcid.org/0000-0002-9101-3362>, shared copyright on simulate.formula), Emi Tanaka [ctb] (ORCID: <https://orcid.org/0000-0002-1455-259X>), Mikael Jagan [ctb] (ORCID: <https://orcid.org/0000-0002-3542-2938>), Ross D. Boylan [ctb] (ORCID: <https://orcid.org/0009-0003-4123-8090>), Anna Ly [ctb] (ORCID: <https://orcid.org/0000-0002-0210-0342>)",
|
||||
"Author": "Douglas Bates [aut] (ORCID: <https://orcid.org/0000-0001-8316-9503>), Martin Maechler [aut] (ORCID: <https://orcid.org/0000-0002-8685-9910>), Ben Bolker [cre, aut] (ORCID: <https://orcid.org/0000-0002-2127-0443>), Steven Walker [aut] (ORCID: <https://orcid.org/0000-0002-4394-9078>), Rune Haubo Bojesen Christensen [ctb] (ORCID: <https://orcid.org/0000-0002-4494-3399>), Henrik Singmann [ctb] (ORCID: <https://orcid.org/0000-0002-4842-3657>), Bin Dai [ctb], Fabian Scheipl [ctb] (ORCID: <https://orcid.org/0000-0001-8172-3603>), Gabor Grothendieck [ctb], Peter Green [ctb] (ORCID: <https://orcid.org/0000-0002-0238-9852>), John Fox [ctb], Alexander Bauer [ctb], Pavel N. Krivitsky [ctb, cph] (ORCID: <https://orcid.org/0000-0002-9101-3362>, shared copyright on simulate.formula), Emi Tanaka [ctb] (ORCID: <https://orcid.org/0000-0002-1455-259X>), Mikael Jagan [aut] (ORCID: <https://orcid.org/0000-0002-3542-2938>), Ross D. Boylan [ctb] (ORCID: <https://orcid.org/0009-0003-4123-8090>), Anna Ly [aut] (ORCID: <https://orcid.org/0000-0002-0210-0342>)",
|
||||
"Maintainer": "Ben Bolker <bbolker+lme4@gmail.com>",
|
||||
"Repository": "CRAN"
|
||||
},
|
||||
|
|
@ -5459,14 +5462,14 @@
|
|||
},
|
||||
"mgcv": {
|
||||
"Package": "mgcv",
|
||||
"Version": "1.9-3",
|
||||
"Version": "1.9-4",
|
||||
"Source": "Repository",
|
||||
"Authors@R": "person(given = \"Simon\", family = \"Wood\", role = c(\"aut\", \"cre\"), email = \"simon.wood@r-project.org\")",
|
||||
"Title": "Mixed GAM Computation Vehicle with Automatic Smoothness Estimation",
|
||||
"Description": "Generalized additive (mixed) models, some of their extensions and other generalized ridge regression with multiple smoothing parameter estimation by (Restricted) Marginal Likelihood, Generalized Cross Validation and similar, or using iterated nested Laplace approximation for fully Bayesian inference. See Wood (2017) <doi:10.1201/9781315370279> for an overview. Includes a gam() function, a wide variety of smoothers, 'JAGS' support and distributions beyond the exponential family.",
|
||||
"Description": "Generalized additive (mixed) models, some of their extensions and other generalized ridge regression with multiple smoothing parameter estimation by (Restricted) Marginal Likelihood, Cross Validation and similar, or using iterated nested Laplace approximation for fully Bayesian inference. See Wood (2025) <doi:10.1146/annurev-statistics-112723-034249> for an overview. Includes a gam() function, a wide variety of smoothers, 'JAGS' support and distributions beyond the exponential family.",
|
||||
"Priority": "recommended",
|
||||
"Depends": [
|
||||
"R (>= 3.6.0)",
|
||||
"R (>= 4.4.0)",
|
||||
"nlme (>= 3.1-64)"
|
||||
],
|
||||
"Imports": [
|
||||
|
|
@ -5672,10 +5675,10 @@
|
|||
},
|
||||
"mvtnorm": {
|
||||
"Package": "mvtnorm",
|
||||
"Version": "1.3-3",
|
||||
"Version": "1.3-2",
|
||||
"Source": "Repository",
|
||||
"Title": "Multivariate Normal and t Distributions",
|
||||
"Date": "2025-01-09",
|
||||
"Date": "2024-11-04",
|
||||
"Authors@R": "c(person(\"Alan\", \"Genz\", role = \"aut\"), person(\"Frank\", \"Bretz\", role = \"aut\"), person(\"Tetsuhisa\", \"Miwa\", role = \"aut\"), person(\"Xuefei\", \"Mi\", role = \"aut\"), person(\"Friedrich\", \"Leisch\", role = \"ctb\"), person(\"Fabian\", \"Scheipl\", role = \"ctb\"), person(\"Bjoern\", \"Bornkamp\", role = \"ctb\", comment = c(ORCID = \"0000-0002-6294-8185\")), person(\"Martin\", \"Maechler\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8685-9910\")), person(\"Torsten\", \"Hothorn\", role = c(\"aut\", \"cre\"), email = \"Torsten.Hothorn@R-project.org\", comment = c(ORCID = \"0000-0001-8301-0471\")))",
|
||||
"Description": "Computes multivariate normal and t probabilities, quantiles, random deviates, and densities. Log-likelihoods for multivariate Gaussian models and Gaussian copulae parameterised by Cholesky factors of covariance or precision matrices are implemented for interval-censored and exact data, or a mix thereof. Score functions for these log-likelihoods are available. A class representing multiple lower triangular matrices and corresponding methods are part of this package.",
|
||||
"Imports": [
|
||||
|
|
@ -5882,7 +5885,7 @@
|
|||
},
|
||||
"openssl": {
|
||||
"Package": "openssl",
|
||||
"Version": "2.3.4",
|
||||
"Version": "2.3.5",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Toolkit for Encryption, Signatures and Certificates Based on OpenSSL",
|
||||
|
|
@ -5915,7 +5918,7 @@
|
|||
},
|
||||
"openxlsx2": {
|
||||
"Package": "openxlsx2",
|
||||
"Version": "1.23.1",
|
||||
"Version": "1.25",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Read, Write and Edit 'xlsx' Files",
|
||||
|
|
@ -5942,10 +5945,10 @@
|
|||
"ggplot2",
|
||||
"knitr",
|
||||
"mschart (>= 0.4)",
|
||||
"openssl",
|
||||
"rmarkdown",
|
||||
"rvg",
|
||||
"testthat (>= 3.0.0)",
|
||||
"waldo",
|
||||
"zip"
|
||||
],
|
||||
"VignetteBuilder": "knitr",
|
||||
|
|
@ -7089,7 +7092,7 @@
|
|||
},
|
||||
"ragg": {
|
||||
"Package": "ragg",
|
||||
"Version": "1.5.0",
|
||||
"Version": "1.5.1",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Graphic Devices Based on AGG",
|
||||
|
|
@ -7118,7 +7121,7 @@
|
|||
"Config/testthat/edition": "3",
|
||||
"Config/usethis/last-upkeep": "2025-04-25",
|
||||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.2",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"SystemRequirements": "freetype2, libpng, libtiff, libjpeg, libwebp, libwebpmux",
|
||||
"NeedsCompilation": "yes",
|
||||
"Author": "Thomas Lin Pedersen [cre, aut] (ORCID: <https://orcid.org/0000-0002-5147-4711>), Maxim Shemanarev [aut, cph] (Author of AGG), Tony Juricic [ctb, cph] (Contributor to AGG), Milan Marusinec [ctb, cph] (Contributor to AGG), Spencer Garrett [ctb] (Contributor to AGG), Posit Software, PBC [cph, fnd] (ROR: <https://ror.org/03wc8by49>)",
|
||||
|
|
@ -7541,7 +7544,7 @@
|
|||
},
|
||||
"renv": {
|
||||
"Package": "renv",
|
||||
"Version": "1.1.7",
|
||||
"Version": "1.1.8",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "Project Environments",
|
||||
|
|
@ -7585,11 +7588,11 @@
|
|||
"Encoding": "UTF-8",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"VignetteBuilder": "knitr",
|
||||
"NeedsCompilation": "yes",
|
||||
"Config/Needs/website": "tidyverse/tidytemplate",
|
||||
"Config/testthat/edition": "3",
|
||||
"Config/testthat/parallel": "true",
|
||||
"Config/testthat/start-first": "bioconductor,python,install,restore,snapshot,retrieve,remotes",
|
||||
"NeedsCompilation": "no",
|
||||
"Author": "Kevin Ushey [aut, cre] (ORCID: <https://orcid.org/0000-0003-2880-7407>), Hadley Wickham [aut] (ORCID: <https://orcid.org/0000-0003-4757-117X>), Posit Software, PBC [cph, fnd]",
|
||||
"Maintainer": "Kevin Ushey <kevin@rstudio.com>",
|
||||
"Repository": "CRAN"
|
||||
|
|
@ -8317,7 +8320,7 @@
|
|||
},
|
||||
"shinyWidgets": {
|
||||
"Package": "shinyWidgets",
|
||||
"Version": "0.9.0",
|
||||
"Version": "0.9.1",
|
||||
"Source": "Repository",
|
||||
"Title": "Custom Inputs Widgets for Shiny",
|
||||
"Authors@R": "c( person(\"Victor\", \"Perrier\", email = \"victor.perrier@dreamrs.fr\", role = c(\"aut\", \"cre\", \"cph\")), person(\"Fanny\", \"Meyer\", role = \"aut\"), person(\"David\", \"Granjon\", role = \"aut\"), person(\"Ian\", \"Fellows\", role = \"ctb\", comment = \"Methods for mutating vertical tabs & updateMultiInput\"), person(\"Wil\", \"Davis\", role = \"ctb\", comment = \"numericRangeInput function\"), person(\"Spencer\", \"Matthews\", role = \"ctb\", comment = \"autoNumeric methods\"), person(family = \"JavaScript and CSS libraries authors\", role = c(\"ctb\", \"cph\"), comment = \"All authors are listed in LICENSE.md\") )",
|
||||
|
|
@ -8327,7 +8330,7 @@
|
|||
"License": "GPL-3",
|
||||
"Encoding": "UTF-8",
|
||||
"LazyData": "true",
|
||||
"RoxygenNote": "7.3.2",
|
||||
"RoxygenNote": "7.3.3",
|
||||
"Depends": [
|
||||
"R (>= 3.1.0)"
|
||||
],
|
||||
|
|
@ -8624,7 +8627,7 @@
|
|||
},
|
||||
"systemfonts": {
|
||||
"Package": "systemfonts",
|
||||
"Version": "1.3.1",
|
||||
"Version": "1.3.2",
|
||||
"Source": "Repository",
|
||||
"Type": "Package",
|
||||
"Title": "System Native Font Finding",
|
||||
|
|
@ -8672,7 +8675,7 @@
|
|||
},
|
||||
"textshaping": {
|
||||
"Package": "textshaping",
|
||||
"Version": "1.0.4",
|
||||
"Version": "1.0.5",
|
||||
"Source": "Repository",
|
||||
"Title": "Bindings to the 'HarfBuzz' and 'Fribidi' Libraries for Text Shaping",
|
||||
"Authors@R": "c( person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )",
|
||||
|
|
@ -9513,21 +9516,23 @@
|
|||
},
|
||||
"xtable": {
|
||||
"Package": "xtable",
|
||||
"Version": "1.8-4",
|
||||
"Version": "1.8-8",
|
||||
"Source": "Repository",
|
||||
"Date": "2019-04-08",
|
||||
"Date": "2026-02-20",
|
||||
"Title": "Export Tables to LaTeX or HTML",
|
||||
"Authors@R": "c(person(\"David B.\", \"Dahl\", role=\"aut\"), person(\"David\", \"Scott\", role=c(\"aut\",\"cre\"), email=\"d.scott@auckland.ac.nz\"), person(\"Charles\", \"Roosen\", role=\"aut\"), person(\"Arni\", \"Magnusson\", role=\"aut\"), person(\"Jonathan\", \"Swinton\", role=\"aut\"), person(\"Ajay\", \"Shah\", role=\"ctb\"), person(\"Arne\", \"Henningsen\", role=\"ctb\"), person(\"Benno\", \"Puetz\", role=\"ctb\"), person(\"Bernhard\", \"Pfaff\", role=\"ctb\"), person(\"Claudio\", \"Agostinelli\", role=\"ctb\"), person(\"Claudius\", \"Loehnert\", role=\"ctb\"), person(\"David\", \"Mitchell\", role=\"ctb\"), person(\"David\", \"Whiting\", role=\"ctb\"), person(\"Fernando da\", \"Rosa\", role=\"ctb\"), person(\"Guido\", \"Gay\", role=\"ctb\"), person(\"Guido\", \"Schulz\", role=\"ctb\"), person(\"Ian\", \"Fellows\", role=\"ctb\"), person(\"Jeff\", \"Laake\", role=\"ctb\"), person(\"John\", \"Walker\", role=\"ctb\"), person(\"Jun\", \"Yan\", role=\"ctb\"), person(\"Liviu\", \"Andronic\", role=\"ctb\"), person(\"Markus\", \"Loecher\", role=\"ctb\"), person(\"Martin\", \"Gubri\", role=\"ctb\"), person(\"Matthieu\", \"Stigler\", role=\"ctb\"), person(\"Robert\", \"Castelo\", role=\"ctb\"), person(\"Seth\", \"Falcon\", role=\"ctb\"), person(\"Stefan\", \"Edwards\", role=\"ctb\"), person(\"Sven\", \"Garbade\", role=\"ctb\"), person(\"Uwe\", \"Ligges\", role=\"ctb\"))",
|
||||
"Maintainer": "David Scott <d.scott@auckland.ac.nz>",
|
||||
"Imports": [
|
||||
"stats",
|
||||
"utils"
|
||||
"utils",
|
||||
"methods"
|
||||
],
|
||||
"Suggests": [
|
||||
"knitr",
|
||||
"plm",
|
||||
"zoo",
|
||||
"survival"
|
||||
"survival",
|
||||
"glue",
|
||||
"tinytex"
|
||||
],
|
||||
"VignetteBuilder": "knitr",
|
||||
"Description": "Coerce data to LaTeX and HTML tables.",
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
local({
|
||||
|
||||
# the requested version of renv
|
||||
version <- "1.1.7"
|
||||
attr(version, "md5") <- "dd5d60f155dadff4c88c2fc6680504b4"
|
||||
version <- "1.1.8"
|
||||
attr(version, "md5") <- "cbffd086c66739a0fdaac7a30b4aa65c"
|
||||
attr(version, "sha") <- NULL
|
||||
|
||||
# the project directory
|
||||
|
|
|
|||
134
tests/testthat/test-default-parsing.R
Normal file
134
tests/testthat/test-default-parsing.R
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
test_that("default_parsing returns a data.frame", {
|
||||
result <- default_parsing(mtcars)
|
||||
expect_true(is.data.frame(result))
|
||||
})
|
||||
|
||||
test_that("default_parsing preserves row count", {
|
||||
result <- default_parsing(mtcars)
|
||||
expect_equal(nrow(result), nrow(mtcars))
|
||||
})
|
||||
|
||||
test_that("default_parsing preserves column count", {
|
||||
result <- default_parsing(mtcars)
|
||||
expect_equal(ncol(result), ncol(mtcars))
|
||||
})
|
||||
|
||||
test_that("default_parsing produces valid column names (make.names compatible)", {
|
||||
# Create data with problematic column names
|
||||
bad_names_df <- data.frame(
|
||||
`1bad` = 1:5,
|
||||
`has space` = letters[1:5],
|
||||
`good_name` = TRUE,
|
||||
check.names = FALSE
|
||||
)
|
||||
result <- default_parsing(bad_names_df)
|
||||
expect_true(all(make.names(names(result)) == names(result)))
|
||||
})
|
||||
|
||||
test_that("default_parsing handles duplicate column names", {
|
||||
dup_df <- data.frame(a = 1:5, b = 6:10)
|
||||
names(dup_df) <- c("x", "x")
|
||||
result <- default_parsing(dup_df)
|
||||
expect_equal(length(names(result)), 2)
|
||||
expect_true(all(!duplicated(names(result))))
|
||||
})
|
||||
|
||||
test_that("default_parsing converts low-cardinality numeric columns to factor", {
|
||||
# A numeric column with <= 8 unique values should become a factor
|
||||
df <- data.frame(
|
||||
group = c(1, 2, 3, 1, 2, 3, 1, 2), # 3 unique → factor
|
||||
value = rnorm(8) # 8 unique → stays numeric
|
||||
)
|
||||
result <- default_parsing(df)
|
||||
expect_true(is.factor(result$group))
|
||||
})
|
||||
|
||||
test_that("default_parsing converts low-cardinality character columns to factor", {
|
||||
# A character column with <= 10 unique values should become a factor
|
||||
df <- data.frame(
|
||||
category = rep(c("a", "b", "c"), 4), # 3 unique → factor
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
result <- default_parsing(df)
|
||||
expect_true(is.factor(result$category))
|
||||
})
|
||||
|
||||
test_that("default_parsing drops unused factor levels", {
|
||||
df <- data.frame(
|
||||
x = factor(c("a", "b", "a"), levels = c("a", "b", "c")) # "c" unused
|
||||
)
|
||||
result <- default_parsing(df)
|
||||
expect_false("c" %in% levels(result$x))
|
||||
})
|
||||
|
||||
test_that("default_parsing converts logical-like columns to logical", {
|
||||
df <- data.frame(
|
||||
flag = c(0L, 1L, 0L, 1L, 0L),
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
result <- default_parsing(df)
|
||||
# as_logical should have converted 0/1 integer to logical
|
||||
expect_true(is.logical(result$flag))
|
||||
})
|
||||
|
||||
test_that("default_parsing preserves column labels when present", {
|
||||
df <- data.frame(a = 1:3, b = c("x", "y", "z"), stringsAsFactors = FALSE)
|
||||
attr(df$a, "label") <- "Column A Label"
|
||||
attr(df$b, "label") <- "Column B Label"
|
||||
|
||||
result <- default_parsing(df)
|
||||
|
||||
expect_equal(attr(result$a, "label"), "Column A Label")
|
||||
expect_equal(attr(result$b, "label"), "Column B Label")
|
||||
})
|
||||
|
||||
test_that("default_parsing handles columns with no label attribute", {
|
||||
df <- data.frame(a = 1:3, b = c("x", "y", "z"), stringsAsFactors = FALSE)
|
||||
result <- default_parsing(df)
|
||||
# Should not error; label attrs simply absent or NULL
|
||||
expect_null(attr(result$a, "label"))
|
||||
})
|
||||
|
||||
test_that("default_parsing handles a single-column data.frame", {
|
||||
df <- data.frame(x = 1:10)
|
||||
result <- default_parsing(df)
|
||||
expect_equal(ncol(result), 1)
|
||||
expect_equal(nrow(result), 10)
|
||||
})
|
||||
|
||||
test_that("default_parsing handles an empty data.frame gracefully", {
|
||||
df <- data.frame(a = integer(0), b = character(0), stringsAsFactors = FALSE)
|
||||
result <- default_parsing(df)
|
||||
expect_equal(nrow(result), 0)
|
||||
})
|
||||
|
||||
test_that("default_parsing handles all-NA columns without error", {
|
||||
df <- data.frame(a = NA_real_, b = NA_character_, stringsAsFactors = FALSE)
|
||||
expect_no_error(default_parsing(df))
|
||||
})
|
||||
|
||||
test_that("default_parsing removes nested list columns", {
|
||||
df <- data.frame(id = 1:3)
|
||||
df$nested <- list(list(1, 2), list(3), list(4, 5)) # nested list column
|
||||
# Should not crash; nested list column is removed by remove_nested_list()
|
||||
expect_no_error(default_parsing(df))
|
||||
})
|
||||
|
||||
test_that("default_parsing works with dplyr::starwars-like tibble", {
|
||||
skip_if_not_installed("dplyr")
|
||||
sw <- head(dplyr::starwars, 10)
|
||||
result <- default_parsing(sw)
|
||||
expect_true(is.data.frame(result))
|
||||
expect_equal(nrow(result), 10)
|
||||
})
|
||||
|
||||
test_that("default_parsing high-cardinality character column stays character or factor", {
|
||||
# > 10 unique values → should NOT be coerced to factor by numchar2fct
|
||||
df <- data.frame(
|
||||
id = paste0("id_", 1:20),
|
||||
stringsAsFactors = FALSE
|
||||
)
|
||||
result <- default_parsing(df)
|
||||
# high cardinality: remains character (not factor)
|
||||
expect_false(is.factor(result$id))
|
||||
})
|
||||
146
tests/testthat/test-plot_colors.R
Normal file
146
tests/testthat/test-plot_colors.R
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
library(testthat)
|
||||
|
||||
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||
|
||||
is_hex_color <- function(x) {
|
||||
all(grepl("^#[0-9A-Fa-f]{6}([0-9A-Fa-f]{2})?$", x))
|
||||
}
|
||||
|
||||
# ── Input validation ──────────────────────────────────────────────────────────
|
||||
|
||||
test_that("n must be a single positive integer", {
|
||||
expect_error(generate_colors(0), "`n` must be a single positive integer")
|
||||
expect_error(generate_colors(-1), "`n` must be a single positive integer")
|
||||
expect_error(generate_colors(1.5), "`n` must be a single positive integer")
|
||||
expect_error(generate_colors(c(2, 3)), "`n` must be a single positive integer")
|
||||
expect_error(generate_colors("5"), "`n` must be a single positive integer")
|
||||
})
|
||||
|
||||
test_that("palette must be a single character string or function", {
|
||||
expect_error(generate_colors(5, 123), "`palette` must be a single character string")
|
||||
expect_error(generate_colors(5, c("a", "b")), "`palette` must be a single character string")
|
||||
})
|
||||
|
||||
test_that("unknown palette falls back to hcl.colors with a message", {
|
||||
expect_message(
|
||||
result <- generate_colors(5, "notapalette"),
|
||||
"Unknown palette: 'notapalette'"
|
||||
)
|
||||
expect_equal(length(result), 5)
|
||||
expect_true(is_hex_color(result))
|
||||
})
|
||||
|
||||
# ── Return type and length ────────────────────────────────────────────────────
|
||||
|
||||
test_that("output is a character vector of correct length for each palette family", {
|
||||
palettes <- c("viridis", "plasma", "rainbow", "heat", "terrain", "topo", "Set1", "Blues")
|
||||
for (pal in palettes) {
|
||||
result <- generate_colors(5, pal)
|
||||
expect_true(is.character(result), label = paste0("is.character [", pal, "]"))
|
||||
expect_equal(length(result), 5, label = paste0("length == 5 [", pal, "]"))
|
||||
}
|
||||
})
|
||||
|
||||
test_that("output colors are valid hex codes", {
|
||||
palettes <- c("viridis", "magma", "rainbow", "hcl", "Set1", "Blues")
|
||||
for (pal in palettes) {
|
||||
result <- generate_colors(5, pal)
|
||||
expect_true(is_hex_color(result), label = paste0("hex check [", pal, "]"))
|
||||
}
|
||||
})
|
||||
|
||||
test_that("n = 1 works for all palette families", {
|
||||
expect_equal(length(generate_colors(1, "viridis")), 1)
|
||||
expect_equal(length(generate_colors(1, "rainbow")), 1)
|
||||
expect_equal(length(generate_colors(1, "Set1")), 1)
|
||||
})
|
||||
|
||||
# ── viridisLite ───────────────────────────────────────────────────────────────
|
||||
|
||||
test_that("all viridisLite palettes return correct length", {
|
||||
viridis_palettes <- c("viridis", "magma", "plasma", "inferno",
|
||||
"cividis", "mako", "rocket", "turbo")
|
||||
for (pal in viridis_palettes) {
|
||||
expect_equal(length(generate_colors(6, pal)), 6, label = paste0("length [", pal, "]"))
|
||||
}
|
||||
})
|
||||
|
||||
test_that("viridisLite palette names are case-insensitive", {
|
||||
expect_equal(generate_colors(5, "VIRIDIS"), generate_colors(5, "viridis"))
|
||||
expect_equal(generate_colors(5, "Plasma"), generate_colors(5, "plasma"))
|
||||
})
|
||||
|
||||
test_that("extra args are forwarded to viridisLite (direction)", {
|
||||
fwd <- generate_colors(5, "viridis", direction = 1)
|
||||
rev <- generate_colors(5, "viridis", direction = -1)
|
||||
expect_false(identical(fwd, rev))
|
||||
})
|
||||
|
||||
# ── grDevices ─────────────────────────────────────────────────────────────────
|
||||
|
||||
test_that("grDevices palettes return correct length", {
|
||||
for (pal in c("hcl", "rainbow", "heat", "terrain", "topo")) {
|
||||
expect_equal(length(generate_colors(7, pal)), 7, label = paste0("length [", pal, "]"))
|
||||
}
|
||||
})
|
||||
|
||||
test_that("grDevices palette names are case-insensitive", {
|
||||
expect_equal(generate_colors(5, "Rainbow"), generate_colors(5, "rainbow"))
|
||||
expect_equal(generate_colors(5, "HEAT"), generate_colors(5, "heat"))
|
||||
})
|
||||
|
||||
# ── RColorBrewer ──────────────────────────────────────────────────────────────
|
||||
|
||||
test_that("RColorBrewer returns exactly n colors for any n >= 1", {
|
||||
expect_equal(length(generate_colors(1, "Set1")), 1) # below brewer min, slices
|
||||
expect_equal(length(generate_colors(2, "Set1")), 2) # below brewer min, slices
|
||||
expect_equal(length(generate_colors(3, "Set1")), 3) # at brewer min
|
||||
expect_equal(length(generate_colors(9, "Set1")), 9) # at brewer max
|
||||
expect_equal(length(generate_colors(15, "Set1")), 15) # above brewer max, interpolates
|
||||
})
|
||||
|
||||
test_that("RColorBrewer n < 3 does not warn or error", {
|
||||
expect_no_warning(generate_colors(1, "Set1"))
|
||||
expect_no_warning(generate_colors(2, "Blues"))
|
||||
})
|
||||
|
||||
test_that("RColorBrewer output is valid hex for all n", {
|
||||
expect_true(is_hex_color(generate_colors(1, "Blues")))
|
||||
expect_true(is_hex_color(generate_colors(9, "Blues")))
|
||||
expect_true(is_hex_color(generate_colors(20, "Blues")))
|
||||
})
|
||||
|
||||
test_that("RColorBrewer sequential and diverging palettes work", {
|
||||
expect_equal(length(generate_colors(5, "Blues")), 5)
|
||||
expect_equal(length(generate_colors(5, "RdBu")), 5)
|
||||
})
|
||||
|
||||
# ── Function passthrough ──────────────────────────────────────────────────────
|
||||
|
||||
test_that("palette accepts a function directly", {
|
||||
result <- generate_colors(5, viridisLite::viridis)
|
||||
expect_equal(length(result), 5)
|
||||
expect_true(is_hex_color(result))
|
||||
})
|
||||
|
||||
test_that("palette accepts an anonymous function", {
|
||||
result <- generate_colors(5, \(n) rep("#FF0000FF", n))
|
||||
expect_equal(result, rep("#FF0000FF", 5))
|
||||
})
|
||||
|
||||
test_that("error message mentions function as valid input type", {
|
||||
expect_error(generate_colors(5, 123), "single character string or a function")
|
||||
})
|
||||
|
||||
# ── Fallback ──────────────────────────────────────────────────────────────────
|
||||
|
||||
test_that("fallback message includes available options", {
|
||||
expect_message(generate_colors(5, "notapalette"), "viridisLite")
|
||||
expect_message(generate_colors(5, "notapalette"), "RColorBrewer")
|
||||
})
|
||||
|
||||
test_that("fallback returns correct length and valid hex colors", {
|
||||
result <- suppressMessages(generate_colors(8, "notapalette"))
|
||||
expect_equal(length(result), 8)
|
||||
expect_true(is_hex_color(result))
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue