From 91e2772a86de66d95119f8ea694fe3eb8a848f48 Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Thu, 26 Jun 2025 09:21:12 +0200 Subject: [PATCH 1/7] visual summary module --- R/visual_summary.R | 291 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 291 insertions(+) create mode 100644 R/visual_summary.R diff --git a/R/visual_summary.R b/R/visual_summary.R new file mode 100644 index 00000000..91f1ca32 --- /dev/null +++ b/R/visual_summary.R @@ -0,0 +1,291 @@ +#' Data correlations evaluation module +#' +#' @param id Module id +#' +#' @name data-missings +#' @returns Shiny ui module +#' @export +visual_summary_ui <- function(id) { + ns <- shiny::NS(id) + + shiny::tagList( + shiny::plotOutput(outputId = ns("visual_plot"), height = "70vh") + ) +} + +visual_summary_server <- function(id, + data_r=shiny::reactive(NULL), + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + # ns <- session$ns + rv <- shiny::reactiveValues(data = NULL) + + shiny::bindEvent(shiny::observe({ + data <- data_r() + rv$data <- data + # vars_num <- vapply(data, \(.x){ + # is.numeric(.x) || is_datetime(.x) + # }, logical(1)) + # vars_num <- names(vars_num)[vars_num] + # shinyWidgets::updateVirtualSelect( + # inputId = "variable", + # choices = vars_num, + # selected = if (isTruthy(input$variable)) input$variable else vars_num[1] + # ) + }), data_r(), input$hidden) + + # datar <- if (is.reactive(data)) data else reactive(data) + + + # apexcharter::renderApexchart({ + # missings_apex_plot(datar(), ...) + # }) + output$visual_plot <- shiny::renderPlot(expr = { + visual_summary(data = rv$data,...) + }) + } + ) +} + +visual_summary_demo_app <- function() { + ui <- shiny::fluidPage( + shiny::actionButton( + inputId = "modal_missings", + label = "Visual summary", + width = "100%", + disabled = FALSE + ) + ) + server <- function(input, output, session) { + data_demo <- mtcars + data_demo[sample(1:32, 10), "cyl"] <- NA + data_demo[sample(1:32, 8), "vs"] <- NA + + visual_summary_server(id = "data", data = shiny::reactive(data_demo)) + + observeEvent(input$modal_missings, { + tryCatch( + { + modal_visual_summary(id = "data") + }, + error = function(err) { + showNotification(paste0("We encountered the following error browsing your data: ", err), type = "err") + } + ) + }) + } + shiny::shinyApp(ui, server) +} + +visual_summary_demo_app() + + +modal_visual_summary <- function(id, + title = "Visual overview of data classes and missing observations", + easyClose = TRUE, + size = "xl", + footer = NULL, + ...) { + showModal(modalDialog( + title = tagList(title, datamods:::button_close_modal()), + visual_summary_ui(id = id), + easyClose = easyClose, + size = size, + footer = footer + )) +} + + +## Slow with many observations... + +#' Plot missings and class with apexcharter +#' +#' @param data data frame +#' +#' @returns An [apexchart()] `htmlwidget` object. +#' @export +#' +#' @examples +#' data_demo <- mtcars +#' data_demo[2:4, "cyl"] <- NA +#' rbind(data_demo, data_demo, data_demo, data_demo) |> missings_apex_plot() +#' data_demo |> missings_apex_plot() +#' mtcars |> missings_apex_plot(animation = TRUE) +#' # dplyr::storms |> missings_apex_plot() +#' visdat::vis_dat(dplyr::storms) +missings_apex_plot <- function(data, animation = FALSE, ...) { + l <- data_summary_gather(data, ...) + + df_plot <- l$data + + out <- apexcharter::apex( + data = df_plot, + type = "heatmap", + mapping = apexcharter::aes(x = variable, y = rows, fill = valueType_num), + ... + ) |> + apexcharter::ax_stroke(width = NULL) |> + apexcharter::ax_plotOptions( + heatmap = apexcharter::heatmap_opts( + radius = 0, + enableShades = FALSE, + colorScale = list( + ranges = l$labels + ), + useFillColorAsStroke = TRUE + ) + ) |> + apexcharter::ax_dataLabels(enabled = FALSE) |> + apexcharter::ax_tooltip( + enabled = FALSE, + intersect = FALSE + ) + + if (!isTRUE(animation)) { + out <- out |> + apexcharter::ax_chart(animations = list(enabled = FALSE)) + } + + out +} + + + +#' Ggplot2 data summary visualisation based on visdat::vis_dat. +#' +#' @param data data +#' @param ... optional arguments passed to data_summary_gather() +#' +#' @returns ggplot2 object +#' @export +#' +#' @examples +#' data_demo <- mtcars +#' data_demo[sample(1:32, 10), "cyl"] <- NA +#' data_demo[sample(1:32, 8), "vs"] <- NA +#' visual_summary(data_demo) +#' visual_summary(data_demo, palette.fun = scales::hue_pal()) +#' visual_summary(dplyr::storms) +#' visual_summary(dplyr::storms, summary.fun = data_type) +visual_summary <- function(data, legend.title = "Data class", ...) { + l <- data_summary_gather(data, ...) + + df <- l$data + + df$valueType <- factor(df$valueType, levels = names(l$colors)) + df$variable <- factor(df$variable, levels = unique_short(names(data))) + + ggplot2::ggplot(data = df, ggplot2::aes(x = variable, y = rows)) + + ggplot2::geom_raster(ggplot2::aes(fill = valueType)) + + ggplot2::theme_minimal() + + ggplot2::theme(axis.text.x = ggplot2::element_text( + angle = 45, + vjust = 1, hjust = 1 + )) + + ggplot2::scale_fill_manual(values = l$colors) + + ggplot2::labs(x = "", y = "Observations") + + ggplot2::scale_y_reverse() + + ggplot2::theme(axis.text.x = ggplot2::element_text(hjust = 0.5)) + + ggplot2::guides(colour = "none") + + ggplot2::guides(fill = ggplot2::guide_legend(title = legend.title)) + + # change the limits etc. + ggplot2::guides(fill = ggplot2::guide_legend(title = "Type")) + + # add info about the axes + ggplot2::scale_x_discrete(position = "top") + + ggplot2::theme(axis.text.x = ggplot2::element_text(hjust = 0)) + + ggplot2::theme( + panel.grid.major = ggplot2::element_blank(), + panel.grid.minor = ggplot2::element_blank(), + text = ggplot2::element_text(size = 18), + plot.title = ggplot2::element_blank() + ) +} + +#' Data summary for printing visual summary +#' +#' @param data data.frame +#' @param fun summary function. Default is "class" +#' @param palette.fun optionally use specific palette functions. First argument +#' has to be the length. +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' mtcars |> data_summary_gather() +data_summary_gather <- function(data, summary.fun = class, palette.fun = viridisLite::viridis) { + df_plot <- setNames(data, unique_short(names(data))) |> + purrr::map_df(\(x){ + ifelse(is.na(x), + yes = NA, + no = glue::glue_collapse(summary.fun(x), + sep = "\n" + ) + ) + }) |> + dplyr::mutate(rows = dplyr::row_number()) |> + tidyr::pivot_longer( + cols = -rows, + names_to = "variable", values_to = "valueType", values_transform = list(valueType = as.character) + ) |> + dplyr::arrange(rows, variable, valueType) + + + df_plot$valueType_num <- df_plot$valueType |> + forcats::as_factor() |> + as.numeric() + + df_plot$valueType[is.na(df_plot$valueType)] <- "NA" + df_plot$valueType_num[is.na(df_plot$valueType_num)] <- max(df_plot$valueType_num, na.rm = TRUE) + 1 + + labels <- setNames(unique(df_plot$valueType_num), unique(df_plot$valueType)) |> sort() + + if (any(df_plot$valueType == "NA")) { + colors <- setNames(c(palette.fun(length(labels) - 1), "#999999"), names(labels)) + } else { + colors <- setNames(palette.fun(length(labels)), names(labels)) + } + + + label_list <- labels |> + purrr::imap(\(.x, .i){ + list( + from = .x, + to = .x, + color = colors[[.i]], + name = .i + ) + }) |> + setNames(NULL) + + list(data = df_plot, colors = colors, labels = label_list) +} + + + +#' Create unique short names of character vector items based on index +#' +#' @description +#' The function will prefer original names, and only append index to long +#' strings. +#' +#' +#' @param data character vector +#' @param max maximum final name length +#' +#' @returns character vector +#' @export +#' +#' @examples +#' c("kahdleidnsallskdj", "hej") |> unique_short() +unique_short <- function(data, max = 15) { + purrr::imap(data, \(.x, .i){ + if (nchar(.x) > max) { + glue::glue("{substr(.x,1,(max-(nchar(.i)+1)))}_{.i}") + } else { + .x + } + }) |> unlist() +} From fde1a5014066998ac7b3e63aa3fa49a45e7df175 Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Thu, 26 Jun 2025 09:21:42 +0200 Subject: [PATCH 2/7] helper functions for nivce labels and FreesearchR color palette --- R/theme.R | 15 +++++++++++++-- man/FreesearchR_palette.Rd | 20 ++++++++++++++++++++ man/unique_short.Rd | 23 +++++++++++++++++++++++ man/visual_summary.Rd | 28 ++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 man/FreesearchR_palette.Rd create mode 100644 man/unique_short.Rd create mode 100644 man/visual_summary.Rd diff --git a/R/theme.R b/R/theme.R index 7f8c7f75..2bcc2699 100644 --- a/R/theme.R +++ b/R/theme.R @@ -46,7 +46,7 @@ FreesearchR_colors <- function(choose = NULL) { secondary = "#FF6F61", success = "#00C896", warning = "#FFB100", - danger = "#FF3A2F", + danger = "#CC2E25", extra = "#8A4FFF", info = "#11A0EC", bg = "#FFFFFF", @@ -60,7 +60,18 @@ FreesearchR_colors <- function(choose = NULL) { } } - +#' Use the FreesearchR colors +#' +#' @param n number of colors +#' +#' @returns character vector +#' @export +#' +#' @examples +#' FreesearchR_palette(n=7) +FreesearchR_palette <- function(n){ + rep_len(FreesearchR_colors(),n) +} diff --git a/man/FreesearchR_palette.Rd b/man/FreesearchR_palette.Rd new file mode 100644 index 00000000..f0033c2c --- /dev/null +++ b/man/FreesearchR_palette.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/theme.R +\name{FreesearchR_palette} +\alias{FreesearchR_palette} +\title{Use the FreesearchR colors} +\usage{ +FreesearchR_palette(n) +} +\arguments{ +\item{n}{number of colors} +} +\value{ +character vector +} +\description{ +Use the FreesearchR colors +} +\examples{ +FreesearchR_palette(n=7) +} diff --git a/man/unique_short.Rd b/man/unique_short.Rd new file mode 100644 index 00000000..6a9d7b18 --- /dev/null +++ b/man/unique_short.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/visual_summary.R +\name{unique_short} +\alias{unique_short} +\title{Create unique short names of character vector items based on index} +\usage{ +unique_short(data, max = 15) +} +\arguments{ +\item{data}{character vector} + +\item{max}{maximum final name length} +} +\value{ +character vector +} +\description{ +The function will prefer original names, and only append index to long +strings. +} +\examples{ +c("kahdleidnsallskdj", "hej") |> unique_short() +} diff --git a/man/visual_summary.Rd b/man/visual_summary.Rd new file mode 100644 index 00000000..4a508ea7 --- /dev/null +++ b/man/visual_summary.Rd @@ -0,0 +1,28 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/visual_summary.R +\name{visual_summary} +\alias{visual_summary} +\title{Ggplot2 data summary visualisation based on visdat::vis_dat.} +\usage{ +visual_summary(data, legend.title = "Data class", ...) +} +\arguments{ +\item{data}{data} + +\item{...}{optional arguments passed to data_summary_gather()} +} +\value{ +ggplot2 object +} +\description{ +Ggplot2 data summary visualisation based on visdat::vis_dat. +} +\examples{ +data_demo <- mtcars +data_demo[sample(1:32, 10), "cyl"] <- NA +data_demo[sample(1:32, 8), "vs"] <- NA +visual_summary(data_demo) +visual_summary(data_demo, palette.fun = scales::hue_pal()) +visual_summary(dplyr::storms) +visual_summary(dplyr::storms, summary.fun = data_type) +} From da37710d6b1741cef772ee96bac946cdfd5530c7 Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Thu, 26 Jun 2025 09:22:00 +0200 Subject: [PATCH 3/7] docs --- man/data-missings.Rd | 9 ++++++++- man/data_summary_gather.Rd | 29 +++++++++++++++++++++++++++++ man/missings_apex_plot.Rd | 2 +- 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 man/data_summary_gather.Rd diff --git a/man/data-missings.Rd b/man/data-missings.Rd index 510d78b0..f3f908df 100644 --- a/man/data-missings.Rd +++ b/man/data-missings.Rd @@ -1,14 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/missings-module.R +% Please edit documentation in R/missings-module.R, R/visual_summary.R \name{data-missings} \alias{data-missings} \alias{data_missings_ui} \alias{data_missings_server} +\alias{visual_summary_ui} \title{Data correlations evaluation module} \usage{ data_missings_ui(id) data_missings_server(id, data, variable, ...) + +visual_summary_ui(id) } \arguments{ \item{id}{Module id} @@ -21,7 +24,11 @@ data_missings_server(id, data, variable, ...) Shiny ui module shiny server module + +Shiny ui module } \description{ +Data correlations evaluation module + Data correlations evaluation module } diff --git a/man/data_summary_gather.Rd b/man/data_summary_gather.Rd new file mode 100644 index 00000000..f904afbf --- /dev/null +++ b/man/data_summary_gather.Rd @@ -0,0 +1,29 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/visual_summary.R +\name{data_summary_gather} +\alias{data_summary_gather} +\title{Data summary for printing visual summary} +\usage{ +data_summary_gather( + data, + summary.fun = class, + palette.fun = viridisLite::viridis +) +} +\arguments{ +\item{data}{data.frame} + +\item{palette.fun}{optionally use specific palette functions. First argument +has to be the length.} + +\item{fun}{summary function. Default is "class"} +} +\value{ +data.frame +} +\description{ +Data summary for printing visual summary +} +\examples{ +mtcars |> data_summary_gather() +} diff --git a/man/missings_apex_plot.Rd b/man/missings_apex_plot.Rd index c9474534..bcf076ed 100644 --- a/man/missings_apex_plot.Rd +++ b/man/missings_apex_plot.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/missings-module.R +% Please edit documentation in R/visual_summary.R \name{missings_apex_plot} \alias{missings_apex_plot} \title{Plot missings and class with apexcharter} From c7a9467b471b1b528c4f3267f49f2b6320ed673f Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Thu, 26 Jun 2025 09:22:21 +0200 Subject: [PATCH 4/7] slimmed missings evaluation module --- R/missings-module.R | 149 +++++--------------------------------------- 1 file changed, 17 insertions(+), 132 deletions(-) diff --git a/R/missings-module.R b/R/missings-module.R index 53ea9298..71791ac6 100644 --- a/R/missings-module.R +++ b/R/missings-module.R @@ -34,7 +34,8 @@ data_missings_server <- function(id, variabler <- if (is.reactive(variable)) variable else reactive(variable) rv <- shiny::reactiveValues( - data = NULL + data = NULL, + table = NULL ) rv$data <- shiny::reactive({ @@ -65,15 +66,25 @@ data_missings_server <- function(id, shiny::req(variabler) if (is.null(variabler()) || variabler() == "" || !variabler() %in% names(datar())) { + if (anyNA(datar())){ + title <- "No variable chosen for analysis" + } else { title <- "No missing observations" + } } else { - title <- paste("Missing vs non-missing observations in", variabler()) + title <- glue::glue("Missing vs non-missing observations in the variable **'{variabler()}'**") } - rv$data() |> + out <- rv$data() |> gtsummary::as_gt() |> gt::tab_header(title = gt::md(title)) + + rv$table <- out + + out }) + + return(reactive(rv$table)) } ) } @@ -100,10 +111,12 @@ missing_demo_app <- function() { data_missings_server(id = "data", data = data_demo, variable = shiny::reactive(input$missings_var)) + visual_summary_server(id = "visual", data = data_demo) + observeEvent(input$modal_missings, { tryCatch( { - modal_visual_missings(data = data_demo, id = "modal_missings") + modal_visual_summary(id = "visual") }, error = function(err) { showNotification(paste0("We encountered the following error browsing your data: ", err), type = "err") @@ -117,137 +130,9 @@ missing_demo_app <- function() { missing_demo_app() -modal_visual_missings <- function(data, - title = "Visual overview of data classes and missing observations", - easyClose = TRUE, - size = "xl", - footer = NULL, - ...) { - datar <- if (is.reactive(data)) data else reactive(data) - - showModal(modalDialog( - title = tagList(title, datamods:::button_close_modal()), - tags$div( - # apexcharter::renderApexchart({ - # missings_apex_plot(datar(), ...) - # }) - shiny::renderPlot({ - visdat::vis_dat(datar(),sort_type = FALSE) + - ggplot2::guides(fill = ggplot2::guide_legend(title = "Data class")) + - # ggplot2::theme_void() + - ggplot2::theme( - # legend.position = "none", - panel.grid.major = ggplot2::element_blank(), - panel.grid.minor = ggplot2::element_blank(), - # axis.text.y = element_blank(), - # axis.title.y = element_blank(), - text = ggplot2::element_text(size = 18), - # axis.text = ggplot2::element_blank(), - # panel.background = ggplot2::element_rect(fill = "white"), - # plot.background = ggplot2::element_rect(fill = "white"), - # panel.border = ggplot2::element_blank() - plot.title = ggplot2::element_blank() - ) - }) - ), - easyClose = easyClose, - size = size, - footer = footer - )) -} -## Slow with many observations... - -#' Plot missings and class with apexcharter -#' -#' @param data data frame -#' -#' @returns An [apexchart()] `htmlwidget` object. -#' @export -#' -#' @examples -#' data_demo <- mtcars -#' data_demo[2:4, "cyl"] <- NA -#' rbind(data_demo, data_demo, data_demo, data_demo) |> missings_apex_plot() -#' data_demo |> missings_apex_plot() -#' mtcars |> missings_apex_plot(animation = TRUE) -#' # dplyr::storms |> missings_apex_plot() -#' visdat::vis_dat(dplyr::storms) -missings_apex_plot <- function(data, animation = FALSE, ...) { - browser() - - df_plot <- purrr::map_df(data, \(x){ - ifelse(is.na(x), - yes = NA, - no = glue::glue_collapse(class(x), - sep = "\n" - ) - ) - }) %>% - dplyr::mutate(rows = dplyr::row_number()) %>% - tidyr::pivot_longer( - cols = -rows, - names_to = "variable", values_to = "valueType", values_transform = list(valueType = as.character) - ) %>% - dplyr::arrange(rows, variable, valueType) - df_plot$valueType_num <- df_plot$valueType |> - forcats::as_factor() |> - as.numeric() - df_plot$valueType[is.na(df_plot$valueType)] <- "NA" - df_plot$valueType_num[is.na(df_plot$valueType_num)] <- max(df_plot$valueType_num, na.rm = TRUE) + 1 - - labels <- setNames(unique(df_plot$valueType_num), unique(df_plot$valueType)) - - if (any(df_plot$valueType == "NA")) { - colors <- setNames(c(viridisLite::viridis(n = length(labels) - 1), "#999999"), names(labels)) - } else { - colors <- setNames(viridisLite::viridis(n = length(labels)), names(labels)) - } - - - label_list <- labels |> - purrr::imap(\(.x, .i){ - list( - from = .x, - to = .x, - color = colors[[.i]], - name = .i - ) - }) |> - setNames(NULL) - - out <- apexcharter::apex( - data = df_plot, - type = "heatmap", - mapping = apexcharter::aes(x = variable, y = rows, fill = valueType_num), - ... - ) %>% - apexcharter::ax_stroke(width = NULL) |> - apexcharter::ax_plotOptions( - heatmap = apexcharter::heatmap_opts( - radius = 0, - enableShades = FALSE, - colorScale = list( - ranges = label_list - ), - useFillColorAsStroke = TRUE - ) - ) %>% - apexcharter::ax_dataLabels(enabled = FALSE) |> - apexcharter::ax_tooltip( - enabled = FALSE, - intersect = FALSE - ) - - if (!isTRUE(animation)) { - out <- out |> - apexcharter::ax_chart(animations = list(enabled = FALSE)) - } - - out -} From 4c42636faaca7e3bcdd1d542a5918ff268f16a2b Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Thu, 26 Jun 2025 09:22:30 +0200 Subject: [PATCH 5/7] docs --- DESCRIPTION | 3 +- NAMESPACE | 5 + NEWS.md | 2 +- R/hosted_version.R | 2 +- R/sysdata.rda | Bin 2757 -> 2785 bytes SESSION.md | 4 + inst/apps/FreesearchR/app.R | 556 ++++++++++++++++--------- inst/apps/FreesearchR/www/web_data.rds | Bin 3564988 -> 1737943 bytes 8 files changed, 371 insertions(+), 201 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index cebd5484..46be9506 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -64,8 +64,7 @@ Imports: RcppArmadillo, ggcorrplot, shinyjs, - emmeans, - visdat + emmeans Suggests: styler, devtools, diff --git a/NAMESPACE b/NAMESPACE index 2e380700..34c6092e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ S3method(cut_var,default) S3method(cut_var,hms) S3method(plot,tbl_regression) +export(FreesearchR_palette) export(add_class_icon) export(add_sparkline) export(align_axes) @@ -32,6 +33,7 @@ export(data_correlations_ui) export(data_description) export(data_missings_server) export(data_missings_ui) +export(data_summary_gather) export(data_summary_server) export(data_summary_ui) export(data_type) @@ -121,12 +123,15 @@ export(supported_plots) export(symmetrical_scale_x_log10) export(tbl_merge) export(type_icons) +export(unique_short) export(update_factor_server) export(update_factor_ui) export(update_variables_server) export(update_variables_ui) export(vectorSelectInput) export(vertical_stacked_bars) +export(visual_summary) +export(visual_summary_ui) export(wide2long) export(winbox_create_column) export(winbox_update_factor) diff --git a/NEWS.md b/NEWS.md index 3ac90ee6..a92e676b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # FreesearchR 25.6.3 -- *NEW* First go at introducing more options to evaluate missings. This has introduced a new dependency to use the visdat package and visualisation. The solution includes the option to visualise data classes and missingness as well as comparisons of variables by missing outcome variable or not to determine the nature of missingness. +- *NEW* Introducing more options to evaluate missing observations. Inspired by the [visdat()] function from the {visdat} package, a specialised function has been introduced to easily visualise data classes and missing observations in the data set. This highly increases the options to visually get an overview of the data and to assess the pattern of missing data. Also under Evaluate, a comparison module has been introduced to compare the distribution of observations across variables depending on the missing vs non-missing in a specified variable. - *FIX* The REDCap import module has been updated visually and the PAI token is now hidden as a password. This module should still only be used when running locally if you are accessing sensitive data. diff --git a/R/hosted_version.R b/R/hosted_version.R index 9c90096e..8e4a70d9 100644 --- a/R/hosted_version.R +++ b/R/hosted_version.R @@ -1 +1 @@ -hosted_version <- function()'v25.6.3-250625' +hosted_version <- function()'v25.6.3-250626' diff --git a/R/sysdata.rda b/R/sysdata.rda index 4350625ec4ea7ca98eb02c613dbef45a0a043737..95b884224dab1448dc4f948cecb9794c7511a93e 100644 GIT binary patch literal 2785 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 + out <- rv$data() |> gtsummary::as_gt() |> gt::tab_header(title = gt::md(title)) + + rv$table <- out + + out }) + + return(reactive(rv$table)) } ) } @@ -4761,10 +4772,12 @@ missing_demo_app <- function() { data_missings_server(id = "data", data = data_demo, variable = shiny::reactive(input$missings_var)) + visual_summary_server(id = "visual", data = data_demo) + observeEvent(input$modal_missings, { tryCatch( { - modal_visual_missings(data = data_demo, id = "modal_missings") + modal_visual_summary(id = "visual") }, error = function(err) { showNotification(paste0("We encountered the following error browsing your data: ", err), type = "err") @@ -4778,140 +4791,12 @@ missing_demo_app <- function() { missing_demo_app() -modal_visual_missings <- function(data, - title = "Visual overview of data classes and missing observations", - easyClose = TRUE, - size = "xl", - footer = NULL, - ...) { - datar <- if (is.reactive(data)) data else reactive(data) - - showModal(modalDialog( - title = tagList(title, datamods:::button_close_modal()), - tags$div( - # apexcharter::renderApexchart({ - # missings_apex_plot(datar(), ...) - # }) - shiny::renderPlot({ - visdat::vis_dat(datar(),sort_type = FALSE) + - ggplot2::guides(fill = ggplot2::guide_legend(title = "Data class")) + - # ggplot2::theme_void() + - ggplot2::theme( - # legend.position = "none", - panel.grid.major = ggplot2::element_blank(), - panel.grid.minor = ggplot2::element_blank(), - # axis.text.y = element_blank(), - # axis.title.y = element_blank(), - text = ggplot2::element_text(size = 18), - # axis.text = ggplot2::element_blank(), - # panel.background = ggplot2::element_rect(fill = "white"), - # plot.background = ggplot2::element_rect(fill = "white"), - # panel.border = ggplot2::element_blank() - plot.title = ggplot2::element_blank() - ) - }) - ), - easyClose = easyClose, - size = size, - footer = footer - )) -} -## Slow with many observations... - -#' Plot missings and class with apexcharter -#' -#' @param data data frame -#' -#' @returns An [apexchart()] `htmlwidget` object. -#' @export -#' -#' @examples -#' data_demo <- mtcars -#' data_demo[2:4, "cyl"] <- NA -#' rbind(data_demo, data_demo, data_demo, data_demo) |> missings_apex_plot() -#' data_demo |> missings_apex_plot() -#' mtcars |> missings_apex_plot(animation = TRUE) -#' # dplyr::storms |> missings_apex_plot() -#' visdat::vis_dat(dplyr::storms) -missings_apex_plot <- function(data, animation = FALSE, ...) { - browser() - - df_plot <- purrr::map_df(data, \(x){ - ifelse(is.na(x), - yes = NA, - no = glue::glue_collapse(class(x), - sep = "\n" - ) - ) - }) %>% - dplyr::mutate(rows = dplyr::row_number()) %>% - tidyr::pivot_longer( - cols = -rows, - names_to = "variable", values_to = "valueType", values_transform = list(valueType = as.character) - ) %>% - dplyr::arrange(rows, variable, valueType) - df_plot$valueType_num <- df_plot$valueType |> - forcats::as_factor() |> - as.numeric() - df_plot$valueType[is.na(df_plot$valueType)] <- "NA" - df_plot$valueType_num[is.na(df_plot$valueType_num)] <- max(df_plot$valueType_num, na.rm = TRUE) + 1 - - labels <- setNames(unique(df_plot$valueType_num), unique(df_plot$valueType)) - - if (any(df_plot$valueType == "NA")) { - colors <- setNames(c(viridisLite::viridis(n = length(labels) - 1), "#999999"), names(labels)) - } else { - colors <- setNames(viridisLite::viridis(n = length(labels)), names(labels)) - } - - - label_list <- labels |> - purrr::imap(\(.x, .i){ - list( - from = .x, - to = .x, - color = colors[[.i]], - name = .i - ) - }) |> - setNames(NULL) - - out <- apexcharter::apex( - data = df_plot, - type = "heatmap", - mapping = apexcharter::aes(x = variable, y = rows, fill = valueType_num), - ... - ) %>% - apexcharter::ax_stroke(width = NULL) |> - apexcharter::ax_plotOptions( - heatmap = apexcharter::heatmap_opts( - radius = 0, - enableShades = FALSE, - colorScale = list( - ranges = label_list - ), - useFillColorAsStroke = TRUE - ) - ) %>% - apexcharter::ax_dataLabels(enabled = FALSE) |> - apexcharter::ax_tooltip( - enabled = FALSE, - intersect = FALSE - ) - - if (!isTRUE(animation)) { - out <- out |> - apexcharter::ax_chart(animations = list(enabled = FALSE)) - } - - out -} ######## @@ -8278,7 +8163,7 @@ FreesearchR_colors <- function(choose = NULL) { secondary = "#FF6F61", success = "#00C896", warning = "#FFB100", - danger = "#FF3A2F", + danger = "#CC2E25", extra = "#8A4FFF", info = "#11A0EC", bg = "#FFFFFF", @@ -8292,7 +8177,18 @@ FreesearchR_colors <- function(choose = NULL) { } } - +#' Use the FreesearchR colors +#' +#' @param n number of colors +#' +#' @returns character vector +#' @export +#' +#' @examples +#' FreesearchR_palette(n=7) +FreesearchR_palette <- function(n){ + rep_len(FreesearchR_colors(),n) +} @@ -9443,6 +9339,303 @@ clean_date <- function(data) { } +######## +#### Current file: /Users/au301842/FreesearchR/R//visual_summary.R +######## + +#' Data correlations evaluation module +#' +#' @param id Module id +#' +#' @name data-missings +#' @returns Shiny ui module +#' @export +visual_summary_ui <- function(id) { + ns <- shiny::NS(id) + + shiny::tagList( + shiny::plotOutput(outputId = ns("visual_plot"), height = "70vh") + ) +} + +visual_summary_server <- function(id, + data_r=shiny::reactive(NULL), + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + # ns <- session$ns + rv <- shiny::reactiveValues(data = NULL) + + shiny::bindEvent(shiny::observe({ + data <- data_r() + rv$data <- data + # vars_num <- vapply(data, \(.x){ + # is.numeric(.x) || is_datetime(.x) + # }, logical(1)) + # vars_num <- names(vars_num)[vars_num] + # shinyWidgets::updateVirtualSelect( + # inputId = "variable", + # choices = vars_num, + # selected = if (isTruthy(input$variable)) input$variable else vars_num[1] + # ) + }), data_r(), input$hidden) + + # datar <- if (is.reactive(data)) data else reactive(data) + + + # apexcharter::renderApexchart({ + # missings_apex_plot(datar(), ...) + # }) + output$visual_plot <- shiny::renderPlot(expr = { + visual_summary(data = rv$data,...) + }) + } + ) +} + +visual_summary_demo_app <- function() { + ui <- shiny::fluidPage( + shiny::actionButton( + inputId = "modal_missings", + label = "Visual summary", + width = "100%", + disabled = FALSE + ) + ) + server <- function(input, output, session) { + data_demo <- mtcars + data_demo[sample(1:32, 10), "cyl"] <- NA + data_demo[sample(1:32, 8), "vs"] <- NA + + visual_summary_server(id = "data", data = shiny::reactive(data_demo)) + + observeEvent(input$modal_missings, { + tryCatch( + { + modal_visual_summary(id = "data") + }, + error = function(err) { + showNotification(paste0("We encountered the following error browsing your data: ", err), type = "err") + } + ) + }) + } + shiny::shinyApp(ui, server) +} + +visual_summary_demo_app() + + +modal_visual_summary <- function(id, + title = "Visual overview of data classes and missing observations", + easyClose = TRUE, + size = "xl", + footer = NULL, + ...) { + showModal(modalDialog( + title = tagList(title, datamods:::button_close_modal()), + visual_summary_ui(id = id), + easyClose = easyClose, + size = size, + footer = footer + )) +} + + +## Slow with many observations... + +#' Plot missings and class with apexcharter +#' +#' @param data data frame +#' +#' @returns An [apexchart()] `htmlwidget` object. +#' @export +#' +#' @examples +#' data_demo <- mtcars +#' data_demo[2:4, "cyl"] <- NA +#' rbind(data_demo, data_demo, data_demo, data_demo) |> missings_apex_plot() +#' data_demo |> missings_apex_plot() +#' mtcars |> missings_apex_plot(animation = TRUE) +#' # dplyr::storms |> missings_apex_plot() +#' visdat::vis_dat(dplyr::storms) +missings_apex_plot <- function(data, animation = FALSE, ...) { + l <- data_summary_gather(data, ...) + + df_plot <- l$data + + out <- apexcharter::apex( + data = df_plot, + type = "heatmap", + mapping = apexcharter::aes(x = variable, y = rows, fill = valueType_num), + ... + ) |> + apexcharter::ax_stroke(width = NULL) |> + apexcharter::ax_plotOptions( + heatmap = apexcharter::heatmap_opts( + radius = 0, + enableShades = FALSE, + colorScale = list( + ranges = l$labels + ), + useFillColorAsStroke = TRUE + ) + ) |> + apexcharter::ax_dataLabels(enabled = FALSE) |> + apexcharter::ax_tooltip( + enabled = FALSE, + intersect = FALSE + ) + + if (!isTRUE(animation)) { + out <- out |> + apexcharter::ax_chart(animations = list(enabled = FALSE)) + } + + out +} + + + +#' Ggplot2 data summary visualisation based on visdat::vis_dat. +#' +#' @param data data +#' @param ... optional arguments passed to data_summary_gather() +#' +#' @returns ggplot2 object +#' @export +#' +#' @examples +#' data_demo <- mtcars +#' data_demo[sample(1:32, 10), "cyl"] <- NA +#' data_demo[sample(1:32, 8), "vs"] <- NA +#' visual_summary(data_demo) +#' visual_summary(data_demo, palette.fun = scales::hue_pal()) +#' visual_summary(dplyr::storms) +#' visual_summary(dplyr::storms, summary.fun = data_type) +visual_summary <- function(data, legend.title = "Data class", ...) { + l <- data_summary_gather(data, ...) + + df <- l$data + + df$valueType <- factor(df$valueType, levels = names(l$colors)) + df$variable <- factor(df$variable, levels = unique_short(names(data))) + + ggplot2::ggplot(data = df, ggplot2::aes(x = variable, y = rows)) + + ggplot2::geom_raster(ggplot2::aes(fill = valueType)) + + ggplot2::theme_minimal() + + ggplot2::theme(axis.text.x = ggplot2::element_text( + angle = 45, + vjust = 1, hjust = 1 + )) + + ggplot2::scale_fill_manual(values = l$colors) + + ggplot2::labs(x = "", y = "Observations") + + ggplot2::scale_y_reverse() + + ggplot2::theme(axis.text.x = ggplot2::element_text(hjust = 0.5)) + + ggplot2::guides(colour = "none") + + ggplot2::guides(fill = ggplot2::guide_legend(title = legend.title)) + + # change the limits etc. + ggplot2::guides(fill = ggplot2::guide_legend(title = "Type")) + + # add info about the axes + ggplot2::scale_x_discrete(position = "top") + + ggplot2::theme(axis.text.x = ggplot2::element_text(hjust = 0)) + + ggplot2::theme( + panel.grid.major = ggplot2::element_blank(), + panel.grid.minor = ggplot2::element_blank(), + text = ggplot2::element_text(size = 18), + plot.title = ggplot2::element_blank() + ) +} + +#' Data summary for printing visual summary +#' +#' @param data data.frame +#' @param fun summary function. Default is "class" +#' @param palette.fun optionally use specific palette functions. First argument +#' has to be the length. +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' mtcars |> data_summary_gather() +data_summary_gather <- function(data, summary.fun = class, palette.fun = viridisLite::viridis) { + df_plot <- setNames(data, unique_short(names(data))) |> + purrr::map_df(\(x){ + ifelse(is.na(x), + yes = NA, + no = glue::glue_collapse(summary.fun(x), + sep = "\n" + ) + ) + }) |> + dplyr::mutate(rows = dplyr::row_number()) |> + tidyr::pivot_longer( + cols = -rows, + names_to = "variable", values_to = "valueType", values_transform = list(valueType = as.character) + ) |> + dplyr::arrange(rows, variable, valueType) + + + df_plot$valueType_num <- df_plot$valueType |> + forcats::as_factor() |> + as.numeric() + + df_plot$valueType[is.na(df_plot$valueType)] <- "NA" + df_plot$valueType_num[is.na(df_plot$valueType_num)] <- max(df_plot$valueType_num, na.rm = TRUE) + 1 + + labels <- setNames(unique(df_plot$valueType_num), unique(df_plot$valueType)) |> sort() + + if (any(df_plot$valueType == "NA")) { + colors <- setNames(c(palette.fun(length(labels) - 1), "#999999"), names(labels)) + } else { + colors <- setNames(palette.fun(length(labels)), names(labels)) + } + + + label_list <- labels |> + purrr::imap(\(.x, .i){ + list( + from = .x, + to = .x, + color = colors[[.i]], + name = .i + ) + }) |> + setNames(NULL) + + list(data = df_plot, colors = colors, labels = label_list) +} + + + +#' Create unique short names of character vector items based on index +#' +#' @description +#' The function will prefer original names, and only append index to long +#' strings. +#' +#' +#' @param data character vector +#' @param max maximum final name length +#' +#' @returns character vector +#' @export +#' +#' @examples +#' c("kahdleidnsallskdj", "hej") |> unique_short() +unique_short <- function(data, max = 15) { + purrr::imap(data, \(.x, .i){ + if (nchar(.x) > max) { + glue::glue("{substr(.x,1,(max-(nchar(.i)+1)))}_{.i}") + } else { + .x + } + }) |> unlist() +} + + ######## #### Current file: /Users/au301842/FreesearchR/R//wide2long.R ######## @@ -9796,7 +9989,7 @@ ui_elements <- list( shiny::column( width = 3, shiny::actionButton( - inputId = "modal_missings", + inputId = "modal_visual_overview", label = "Visual overview", width = "100%", disabled = TRUE @@ -10323,6 +10516,7 @@ server <- function(input, output, session) { rv <- shiny::reactiveValues( list = list(), regression = NULL, + missings = NULL, ds = NULL, local_temp = NULL, ready = NULL, @@ -10342,28 +10536,6 @@ server <- function(input, output, session) { ######### ############################################################################## - ## This does not render correctly apparently due to css and load order - # output$source <- shiny::renderUI({ - # - # choices <- c( - # "File upload" = "file", - # "REDCap server export" = "redcap", - # "Local or sample data" = "env" - # ) - # - # if (isTRUE(is_local)){ - # choices <- choices[c(1,3)] - # } - # - # shinyWidgets::radioGroupButtons( - # inputId = "source", - # selected = "file", - # choices = choices, - # size = "lg" - # ) - # }) - - data_file <- import_file_server( id = "file_import", show_data_in = "popup", @@ -10386,16 +10558,6 @@ server <- function(input, output, session) { rv$code <- modifyList(x = rv$code, list(import = from_redcap$code())) }) - ## This is used to ensure the reactive data is retrieved - # output$redcap_prev <- DT::renderDT( - # { - # DT::datatable(head(from_redcap$data(), 5), - # caption = "First 5 observations" - # ) - # }, - # server = TRUE - # ) - from_env <- datamods::import_globalenv_server( id = "env", trigger_return = "change", @@ -10410,11 +10572,20 @@ server <- function(input, output, session) { rv$code <- modifyList(x = rv$code, list(import = from_env$name())) }) + visual_summary_server( + id = "initial_summary", + data_r = shiny::reactive({ + shiny::req(rv$data_temp) + default_parsing(rv$data_temp) + }), + palette.fun = FreesearchR_palette + ) + observeEvent(input$modal_initial_view, { tryCatch( { - modal_visual_missings( - data = default_parsing(rv$data_temp), + modal_visual_summary( + id = "initial_summary", footer = NULL, size = "xl" ) @@ -10497,12 +10668,12 @@ server <- function(input, output, session) { if (is.null(rv$data_original) | NROW(rv$data_original) == 0) { shiny::updateActionButton(inputId = "act_start", disabled = TRUE) shiny::updateActionButton(inputId = "modal_browse", disabled = TRUE) - shiny::updateActionButton(inputId = "modal_missings", disabled = TRUE) + shiny::updateActionButton(inputId = "modal_visual_overview", disabled = TRUE) shiny::updateActionButton(inputId = "act_eval", disabled = TRUE) } else { shiny::updateActionButton(inputId = "act_start", disabled = FALSE) shiny::updateActionButton(inputId = "modal_browse", disabled = FALSE) - shiny::updateActionButton(inputId = "modal_missings", disabled = FALSE) + shiny::updateActionButton(inputId = "modal_visual_overview", disabled = FALSE) shiny::updateActionButton(inputId = "act_eval", disabled = FALSE) } }) @@ -10548,7 +10719,6 @@ server <- function(input, output, session) { ) }) - ######### ######### Modifications ######### @@ -10741,11 +10911,20 @@ server <- function(input, output, session) { ) }) - observeEvent(input$modal_missings, { + visual_summary_server( + id = "visual_overview", + data_r = shiny::reactive({ + shiny::req(rv$data_filtered) + REDCapCAST::fct_drop(rv$data_filtered) + }), + palette.fun = FreesearchR_palette + ) + + observeEvent(input$modal_visual_overview, { tryCatch( { - modal_visual_missings( - data = REDCapCAST::fct_drop(rv$data_filtered), + modal_visual_summary( + id = "visual_overview", footer = "Here is an overview of how your data is interpreted, and where data is missing. Use this information to consider if data is missing at random or if some observations are missing systematically wich may be caused by an observation bias.", size = "xl" ) @@ -10756,7 +10935,6 @@ server <- function(input, output, session) { ) }) - output$original_str <- renderPrint({ str(rv$data_original) }) @@ -10779,7 +10957,6 @@ server <- function(input, output, session) { shiny::req(rv$data_filtered) rv$list$table1 <- NULL - # rv$regression <- NULL } ) @@ -10904,7 +11081,7 @@ server <- function(input, output, session) { rv$list$table1 <- rlang::exec(create_baseline, !!!append_list(rv$list$data, parameters, "data")) }) - rv$code$table1 <- glue::glue("FreesearchR::create_baseline(data,{list2str(parameters)})") + rv$code$table1 <- glue::glue("FreesearchR::create_baseline(df,{list2str(parameters)})") } ) @@ -10951,12 +11128,12 @@ server <- function(input, output, session) { label = "Select variable to stratify analysis", data = shiny::reactive({ shiny::req(rv$data_filtered) - rv$data_filtered[apply(rv$data_filtered,2,anyNA)] + rv$data_filtered[apply(rv$data_filtered, 2, anyNA)] })() ) }) - data_missings_server( + rv$missings <- data_missings_server( id = "missingness", data = shiny::reactive(rv$data_filtered), variable = shiny::reactive(input$missings_var) @@ -10979,22 +11156,6 @@ server <- function(input, output, session) { rv$regression <- regression_server("regression", data = shiny::reactive(rv$list$data)) - # shiny::observeEvent(rv$regression, { - # browser() - # if (shiny::is.reactive(rv$regression)) { - # rv$list$regression <- rv$regression() - # } else { - # rv$list$regression <- rv$regression - # } - # # rv$list$regression <- rv$regression() - # }) - - # output$regression_models <- renderText({ - # req(rv$list$regression) - # browser() - # names(rv$list$regression) - # }) - ############################################################################## ######### ######### Page navigation @@ -11051,6 +11212,7 @@ server <- function(input, output, session) { format <- ifelse(type == "docx", "word_document", "odt_document") rv$list$regression <- rv$regression() + rv$list$missings <- rv$missings() shiny::withProgress(message = "Generating the report. Hold on for a moment..", { tryCatch( diff --git a/inst/apps/FreesearchR/www/web_data.rds b/inst/apps/FreesearchR/www/web_data.rds index a3256d47bc6241048b8206d178cfbde878d37a14..d81c8b24c3dbdb079353ec4940d2ce756a9ac1e0 100644 GIT binary patch literal 1737943 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"x!M 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 U?ua#hW$whv9Ei3=hWYXT4@bvznE(I) literal 3564988 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 From 4f0a17d821c23218562e22daa61d041f52143224 Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Thu, 26 Jun 2025 10:17:24 +0200 Subject: [PATCH 6/7] publishing with docker --- .github/workflows/docker-build.yml | 49 + CITATION.cff | 13 - DESCRIPTION | 3 +- R/sysdata.rda | Bin 2785 -> 2769 bytes SESSION.md | 10 +- app_docker/.dockerignore | 6 + app_docker/Dockerfile | 12 + app_docker/app.R | 11275 ++++++++++++++++++++++++++ app_docker/www/FreesearchR-logo.png | Bin 0 -> 22712 bytes app_docker/www/favicon.ico | Bin 0 -> 15086 bytes app_docker/www/favicon.png | Bin 0 -> 28511 bytes app_docker/www/favicon.svg | 3 + app_docker/www/intro.html | 438 + app_docker/www/intro.md | 31 + app_docker/www/references.bib | 11 + app_docker/www/report.rmd | 83 + app_docker/www/style.css | 125 + app_docker/www/umami-app.html | 1 + app_docker/www/web_data.rds | Bin 0 -> 1737943 bytes renv.lock | 48 - 20 files changed, 12040 insertions(+), 68 deletions(-) create mode 100644 .github/workflows/docker-build.yml create mode 100644 app_docker/.dockerignore create mode 100644 app_docker/Dockerfile create mode 100644 app_docker/app.R create mode 100644 app_docker/www/FreesearchR-logo.png create mode 100755 app_docker/www/favicon.ico create mode 100644 app_docker/www/favicon.png create mode 100755 app_docker/www/favicon.svg create mode 100644 app_docker/www/intro.html create mode 100644 app_docker/www/intro.md create mode 100644 app_docker/www/references.bib create mode 100644 app_docker/www/report.rmd create mode 100644 app_docker/www/style.css create mode 100644 app_docker/www/umami-app.html create mode 100644 app_docker/www/web_data.rds diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml new file mode 100644 index 00000000..3cd45b8b --- /dev/null +++ b/.github/workflows/docker-build.yml @@ -0,0 +1,49 @@ +name: Build and Push Docker Image +permissions: + contents: read + packages: write + +on: + # push: + # branches: + # - main + # - master + release: + types: [published] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Define lowercase variables + id: vars + run: | + REPO_OWNER_LOWER=$(echo "$GITHUB_REPOSITORY_OWNER" | tr '[:upper:]' '[:lower:]') + REPO_NAME_LOWER=$(echo "$GITHUB_REPOSITORY" | cut -d'/' -f2 | tr '[:upper:]' '[:lower:]') + echo "REPO_OWNER_LOWER=$REPO_OWNER_LOWER" >> $GITHUB_ENV + echo "REPO_NAME_LOWER=$REPO_NAME_LOWER" >> $GITHUB_ENV + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: app_docker/Dockerfile + push: true + tags: | + ghcr.io/${{ env.REPO_OWNER_LOWER }}/${{ env.REPO_NAME_LOWER }}:latest + ghcr.io/${{ env.REPO_OWNER_LOWER }}/${{ env.REPO_NAME_LOWER }}:${{ github.sha }} diff --git a/CITATION.cff b/CITATION.cff index ed962eb8..fbe84208 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1002,19 +1002,6 @@ references: email: russell-lenth@uiowa.edu year: '2025' doi: 10.32614/CRAN.package.emmeans -- type: software - title: visdat - abstract: 'visdat: Preliminary Visualisation of Data' - notes: Imports - url: https://docs.ropensci.org/visdat/ - repository: https://CRAN.R-project.org/package=visdat - authors: - - family-names: Tierney - given-names: Nicholas - email: nicholas.tierney@gmail.com - orcid: https://orcid.org/0000-0003-1460-8722 - year: '2025' - doi: 10.32614/CRAN.package.visdat - type: software title: styler abstract: 'styler: Non-Invasive Pretty Printing of R Code' diff --git a/DESCRIPTION b/DESCRIPTION index 46be9506..439b7312 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -79,7 +79,8 @@ Suggests: testthat (>= 3.0.0), shinytest, covr, - cffr + cffr, + shiny2docker URL: https://github.com/agdamsbo/FreesearchR, https://agdamsbo.github.io/FreesearchR/, https://app.FreesearchR.org/ BugReports: https://github.com/agdamsbo/FreesearchR/issues VignetteBuilder: knitr diff --git a/R/sysdata.rda b/R/sysdata.rda index 95b884224dab1448dc4f948cecb9794c7511a93e..e24deec4ecb011461697641b10e8b02eeacf8de7 100644 GIT binary patch literal 2769 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 X@}b?W8UWGb5B@IXig2MJn5xviS$-B@ literal 2785 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 baseline_table() +#' mtcars |> baseline_table(fun.args = list(by = "gear")) +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) +} + + + +#' Create a baseline table +#' +#' @param data data +#' @param ... passed as fun.arg to baseline_table() +#' @param strat.var grouping/strat variable +#' @param add.p add comparison/p-value +#' @param add.overall add overall column +#' +#' @returns gtsummary table list object +#' @export +#' +#' @examples +#' mtcars |> create_baseline(by.var = "gear", add.p = "yes" == "yes") +#' 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.overall = FALSE, theme = c("jama", "lancet", "nejm", "qjecon")) { + theme <- match.arg(theme) + + if (by.var == "none" | !by.var %in% names(data)) { + by.var <- NULL + } + + ## These steps are to handle logicals/booleans, that messes up the order of columns + ## Has been reported and should be fixed soon (02042025) + + if (!is.null(by.var)) { + if (identical("logical", class(data[[by.var]]))) { + data[by.var] <- as.character(data[[by.var]]) + } + } + + suppressMessages(gtsummary::theme_gtsummary_journal(journal = theme)) + + args <- list(...) + + parameters <- list( + data = data, + fun.args = list(by = by.var, ...) + ) + + out <- do.call( + baseline_table, + parameters + ) + + + if (!is.null(by.var)) { + if (isTRUE(add.overall)) { + out <- out |> gtsummary::add_overall() + } + if (isTRUE(add.p)) { + out <- out |> + gtsummary::add_p() |> + gtsummary::bold_p() + } + } + + out +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//contrast_text.R +######## + +#' @title Contrast Text Color +#' @description Calculates the best contrast text color for a given +#' background color. +#' @param background A hex/named color value that represents the background. +#' @param light_text A hex/named color value that represents the light text +#' color. +#' @param dark_text A hex/named color value that represents the dark text color. +#' @param threshold A numeric value between 0 and 1 that is used to determine +#' the luminance threshold of the background color for text color. +#' @param method A character string that specifies the method for calculating +#' the luminance. Three different methods are available: +#' c("relative","perceived","perceived_2") +#' @param ... parameter overflow. Ignored. +#' @details +#' This function aids in deciding the font color to print on a given background. +#' The function is based on the example provided by teppo: +#' https://stackoverflow.com/a/66669838/21019325. +#' The different methods provided are based on the methods outlined in the +#' StackOverflow thread: +#' https://stackoverflow.com/questions/596216/formula-to-determine-perceived-brightness-of-rgb-color +#' @return A character string that contains the best contrast text color. +#' @examples +#' contrast_text(c("#F2F2F2", "blue")) +#' +#' contrast_text(c("#F2F2F2", "blue"), method="relative") +#' @export +#' +#' +contrast_text <- function(background, + light_text = 'white', + dark_text = 'black', + threshold = 0.5, + method = "perceived_2", + ...) { + if (method == "relative") { + luminance <- + c(c(.2126, .7152, .0722) %*% grDevices::col2rgb(background) / 255) + } else if (method == "perceived") { + luminance <- + c(c(.299, .587, .114) %*% grDevices::col2rgb(background) / 255) + } else if (method == "perceived_2") { + luminance <- c(sqrt(colSums(( + c(.299, .587, .114) * grDevices::col2rgb(background) + ) ^ 2)) / 255) + } + + ifelse(luminance < threshold, + light_text, + dark_text) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//correlations-module.R +######## + +#' Data correlations evaluation module +#' +#' @param id Module id. (Use 'ns("id")') +#' +#' @name data-correlations +#' @returns Shiny ui module +#' @export +data_correlations_ui <- function(id, ...) { + ns <- shiny::NS(id) + + shiny::tagList( + shiny::textOutput(outputId = ns("suggest")), + shiny::plotOutput(outputId = ns("correlation_plot"), ...) + ) +} + + +#' +#' @param data data +#' @param color.main main color +#' @param color.sec secondary color +#' @param ... arguments passed to toastui::datagrid +#' +#' @name data-correlations +#' @returns shiny server module +#' @export +data_correlations_server <- function(id, + data, + include.class = NULL, + cutoff = .7, + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + # ns <- session$ns + + rv <- shiny::reactiveValues( + data = NULL + ) + + rv$data <- shiny::reactive({ + shiny::req(data) + if (!is.null(include.class)) { + filter <- sapply(data(), class) %in% include.class + out <- data()[filter] + } else { + out <- data() + } + # out |> dplyr::mutate(dplyr::across(tidyselect::everything(),as.numeric)) + sapply(out,as.numeric) + # as.numeric() + }) + + # rv <- list() + # rv$data <- mtcars + + output$suggest <- shiny::renderPrint({ + shiny::req(rv$data) + shiny::req(cutoff) + pairs <- correlation_pairs(rv$data(), threshold = cutoff()) + + more <- ifelse(nrow(pairs) > 1, "from each pair ", "") + + if (nrow(pairs) == 0) { + out <- glue::glue("No variables have a correlation measure above the threshold.") + } else { + out <- pairs |> + apply(1, \(.x){ + glue::glue("'{.x[1]}'x'{.x[2]}'({round(as.numeric(.x[3]),2)})") + }) |> + (\(.x){ + glue::glue("The following variable pairs are highly correlated: {sentence_paste(.x)}.\nConsider excluding one {more}from the dataset to ensure variables are independent.") + })() + } + out + }) + + output$correlation_plot <- shiny::renderPlot({ + ggcorrplot::ggcorrplot(cor(rv$data())) + + # ggplot2::theme_void() + + ggplot2::theme( + # legend.position = "none", + legend.title = ggplot2::element_text(size = 20), + legend.text = ggplot2::element_text(size = 14), + # panel.grid.major = element_blank(), + # panel.grid.minor = element_blank(), + # axis.text.y = element_blank(), + # axis.title.y = element_blank(), + axis.text.x = ggplot2::element_text(size = 20), + axis.text.y = ggplot2::element_text(size = 20), + # text = element_text(size = 5), + # plot.title = element_blank(), + # panel.background = ggplot2::element_rect(fill = "white"), + # plot.background = ggplot2::element_rect(fill = "white"), + panel.border = ggplot2::element_blank() + ) + # psych::pairs.panels(rv$data()) + }) + } + ) +} + +correlation_pairs <- function(data, threshold = .8) { + data <- as.data.frame(data)[!sapply(as.data.frame(data), is.character)] + data <- sapply(data,\(.x)if (is.factor(.x)) as.numeric(.x) else .x) |> as.data.frame() + # data <- data |> dplyr::mutate(dplyr::across(dplyr::where(is.factor), as.numeric)) + cor <- Hmisc::rcorr(as.matrix(data)) + r <- cor$r %>% as.table() + d <- r |> + as.data.frame() |> + dplyr::filter(abs(Freq) > threshold, Freq != 1) + + d[1:2] |> + apply(1, \(.x){ + sort(unname(.x)) + }, + simplify = logical(1) + ) |> + duplicated() |> + (\(.x){ + d[!.x, ] + })() |> + setNames(c("var1", "var2", "cor")) +} + +sentence_paste <- function(data, and.str = "and") { + and.str <- gsub(" ", "", and.str) + if (length(data) < 2) { + data + } else if (length(data) == 2) { + paste(data, collapse = glue::glue(" {and.str} ")) + } else if (length(data) > 2) { + paste(paste(data[-length(data)], collapse = ", "), data[length(data)], sep = glue::glue(" {and.str} ")) + } +} + + + + + + +######## +#### Current file: /Users/au301842/FreesearchR/R//create-column-mod.R +######## + +#' @title Create new column +#' +#' @description +#' This module allow to enter an expression to create a new column in a `data.frame`. +#' +#' +#' @param id Module's ID. +#' +#' @return A [shiny::reactive()] function returning the data. +#' +#' @note User can only use a subset of function: `r paste(list_allowed_operations(), collapse=", ")`. +#' You can add more operations using the `allowed_operations` argument, for example if you want to allow to use package lubridate, you can do: +#' ```r +#' c(list_allowed_operations(), getNamespaceExports("lubridate")) +#' ``` +#' +#' @export +#' +#' @importFrom htmltools tagList tags css +#' +#' @name create-column +#' +#' @example examples/create_column_module_demo.R +create_column_ui <- function(id) { + ns <- NS(id) + htmltools::tagList( + # datamods:::html_dependency_datamods(), + # html_dependency_FreesearchR(), + shiny::tags$head( + shiny::tags$link(rel = "stylesheet", type = "text/css", href = "FreesearchR/inst/assets/css/FreesearchR.css") + ), + # tags$head( + # # Note the wrapping of the string in HTML() + # tags$style(HTML(" + # /* modified from esquisse for data types */ + # .btn-column-categorical { + # background-color: #EF562D; + # color: #FFFFFF; + # } + # .btn-column-continuous { + # background-color: #0C4C8A; + # color: #FFFFFF; + # } + # .btn-column-dichotomous { + # background-color: #97D5E0; + # color: #FFFFFF; + # } + # .btn-column-datetime { + # background-color: #97D5E0; + # color: #FFFFFF; + # } + # .btn-column-id { + # background-color: #848484; + # color: #FFFFFF; + # } + # .btn-column-text { + # background-color: #2E2E2E; + # color: #FFFFFF; + # }")) + # ), + fluidRow( + column( + width = 6, + textInput( + inputId = ns("new_column"), + label = i18n("New column name:"), + value = "new_column1", + width = "100%" + ) + ), + column( + width = 6, + shinyWidgets::virtualSelectInput( + inputId = ns("group_by"), + label = i18n("Group calculation by:"), + choices = NULL, + multiple = TRUE, + disableSelectAll = TRUE, + hasOptionDescription = TRUE, + width = "100%" + ) + ) + ), + shiny::textAreaInput( + inputId = ns("expression"), + label = i18n("Enter an expression to define new column:"), + value = "", + width = "100%", + rows = 6 + ), + tags$i( + class = "d-block", + phosphoricons::ph("info"), + datamods::i18n("Click on a column name to add it to the expression:") + ), + uiOutput(outputId = ns("columns")), + uiOutput(outputId = ns("feedback")), + tags$div( + style = htmltools::css( + display = "grid", + gridTemplateColumns = "3fr 1fr", + columnGap = "10px", + margin = "10px 0" + ), + actionButton( + inputId = ns("compute"), + label = tagList( + phosphoricons::ph("gear"), i18n("Create column") + ), + class = "btn-outline-primary", + width = "100%" + ), + actionButton( + inputId = ns("remove"), + label = tagList( + phosphoricons::ph("trash") + ), + class = "btn-outline-danger", + width = "100%" + ) + ) + ) +} + +#' @param data_r A [shiny::reactive()] function returning a `data.frame`. +#' @param allowed_operations A `list` of allowed operations, see below for details. +#' +#' @export +#' +#' @rdname create-column +#' +create_column_server <- function(id, + data_r = reactive(NULL), + allowed_operations = list_allowed_operations()) { + moduleServer( + id, + function(input, output, session) { + ns <- session$ns + + info_alert <- shinyWidgets::alert( + status = "info", + phosphoricons::ph("question"), + datamods::i18n("Choose a name for the column to be created or modified,"), + datamods::i18n("then enter an expression before clicking on the button above to validate or on "), + phosphoricons::ph("trash"), datamods::i18n("to delete it.") + ) + + rv <- reactiveValues( + data = NULL, + feedback = info_alert + ) + + observeEvent(input$hidden, rv$feedback <- info_alert) + + bindEvent(observe({ + data <- data_r() + shinyWidgets::updateVirtualSelect( + inputId = "group_by", + choices = make_choices_with_infos(data) + ) + }), data_r(), input$hidden) + + observeEvent(data_r(), rv$data <- data_r()) + + output$feedback <- renderUI(rv$feedback) + + output$columns <- renderUI({ + data <- req(rv$data) + mapply( + label = names(data), + data = data, + FUN = btn_column, + MoreArgs = list(inputId = ns("add_column")), + SIMPLIFY = FALSE + ) + }) + + observeEvent(input$add_column, { + updateTextAreaInput( + session = session, + inputId = "expression", + value = paste0(input$expression, input$add_column) + ) + }) + + observeEvent(input$new_column, { + if (input$new_column == "") { + rv$feedback <- shinyWidgets::alert( + status = "warning", + phosphoricons::ph("warning"), datamods::i18n("New column name cannot be empty") + ) + } + }) + + observeEvent(input$remove, { + rv$data[[input$new_column]] <- NULL + }) + observeEvent(input$compute, { + rv$feedback <- try_compute_column( + expression = input$expression, + name = input$new_column, + rv = rv, + allowed_operations = allowed_operations, + by = input$group_by + ) + }) + + return(reactive(rv$data)) + } + ) +} + +#' @export +#' +#' @rdname create-column +# @importFrom methods getGroupMembers +list_allowed_operations <- function() { + c( + "(", "c", + # getGroupMembers("Arith"), + c("+", "-", "*", "^", "%%", "%/%", "/"), + # getGroupMembers("Compare"), + c("==", ">", "<", "!=", "<=", ">="), + # getGroupMembers("Logic"), + c("&", "|"), + # getGroupMembers("Math"), + c( + "abs", "sign", "sqrt", "ceiling", "floor", "trunc", "cummax", + "cummin", "cumprod", "cumsum", "exp", "expm1", "log", "log10", + "log2", "log1p", "cos", "cosh", "sin", "sinh", "tan", "tanh", + "acos", "acosh", "asin", "asinh", "atan", "atanh", "cospi", "sinpi", + "tanpi", "gamma", "lgamma", "digamma", "trigamma" + ), + # getGroupMembers("Math2"), + c("round", "signif"), + # getGroupMembers("Summary"), + c("max", "min", "range", "prod", "sum", "any", "all"), + "pmin", "pmax", "mean", + "paste", "paste0", "substr", "nchar", "trimws", + "gsub", "sub", "grepl", "ifelse", "length", + "as.numeric", "as.character", "as.integer", "as.Date", "as.POSIXct", + "as.factor", "factor" + ) +} + + +#' @inheritParams shiny::modalDialog +#' @export +#' +#' @importFrom shiny showModal modalDialog textInput +#' @importFrom htmltools tagList +#' +#' @rdname create-column +modal_create_column <- function(id, + title = i18n("Create a new column"), + easyClose = TRUE, + size = "l", + footer = NULL) { + ns <- NS(id) + showModal(modalDialog( + title = tagList(title, datamods:::button_close_modal()), + create_column_ui(id), + tags$div( + style = "display: none;", + textInput(inputId = ns("hidden"), label = NULL, value = datamods:::genId()) + ), + easyClose = easyClose, + size = size, + footer = footer + )) +} + +#' @inheritParams shinyWidgets::WinBox +#' @export +#' +#' @importFrom shinyWidgets WinBox wbOptions wbControls +#' @importFrom htmltools tagList +#' @rdname create-column +winbox_create_column <- function(id, + title = i18n("Create a new column"), + options = shinyWidgets::wbOptions(), + controls = shinyWidgets::wbControls()) { + ns <- NS(id) + WinBox( + title = title, + ui = tagList( + create_column_ui(id), + tags$div( + style = "display: none;", + textInput(inputId = ns("hidden"), label = NULL, value = datamods:::genId()) + ) + ), + options = modifyList( + shinyWidgets::wbOptions(height = "550px", modal = TRUE), + options + ), + controls = controls, + auto_height = FALSE + ) +} + + +try_compute_column <- function(expression, + name, + rv, + allowed_operations, + by = NULL) { + parsed <- try(parse(text = expression, keep.source = FALSE), silent = TRUE) + if (inherits(parsed, "try-error")) { + return(datamods:::alert_error(attr(parsed, "condition")$message)) + } + funs <- unlist(c(extract_calls(parsed), lapply(parsed, extract_calls)), recursive = TRUE) + if (!are_allowed_operations(funs, allowed_operations)) { + return(datamods:::alert_error(datamods::i18n("Some operations are not allowed"))) + } + if (!isTruthy(by)) { + result <- try( + rlang::eval_tidy(rlang::parse_expr(expression), data = rv$data), + silent = TRUE + ) + } else { + result <- try( + { + dt <- as.data.table(rv$data) + new_col <- NULL + dt[, new_col := rlang::eval_tidy(rlang::parse_expr(expression), data = .SD), by = by] + dt$new_col + }, + silent = TRUE + ) + } + if (inherits(result, "try-error")) { + return(alert_error(attr(result, "condition")$message)) + } + adding_col <- try(rv$data[[name]] <- result, silent = TRUE) + if (inherits(adding_col, "try-error")) { + return(alert_error(attr(adding_col, "condition")$message)) + } + code <- if (!isTruthy(by)) { + rlang::call2("mutate", !!!rlang::set_names(list(rlang::parse_expr(expression)), name)) + } else { + rlang::call2( + "mutate", + !!!rlang::set_names(list(rlang::parse_expr(expression)), name), + !!!list(.by = rlang::expr(c(!!!rlang::syms(by)))) + ) + } + attr(rv$data, "code") <- Reduce( + f = function(x, y) rlang::expr(!!x %>% !!y), + x = c(attr(rv$data, "code"), code) + ) + shinyWidgets::alert( + status = "success", + phosphoricons::ph("check"), datamods::i18n("Column added!") + ) +} + +are_allowed_operations <- function(x, allowed_operations) { + all( + x %in% allowed_operations + ) +} + + +extract_calls <- function(exp) { + if (is.call(exp)) { + return(list( + as.character(exp[[1L]]), + lapply(exp[-1L], extract_calls) + )) + } +} + +alert_error <- function(text) { + alert( + status = "danger", + phosphoricons::ph("bug"), text + ) +} + + +btn_column <- function(label, data, inputId) { + icon <- get_var_icon(data, "class") + type <- data_type(data) + tags$button( + type = "button", + class = paste0("btn btn-column-", type), + style = htmltools::css( + "--bs-btn-padding-y" = ".25rem", + "--bs-btn-padding-x" = ".5rem", + "--bs-btn-font-size" = ".75rem", + "margin-bottom" = "5px" + ), + if (!is.null(icon)) icon, + label, + onclick = sprintf( + "Shiny.setInputValue('%s', '%s', {priority: 'event'})", + inputId, label + ) + ) +} + +make_choices_with_infos <- function(data) { + lapply( + X = seq_along(data), + FUN = function(i) { + nm <- names(data)[i] + values <- data[[nm]] + icon <- get_var_icon(values, "class") + # icon <- if (inherits(values, "character")) { + # phosphoricons::ph("text-aa") + # } else if (inherits(values, "factor")) { + # phosphoricons::ph("list-bullets") + # } else if (inherits(values, c("numeric", "integer"))) { + # phosphoricons::ph("hash") + # } else if (inherits(values, c("Date"))) { + # phosphoricons::ph("calendar") + # } else if (inherits(values, c("POSIXt"))) { + # phosphoricons::ph("clock") + # } else { + # NULL + # } + description <- if (is.atomic(values)) { + paste(i18n("Unique values:"), data.table::uniqueN(values)) + } else { + "" + } + list( + label = htmltools::doRenderTags(tagList( + icon, nm + )), + value = nm, + description = description + ) + } + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//custom_SelectInput.R +######## + +#' A selectizeInput customized for data frames with column labels +#' +#' @description +#' Copied and modified from the IDEAFilter package +#' Adds the option to select "none" which is handled later +#' +#' @param inputId passed to \code{\link[shiny]{selectizeInput}} +#' @param label passed to \code{\link[shiny]{selectizeInput}} +#' @param data \code{data.frame} object from which fields should be populated +#' @param selected default selection +#' @param ... passed to \code{\link[shiny]{selectizeInput}} +#' @param col_subset a \code{vector} containing the list of allowable columns to select +#' @param placeholder passed to \code{\link[shiny]{selectizeInput}} options +#' @param onInitialize passed to \code{\link[shiny]{selectizeInput}} options +#' @param none_label label for "none" item +#' @param maxItems max number of items +#' +#' @return a \code{\link[shiny]{selectizeInput}} dropdown element +#' +#' @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) + + labels <- Map(function(col) { + json <- sprintf( + IDEAFilter:::strip_leading_ws(' + { + "name": "%s", + "label": "%s", + "dataclass": "%s", + "datatype": "%s" + }'), + col, + attr(datar()[[col]], "label") %||% "", + IDEAFilter:::get_dataFilter_class(datar()[[col]]), + data_type(datar()[[col]]) + ) + }, 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) + choices <- setNames(names(labels), labels) + 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)] + } + + shiny::selectizeInput( + inputId = inputId, + label = label, + choices = choices, + selected = selected, + ..., + options = c( + list(render = I("{ + // format the way that options are rendered + option: function(item, escape) { + item.data = JSON.parse(item.label); + return '

'; + }, + + // avoid data vomit splashing on screen when an option is selected + item: function(item, escape) { + item.data = JSON.parse(item.label); + return '
' + + escape(item.data.name) + + '
'; + } + }")), + if (!is.null(maxItems)) list(maxItems=maxItems) + ) + ) +} + + +#' A selectizeInput customized for named vectors +#' +#' @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 ... 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()) { +#' shinyApp( +#' ui = fluidPage( +#' shiny::uiOutput("select"), +#' tableOutput("data") +#' ), +#' server = function(input, output) { +#' output$select <- shiny::renderUI({ +#' vectorSelectInput( +#' inputId = "variable", label = "Variable:", +#' data = c( +#' "Cylinders" = "cyl", +#' "Transmission" = "am", +#' "Gears" = "gear" +#' ) +#' ) +#' }) +#' +#' output$data <- renderTable( +#' { +#' mtcars[, c("mpg", input$variable), drop = FALSE] +#' }, +#' rownames = TRUE +#' ) +#' } +#' ) +#' } +vectorSelectInput <- function(inputId, + label, + choices, + selected = "", + ..., + placeholder = "", + onInitialize) { + datar <- if (shiny::is.reactive(choices)) data else shiny::reactive(choices) + + labels <- sprintf( + IDEAFilter:::strip_leading_ws(' + { + "name": "%s", + "label": "%s" + }'), + datar(), + names(datar()) %||% "" + ) + + choices_new <- stats::setNames(datar(), labels) + + shiny::selectizeInput( + inputId = inputId, + label = label, + choices = choices_new, + selected = selected, + ..., + options = c( + list(render = I("{ + // format the way that options are rendered + option: function(item, escape) { + item.data = JSON.parse(item.label); + return '
' + + '
' + + escape(item.data.name) + ' ' + + '
' + + (item.data.label != '' ? '
' + escape(item.data.label) + '
' : '') + + '
'; + }, + + // avoid data vomit splashing on screen when an option is selected + item: function(item, escape) { + item.data = JSON.parse(item.label); + return '
' + + escape(item.data.name) + + '
'; + } + }")) + ) + ) +} + + + + +######## +#### Current file: /Users/au301842/FreesearchR/R//cut-variable-dates.R +######## + +#' Extended cutting function with fall-back to the native base::cut +#' +#' @param x an object inheriting from class "hms" +#' @param ... passed on +#' +#' @export +#' @name cut_var +cut_var <- function(x, ...) { + UseMethod("cut_var") +} + +#' @export +#' @name cut_var +cut_var.default <- function(x, ...) { + base::cut(x, ...) +} + +#' @name cut_var +#' +#' @return factor +#' @export +#' +#' @examples +#' readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "08:20:20", "21:20:20", "03:02:20")) |> cut_var(2) +#' readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "08:20:20", "21:20:20", "03:02:20")) |> cut_var("min") +#' readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "08:20:20", "21:20:20", "03:02:20")) |> cut_var(breaks = "hour") +#' readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "08:20:20", "21:20:20", "03:02:20")) |> cut_var(breaks = hms::as_hms(c("01:00:00", "03:01:20", "9:20:20"))) +#' d_t <- readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "03:02:20", NA)) +#' f <- d_t |> cut_var(2) +#' readr::parse_time(c("01:00:20", "03:00:20", "01:20:20", "03:02:20", NA)) |> cut_var(breaks = lubridate::as_datetime(c(hms::as_hms(levels(f)), hms::as_hms(max(d_t, na.rm = TRUE) + 1))), right = FALSE) +cut_var.hms <- function(x, breaks, ...) { + ## as_hms keeps returning warnings on tz(); ignored + suppressWarnings({ + if (hms::is_hms(breaks)) { + breaks <- lubridate::as_datetime(breaks) + } + x <- lubridate::as_datetime(x) + out <- cut_var.POSIXt(x, breaks = breaks, ...) + attr(out, which = "brks") <- hms::as_hms(lubridate::as_datetime(attr(out, which = "brks"))) + attr(out, which = "levels") <- as.character(hms::as_hms(lubridate::as_datetime(attr(out, which = "levels")))) + }) + out +} + +#' @name cut_var +#' @param x an object inheriting from class "POSIXt" or "Date" +#' +#' @examples +#' readr::parse_datetime(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(2) +#' readr::parse_datetime(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(breaks = "weekday") +#' readr::parse_datetime(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(breaks = "month_only") +#' readr::parse_datetime(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(breaks=NULL,format = "%A-%H") +#' readr::parse_datetime(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(breaks=NULL,format = "%W") +cut_var.POSIXt <- function(x, breaks, right = FALSE, include.lowest = TRUE, start.on.monday = TRUE, ...) { + breaks_o <- breaks + args <- list(...) + # browser() + if (is.numeric(breaks)) { + breaks <- quantile( + x, + probs = seq(0, 1, 1 / breaks), + right = right, + include.lowest = include.lowest, + na.rm = TRUE + ) + } + + if ("format" %in% names(args)){ + assertthat::assert_that(is.character(args$format)) + out <- forcats::as_factor(format(x,format=args$format)) + } else if (identical(breaks, "weekday")) { + ## This is + ds <- as.Date(1:7) |> + (\(.x){ + sort_by(format(.x,"%A"),as.numeric(format(.x,"%w"))) + })() + + if (start.on.monday) { + ds <- ds[c(7, 1:6)] + } + out <- factor(weekdays(x), levels = ds) |> forcats::fct_drop() + } else if (identical(breaks, "month_only")) { + ## Simplest way to create a vector of all months in order + ## which will also follow the locale of the machine + ms <- paste0("1970-", 1:12, "-01") |> + as.Date() |> + months() + + out <- factor(months(x), levels = ms) |> forcats::fct_drop() + } else { + ## Doesn't really work very well for breaks other than the special character cases as right border is excluded + out <- base::cut.POSIXt(x, breaks = breaks, right = right, ...) |> forcats::fct_drop() + # browser() + } + l <- levels(out) + if (is.numeric(breaks_o)) { + l <- breaks + } else if (is.character(breaks) && length(breaks) == 1 && !(identical(breaks, "weekday") | identical(breaks, "month_only"))) { + if (include.lowest) { + if (right) { + l <- c(l, min(as.character(x))) + } else { + l <- c(l, max(as.character(x))) + } + } + } else if (length(l) < length(breaks_o)) { + l <- breaks_o + } + + attr(out, which = "brks") <- l + out +} + +#' @name cut_var +#' @param x an object inheriting from class "POSIXct" +cut_var.POSIXct <- cut_var.POSIXt + +#' @name cut_var +#' @param x an object inheriting from class "POSIXct" +#' +#' @examples +#' as.Date(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(2) +#' as.Date(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(breaks = "weekday") +#' as.Date(c("1992-02-01 01:00:20", "1992-02-06 03:00:20", "1992-05-01 01:20:20", "1992-09-01 08:20:20", "1999-02-01 21:20:20", "1992-12-01 03:02:20")) |> cut_var(format = "%W") +cut_var.Date <- function(x, breaks=NULL, start.on.monday = TRUE, ...) { + args <- list(...) + + if ("format" %in% names(args)){ + assertthat::assert_that(is.character(args$format)) + out <- forcats::as_factor(format(x,format=args$format)) + } else if (identical(breaks, "weekday")) { + ds <- as.Date(1:7) |> + (\(.x){ + sort_by(format(.x,"%A"),as.numeric(format(.x,"%w"))) + })() + + if (start.on.monday) { + ds <- ds[c(7, 1:6)] + } + out <- factor(weekdays(x), levels = ds) |> forcats::fct_drop() + } else if (identical(breaks, "month_only")) { + ms <- paste0("1970-", 1:12, "-01") |> + as.Date() |> + months() + + out <- factor(months(x), levels = ms) |> forcats::fct_drop() + } else { + ## Doesn't really work very well for breaks other than the special character cases as right border is excluded + out <- base::cut.Date(x, breaks = breaks, ...) |> forcats::fct_drop() + # browser() + } + out +} + +#' Test class +#' +#' @param data data +#' @param class.vec vector of class names to test +#' +#' @return factor +#' @export +#' +#' @examples +#' \dontrun{ +#' vapply(REDCapCAST::redcapcast_data, \(.x){ +#' is_any_class(.x, c("hms", "Date", "POSIXct", "POSIXt")) +#' }, logical(1)) +#' } +is_any_class <- function(data, class.vec) { + any(class(data) %in% class.vec) +} + +#' Test is date/datetime/time +#' +#' @param data data +#' +#' @return factor +#' @export +#' +#' @examples +#' vapply(REDCapCAST::redcapcast_data, is_datetime, logical(1)) +is_datetime <- function(data) { + is_any_class(data, class.vec = c("hms", "Date", "POSIXct", "POSIXt")) +} + +#' @title Module to Convert Numeric to Factor +#' +#' @description +#' This module contain an interface to cut a numeric into several intervals. +#' +#' +#' @param id Module ID. +#' +#' @return A [shiny::reactive()] function returning the data. +#' @export +#' +#' @importFrom shiny NS fluidRow column numericInput checkboxInput checkboxInput plotOutput uiOutput +#' @importFrom shinyWidgets virtualSelectInput +#' @importFrom toastui datagridOutput2 +#' +#' @name cut-variable +#' +cut_variable_ui <- function(id) { + ns <- NS(id) + tagList( + shiny::fluidRow( + column( + width = 3, + shinyWidgets::virtualSelectInput( + inputId = ns("variable"), + label = datamods:::i18n("Variable to cut:"), + choices = NULL, + width = "100%" + ) + ), + column( + width = 3, + shiny::uiOutput(ns("cut_method")) + ), + column( + width = 3, + numericInput( + inputId = ns("n_breaks"), + label = datamods:::i18n("Number of breaks:"), + value = 3, + min = 2, + max = 12, + width = "100%" + ) + ), + column( + width = 3, + checkboxInput( + inputId = ns("right"), + label = datamods:::i18n("Close intervals on the right"), + value = TRUE + ), + checkboxInput( + inputId = ns("include_lowest"), + label = datamods:::i18n("Include lowest value"), + value = TRUE + ) + ) + ), + conditionalPanel( + condition = "input.method == 'fixed'", + ns = ns, + uiOutput(outputId = ns("slider_fixed")) + ), + plotOutput(outputId = ns("plot"), width = "100%", height = "270px"), + toastui::datagridOutput2(outputId = ns("count")), + actionButton( + inputId = ns("create"), + label = tagList(phosphoricons::ph("scissors"), datamods:::i18n("Create factor variable")), + class = "btn-outline-primary float-end" + ), + tags$div(class = "clearfix") + ) +} + +#' @param data_r A [shiny::reactive()] function returning a `data.frame`. +#' +#' @export +#' +#' @importFrom shiny moduleServer observeEvent reactive req bindEvent renderPlot +#' @importFrom shinyWidgets updateVirtualSelect noUiSliderInput +#' @importFrom toastui renderDatagrid2 datagrid grid_colorbar +#' @importFrom rlang %||% call2 set_names expr syms +#' @importFrom classInt classIntervals +#' +#' @rdname cut-variable +cut_variable_server <- function(id, data_r = reactive(NULL)) { + moduleServer( + id, + function(input, output, session) { + rv <- reactiveValues(data = NULL, new_var_name = NULL) + + bindEvent(observe({ + data <- data_r() + rv$data <- data + vars_num <- vapply(data, \(.x){ + is.numeric(.x) || is_datetime(.x) + }, logical(1)) + vars_num <- names(vars_num)[vars_num] + shinyWidgets::updateVirtualSelect( + inputId = "variable", + choices = vars_num, + selected = if (isTruthy(input$variable)) input$variable else vars_num[1] + ) + }), data_r(), input$hidden) + + output$slider_fixed <- renderUI({ + data <- req(data_r()) + variable <- req(input$variable) + req(hasName(data, variable)) + + if (is_datetime(data[[variable]])) { + brks <- cut_var(data[[variable]], + breaks = input$n_breaks + )$brks + } else { + brks <- classInt::classIntervals( + var = data[[variable]], + n = input$n_breaks, + style = "quantile" + )$brks + } + + if (is_datetime(data[[variable]])) { + lower <- min(data[[variable]], na.rm = TRUE) + } else { + lower <- floor(min(data[[variable]], na.rm = TRUE)) + } + + if (is_datetime(data[[variable]])) { + upper <- max(data[[variable]], na.rm = TRUE) + } else { + upper <- ceiling(max(data[[variable]], na.rm = TRUE)) + } + + + shinyWidgets::noUiSliderInput( + inputId = session$ns("fixed_brks"), + label = datamods:::i18n("Fixed breaks:"), + min = lower, + max = upper, + value = brks, + color = datamods:::get_primary_color(), + width = "100%" + ) + }) + + output$cut_method <- renderUI({ + data <- req(data_r()) + variable <- req(input$variable) + + choices <- c( + # "fixed", + # "quantile" + ) + + if (any(c("hms","POSIXct") %in% class(data[[variable]]))) { + choices <- c(choices, "hour") + } else if (any(c("POSIXt", "Date") %in% class(data[[variable]]))) { + choices <- c( + choices, + "day", + "weekday", + "week", + # "week_only", + "month", + "month_only", + "quarter", + "year" + ) + } else { + choices <- c( + choices, + "fixed", + "quantile", + # "sd", + # "equal", + # "pretty", + # "kmeans", + # "hclust", + # "bclust", + # "fisher", + # "jenks", + "headtails" # , + # "maximum", + # "box" + ) + } + + choices <- unique(choices) + + shinyWidgets::virtualSelectInput( + inputId = session$ns("method"), + label = datamods:::i18n("Method:"), + choices = choices, + selected = NULL, + width = "100%" + ) + }) + + + breaks_r <- reactive({ + data <- req(data_r()) + variable <- req(input$variable) + req(hasName(data, variable)) + req(input$n_breaks, input$method) + if (input$method == "fixed") { + req(input$fixed_brks) + if (any(c("hms", "POSIXct") %in% class(data[[variable]]))) { + # cut.POSIXct <- cut.POSIXt + f <- cut_var(data[[variable]], breaks = input$fixed_brks) + list(var = f, brks = levels(f)) + } else { + classInt::classIntervals( + var = as.numeric(data[[variable]]), + n = input$n_breaks, + style = "fixed", + fixedBreaks = input$fixed_brks + ) + } + } else if (input$method == "quantile") { + req(input$fixed_brks) + if (any(c("hms", "POSIXt") %in% class(data[[variable]]))) { + # cut.POSIXct <- cut.POSIXt + f <- cut_var(data[[variable]], breaks = input$n_breaks) + list(var = f, brks = levels(f)) + } else { + classInt::classIntervals( + var = as.numeric(data[[variable]]), + n = input$n_breaks, + style = "quantile" + ) + } + } else if (input$method %in% c( + "day", + "weekday", + "week", + "month", + "month_only", + "quarter", + "year" + )) { + # To enable datetime cutting + # cut.POSIXct <- cut.POSIXt + f <- cut_var(data[[variable]], breaks = input$method) + list(var = f, brks = levels(f)) + } else if (input$method %in% c("hour")) { + # To enable datetime cutting + # cut.POSIXct <- cut.POSIXt + f <- cut_var(data[[variable]], breaks = "hour") + list(var = f, brks = levels(f)) + # } else if (input$method %in% c("week_only")) { + # # As a proof of concept a single option to use "format" parameter + # # https://www.stat.berkeley.edu/~s133/dates.html + # f <- cut_var(data[[variable]], format = "%W") + # list(var = f, brks = levels(f)) + } else { + classInt::classIntervals( + var = as.numeric(data[[variable]]), + n = input$n_breaks, + style = input$method + ) + } + }) + + output$plot <- renderPlot({ + data <- req(data_r()) + variable <- req(input$variable) + plot_histogram(data, variable, breaks = breaks_r()$brks, color = datamods:::get_primary_color()) + # plot_histogram(data = breaks_r()$var, breaks = breaks_r()$brks, color = datamods:::get_primary_color()) + }) + + + data_cutted_r <- reactive({ + req(input$method) + data <- req(data_r()) + variable <- req(input$variable) + + + if (input$method %in% c("day", "weekday", "week", "month", "month_only", "quarter", "year", "hour")) { + breaks <- input$method + } else { + breaks <- breaks_r()$brks + } + + parameters <- list( + x = data[[variable]], + breaks = breaks, + include.lowest = input$include_lowest, + right = input$right + ) + + new_variable <- tryCatch( + { + rlang::exec(cut_var, !!!parameters) + }, + error = function(err) { + showNotification(paste0("We encountered the following error creating your report: ", err), type = "err") + } + ) + + # new_variable <- do.call( + # cut, + # parameters + # ) + + + data <- append_column(data, column = new_variable, name = paste0(variable, "_cut"), index = "right") + + # setNames(paste0(variable, "_cut")) + # + # data <- dplyr::bind_cols(data, new_variable, .name_repair = "unique_quiet") + + # rv$new_var_name <- names(data)[length(data)] + # browser() + + # browser() + code <- rlang::call2( + "append_column", + !!!list( + column = rlang::call2("cut_var", + !!!modifyList(parameters, list(x = as.symbol(paste0("data$", variable)))), + .ns = "FreesearchR"), + name = paste0(variable, "_cut"), index = "right" + ), + .ns = "FreesearchR" + ) + attr(data, "code") <- code + + # attr(data, "code") <- Reduce( + # f = function(x, y) expr(!!x %>% !!y), + # x = c(attr(data, "code"), code) + # ) + data + }) + + output$count <- toastui::renderDatagrid2({ + # shiny::req(rv$new_var_name) + data <- req(data_cutted_r()) + # variable <- req(input$variable) + count_data <- as.data.frame( + table( + breaks = data[[length(data)]], + useNA = "ifany" + ), + responseName = "count" + ) + gridTheme <- getOption("datagrid.theme") + if (length(gridTheme) < 1) { + datamods:::apply_grid_theme() + } + on.exit(toastui::reset_grid_theme()) + grid <- toastui::datagrid( + data = count_data, + colwidths = "guess", + theme = "default", + bodyHeight = "auto" + ) + grid <- toastui::grid_columns(grid, className = "font-monospace") + toastui::grid_colorbar( + grid, + column = "count", + label_outside = TRUE, + label_width = "40px", + bar_bg = datamods:::get_primary_color(), + from = c(0, max(count_data$count) + 1) + ) + }) + + data_returned_r <- observeEvent(input$create, { + rv$data <- data_cutted_r() + }) + return(reactive(rv$data)) + } + ) +} + + + +#' @inheritParams shiny::modalDialog +#' @export +#' +#' @importFrom shiny showModal modalDialog textInput +#' @importFrom htmltools tagList +#' +#' @rdname cut-variable +modal_cut_variable <- function(id, + title = datamods:::i18n("Convert Numeric to Factor"), + easyClose = TRUE, + size = "l", + footer = NULL) { + ns <- NS(id) + showModal(modalDialog( + title = tagList(title, datamods:::button_close_modal()), + cut_variable_ui(id), + tags$div( + style = "display: none;", + textInput(inputId = ns("hidden"), label = NULL, value = datamods:::genId()) + ), + easyClose = easyClose, + size = size, + footer = footer + )) +} + + +#' @importFrom graphics abline axis hist par plot.new plot.window +plot_histogram <- function(data, column=NULL, bins = 30, breaks = NULL, color = "#112466") { + if (is.vector(data)){ + x <- data + } else { + x <- data[[column]] + + } + x <- as.numeric(x) + op <- par(mar = rep(1.5, 4)) + on.exit(par(op)) + plot.new() + plot.window(xlim = range(pretty(x)), ylim = range(pretty(hist(x, breaks = bins, plot = FALSE)$counts))) + abline(v = pretty(x), col = "#D8D8D8") + abline(h = pretty(hist(x, breaks = bins, plot = FALSE)$counts), col = "#D8D8D8") + hist(x, breaks = bins, xlim = range(pretty(x)), xaxs = "i", yaxs = "i", col = color, add = TRUE) + axis(side = 1, at = pretty(x), pos = 0) + axis(side = 2, at = pretty(hist(x, breaks = bins, plot = FALSE)$counts), pos = min(pretty(x))) + abline(v = breaks, col = "#FFFFFF", lty = 1, lwd = 1.5) + abline(v = breaks, col = "#2E2E2E", lty = 2, lwd = 1.5) +} + + + +######## +#### Current file: /Users/au301842/FreesearchR/R//data_plots.R +######## + +# source(here::here("functions.R")) + +#' Data correlations evaluation module +#' +#' @param id Module id. (Use 'ns("id")') +#' +#' @name data-plots +#' @returns Shiny ui module +#' @export +#' +data_visuals_ui <- function(id, tab_title = "Plots", ...) { + ns <- shiny::NS(id) + + # bslib::navset_bar( + list( + + # Sidebar with a slider input + sidebar = bslib::sidebar( + bslib::accordion( + multiple = FALSE, + bslib::accordion_panel( + title = "Creating plot", + icon = bsicons::bs_icon("graph-up"), + shiny::uiOutput(outputId = ns("primary")), + shiny::helpText('Only non-text variables are available for plotting. Go the "Data" to reclass data to plot.'), + shiny::tags$br(), + shiny::uiOutput(outputId = ns("type")), + shiny::uiOutput(outputId = ns("secondary")), + shiny::uiOutput(outputId = ns("tertiary")), + shiny::br(), + shiny::actionButton( + inputId = ns("act_plot"), + label = "Plot", + width = "100%", + icon = shiny::icon("palette"), + disabled = FALSE + ), + shiny::helpText('Adjust settings, then press "Plot".') + ), + # bslib::accordion_panel( + # title = "Advanced", + # icon = bsicons::bs_icon("gear") + # ), + bslib::accordion_panel( + title = "Download", + icon = bsicons::bs_icon("download"), + shinyWidgets::noUiSliderInput( + inputId = ns("height_slide"), + label = "Plot height (mm)", + min = 50, + max = 300, + value = 100, + step = 1, + format = shinyWidgets::wNumbFormat(decimals = 0), + color = datamods:::get_primary_color(), + inline = TRUE + ), + # shiny::numericInput( + # inputId = ns("height_numeric"), + # label = "Plot height (mm)", + # min = 50, + # max = 300, + # value = 100 + # ), + shinyWidgets::noUiSliderInput( + inputId = ns("width"), + label = "Plot width (mm)", + min = 50, + max = 300, + value = 100, + step = 1, + format = shinyWidgets::wNumbFormat(decimals = 0), + color = datamods:::get_primary_color() + ), + shiny::selectInput( + inputId = ns("plot_type"), + label = "File format", + choices = list( + "png", + "tiff", + "eps", + "pdf", + "jpeg", + "svg" + ) + ), + shiny::br(), + # Button + shiny::downloadButton( + outputId = ns("download_plot"), + label = "Download plot", + icon = shiny::icon("download") + ) + ) + ) + ), + bslib::nav_panel( + title = tab_title, + shiny::plotOutput(ns("plot"), height = "70vh"), + shiny::tags$br(), + shiny::tags$br(), + shiny::htmlOutput(outputId = ns("code_plot")) + ) + ) +} + + +#' +#' @param data data +#' @param ... ignored +#' +#' @name data-plots +#' @returns shiny server module +#' @export +data_visuals_server <- function(id, + data, + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + ns <- session$ns + + rv <- shiny::reactiveValues( + plot.params = NULL, + plot = NULL, + code = NULL + ) + + # ## --- New attempt + # + # rv$plot.params <- shiny::reactive({ + # get_plot_options(input$type) |> purrr::pluck(1) + # }) + # + # c(output, + # list(shiny::renderUI({ + # columnSelectInput( + # inputId = ns("primary"), + # data = data, + # placeholder = "Select variable", + # label = "Response variable", + # multiple = FALSE + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$primary) + # # browser() + # + # if (!input$primary %in% names(data())) { + # plot_data <- data()[1] + # } else { + # plot_data <- data()[input$primary] + # } + # + # plots <- possible_plots( + # data = plot_data + # ) + # + # plots_named <- get_plot_options(plots) |> + # lapply(\(.x){ + # stats::setNames(.x$descr, .x$note) + # }) + # + # vectorSelectInput( + # inputId = ns("type"), + # selected = NULL, + # label = shiny::h4("Plot type"), + # choices = Reduce(c, plots_named), + # multiple = FALSE + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$type) + # + # cols <- c( + # rv$plot.params()[["secondary.extra"]], + # all_but( + # colnames(subset_types( + # data(), + # rv$plot.params()[["secondary.type"]] + # )), + # input$primary + # ) + # ) + # + # columnSelectInput( + # inputId = ns("secondary"), + # data = data, + # selected = cols[1], + # placeholder = "Please select", + # label = if (isTRUE(rv$plot.params()[["secondary.multi"]])) "Additional variables" else "Secondary variable", + # multiple = rv$plot.params()[["secondary.multi"]], + # maxItems = rv$plot.params()[["secondary.max"]], + # col_subset = cols, + # none_label = "No variable" + # ) + # }), + # shiny::renderUI({ + # shiny::req(input$type) + # columnSelectInput( + # inputId = ns("tertiary"), + # data = data, + # placeholder = "Please select", + # label = "Grouping variable", + # multiple = FALSE, + # col_subset = c( + # "none", + # all_but( + # colnames(subset_types( + # data(), + # rv$plot.params()[["tertiary.type"]] + # )), + # input$primary, + # input$secondary + # ) + # ), + # none_label = "No stratification" + # ) + # }) + # )|> setNames(c("primary","type","secondary","tertiary")),keep.null = TRUE) + + + output$primary <- shiny::renderUI({ + shiny::req(data()) + columnSelectInput( + inputId = ns("primary"), + col_subset = names(data())[sapply(data(), data_type) != "text"], + data = data, + placeholder = "Select variable", + label = "Response variable", + multiple = FALSE + ) + }) + + # shiny::observeEvent(data, { + # if (is.null(data()) | NROW(data()) == 0) { + # shiny::updateActionButton(inputId = ns("act_plot"), disabled = TRUE) + # } else { + # shiny::updateActionButton(inputId = ns("act_plot"), disabled = FALSE) + # } + # }) + + + output$type <- shiny::renderUI({ + shiny::req(input$primary) + shiny::req(data()) + # browser() + + if (!input$primary %in% names(data())) { + plot_data <- data()[1] + } else { + plot_data <- data()[input$primary] + } + + plots <- possible_plots( + data = plot_data + ) + + plots_named <- get_plot_options(plots) |> + lapply(\(.x){ + stats::setNames(.x$descr, .x$note) + }) + + vectorSelectInput( + inputId = ns("type"), + selected = NULL, + label = shiny::h4("Plot type"), + choices = Reduce(c, plots_named), + multiple = FALSE + ) + }) + + rv$plot.params <- shiny::reactive({ + get_plot_options(input$type) |> purrr::pluck(1) + }) + + output$secondary <- shiny::renderUI({ + shiny::req(input$type) + + cols <- c( + rv$plot.params()[["secondary.extra"]], + all_but( + colnames(subset_types( + data(), + rv$plot.params()[["secondary.type"]] + )), + input$primary + ) + ) + + columnSelectInput( + inputId = ns("secondary"), + data = data, + selected = cols[1], + placeholder = "Please select", + label = if (isTRUE(rv$plot.params()[["secondary.multi"]])) "Additional variables" else "Secondary variable", + multiple = rv$plot.params()[["secondary.multi"]], + maxItems = rv$plot.params()[["secondary.max"]], + col_subset = cols, + none_label = "No variable" + ) + }) + + output$tertiary <- shiny::renderUI({ + shiny::req(input$type) + columnSelectInput( + inputId = ns("tertiary"), + data = data, + placeholder = "Please select", + label = "Grouping variable", + multiple = FALSE, + col_subset = c( + "none", + all_but( + colnames(subset_types( + data(), + rv$plot.params()[["tertiary.type"]] + )), + input$primary, + input$secondary + ) + ), + none_label = "No stratification" + ) + }) + + shiny::observeEvent(input$act_plot, + { + if (NROW(data()) > 0) { + tryCatch( + { + parameters <- list( + type = rv$plot.params()[["fun"]], + pri = input$primary, + sec = input$secondary, + ter = input$tertiary + ) + + shiny::withProgress(message = "Drawing the plot. Hold tight for a moment..", { + rv$plot <- rlang::exec(create_plot, !!!append_list(data(), parameters, "data")) + }) + + rv$code <- glue::glue("FreesearchR::create_plot(data,{list2str(parameters)})") + }, + # warning = function(warn) { + # showNotification(paste0(warn), type = "warning") + # }, + error = function(err) { + showNotification(paste0(err), type = "err") + } + ) + } + }, + ignoreInit = TRUE + ) + + output$code_plot <- shiny::renderUI({ + shiny::req(rv$code) + prismCodeBlock(paste0("#Plotting\n", rv$code)) + }) + + shiny::observeEvent( + list( + data() + ), + { + shiny::req(data()) + + rv$plot <- NULL + } + ) + + output$plot <- shiny::renderPlot({ + # shiny::req(rv$plot) + # rv$plot + if (!is.null(rv$plot)) { + rv$plot + } else { + return(NULL) + } + }) + + # shiny::observeEvent(input$height_numeric, { + # shinyWidgets::updateNoUiSliderInput(session, ns("height_slide"), value = input$height_numeric) + # }, ignoreInit = TRUE) + # shiny::observeEvent(input$height_slide, { + # shiny::updateNumericInput(session, ns("height_numeric"), value = input$height_slide) + # }, ignoreInit = TRUE) + + + output$download_plot <- shiny::downloadHandler( + filename = shiny::reactive({ + paste0("plot.", input$plot_type) + }), + content = function(file) { + if (inherits(rv$plot,"patchwork")){ + plot <- rv$plot + } else if (inherits(rv$plot,"ggplot")){ + plot <- rv$plot + }else { + plot <- rv$plot[[1]] + + } + # browser() + shiny::withProgress(message = "Drawing the plot. Hold on for a moment..", { + ggplot2::ggsave( + filename = file, + plot = plot, + width = input$width, + height = input$height_slide, + dpi = 300, + units = "mm", scale = 2 + ) + }) + } + ) + + + shiny::observe( + return(rv$plot) + ) + } + ) +} + +#' 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_hbars = list( + fun = "plot_hbars", + descr = "Stacked horizontal bars", + note = "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 = "Violin plot", + note = "A modern alternative to the classic boxplot to visualise data distribution", + primary.type = c("datatime", "continuous", "dichotomous", "categorical"), + 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 = "Sankey plot", + note = "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 = "Scatter plot", + note = "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 = "Box plot", + note = "A classic way to plot data distribution by groups", + primary.type = c("datatime", "continuous", "dichotomous", "categorical"), + secondary.type = c("dichotomous", "categorical"), + secondary.multi = FALSE, + tertiary.type = c("dichotomous", "categorical"), + secondary.extra = "none" + ), + plot_euler = list( + fun = "plot_euler", + descr = "Euler diagram", + note = "Generate area-proportional Euler diagrams to display set relationships", + primary.type = c("dichotomous", "categorical"), + secondary.type = c("dichotomous", "categorical"), + secondary.multi = TRUE, + secondary.max = 4, + 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) { + # 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 <- supported_plots() |> + 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)] + })() +} + + + +#' 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 ... 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, ...) { + 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, + ... + ) + + 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 +#' +#' @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)) { + 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 +#' +#' @returns list of ggplot2 objects +#' @export +#' +wrap_plot_list <- function(data, tag_levels = NULL) { + if (ggplot2::is_ggplot(data[[1]])) { + if (length(data) > 1) { + out <- data |> + (\(.x){ + if (rlang::is_named(.x)) { + purrr::imap(.x, \(.y, .i){ + .y + ggplot2::ggtitle(.i) + }) + } else { + .x + } + })() |> + align_axes() |> + patchwork::wrap_plots(guides = "collect", axes = "collect", axis_titles = "collect") + if (!is.null(tag_levels)) { + out <- out + patchwork::plot_annotation(tag_levels = tag_levels) + } + } else { + out <- data + } + } else { + cli::cli_abort("Can only wrap lists of {.cls ggplot} objects") + } + out +} + + +#' Aligns axes between plots +#' +#' @param ... ggplot2 objects or list of ggplot2 objects +#' +#' @returns list of ggplot2 objects +#' @export +#' +align_axes <- function(...) { + # https://stackoverflow.com/questions/62818776/get-axis-limits-from-ggplot-object + # https://github.com/thomasp85/patchwork/blob/main/R/plot_multipage.R#L150 + 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 |> purrr::map(~ .x + ggplot2::xlim(xr) + ggplot2::ylim(yr)) + }) +} + +#' Extract and clean axis ranges +#' +#' @param p plot +#' @param axis axis. x or y. +#' +#' @returns vector +#' @export +#' +clean_common_axis <- function(p, axis) { + purrr::map(p, ~ ggplot2::layer_scales(.x)[[axis]]$get_limits()) |> + unlist() |> + (\(.x){ + if (is.numeric(.x)) { + range(.x) + } else { + as.character(.x) + } + })() |> + unique() +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//data-import.R +######## + +data_import_ui <- function(id) { + ns <- shiny::NS(id) + + shiny::fluidRow( + shiny::column(width = 2), + shiny::column( + width = 8, + shiny::h4("Choose your data source"), + shiny::br(), + shinyWidgets::radioGroupButtons( + inputId = "source", + selected = "env", + choices = c( + "File upload" = "file", + "REDCap server export" = "redcap", + "Local or sample data" = "env" + ), + width = "100%" + ), + shiny::helpText("Upload a file from your device, get data directly from REDCap or select a sample data set for testing from the app."), + shiny::br(), + shiny::br(), + shiny::conditionalPanel( + condition = "input.source=='file'", + import_file_ui( + id = ns("file_import"), + layout_params = "dropdown", + title = "Choose a datafile to upload", + file_extensions = c(".csv", ".tsv", ".txt", ".xls", ".xlsx", ".rds", ".sas7bdat", ".ods", ".dta") + ) + ), + shiny::conditionalPanel( + condition = "input.source=='redcap'", + m_redcap_readUI(id = ns("redcap_import")) + ), + shiny::conditionalPanel( + condition = "input.source=='env'", + datamods::import_globalenv_ui(id = ns("env"), title = NULL) + ), + shiny::conditionalPanel( + condition = "input.source=='redcap'", + DT::DTOutput(outputId = ns("redcap_prev")) + ) + ) + ) + } + + +data_import_server <- function(id) { + module <- function(input, output, session) { + ns <- session$ns + + rv <- shiny::reactiveValues( + data_temp = NULL, + code = list() + ) + + data_file <- import_file_server( + id = ns("file_import"), + show_data_in = "popup", + trigger_return = "change", + return_class = "data.frame" + ) + + shiny::observeEvent(data_file$data(), { + shiny::req(data_file$data()) + + rv$data_temp <- data_file$data() + rv$code <- append_list(data = data_file$code(), list = rv$code, index = "import") + }) + + data_redcap <- m_redcap_readServer( + id = "redcap_import" + ) + + shiny::observeEvent(data_redcap(), { + # rv$data_original <- purrr::pluck(data_redcap(), "data")() + rv$data_temp <- data_redcap() + }) + + from_env <- datamods::import_globalenv_server( + id = "env", + trigger_return = "change", + btn_show_data = FALSE, + reset = reactive(input$hidden) + ) + + shiny::observeEvent(from_env$data(), { + shiny::req(from_env$data()) + + rv$data_temp <- from_env$data() + # rv$code <- append_list(data = from_env$code(),list = rv$code,index = "import") + }) + + return(list( + # status = reactive(temporary_rv$status), + # name = reactive(temporary_rv$name), + # code = reactive(temporary_rv$code), + data = shiny::reactive(rv$data_temp) + )) + + } + + shiny::moduleServer( + id = id, + module = module + ) + + } + + +#' Test app for the data-import module +#' +#' @rdname data-import +#' +#' @examples +#' \dontrun{ +#' data_import_demo_app() +#' } +data_import_demo_app <- function() { + ui <- shiny::fluidPage( + data_import_ui("data_import"), + toastui::datagridOutput2(outputId = "table"), + DT::DTOutput("data_summary") + ) + server <- function(input, output, session) { + imported <- shiny::reactive(data_import_server(id = "data_import")) + + # output$data_summary <- DT::renderDataTable( + # { + # shiny::req(data_val$data) + # data_val$data + # }, + # options = list( + # scrollX = TRUE, + # pageLength = 5 + # ) + # ) + output$table <- toastui::renderDatagrid2({ + req(imported$data) + toastui::datagrid( + data = head(imported$data, 5), + theme = "striped", + colwidths = "guess", + minBodyHeight = 250 + ) + }) + + } + shiny::shinyApp(ui, server) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//data-summary.R +######## + +#' Data summary module +#' +#' @param id Module id. (Use 'ns("id")') +#' +#' @name data-summary +#' @returns Shiny ui module +#' @export +data_summary_ui <- function(id) { + ns <- NS(id) + + toastui::datagridOutput(outputId = ns("tbl_summary")) +} + + +#' +#' @param data data +#' @param color.main main color +#' @param color.sec secondary color +#' @param ... arguments passed to create_overview_datagrid +#' +#' @name data-summary +#' @returns shiny server module +#' @export +data_summary_server <- function(id, + data, + color.main, + color.sec, + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + ns <- session$ns + + output$tbl_summary <- + toastui::renderDatagrid( + { + shiny::req(data()) + data() |> + overview_vars() |> + create_overview_datagrid(...) |> + add_sparkline( + column = "vals", + color.main = color.main, + color.sec = color.sec + ) + } + ) + + } + ) +} + +#' Add sparkline to datagrid +#' +#' @param grid grid +#' @param column clumn to transform +#' +#' @returns datagrid +#' @export +#' +#' @examples +#' grid <- mtcars |> +#' default_parsing() |> +#' overview_vars() |> +#' toastui::datagrid() |> +#' add_sparkline() +#' grid +add_sparkline <- function(grid, column = "vals", color.main = "#2a8484", color.sec = "#84EF84") { + out <- toastui::grid_sparkline( + grid = grid, + column = column, + renderer = function(data) { + data_cl <- class(data) + if (all(sapply(data,is.na))){ + type <- "line" + ds <- data.frame(x = NA, y = NA) + horizontal <- FALSE + } else if (identical(data_cl, "factor")) { + type <- "column" + s <- summary(data) + ds <- data.frame(x = names(s), y = s) + horizontal <- FALSE + } else if (identical(data_cl, "logical")) { + type <- "column" + s <- table(data) + ds <- data.frame(x = names(s), y = as.vector(s)) + horizontal <- FALSE + } else if (any(c("numeric", "integer") %in% data_cl)) { + if (is_consecutive(data)) { + type <- "line" + ds <- data.frame(x = NA, y = NA) + horizontal <- FALSE + } else { + type <- "box" + ds <- data.frame(x = 1, y = data) + horizontal <- TRUE + } + } else if (any(c("Date", "POSIXct", "POSIXt", "hms", "difftime") %in% data_cl)) { + type <- "line" + ds <- data.frame(x = seq_along(data), y = data) + horizontal <- FALSE + } else { + type <- "line" + ds <- data.frame(x = NA, y = NA) + horizontal <- FALSE + } + apexcharter::apex( + ds, + apexcharter::aes(x, y), + type = type, + auto_update = TRUE + ) |> + apexcharter::ax_chart(sparkline = list(enabled = TRUE)) |> + apexcharter::ax_plotOptions( + boxPlot = apexcharter::boxplot_opts(color.upper = color.sec, color.lower = color.main), + bar = apexcharter::bar_opts(horizontal = horizontal) + ) |> + apexcharter::ax_colors( + c(color.main, color.sec) + ) + } + ) + + toastui::grid_columns( + grid = out, + columns = column, + minWidth = 200 + ) +} + +#' Checks if elements in vector are equally spaced as indication of ID +#' +#' @param data vector +#' +#' @returns logical +#' @export +#' +#' @examples +#' 1:10 |> is_consecutive() +#' sample(1:100,40) |> is_consecutive() +is_consecutive <- function(data){ + suppressWarnings(length(unique(diff(as.numeric(data))))==1) +} + +#' Create a data overview data.frame ready for sparklines +#' +#' @param data data +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' mtcars |> overview_vars() +overview_vars <- function(data) { + data <- as.data.frame(data) + + dplyr::tibble( + icon = get_classes(data), + class = icon, + name = names(data), + n_missing = unname(colSums(is.na(data))), + p_complete = 1 - n_missing / nrow(data), + n_unique = get_n_unique(data), + vals = as.list(data) + ) +} + +#' Create a data overview datagrid +#' +#' @param data data +#' +#' @returns datagrid +#' @export +#' +#' @examples +#' mtcars |> +#' overview_vars() |> +#' create_overview_datagrid() +create_overview_datagrid <- function(data,...) { + # browser() + gridTheme <- getOption("datagrid.theme") + if (length(gridTheme) < 1) { + datamods:::apply_grid_theme() + } + on.exit(toastui::reset_grid_theme()) + + col.names <- names(data) + + std_names <- c( + "Name" = "name", + "Icon" = "icon", + "Class" = "class", + "Type" = "type", + "Missings" = "n_missing", + "Complete" = "p_complete", + "Unique" = "n_unique", + "Distribution" = "vals" + ) + + headers <- lapply(col.names, \(.x){ + if (.x %in% std_names) { + names(std_names)[match(.x, std_names)] + } else { + .x + } + }) |> unlist() + + grid <- toastui::datagrid( + data = data, + theme = "default", + colwidths = "fit", + ... + ) + + grid <- toastui::grid_columns( + grid = grid, + columns = col.names, + header = headers, + resizable = TRUE + ) + + grid <- toastui::grid_columns( + grid = grid, + columns = "vals", + width = 120 + ) + + grid <- toastui::grid_columns( + grid = grid, + columns = "icon", + header = " ", + align = "center",sortable = FALSE, + width = 40 + ) + + grid <- add_class_icon( + grid = grid, + column = "icon", + fun = class_icons + ) + + grid <- toastui::grid_format( + grid = grid, + "p_complete", + formatter = toastui::JS("function(obj) {return (obj.value*100).toFixed(0) + '%';}") + ) + + ## This could obviously be extended, which will added even more complexity. + + grid <- toastui::grid_filters( + grid = grid, + column = "name", + # columns = unname(std_names[std_names!="vals"]), + showApplyBtn = FALSE, + showClearBtn = TRUE, + type = "text" + ) + + + return(grid) +} + +#' Convert class grid column to icon +#' +#' @param grid grid +#' @param column column +#' +#' @returns datagrid +#' @export +#' +#' @examples +#' mtcars |> +#' overview_vars() |> +#' toastui::datagrid() |> +#' add_class_icon() +add_class_icon <- function(grid, column = "class", fun=class_icons) { + out <- toastui::grid_format( + grid = grid, + column = column, + formatter = function(value) { + lapply( + X = value, + FUN = fun + ) + } + ) + + toastui::grid_columns( + grid = out, + header = NULL, + columns = column, + width = 60 + ) +} + + +#' Get data class icons +#' +#' @param x character vector of data classes +#' +#' @returns list +#' @export +#' +#' @examples +#' "numeric" |> class_icons()|> str() +#' mtcars |> sapply(class) |> class_icons() |> str() +class_icons <- function(x) { + if (length(x)>1){ + lapply(x,class_icons) + } else { + if (identical(x, "numeric")) { + shiny::icon("calculator") + } else if (identical(x, "factor")) { + shiny::icon("chart-simple") + } else if (identical(x, "integer")) { + shiny::icon("arrow-down-1-9") + } else if (identical(x, "character")) { + shiny::icon("arrow-down-a-z") + } else if (identical(x, "logical")) { + shiny::icon("toggle-off") + } else if (any(c("Date", "POSIXt") %in% x)) { + shiny::icon("calendar-days") + } else if (any("POSIXct", "hms") %in% x) { + shiny::icon("clock") + } else { + shiny::icon("table") + }} +} + +#' Get data type icons +#' +#' @param x character vector of data classes +#' +#' @returns list +#' @export +#' +#' @examples +#' "ordinal" |> type_icons() +#' default_parsing(mtcars) |> sapply(data_type) |> type_icons() +type_icons <- function(x) { + if (length(x)>1){ + lapply(x,class_icons) + } else { + if (identical(x, "continuous")) { + shiny::icon("calculator") + } else if (identical(x, "categorical")) { + shiny::icon("chart-simple") + } else if (identical(x, "ordinal")) { + shiny::icon("arrow-down-1-9") + } else if (identical(x, "text")) { + shiny::icon("arrow-down-a-z") + } else if (identical(x, "dichotomous")) { + shiny::icon("toggle-off") + } else if (identical(x,"datetime")) { + shiny::icon("calendar-days") + } else if (identical(x,"id")) { + shiny::icon("id-card") + } else { + shiny::icon("table") + } + } +} + +#' Easily get variable icon based on data type or class +#' +#' @param data variable or data frame +#' @param class.type "type" or "class". Default is "class" +#' +#' @returns svg icon +#' @export +#' +#' @examples +#' mtcars[1] |> get_var_icon("class") +#' default_parsing(mtcars) |> get_var_icon() +get_var_icon <- function(data,class.type=c("class","type")){ + if (is.data.frame(data)){ + lapply(data,get_var_icon) + } else { + + class.type <- match.arg(class.type) + + switch(class.type, + type = { + type_icons(data_type(data)) + }, + class = { + class(data)[1] |> class_icons() + } + ) +} + +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//datagrid-infos-mod.R +######## + + +#' Display a table in a window +#' +#' @param data a data object (either a `matrix` or a `data.frame`). +#' @param title Title to be displayed in window. +#' @param show_classes Show variables classes under variables names in table header. +#' @param type Display table in a pop-up with [shinyWidgets::show_alert()], +#' in modal window with [shiny::showModal()] or in a WinBox window with [shinyWidgets::WinBox()]. +#' @param options Arguments passed to [toastui::datagrid()]. +#' @param width Width of the window, only used if `type = "popup"` or `type = "winbox"`. +#' @param ... Additional options, such as `wbOptions = wbOptions()` or `wbControls = wbControls()`. +#' +#' @note +#' If you use `type = "winbox"`, you'll need to use `shinyWidgets::html_dependency_winbox()` somewhere in your UI. +#' +#' @return No value. +#' @export +#' +show_data <- function(data, + title = NULL, + options = NULL, + show_classes = TRUE, + type = c("popup", "modal", "winbox"), + width = "65%", + ...) { # nocov start + type <- match.arg(type) + data <- as.data.frame(data) + args <- list(...) + gridTheme <- getOption("datagrid.theme") + if (length(gridTheme) < 1) { + datamods:::apply_grid_theme() + } + on.exit(toastui::reset_grid_theme()) + + if (is.null(options)) + options <- list() + + options$height <- 500 + options$minBodyHeight <- 400 + options$data <- data + options$theme <- "default" + options$colwidths <- "guess" + options$guess_colwidths_opts <- list(min_width = 90, max_width = 400, mul = 1, add = 10) + if (isTRUE(show_classes)) + options$summary <- construct_col_summary(data) + datatable <- rlang::exec(toastui::datagrid, !!!options) + datatable <- toastui::grid_columns(datatable, className = "font-monospace") + if (identical(type, "winbox")) { + stopifnot( + "You need shinyWidgets >= 0.8.4" = packageVersion("shinyWidgets") >= "0.8.4" + ) + wb_options <- if (is.null(args$wbOptions)) { + shinyWidgets::wbOptions( + height = "600px", + width = width, + modal = TRUE + ) + } else { + modifyList( + shinyWidgets::wbOptions( + height = "600px", + width = width, + modal = TRUE + ), + args$wbOptions + ) + } + wb_controls <- if (is.null(args$wbControls)) { + shinyWidgets::wbControls() + } else { + args$wbControls + } + shinyWidgets::WinBox( + title = title, + ui = datatable, + options = wb_options, + controls = wb_controls, + padding = "0 5px" + ) + } else if (identical(type, "popup")) { + shinyWidgets::show_alert( + title = NULL, + text = tags$div( + if (!is.null(title)) { + tagList( + tags$h3(title), + tags$hr() + ) + }, + style = "color: #000 !important;", + datatable + ), + closeOnClickOutside = TRUE, + showCloseButton = TRUE, + btn_labels = NA, + html = TRUE, + width = width + ) + } else { + showModal(modalDialog( + title = tagList( + datamods:::button_close_modal(), + title + ), + tags$div( + style = htmltools::css(minHeight = htmltools::validateCssUnit(options$height)), + toastui::renderDatagrid2(datatable) + ), + size = "xl", + footer = NULL, + easyClose = TRUE + )) + } +} # nocov end + + + +#' @importFrom htmltools tagList tags css +describe_col_char <- function(x, with_summary = TRUE) { + tags$div( + style = htmltools::css(padding = "3px 0", fontSize = "x-small"), + tags$div( + style = htmltools::css(fontStyle = "italic"), + get_var_icon(x), + # phosphoricons::ph("text-aa"), + "character" + ), + if (with_summary) { + tagList( + tags$hr(style = htmltools::css(margin = "3px 0")), + tags$div( + datamods:::i18n("Unique:"), length(unique(x)) + ), + tags$div( + datamods:::i18n("Missing:"), sum(is.na(x)) + ), + tags$div( + style = htmltools::css(whiteSpace = "normal", wordBreak = "break-all"), + datamods:::i18n("Most Common:"), gsub( + pattern = "'", + replacement = "\u07F4", + x = names(sort(table(x), decreasing = TRUE))[1] + ) + ), + tags$div( + "\u00A0" + ) + ) + } + ) +} + +fmt_p <- function(val, tot) { + paste0(round(val / tot * 100, 1), "%") +} + +describe_col_factor <- function(x, with_summary = TRUE) { + count <- sort(table(x, useNA = "always"), decreasing = TRUE) + total <- sum(count) + one <- count[!is.na(names(count))][1] + two <- count[!is.na(names(count))][2] + missing <- count[is.na(names(count))] + tags$div( + style = htmltools::css(padding = "3px 0", fontSize = "x-small"), + tags$div( + style = htmltools::css(fontStyle = "italic"), + get_var_icon(x), + # phosphoricons::ph("list-bullets"), + "factor" + ), + if (with_summary) { + tagList( + tags$hr(style = htmltools::css(margin = "3px 0")), + tags$div( + names(one), ":", fmt_p(one, total) + ), + tags$div( + names(two), ":", fmt_p(two, total) + ), + tags$div( + "Missing", ":", fmt_p(missing, total) + ), + tags$div( + "\u00A0" + ) + ) + } + ) +} + +describe_col_num <- function(x, with_summary = TRUE) { + tags$div( + style = htmltools::css(padding = "3px 0", fontSize = "x-small"), + tags$div( + style = htmltools::css(fontStyle = "italic"), + get_var_icon(x), + # phosphoricons::ph("hash"), + "numeric" + ), + if (with_summary) { + tagList( + tags$hr(style = htmltools::css(margin = "3px 0")), + tags$div( + datamods:::i18n("Min:"), round(min(x, na.rm = TRUE), 2) + ), + tags$div( + datamods:::i18n("Mean:"), round(mean(x, na.rm = TRUE), 2) + ), + tags$div( + datamods:::i18n("Max:"), round(max(x, na.rm = TRUE), 2) + ), + tags$div( + datamods:::i18n("Missing:"), sum(is.na(x)) + ) + ) + } + ) +} + + +describe_col_date <- function(x, with_summary = TRUE) { + tags$div( + style = htmltools::css(padding = "3px 0", fontSize = "x-small"), + tags$div( + style = htmltools::css(fontStyle = "italic"), + get_var_icon(x), + # phosphoricons::ph("calendar"), + "date" + ), + if (with_summary) { + tagList( + tags$hr(style = htmltools::css(margin = "3px 0")), + tags$div( + datamods:::i18n("Min:"), min(x, na.rm = TRUE) + ), + tags$div( + datamods:::i18n("Max:"), max(x, na.rm = TRUE) + ), + tags$div( + datamods:::i18n("Missing:"), sum(is.na(x)) + ), + tags$div( + "\u00A0" + ) + ) + } + ) +} + +describe_col_datetime <- function(x, with_summary = TRUE) { + tags$div( + style = htmltools::css(padding = "3px 0", fontSize = "x-small"), + tags$div( + style = htmltools::css(fontStyle = "italic"), + get_var_icon(x), + # phosphoricons::ph("clock"), + "datetime" + ), + if (with_summary) { + tagList( + tags$hr(style = htmltools::css(margin = "3px 0")), + tags$div( + datamods:::i18n("Min:"), min(x, na.rm = TRUE) + ), + tags$div( + datamods:::i18n("Max:"), max(x, na.rm = TRUE) + ), + tags$div( + datamods:::i18n("Missing:"), sum(is.na(x)) + ), + tags$div( + "\u00A0" + ) + ) + } + ) +} + + +describe_col_other <- function(x, with_summary = TRUE) { + tags$div( + style = htmltools::css(padding = "3px 0", fontSize = "x-small"), + tags$div( + style = htmltools::css(fontStyle = "italic"), + get_var_icon(x), + # phosphoricons::ph("clock"), + paste(class(x), collapse = ", ") + ), + if (with_summary) { + tagList( + tags$hr(style = htmltools::css(margin = "3px 0")), + tags$div( + datamods:::i18n("Unique:"), length(unique(x)) + ), + tags$div( + datamods:::i18n("Missing:"), sum(is.na(x)) + ), + tags$div( + "\u00A0" + ), + tags$div( + "\u00A0" + ) + ) + } + ) +} + +construct_col_summary <- function(data) { + list( + position = "top", + height = 90, + columnContent = lapply( + X = setNames(names(data), names(data)), + FUN = function(col) { + values <- data[[col]] + content <- if (inherits(values, "character")) { + describe_col_char(values) + } else if (inherits(values, "factor")) { + describe_col_factor(values) + } else if (inherits(values, c("numeric", "integer"))) { + describe_col_num(values) + } else if (inherits(values, c("Date"))) { + describe_col_date(values) + } else if (inherits(values, c("POSIXt"))) { + describe_col_datetime(values) + } else { + describe_col_other(values) + } + list( + template = toastui::JS( + "function(value) {", + sprintf( + "return '%s';", + gsub(replacement = "", pattern = "\n", x = htmltools::doRenderTags(content)) + ), + "}" + ) + ) + } + ) + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//helpers.R +######## + +#' Wrapper function to get function from character vector referring to function from namespace. Passed to 'do.call()' +#' +#' @description +#' This function follows the idea from this comment: https://stackoverflow.com/questions/38983179/do-call-a-function-in-r-without-loading-the-package +#' @param x function or function name +#' +#' @return function or character vector +#' @export +#' +#' @examples +#' getfun("stats::lm") +getfun <- function(x) { + if ("character" %in% class(x)) { + if (length(grep("::", x)) > 0) { + parts <- strsplit(x, "::")[[1]] + requireNamespace(parts[1]) + getExportedValue(parts[1], parts[2]) + } + } else { + x + } +} + +#' Wrapper to save data in RDS, load into specified qmd and render +#' +#' @param data list to pass to qmd +#' @param ... Passed to `quarto::quarto_render()` +#' +#' @return output file name +#' @export +#' +write_quarto <- function(data, ...) { + # Exports data to temporary location + # + # I assume this is more secure than putting it in the www folder and deleting + # on session end + + # temp <- base::tempfile(fileext = ".rds") + # readr::write_rds(data, file = here) + + readr::write_rds(data, file = "www/web_data.rds") + + ## Specifying a output path will make the rendering fail + ## Ref: https://github.com/quarto-dev/quarto-cli/discussions/4041 + ## Outputs to the same as the .qmd file + quarto::quarto_render( + execute_params = list(data.file = "web_data.rds"), + # execute_params = list(data.file = temp), + ... + ) +} + +write_rmd <- function(data, ..., params.args=NULL) { + # Exports data to temporary location + # + # I assume this is more secure than putting it in the www folder and deleting + # on session end + + # temp <- base::tempfile(fileext = ".rds") + # readr::write_rds(data, file = here) + + readr::write_rds(data, file = "www/web_data.rds") + + ## Specifying a output path will make the rendering fail + ## Ref: https://github.com/quarto-dev/quarto-cli/discussions/4041 + ## Outputs to the same as the .qmd file + rmarkdown::render( + params = modifyList(list(data.file = "web_data.rds",version=app_version()),params.args), + # execute_params = list(data.file = temp), + ... + ) +} + +#' Flexible file import based on extension +#' +#' @param file file name +#' @param consider.na character vector of strings to consider as NAs +#' +#' @return tibble +#' @export +#' +#' @examples +#' read_input("https://raw.githubusercontent.com/agdamsbo/cognitive.index.lookup/main/data/sample.csv") +read_input <- function(file, consider.na = c("NA", '""', "")) { + ext <- tools::file_ext(file) + + if (ext == "csv") { + df <- readr::read_csv(file = file, na = consider.na) + } else if (ext %in% c("xls", "xlsx")) { + df <- readxl::read_excel(file = file, na.strings = consider.na) + } else if (ext == "dta") { + df <- haven::read_dta(file = file) + } else if (ext == "ods") { + df <- readODS::read_ods(path = file) + } else if (ext == "rds") { + df <- readr::read_rds(file = file) + } else { + stop("Input file format has to be on of: + '.csv', '.xls', '.xlsx', '.dta', '.ods' or '.rds'") + } + + df +} + +#' Convert string of arguments to list of arguments +#' +#' @description +#' Idea from the answer: https://stackoverflow.com/a/62979238 +#' +#' @param string string to convert to list to use with do.call +#' +#' @return list +#' @export +#' +#' @examples +#' argsstring2list("A=1:5,b=2:4") +#' +argsstring2list <- function(string) { + eval(parse(text = paste0("list(", string, ")"))) +} + + +#' Factorize variables in data.frame +#' +#' @param data data.frame +#' @param vars variables to force factorize +#' +#' @return data.frame +#' @export +#' +#' @examples +#' factorize(mtcars, names(mtcars)) +factorize <- function(data, vars) { + if (!is.null(vars)) { + data |> + dplyr::mutate( + dplyr::across( + dplyr::all_of(vars), + REDCapCAST::as_factor + ) + ) + } else { + data + } +} + +dummy_Imports <- function() { + list( + MASS::as.fractions(), + broom::augment(), + broom.helpers::all_categorical(), + here::here(), + cardx::all_of(), + parameters::ci(), + DT::addRow(), + bslib::accordion() + ) + # https://github.com/hadley/r-pkgs/issues/828 +} + + +#' Title +#' +#' @param data data +#' @param output.format output +#' @param filename filename +#' @param ... passed on +#' +#' @returns data +#' @export +#' +file_export <- function(data, output.format = c("df", "teal", "list"), filename, ...) { + output.format <- match.arg(output.format) + + filename <- gsub("-", "_", filename) + + if (output.format == "teal") { + out <- within( + teal_data(), + { + assign(name, value |> + dplyr::bind_cols(.name_repair = "unique_quiet") |> + default_parsing()) + }, + value = data, + name = filename + ) + + datanames(out) <- filename + } else if (output.format == "df") { + out <- data |> + default_parsing() + } else if (output.format == "list") { + out <- list( + data = data, + name = filename + ) + + out <- c(out, ...) + } + + out +} + + +#' Default data parsing +#' +#' @param data data +#' +#' @returns data.frame or tibble +#' @export +#' +#' @examples +#' mtcars |> str() +#' mtcars |> +#' default_parsing() |> +#' str() +#' head(starwars, 5) |> str() +#' starwars |> +#' default_parsing() |> +#' head(5) |> +#' str() +default_parsing <- function(data) { + 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) + + # purrr::map2( + # out, + # name_labels[names(name_labels) %in% names(out)], + # \(.x, .l){ + # if (!(is.na(.l) | .l == "")) { + # REDCapCAST::set_attr(.x, .l, attr = "label") + # } else { + # attr(x = .x, which = "label") <- NULL + # .x + # } + # # REDCapCAST::set_attr(data = .x, label = .l,attr = "label", overwrite = FALSE) + # } + # ) |> dplyr::bind_cols() +} + +#' Remove empty/NA attributes +#' +#' @param data data +#' +#' @returns data of same class as input +#' @export +#' +#' @examples +#' ds <- mtcars |> +#' lapply(\(.x) REDCapCAST::set_attr(.x, label = NA, attr = "label")) |> +#' dplyr::bind_cols() +#' ds |> +#' remove_empty_attr() |> +#' str() +#' mtcars |> +#' lapply(\(.x) REDCapCAST::set_attr(.x, label = NA, attr = "label")) |> +#' remove_empty_attr() |> +#' str() +#' +remove_empty_attr <- function(data) { + if (is.data.frame(data)) { + data |> + lapply(remove_empty_attr) |> + dplyr::bind_cols() + } else if (is.list(data)) { + data |> lapply(remove_empty_attr) + } else { + attributes(data)[is.na(attributes(data))] <- NULL + data + } +} + +#' Removes columns with completenes below cutoff +#' +#' @param data data frame +#' @param cutoff numeric +#' +#' @returns data frame +#' @export +#' +#' @examples +#' data.frame(a = 1:10, b = NA, c = c(2, NA)) |> remove_empty_cols(cutoff = .5) +remove_empty_cols <- function(data, cutoff = .7) { + filter <- apply(X = data, MARGIN = 2, FUN = \(.x){ + sum(as.numeric(!is.na(.x))) / length(.x) + }) >= cutoff + data[filter] +} + + +#' Append list with named index +#' +#' @param data data to add to list +#' @param list list +#' @param index index name +#' +#' @returns list +#' @export +#' +#' @examples +#' ls_d <- list(test = c(1:20)) +#' ls_d <- list() +#' data.frame(letters[1:20], 1:20) |> append_list(ls_d, "letters") +#' letters[1:20] |> append_list(ls_d, "letters") +append_list <- function(data, list, index) { + ## This will overwrite and not warn + ## Not very safe, but convenient to append code to list + if (index %in% names(list)) { + list[[index]] <- data + out <- list + } else { + out <- setNames(c(list, list(data)), c(names(list), index)) + } + out +} + + +#' Get missingsness fraction +#' +#' @param data data +#' +#' @returns numeric vector +#' @export +#' +#' @examples +#' c(NA, 1:10, rep(NA, 3)) |> missing_fraction() +missing_fraction <- function(data) { + NROW(data[is.na(data)]) / NROW(data) +} + + + +#' Ultra short data dascription +#' +#' @param data +#' +#' @returns character vector +#' @export +#' +#' @examples +#' data.frame( +#' sample(1:8, 20, TRUE), +#' 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 + + n <- nrow(data) + n_var <- ncol(data) + n_complete <- sum(complete.cases(data)) + p_complete <- n_complete / n + + sprintf( + "%s has %s observations and %s variables, with %s (%s%%) complete cases.", + data_text, + n, + n_var, + n_complete, + signif(100 * p_complete, 3) + ) +} + + +#' Filter function to filter data set by variable type +#' +#' @param data data frame +#' @param type vector of data types (recognised: data_types) +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' default_parsing(mtcars) |> +#' data_type_filter(type = c("categorical", "continuous")) |> +#' attributes() +#' default_parsing(mtcars) |> +#' data_type_filter(type = NULL) |> +#' attributes() +#' \dontrun{ +#' default_parsing(mtcars) |> data_type_filter(type = c("test", "categorical", "continuous")) +#' } +data_type_filter <- function(data, type) { + ## Please ensure to only provide recognised data types + assertthat::assert_that(all(type %in% names(data_types()))) + + if (!is.null(type)) { + out <- data[data_type(data) %in% type] + code <- rlang::call2("data_type_filter", !!!list(type = type), .ns = "FreesearchR") + attr(out, "code") <- code + } else { + out <- data + } + out +} + +#' Drop-in replacement for the base::sort_by with option to remove NAs +#' +#' @param x x +#' @param y y +#' @param na.rm remove NAs +#' @param ... passed to base_sort_by +#' +#' @returns vector +#' @export +#' +#' @examples +#' sort_by(c("Multivariable", "Univariable"), c("Univariable", "Minimal", "Multivariable")) +sort_by <- function(x, y, na.rm = FALSE, ...) { + out <- base::sort_by(x, y, ...) + if (na.rm == TRUE) { + out[!is.na(out)] + } else { + out + } +} + + +get_ggplot_label <- function(data, label) { + assertthat::assert_that(ggplot2::is_ggplot(data)) + data$labels[[label]] +} + + +#' Return if available +#' +#' @param data vector +#' @param default assigned value for missings +#' +#' @returns vector +#' @export +#' +#' @examples +#' NULL |> if_not_missing("new") +#' c(2, "a", NA) |> if_not_missing() +#' "See" |> if_not_missing() +if_not_missing <- function(data, default = NULL) { + if (length(data) > 1) { + Reduce(c, lapply(data, if_not_missing)) + } else if (is.na(data) || is.null(data)) { + return(default) + } else { + return(data) + } +} + + +#' Merge list of expressions +#' +#' @param data list +#' +#' @returns expression +#' @export +#' +#' @examples +#' list( +#' rlang::call2(.fn = "select", !!!list(c("cyl", "disp")), .ns = "dplyr"), +#' rlang::call2(.fn = "default_parsing", .ns = "FreesearchR") +#' ) |> merge_expression() +merge_expression <- function(data) { + Reduce( + f = function(x, y) rlang::expr(!!x %>% !!y), + x = data + ) +} + +#' Reduce character vector with the native pipe operator or character string +#' +#' @param data list +#' +#' @returns character string +#' @export +#' +#' @examples +#' list( +#' "mtcars", +#' rlang::call2(.fn = "select", !!!list(c("cyl", "disp")), .ns = "dplyr"), +#' rlang::call2(.fn = "default_parsing", .ns = "FreesearchR") +#' ) |> +#' lapply(expression_string) |> +#' pipe_string() |> +#' expression_string("data<-") +pipe_string <- function(data, collapse = "|>\n") { + if (is.list(data)) { + Reduce( + f = function(x, y) glue::glue("{x}{collapse}{y}"), + x = data + ) + } else { + data + } +} + +#' Deparses expression as string, substitutes native pipe and adds assign +#' +#' @param data expression +#' +#' @returns string +#' @export +#' +#' @examples +#' list( +#' as.symbol(paste0("mtcars$", "mpg")), +#' rlang::call2(.fn = "select", !!!list(c("cyl", "disp")), .ns = "dplyr"), +#' rlang::call2(.fn = "default_parsing", .ns = "FreesearchR") +#' ) |> +#' merge_expression() |> +#' expression_string() +expression_string <- function(data, assign.str = "") { + exp.str <- if (is.call(data)) deparse(data) else data + # browser() + out <- paste0(assign.str, gsub("%>%", "|>\n", paste(gsub('"', "'", paste(exp.str, collapse = "")), collapse = ""))) + gsub(" |`", "", out) +} + + +#' Very simple function to remove nested lists, like when uploading .rds +#' +#' @param data data +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' dplyr::tibble(a = 1:10, b = rep(list("a"), 10)) |> remove_nested_list() +#' dplyr::tibble(a = 1:10, b = rep(list(c("a", "b")), 10)) |> as.data.frame() +remove_nested_list <- function(data) { + data[!sapply(data, is.list)] +} + + + + +#' (Re)label columns in data.frame +#' +#' @param data data.frame to be labelled +#' @param label named list or vector +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' ls <- list("mpg" = "", "cyl" = "Cylinders", "disp" = "", "hp" = "", "drat" = "", "wt" = "", "qsec" = "", "vs" = "", "am" = "", "gear" = "", "carb" = "") +#' ls2 <- c("mpg" = "", "cyl" = "Cylinders", "disp" = "", "hp" = "Horses", "drat" = "", "wt" = "", "qsec" = "", "vs" = "", "am" = "", "gear" = "", "carb" = "") +#' ls3 <- c("mpg" = "", "cyl" = "", "disp" = "", "hp" = "Horses", "drat" = "", "wt" = "", "qsec" = "", "vs" = "", "am" = "", "gear" = "", "carb" = "") +#' mtcars |> +#' set_column_label(ls) |> +#' set_column_label(ls2) |> +#' set_column_label(ls3) +#' rlang::expr(FreesearchR::set_column_label(label = !!ls3)) |> expression_string() +set_column_label <- function(data, label, overwrite = TRUE) { + purrr::imap(data, function(.data, .name) { + ls <- if (is.list(label)) unlist(label) else label + ls[ls == ""] <- NA + if (.name %in% names(ls)) { + out <- REDCapCAST::set_attr(.data, unname(ls[.name]), attr = "label", overwrite = overwrite) + remove_empty_attr(out) + } else { + .data + } + }) |> dplyr::bind_cols(.name_repair = "unique_quiet") +} + + +#' Append a column to a data.frame +#' +#' @param data data +#' @param column new column (vector) or data.frame with 1 column +#' @param name new name (pre-fix) +#' @param index desired location. May be "left", "right" or numeric index. +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' mtcars |> +#' dplyr::mutate(mpg_cut = mpg) |> +#' append_column(mtcars$mpg, "mpg_cutter") +append_column <- function(data, column, name, index = "right") { + assertthat::assert_that(NCOL(column) == 1) + assertthat::assert_that(length(index) == 1) + + if (index == "right") { + index <- ncol(data) + 1 + } else if (index == "left") { + index <- 1 + } else if (is.numeric(index)) { + if (index > ncol(data)) { + index <- ncol(data) + 1 + } + } else { + index <- ncol(data) + 1 + } + + ## Identifying potential naming conflicts + nm_conflicts <- names(data)[startsWith(names(data), name)] + ## Simple attemt to create new unique name + if (length(nm_conflicts) > 0) { + name <- glue::glue("{name}_{length(nm_conflicts)+1}") + } + ## If the above not achieves a unique name, the generic approach is used + if (name %in% names(data)) { + name <- make.names(c(name, names(data)), unique = TRUE)[1] + } + new_df <- setNames(data.frame(column), name) + + list( + data[seq_len(index - 1)], + new_df, + if (!index > ncol(data)) data[index:ncol(data)] + ) |> + dplyr::bind_cols() +} + + + +#' Test if element is identical to the previous +#' +#' @param data data. vector, data.frame or list +#' @param no.name logical to remove names attribute before testing +#' +#' @returns logical vector +#' @export +#' +#' @examples +#' c(1, 1, 2, 3, 3, 2, 4, 4) |> is_identical_to_previous() +#' mtcars[c(1, 1, 2, 3, 3, 2, 4, 4)] |> is_identical_to_previous() +#' list(1, 1, list(2), "A", "a", "a") |> is_identical_to_previous() +is_identical_to_previous <- function(data, no.name = TRUE) { + if (is.data.frame(data)) { + lagged <- data.frame(FALSE, data[seq_len(length(data) - 1)]) + } else { + lagged <- c(FALSE, data[seq_len(length(data) - 1)]) + } + + vapply(seq_len(length(data)), \(.x){ + if (isTRUE(no.name)) { + identical(unname(lagged[.x]), unname(data[.x])) + } else { + identical(lagged[.x], data[.x]) + } + }, FUN.VALUE = logical(1)) +} + + +#' Simplified version of the snakecase packages to_snake_case +#' +#' @param data character string vector +#' +#' @returns vector +#' @export +#' +#' @examples +#' c("foo bar", "fooBar21", "!!Foo'B'a-r", "foo_bar", "F OO bar") |> simple_snake() +simple_snake <- function(data){ + gsub("[\\s+]","_",gsub("[^\\w\\s:-]", "", tolower(data), perl=TRUE), perl=TRUE) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//hosted_version.R +######## + +hosted_version <- function()'v25.6.3-250626' + + +######## +#### Current file: /Users/au301842/FreesearchR/R//html_dependency_freesearchr.R +######## + +html_dependency_FreesearchR <- function() { + htmltools::htmlDependency( + name = "FreesearchR", + version = packageVersion("FreesearchR"), + src = list(href = "FreesearchR", file = "assets"), + package = "FreesearchR", + stylesheet = "css/FreesearchR.css" + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//import-file-ext.R +######## + +#' @title Import data from a file +#' +#' @description Let user upload a file and import data +#' +#' @param preview_data Show or not a preview of the data under the file input. +#' @param file_extensions File extensions accepted by [shiny::fileInput()], can also be MIME type. +#' @param layout_params How to display import parameters : in a dropdown button or inline below file input. +#' +#' @export +#' +#' @name import-file +#' +#' +import_file_ui <- function(id, + title = "", + preview_data = TRUE, + file_extensions = c(".csv", ".txt", ".xls", ".xlsx", ".rds", ".fst", ".sas7bdat", ".sav"), + layout_params = c("dropdown", "inline")) { + ns <- shiny::NS(id) + + if (!is.null(layout_params)) { + layout_params <- match.arg(layout_params) + } + + if (isTRUE(title)) { + title <- shiny::tags$h4( + datamods:::i18n("Import a file"), + class = "datamods-title" + ) + } + + + params_ui <- shiny::fluidRow( + shiny::column( + width = 6, + shinyWidgets::numericInputIcon( + inputId = ns("skip_rows"), + label = datamods:::i18n("Rows to skip before reading data:"), + value = 0, + min = 0, + icon = list("n ="), + size = "sm", + width = "100%" + ), + shiny::tagAppendChild( + shinyWidgets::textInputIcon( + inputId = ns("na_label"), + label = datamods:::i18n("Missing values character(s):"), + value = "NA,,'',na", + icon = list("NA"), + size = "sm", + width = "100%" + ), + shiny::helpText(phosphoricons::ph("info"), datamods:::i18n("if several use a comma (',') to separate them")) + ) + ), + shiny::column( + width = 6, + shinyWidgets::textInputIcon( + inputId = ns("dec"), + label = datamods:::i18n("Decimal separator:"), + value = ".", + icon = list("0.00"), + size = "sm", + width = "100%" + ), + selectInputIcon( + inputId = ns("encoding"), + label = datamods:::i18n("Encoding:"), + choices = c( + "UTF-8" = "UTF-8", + "Latin1" = "latin1" + ), + icon = phosphoricons::ph("text-aa"), + size = "sm", + width = "100%" + ) + ) + ) + + file_ui <- shiny::tagAppendAttributes( + shiny::fileInput( + inputId = ns("file"), + label = datamods:::i18n("Upload a file:"), + buttonLabel = datamods:::i18n("Browse..."), + placeholder = datamods:::i18n("No file selected; maximum file size is 5 mb"), + accept = file_extensions, + width = "100%", + ## A solution to allow multiple file upload is being considered + multiple = FALSE + ), + class = "mb-0" + ) + if (identical(layout_params, "dropdown")) { + file_ui <- shiny::tags$div( + style = htmltools::css( + display = "grid", + gridTemplateColumns = "1fr 50px", + gridColumnGap = "10px" + ), + file_ui, + shiny::tags$div( + class = "shiny-input-container", + shiny::tags$label( + class = "control-label", + `for` = ns("dropdown_params"), + "...", + style = htmltools::css(visibility = "hidden") + ), + shinyWidgets::dropMenu( + shiny::actionButton( + inputId = ns("dropdown_params"), + label = phosphoricons::ph("gear", title = "Parameters"), + width = "50px", + class = "px-1" + ), + params_ui + ) + ) + ) + } + shiny::tags$div( + class = "datamods-import", + datamods:::html_dependency_datamods(), + title, + file_ui, + if (identical(layout_params, "inline")) params_ui, + shiny::tags$div( + class = "hidden", + id = ns("sheet-container"), + shinyWidgets::pickerInput( + inputId = ns("sheet"), + label = datamods:::i18n("Select sheet to import:"), + choices = NULL, + width = "100%", + multiple = TRUE + ) + ), + shiny::tags$div( + id = ns("import-placeholder"), + shinyWidgets::alert( + id = ns("import-result"), + status = "info", + shiny::tags$b(datamods:::i18n("No file selected:")), + sprintf(datamods:::i18n("You can import %s files"), paste(file_extensions, collapse = ", ")), + dismissible = TRUE + ) + ), + if (isTRUE(preview_data)) { + toastui::datagridOutput2(outputId = ns("table")) + }, + shiny::uiOutput( + outputId = ns("container_confirm_btn"), + style = "margin-top: 20px;" + ), + tags$div( + style = htmltools::css(display = "none"), + shiny::checkboxInput( + inputId = ns("preview_data"), + label = NULL, + value = isTRUE(preview_data) + ) + ) + ) +} + +#' +#' @export +#' +#' +#' @rdname import-file +import_file_server <- function(id, + btn_show_data = TRUE, + show_data_in = c("popup", "modal"), + trigger_return = c("button", "change"), + return_class = c("data.frame", "data.table", "tbl_df", "raw"), + reset = reactive(NULL)) { + 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" + ) + + trigger_return <- match.arg(trigger_return) + return_class <- match.arg(return_class) + + module <- function(input, output, session) { + ns <- session$ns + imported_rv <- shiny::reactiveValues(data = NULL, name = NULL) + temporary_rv <- shiny::reactiveValues(data = NULL, name = NULL, status = NULL, sheets = 1) + + shiny::observeEvent(reset(), { + temporary_rv$data <- NULL + temporary_rv$name <- NULL + temporary_rv$status <- NULL + }) + + output$container_confirm_btn <- shiny::renderUI({ + if (identical(trigger_return, "button")) { + datamods:::button_import() + } + }) + + shiny::observeEvent(input$file, { + ## Several steps are taken to ensure no errors on changed input file + temporary_rv$sheets <- 1 + if (isTRUE(is_workbook(input$file$datapath))) { + if (isTRUE(is_excel(input$file$datapath))) { + temporary_rv$sheets <- readxl::excel_sheets(input$file$datapath) + } else if (isTRUE(is_ods(input$file$datapath))) { + temporary_rv$sheets <- readODS::ods_sheets(input$file$datapath) + } + selected <- temporary_rv$sheets[1] + + shinyWidgets::updatePickerInput( + session = session, + inputId = "sheet", + selected = selected, + choices = temporary_rv$sheets + ) + datamods:::showUI(paste0("#", ns("sheet-container"))) + } else { + datamods:::hideUI(paste0("#", ns("sheet-container"))) + } + }) + + observeEvent( + list( + input$file, + input$sheet, + input$skip_rows, + input$dec, + input$encoding, + input$na_label + ), + { + req(input$file) + + if (!all(input$sheet %in% temporary_rv$sheets)) { + sheets <- 1 + } else { + sheets <- input$sheet + } + + extension <- tools::file_ext(input$file$datapath) + + parameters <- list( + file = input$file$datapath, + sheet = sheets, + skip = input$skip_rows, + dec = input$dec, + encoding = input$encoding, + na.strings = datamods:::split_char(input$na_label) + ) + + parameters <- parameters[which(names(parameters) %in% rlang::fn_fmls_names(get(read_fns[[extension]])))] + # parameters <- parameters[which(names(parameters) %in% rlang::fn_fmls_names(read_fns[[extension]]))] + imported <- try(rlang::exec(read_fns[[extension]], !!!parameters), silent = TRUE) + code <- rlang::call2(read_fns[[extension]], !!!modifyList(parameters, list(file = input$file$name)), .ns = "FreesearchR") + + if (inherits(imported, "try-error")) { + imported <- try(rlang::exec(rio::import, !!!parameters[1]), silent = TRUE) + code <- rlang::call2("import", !!!list(file = input$file$name), .ns = "rio") + } + + if (inherits(imported, "try-error") || NROW(imported) < 1) { + datamods:::toggle_widget(inputId = "confirm", enable = FALSE) + datamods:::insert_error(mssg = datamods:::i18n(attr(imported, "condition")$message)) + temporary_rv$status <- "error" + temporary_rv$data <- NULL + temporary_rv$name <- NULL + temporary_rv$code <- NULL + } else { + datamods:::toggle_widget(inputId = "confirm", enable = TRUE) + + datamods:::insert_alert( + selector = ns("import"), + status = "success", + datamods:::make_success_alert( + imported, + trigger_return = trigger_return, + btn_show_data = btn_show_data, + extra = if (isTRUE(input$preview_data)) datamods:::i18n("First five rows are shown below:") + ) + ) + temporary_rv$status <- "success" + temporary_rv$data <- imported + temporary_rv$name <- input$file$name + temporary_rv$code <- code + } + }, + ignoreInit = TRUE + ) + + observeEvent(input$see_data, { + tryCatch( + { + datamods:::show_data(default_parsing(temporary_rv$data), title = datamods:::i18n("Imported data"), type = show_data_in) + }, + # warning = function(warn) { + # showNotification(warn, type = "warning") + # }, + error = function(err) { + showNotification(err, type = "err") + } + ) + }) + + output$table <- toastui::renderDatagrid2({ + req(temporary_rv$data) + tryCatch( + { + toastui::datagrid( + data = setNames(head(temporary_rv$data, 5), make.names(names(temporary_rv$data), unique = TRUE)), + theme = "striped", + colwidths = "guess", + minBodyHeight = 250 + ) + }, + error = function(err) { + showNotification(err, type = "err") + } + ) + }) + + observeEvent(input$confirm, { + imported_rv$data <- temporary_rv$data + imported_rv$name <- temporary_rv$name + imported_rv$code <- temporary_rv$code + }) + + if (identical(trigger_return, "button")) { + return(list( + status = reactive(temporary_rv$status), + name = reactive(imported_rv$name), + code = reactive(imported_rv$code), + data = reactive(datamods:::as_out(imported_rv$data, return_class)) + )) + } else { + return(list( + status = reactive(temporary_rv$status), + name = reactive(temporary_rv$name), + code = reactive(temporary_rv$code), + data = reactive(datamods:::as_out(temporary_rv$data, return_class)) + )) + } + } + + moduleServer( + id = id, + module = module + ) +} + +# utils ------------------------------------------------------------------- + +is_excel <- function(path) { + isTRUE(tools::file_ext(path) %in% c("xls", "xlsx")) +} + +is_ods <- function(path) { + isTRUE(tools::file_ext(path) %in% c("ods")) +} + +is_sas <- function(path) { + isTRUE(tools::file_ext(path) %in% c("sas7bdat")) +} + +is_workbook <- function(path) { + is_excel(path) || is_ods(path) +} + + +# File import functions --------------------------------------------------- + +#' Wrapper to ease data file import +#' +#' @param file path to the file +#' @param sheet for Excel files, sheet to read +#' @param skip number of row to skip +#' @param encoding file encoding +#' @param na.strings character(s) to interpret as missing values. +#' +#' +#' @name import-file-type +#' +#' @returns data.frame +#' @export +#' +import_delim <- function(file, skip, encoding, na.strings) { + data.table::fread( + file = file, + na.strings = na.strings, + skip = skip, + check.names = TRUE, + encoding = encoding, + data.table = FALSE, + logical01 = TRUE, + logicalYN = TRUE, + keepLeadingZeros = TRUE + ) +} + + +#' @name import-file-type +#' +#' @returns data.frame +#' @export +#' +import_xls <- function(file, sheet, skip, na.strings) { + tryCatch( + { + ## If sheet is null, this allows purrr::map to run + if (is.null(sheet)) sheet <- 1 + + sheet |> + purrr::map(\(.x){ + readxl::read_excel( + path = file, + sheet = .x, + na = na.strings, + skip = skip, + .name_repair = "unique_quiet", + trim_ws = TRUE + ) + + # openxlsx2::read_xlsx( + # file = file, + # sheet = .x, + # skip_empty_rows = TRUE, + # start_row = skip - 1, + # na.strings = na.strings + # ) + }) |> + purrr::reduce(dplyr::full_join) + }, + # warning = function(warn) { + # showNotification(paste0(warn), type = "warning") + # }, + error = function(err) { + showNotification(paste0(err), type = "err") + } + ) +} + + +#' @name import-file-type +#' +#' @returns data.frame +#' @export +#' +import_ods <- function(file, sheet, skip, na.strings) { + tryCatch( + { + if (is.null(sheet)) sheet <- 1 + sheet |> + purrr::map(\(.x){ + readODS::read_ods( + path = file, + sheet = .x, + skip = skip, + na = na.strings + ) + }) |> + purrr::reduce(dplyr::full_join) + }, + # warning = function(warn) { + # showNotification(paste0(warn), type = "warning") + # }, + error = function(err) { + showNotification(paste0(err), type = "err") + } + ) +} + +#' @name import-file-type +#' +#' @returns data.frame +#' @export +#' +import_dta <- function(file) { + haven::read_dta( + file = file, + .name_repair = "unique_quiet" + ) +} + +#' @name import-file-type +#' +#' @returns data.frame +#' @export +#' +import_rds <- function(file) { + readr::read_rds( + file = file + ) +} + +#' @title Create a select input control with icon(s) +#' +#' @description Extend form controls by adding text or icons before, +#' after, or on both sides of a classic `selectInput`. +#' +#' @inheritParams shiny::selectInput +#' +#' @return A numeric input control that can be added to a UI definition. +#' @export +#' +#' @importFrom shiny restoreInput +#' @importFrom htmltools tags validateCssUnit css +#' +selectInputIcon <- function(inputId, + label, + choices, + selected = NULL, + multiple = FALSE, + selectize = TRUE, + size = NULL, + width = NULL, + icon = NULL) { + selected <- shiny::restoreInput(id = inputId, default = selected) + shiny::tags$div( + class = "form-group shiny-input-container", + shinyWidgets:::label_input(inputId, label), + style = htmltools:::css(width = htmltools:::validateCssUnit(width)), + shiny::tags$div( + class = "input-group", + class = shinyWidgets:::validate_size(size), + shinyWidgets:::markup_input_group(icon, "left", theme_func = shiny::getCurrentTheme), + shiny::tags$select( + id = inputId, + class = "form-control select-input-icon", + shiny:::selectOptions(choices, selected, inputId, selectize) + ), + shinyWidgets:::markup_input_group(icon, "right", theme_func = shiny::getCurrentTheme) + ), + shinyWidgets:::html_dependency_input_icons() + ) +} + + +#' Test app for the import_file module +#' +#' @rdname import-file_module +#' +#' @examples +#' \dontrun{ +#' import_file_demo_app() +#' } +import_file_demo_app <- function() { + ui <- shiny::fluidPage( + # theme = bslib::bs_theme(version = 5L), + # theme = bslib::bs_theme(version = 5L, preset = "bootstrap"), + shiny::tags$h3("Import data from a file"), + shiny::fluidRow( + shiny::column( + width = 4, + import_file_ui( + id = "myid", + file_extensions = c(".csv", ".tsv", ".txt", ".xls", ".xlsx", ".rds", ".sas7bdat", ".ods", ".dta"), + layout_params = "dropdown" # "inline" # or "dropdown" + ) + ), + shiny::column( + width = 8, + shiny::tags$b("Import status:"), + shiny::verbatimTextOutput(outputId = "status"), + shiny::tags$b("Name:"), + shiny::verbatimTextOutput(outputId = "name"), + shiny::tags$b("Code:"), + shiny::verbatimTextOutput(outputId = "code"), + shiny::tags$b("Data:"), + shiny::verbatimTextOutput(outputId = "data") + ) + ) + ) + server <- function(input, output, session) { + imported <- import_file_server( + id = "myid", + show_data_in = "popup", + trigger_return = "change", + return_class = "data.frame" + ) + + output$status <- shiny::renderPrint({ + imported$status() + }) + output$name <- shiny::renderPrint({ + imported$name() + }) + output$code <- shiny::renderPrint({ + imported$code() + }) + output$data <- shiny::renderPrint({ + imported$data() + }) + } + shiny::shinyApp(ui, server) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//launch_FreesearchR.R +######## + +#' Easily launch the FreesearchR app +#' +#' @description +#' All data.frames in the global environment will be accessible through the app. +#' +#' @param ... passed on to `shiny::runApp()` +#' +#' @returns shiny app +#' @export +#' +#' @examples +#' \dontrun{ +#' data(mtcars) +#' launch_FreesearchR(launch.browser = TRUE) +#' } +launch_FreesearchR <- function(...){ + appDir <- system.file("apps", "FreesearchR", package = "FreesearchR") + if (appDir == "") { + stop("Could not find the app directory. Try re-installing `FreesearchR`.", call. = FALSE) + } + + a <- shiny::runApp(appDir = paste0(appDir,"/app.R"), ...) + return(invisible(a)) +} + + + +######## +#### Current file: /Users/au301842/FreesearchR/R//missings-module.R +######## + +#' Data correlations evaluation module +#' +#' @param id Module id +#' +#' @name data-missings +#' @returns Shiny ui module +#' @export +data_missings_ui <- function(id) { + ns <- shiny::NS(id) + + shiny::tagList( + gt::gt_output(outputId = ns("missings_table")) + ) +} + + +#' +#' @param data data +#' @param output.format output format +#' +#' @name data-missings +#' @returns shiny server module +#' @export +data_missings_server <- function(id, + data, + variable, + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + # ns <- session$ns + + datar <- if (is.reactive(data)) data else reactive(data) + variabler <- if (is.reactive(variable)) variable else reactive(variable) + + rv <- shiny::reactiveValues( + data = NULL, + table = NULL + ) + + rv$data <- shiny::reactive({ + df_tbl <- datar() + by_var <- variabler() + + tryCatch( + { + if (!is.null(by_var) && by_var != "" && by_var %in% names(df_tbl)) { + df_tbl[[by_var]] <- ifelse(is.na(df_tbl[[by_var]]), "Missing", "Non-missing") + + out <- gtsummary::tbl_summary(df_tbl, by = by_var) |> + gtsummary::add_p() + } else { + out <- gtsummary::tbl_summary(df_tbl) + } + }, + error = function(err) { + showNotification(paste0("Error: ", err), type = "err") + } + ) + + out + }) + + output$missings_table <- gt::render_gt({ + shiny::req(datar) + shiny::req(variabler) + + if (is.null(variabler()) || variabler() == "" || !variabler() %in% names(datar())) { + if (anyNA(datar())){ + title <- "No variable chosen for analysis" + } else { + title <- "No missing observations" + } + } else { + title <- glue::glue("Missing vs non-missing observations in the variable **'{variabler()}'**") + } + + out <- rv$data() |> + gtsummary::as_gt() |> + gt::tab_header(title = gt::md(title)) + + rv$table <- out + + out + }) + + return(reactive(rv$table)) + } + ) +} + + +missing_demo_app <- function() { + ui <- shiny::fluidPage( + shiny::actionButton( + inputId = "modal_missings", + label = "Browse data", + width = "100%", + disabled = FALSE + ), + shiny::selectInput( + inputId = "missings_var", + label = "Select variable to stratify analysis", choices = c("cyl", "vs") + ), + data_missings_ui("data") + ) + server <- function(input, output, session) { + data_demo <- mtcars + data_demo[sample(1:32, 10), "cyl"] <- NA + data_demo[sample(1:32, 8), "vs"] <- NA + + data_missings_server(id = "data", data = data_demo, variable = shiny::reactive(input$missings_var)) + + visual_summary_server(id = "visual", data = data_demo) + + observeEvent(input$modal_missings, { + tryCatch( + { + modal_visual_summary(id = "visual") + }, + error = function(err) { + showNotification(paste0("We encountered the following error browsing your data: ", err), type = "err") + } + ) + }) + } + shiny::shinyApp(ui, server) +} + +missing_demo_app() + + + + + + + + + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot_box.R +######## + +#' Beautiful box plot(s) +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' mtcars |> plot_box(pri = "mpg", sec = "cyl", ter = "gear") +#' mtcars |> +#' default_parsing() |> +#' plot_box(pri = "mpg", sec = "cyl", ter = "gear") +plot_box <- function(data, pri, sec, ter = NULL) { + if (!is.null(ter)) { + ds <- split(data, data[ter]) + } else { + ds <- list(data) + } + + out <- lapply(ds, \(.ds){ + plot_box_single( + data = .ds, + pri = pri, + sec = sec + ) + }) + + wrap_plot_list(out) +} + + + + +#' Create nice box-plots +#' +#' @name data-plots +#' +#' @returns ggplot object +#' @export +#' +#' @examples +#' mtcars |> plot_box_single("mpg") +#' mtcars |> plot_box_single("mpg","cyl") +plot_box_single <- function(data, pri, sec=NULL, seed = 2103) { + set.seed(seed) + + if (is.null(sec)) { + sec <- "All" + data[[sec]] <- sec + } + + discrete <- !data_type(data[[sec]]) %in% "continuous" + + data |> + ggplot2::ggplot(ggplot2::aes(x = !!dplyr::sym(pri), y = !!dplyr::sym(sec), fill = !!dplyr::sym(sec), group = !!dplyr::sym(sec))) + + ggplot2::geom_boxplot(linewidth = 1.8, outliers = FALSE) + + ## THis could be optional in future + ggplot2::geom_jitter(color = "black", size = 2, alpha = 0.9, width = 0.1, height = .2) + + ggplot2::coord_flip() + + viridis::scale_fill_viridis(discrete = discrete, option = "D") + + # ggplot2::theme_void() + + ggplot2::theme_bw(base_size = 24) + + ggplot2::theme( + legend.position = "none", + # panel.grid.major = element_blank(), + # panel.grid.minor = element_blank(), + # axis.text.y = element_blank(), + # axis.title.y = element_blank(), + # text = ggplot2::element_text(size = 20), + # axis.text = ggplot2::element_blank(), + # plot.title = element_blank(), + panel.background = ggplot2::element_rect(fill = "white"), + plot.background = ggplot2::element_rect(fill = "white"), + panel.border = ggplot2::element_blank(), + panel.grid.major = ggplot2::element_blank(), + panel.grid.minor = ggplot2::element_blank(), + axis.line = ggplot2::element_line(colour = "black"), + axis.ticks = ggplot2::element_line(colour = "black") + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot_euler.R +######## + +#' Area proportional venn diagrams +#' +#' @description +#' THis is slightly modified from https://gist.github.com/danlooo/d23d8bcf8856c7dd8e86266097404ded +#' +#' This functions uses eulerr::euler to plot area proportional venn diagramms +#' but plots it using ggplot2 +#' +#' @param combinations set relationships as a named numeric vector, matrix, or +#' data.frame(See `eulerr::euler`) +#' @param show_quantities whether to show number of intersecting elements +#' @param show_labels whether to show set names +#' @param ... further arguments passed to eulerr::euler +ggeulerr <- function( + combinations, + show_quantities = TRUE, + show_labels = TRUE, + ...) { + # browser() + data <- + eulerr::euler(combinations = combinations, ...) |> + plot(quantities = show_quantities) |> + purrr::pluck("data") + + + tibble::as_tibble(data$ellipses, rownames = "Variables") |> + ggplot2::ggplot() + + ggforce::geom_ellipse( + mapping = ggplot2::aes( + x0 = h, y0 = k, a = a, b = b, angle = 0, fill = Variables + ), + alpha = 0.5, + linewidth = 1.5 + ) + + ggplot2::geom_text( + data = { + data$centers |> + dplyr::mutate( + label = labels |> purrr::map2(quantities, ~ { + if (!is.na(.x) && !is.na(.y) && show_labels) { + paste0(.x, "\n", sprintf(.y, fmt = "%.2g")) + } else if (!is.na(.x) && show_labels) { + .x + } else if (!is.na(.y)) { + .y + } else { + "" + } + }) + ) + }, + mapping = ggplot2::aes(x = x, y = y, label = label), + size = 8 + ) + + ggplot2::theme(panel.grid = ggplot2::element_blank()) + + ggplot2::coord_fixed() + + ggplot2::scale_fill_hue() +} + +#' Easily plot euler diagrams +#' +#' @param data data +#' @param x name of main variable +#' @param y name of secondary variables +#' @param z grouping variable +#' @param seed seed +#' +#' @returns patchwork object +#' @export +#' +#' @examples +#' data.frame( +#' A = sample(c(TRUE, TRUE, FALSE), 50, TRUE), +#' B = sample(c("A", "C"), 50, TRUE), +#' C = sample(c(TRUE, FALSE, FALSE, FALSE), 50, TRUE), +#' D = sample(c(TRUE, FALSE, FALSE, FALSE), 50, TRUE) +#' ) |> plot_euler("A", c("B", "C"), "D", seed = 4) +#' mtcars |> plot_euler("vs", "am", seed = 1) +plot_euler <- function(data, pri, sec, ter = NULL, seed = 2103) { + set.seed(seed = seed) + if (!is.null(ter)) { + ds <- split(data, data[ter]) + } else { + ds <- list(data) + } + + out <- lapply(ds, \(.x){ + .x[c(pri, sec)] |> + as.data.frame() |> + na.omit() |> + plot_euler_single() + }) + + # names(out) + wrap_plot_list(out) + # patchwork::wrap_plots(out, guides = "collect") +} + +#' Easily plot single euler diagrams +#' +#' @returns ggplot2 object +#' @export +#' +#' @examples +#' data.frame( +#' A = sample(c(TRUE, TRUE, FALSE), 50, TRUE), +#' B = sample(c("A", "C"), 50, TRUE), +#' 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" + # } + + data |> + ggeulerr(shape = "circle") + + ggplot2::theme_void() + + ggplot2::theme( + legend.position = "none", + # panel.grid.major = element_blank(), + # panel.grid.minor = element_blank(), + # axis.text.y = element_blank(), + # axis.title.y = element_blank(), + text = ggplot2::element_text(size = 20), + axis.text = ggplot2::element_blank(), + # plot.title = element_blank(), + # panel.background = ggplot2::element_rect(fill = "white"), + plot.background = ggplot2::element_rect(fill = "white"), + panel.border = ggplot2::element_blank() + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot_hbar.R +######## + +#' Nice horizontal stacked bars (Grotta bars) +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' mtcars |> plot_hbars(pri = "carb", sec = "cyl") +#' 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 +} + + +#' Vertical stacked bar plot wrapper +#' +#' @param data data.frame +#' @param score outcome variable +#' @param group grouping variable +#' @param strata stratifying variable +#' @param t.size text size +#' +#' @return ggplot2 object +#' @export +#' +vertical_stacked_bars <- function(data, + score = "full_score", + group = "pase_0_q", + strata = NULL, + t.size = 10, + l.color = "black", + l.size = .5, + draw.lines = TRUE) { + if (is.null(group)) { + df.table <- data[c(score, group, strata)] |> + dplyr::mutate("All" = 1) |> + table() + group <- "All" + draw.lines <- FALSE + } else { + df.table <- data[c(score, group, strata)] |> + table() + } + + p <- df.table |> + rankinPlot::grottaBar( + scoreName = score, + groupName = group, + textColor = c("black", "white"), + strataName = strata, + textCut = 6, + textSize = 20, + printNumbers = "none", + lineSize = l.size, + returnData = TRUE + ) + + colors <- viridisLite::viridis(nrow(df.table)) + contrast_cut <- + sum(contrast_text(colors, threshold = .3) == "white") + + score_label <- data |> get_label(var = score) + group_label <- data |> get_label(var = group) + + p |> + (\(.x){ + .x$plot + + ggplot2::geom_text( + data = .x$rectData[which(.x$rectData$n > + 0), ], + size = t.size, + fontface = "plain", + ggplot2::aes( + x = group, + y = p_prev + 0.49 * p, + color = as.numeric(score) > contrast_cut, + # label = paste0(sprintf("%2.0f", 100 * p),"%"), + label = sprintf("%2.0f", 100 * p) + ) + ) + + ggplot2::labs(fill = score_label) + + ggplot2::scale_fill_manual(values = rev(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") + })() +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot_ridge.R +######## + +#' Plot nice ridge plot +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' mtcars |> +#' 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, ...) { + if (!is.null(z)) { + ds <- split(data, data[z]) + } else { + ds <- list(data) + } + + out <- lapply(ds, \(.ds){ + ggplot2::ggplot(.ds, ggplot2::aes(x = !!dplyr::sym(x), y = !!dplyr::sym(y), fill = !!dplyr::sym(y))) + + ggridges::geom_density_ridges() + + ggridges::theme_ridges() + + ggplot2::theme(legend.position = "none") |> rempsyc:::theme_apa() + }) + + patchwork::wrap_plots(out) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot_sankey.R +######## + +#' Readying data for sankey plot +#' +#' @name data-plots +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' ds <- data.frame(g = sample(LETTERS[1:2], 100, TRUE), first = REDCapCAST::as_factor(sample(letters[1:4], 100, TRUE)), last = sample(c(letters[1:4], NA), 100, TRUE, prob = c(rep(.23, 4), .08))) +#' ds |> sankey_ready("first", "last") +#' ds |> sankey_ready("first", "last", numbers = "percentage") +#' data.frame( +#' g = sample(LETTERS[1:2], 100, TRUE), +#' first = REDCapCAST::as_factor(sample(letters[1:4], 100, TRUE)), +#' last = sample(c(TRUE, FALSE, FALSE), 100, TRUE) +#' ) |> +#' sankey_ready("first", "last") +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)] |> + dplyr::mutate(dplyr::across(!dplyr::where(is.factor), forcats::as_factor)) + + out <- dplyr::count(data, !!dplyr::sym(pri), !!dplyr::sym(sec), .drop = FALSE) + + out <- out |> + dplyr::group_by(!!dplyr::sym(pri)) |> + dplyr::mutate(gx.sum = sum(n)) |> + dplyr::ungroup() |> + dplyr::group_by(!!dplyr::sym(sec)) |> + dplyr::mutate(gy.sum = sum(n)) |> + 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, ")")) + ) + } 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), "%)")) + ) + } + + if (is.factor(data[[pri]])) { + index <- match(levels(data[[pri]]), str_remove_last(levels(out$lx), "\n")) + out$lx <- factor(out$lx, levels = levels(out$lx)[index]) + } + + if (is.factor(data[[sec]])) { + index <- match(levels(data[[sec]]), str_remove_last(levels(out$ly), "\n")) + out$ly <- factor(out$ly, levels = levels(out$ly)[index]) + } + + out +} + +str_remove_last <- function(data, pattern = "\n") { + strsplit(data, split = pattern) |> + lapply(\(.x)paste(unlist(.x[[-length(.x)]]), collapse = pattern)) |> + unlist() +} + +#' Beautiful sankey plot with option to split by a tertiary group +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' ds <- data.frame(g = sample(LETTERS[1:2], 100, TRUE), first = REDCapCAST::as_factor(sample(letters[1:4], 100, TRUE)), last = REDCapCAST::as_factor(sample(letters[1:4], 100, TRUE))) +#' ds |> plot_sankey("first", "last") +#' ds |> plot_sankey("first", "last", color.group = "sec") +#' ds |> plot_sankey("first", "last", ter = "g", color.group = "sec") +#' mtcars |> +#' default_parsing() |> +#' plot_sankey("cyl", "gear", "am", color.group = "pri") +#' ## In this case, the last plot as the secondary variable in wrong order +#' ## 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) { + 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) + }) + + patchwork::wrap_plots(out) +} + +#' Beautiful sankey plot +#' +#' @param color.group set group to colour by. "x" or "y". +#' @param colors optinally specify colors. Give NA color, color for each level +#' in primary group and color for each level in secondary group. +#' @param ... passed to sankey_ready() +#' +#' @returns ggplot2 object +#' @export +#' +#' @examples +#' ds <- data.frame(g = sample(LETTERS[1:2], 100, TRUE), first = REDCapCAST::as_factor(sample(letters[1:4], 100, TRUE)), last = REDCapCAST::as_factor(sample(letters[1:4], 100, TRUE))) +#' ds |> plot_sankey_single("first", "last") +#' ds |> plot_sankey_single("first", "last", color.group = "sec") +#' data.frame( +#' g = sample(LETTERS[1:2], 100, TRUE), +#' first = REDCapCAST::as_factor(sample(letters[1:4], 100, TRUE)), +#' last = sample(c(TRUE, FALSE, FALSE), 100, TRUE) +#' ) |> +#' plot_sankey_single("first", "last", color.group = "pri") +#' mtcars |> +#' default_parsing() |> +#' plot_sankey_single("cyl", "vs", color.group = "pri") +plot_sankey_single <- function(data, pri, sec, color.group = c("pri", "sec"), colors = NULL, ...) { + color.group <- match.arg(color.group) + + data_orig <- data + data[c(pri, sec)] <- data[c(pri, sec)] |> + dplyr::mutate(dplyr::across(dplyr::where(is.factor), forcats::fct_drop)) + + # browser() + + data <- data |> sankey_ready(pri = pri, sec = sec, ...) + + na.color <- "#2986cc" + box.color <- "#1E4B66" + + 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]]))] + + secondary.colors <- rep(na.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]]))] + + secondary.colors <- rep(na.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) + } else { + label.colors <- contrast_text(colors) + } + + group_labels <- c(get_label(data, pri), get_label(data, sec)) |> + sapply(line_break) |> + unname() + + p <- ggplot2::ggplot(data, ggplot2::aes(y = n, axis1 = lx, axis2 = ly)) + + if (color.group == "sec") { + p <- p + + ggalluvial::geom_alluvium( + ggplot2::aes( + fill = !!dplyr::sym(sec) # , + ## Including will print strings when levels are empty + # color = !!dplyr::sym(sec) + ), + width = 1 / 16, + alpha = .8, + knot.pos = 0.4, + curve_type = "sigmoid" + ) + ggalluvial::geom_stratum(ggplot2::aes(fill = !!dplyr::sym(sec)), + size = 2, + width = 1 / 3.4 + ) + } else { + p <- p + + ggalluvial::geom_alluvium( + ggplot2::aes( + fill = !!dplyr::sym(pri) # , + # color = !!dplyr::sym(pri) + ), + width = 1 / 16, + alpha = .8, + knot.pos = 0.4, + curve_type = "sigmoid" + ) + ggalluvial::geom_stratum(ggplot2::aes(fill = !!dplyr::sym(pri)), + size = 2, + width = 1 / 3.4 + ) + } + + ## Will fail to use stat="stratum" if library is not loaded. + library(ggalluvial) + p + + ggplot2::geom_text( + stat = "stratum", + ggplot2::aes(label = after_stat(stratum)), + colour = label.colors, + size = 8, + lineheight = 1 + ) + + 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() + + ggplot2::theme( + legend.position = "none", + # panel.grid.major = element_blank(), + # panel.grid.minor = element_blank(), + # axis.text.y = element_blank(), + # axis.title.y = element_blank(), + axis.text.x = ggplot2::element_text(size = 20), + # text = element_text(size = 5), + # plot.title = element_blank(), + # panel.background = ggplot2::element_rect(fill = "white"), + plot.background = ggplot2::element_rect(fill = "white"), + panel.border = ggplot2::element_blank() + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot_scatter.R +######## + +#' Beautiful violin plot +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' mtcars |> plot_scatter(pri = "mpg", sec = "wt") +plot_scatter <- function(data, pri, sec, ter = NULL) { + if (is.null(ter)) { + rempsyc::nice_scatter( + data = data, + predictor = sec, + response = pri, + xtitle = get_label(data, var = sec), + ytitle = get_label(data, var = pri) + ) + } else { + rempsyc::nice_scatter( + data = data, + predictor = sec, + response = pri, + group = ter, + xtitle = get_label(data, var = sec), + ytitle = get_label(data, var = pri) + ) + } +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot_violin.R +######## + +#' Beatiful violin plot +#' +#' @returns ggplot2 object +#' @export +#' +#' @name data-plots +#' +#' @examples +#' mtcars |> plot_violin(pri = "mpg", sec = "cyl", ter = "gear") +plot_violin <- function(data, pri, sec, ter = NULL) { + if (!is.null(ter)) { + ds <- split(data, data[ter]) + } else { + ds <- list(data) + } + + out <- lapply(ds, \(.ds){ + rempsyc::nice_violin( + data = .ds, + group = sec, + response = pri, + xtitle = get_label(data, var = sec), + ytitle = get_label(data, var = pri) + ) + }) + + wrap_plot_list(out) + # patchwork::wrap_plots(out,guides = "collect") +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//plot-download-module.R +######## + +plot_download_ui <- regression_ui <- function(id, ...) { + ns <- shiny::NS(id) + + shiny::tagList( + shinyWidgets::noUiSliderInput( + inputId = ns("plot_height"), + label = "Plot height (mm)", + min = 50, + max = 300, + value = 100, + step = 1, + format = shinyWidgets::wNumbFormat(decimals = 0), + color = datamods:::get_primary_color() + ), + shinyWidgets::noUiSliderInput( + inputId = ns("plot_width"), + label = "Plot width (mm)", + min = 50, + max = 300, + value = 100, + step = 1, + format = shinyWidgets::wNumbFormat(decimals = 0), + color = datamods:::get_primary_color() + ), + shiny::selectInput( + inputId = ns("plot_type"), + label = "File format", + choices = list( + "png", + "tiff", + "eps", + "pdf", + "jpeg", + "svg" + ) + ), + shiny::br(), + # Button + shiny::downloadButton( + outputId = ns("download_plot"), + label = "Download plot", + icon = shiny::icon("download") + ) + ) +} + +plot_download_server <- function(id, + data, + file_name = "reg_plot", + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + # ns <- session$ns + + + + output$download_plot <- shiny::downloadHandler( + filename = paste0(file_name, ".", input$plot_type), + content = function(file) { + shiny::withProgress(message = "Saving the plot. Hold on for a moment..", { + ggplot2::ggsave( + filename = file, + plot = data, + width = input$plot_width, + height = input$plot_height, + dpi = 300, + units = "mm", scale = 2 + ) + }) + } + ) + } + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//redcap_read_shiny_module.R +######## + +#' Shiny module to browser and export REDCap data +#' +#' @param id Namespace id +#' @param include_title logical to include title +#' +#' @rdname redcap_read_shiny_module +#' +#' @return shiny ui element +#' @export +m_redcap_readUI <- function(id, title = TRUE, url = NULL) { + ns <- shiny::NS(id) + + if (isTRUE(title)) { + title <- shiny::tags$h4( + "Import data from REDCap", + class = "redcap-module-title" + ) + } + + server_ui <- shiny::tagList( + shiny::tags$h4("REDCap server"), + shiny::textInput( + inputId = ns("uri"), + label = "Web address", + value = if_not_missing(url, "https://redcap.your.institution/"), + width = "100%" + ), + shiny::helpText("Format should be either 'https://redcap.your.institution/' or 'https://your.institution/redcap/'"), + # shiny::textInput( + # inputId = ns("api"), + # label = "API token", + # value = "", + # width = "100%" + # ), + shiny::passwordInput( + inputId = ns("api"), + label = "API token", + value = "", + width = "100%" + ), + shiny::helpText("The token is a string of 32 numbers and letters."), + shiny::br(), + shiny::br(), + shiny::actionButton( + inputId = ns("data_connect"), + label = "Connect", + icon = shiny::icon("link", lib = "glyphicon"), + width = "100%", + disabled = TRUE + ), + shiny::br(), + shiny::br(), + tags$div( + id = ns("connect-placeholder"), + shinyWidgets::alert( + id = ns("connect-result"), + status = "info", + tags$p(phosphoricons::ph("info", weight = "bold"), "Please fill in server address (URI) and API token, then press 'Connect'.") + ), + dismissible = TRUE + ), + shiny::br() + ) + + filter_ui <- + shiny::tagList( + # width = 6, + shiny::uiOutput(outputId = ns("arms")), + shiny::textInput( + inputId = ns("filter"), + label = "Optional filter logic (e.g., ⁠[gender] = 'female')" + ) + ) + + params_ui <- + shiny::tagList( + shiny::tags$h4("Data import parameters"), + shiny::tags$div( + style = htmltools::css( + display = "grid", + gridTemplateColumns = "1fr 50px", + gridColumnGap = "10px" + ), + shiny::uiOutput(outputId = ns("fields")), + shiny::tags$div( + class = "shiny-input-container", + shiny::tags$label( + class = "control-label", + `for` = ns("dropdown_params"), + "...", + style = htmltools::css(visibility = "hidden") + ), + shinyWidgets::dropMenu( + shiny::actionButton( + inputId = ns("dropdown_params"), + label = shiny::icon("filter"), + width = "50px" + ), + filter_ui + ) + ) + ), + shiny::helpText("Select fields/variables to import and click the funnel to apply optional filters"), + shiny::tags$br(), + shiny::tags$br(), + shiny::uiOutput(outputId = ns("data_type")), + shiny::uiOutput(outputId = ns("fill")), + shiny::actionButton( + inputId = ns("data_import"), + label = "Import", + icon = shiny::icon("download", lib = "glyphicon"), + width = "100%", + disabled = TRUE + ), + shiny::tags$br(), + shiny::tags$br(), + tags$div( + id = ns("retrieved-placeholder"), + shinyWidgets::alert( + id = ns("retrieved-result"), + status = "info", + tags$p(phosphoricons::ph("info", weight = "bold"), "Please specify data to download, then press 'Import'.") + ), + dismissible = TRUE + ) + ) + + + shiny::fluidPage( + title = title, + server_ui, + # shiny::uiOutput(ns("params_ui")), + shiny::conditionalPanel( + condition = "output.connect_success == true", + params_ui, + ns = ns + ), + shiny::br() + ) +} + + +#' @rdname redcap_read_shiny_module +#' +#' @return shiny server module +#' @export +#' +m_redcap_readServer <- function(id) { + module <- function(input, output, session) { + ns <- session$ns + + data_rv <- shiny::reactiveValues( + dd_status = NULL, + data_status = NULL, + uri = NULL, + project_name = NULL, + info = NULL, + arms = NULL, + dd_list = NULL, + data = NULL, + rep_fields = NULL, + code = NULL + ) + + shiny::observeEvent(list(input$api, input$uri), { + shiny::req(input$api) + shiny::req(input$uri) + if (!is.null(input$uri)) { + uri <- paste0(ifelse(endsWith(input$uri, "/"), input$uri, paste0(input$uri, "/")), "api/") + } else { + uri <- input$uri + } + + if (is_valid_redcap_url(uri) & is_valid_token(input$api)) { + data_rv$uri <- uri + shiny::updateActionButton(inputId = "data_connect", disabled = FALSE) + } else { + shiny::updateActionButton(inputId = "data_connect", disabled = TRUE) + } + }) + + + tryCatch( + { + shiny::observeEvent( + list( + input$data_connect + ), + { + shiny::req(input$api) + shiny::req(data_rv$uri) + + parameters <- list( + redcap_uri = data_rv$uri, + token = input$api + ) + + # browser() + shiny::withProgress( + { + imported <- try(rlang::exec(REDCapR::redcap_metadata_read, !!!parameters), silent = TRUE) + }, + message = paste("Connecting to", data_rv$uri) + ) + + ## TODO: Simplify error messages + if (inherits(imported, "try-error") || NROW(imported) < 1 || ifelse(is.list(imported), !isTRUE(imported$success), FALSE)) { + if (ifelse(is.list(imported), !isTRUE(imported$success), FALSE)) { + mssg <- imported$raw_text + } else { + mssg <- attr(imported, "condition")$message + } + + datamods:::insert_error(mssg = mssg, selector = "connect") + data_rv$dd_status <- "error" + data_rv$dd_list <- NULL + } else if (isTRUE(imported$success)) { + data_rv$dd_status <- "success" + + data_rv$info <- REDCapR::redcap_project_info_read( + redcap_uri = data_rv$uri, + token = input$api + )$data + + datamods:::insert_alert( + selector = ns("connect"), + status = "success", + include_data_alert( + see_data_text = "Click to see data dictionary", + dataIdName = "see_dd", + extra = tags$p( + tags$b(phosphoricons::ph("check", weight = "bold"), "Connected to server!"), + glue::glue("The {data_rv$info$project_title} project is loaded.") + ), + btn_show_data = TRUE + ) + ) + + data_rv$dd_list <- imported + } + }, + ignoreInit = TRUE + ) + }, + warning = function(warn) { + showNotification(paste0(warn), type = "warning") + }, + error = function(err) { + showNotification(paste0(err), type = "err") + } + ) + + output$connect_success <- shiny::reactive(identical(data_rv$dd_status, "success")) + shiny::outputOptions(output, "connect_success", suspendWhenHidden = FALSE) + + + shiny::observeEvent(input$see_dd, { + show_data( + purrr::pluck(data_rv$dd_list, "data"), + title = "Data dictionary", + type = "modal", + show_classes = FALSE, + tags$b("Preview:") + ) + }) + + shiny::observeEvent(input$see_data, { + show_data( + # purrr::pluck(data_rv$dd_list, "data"), + data_rv$data, + title = "Imported data set", + type = "modal", + show_classes = FALSE, + tags$b("Preview:") + ) + }) + + arms <- shiny::reactive({ + shiny::req(input$api) + shiny::req(data_rv$uri) + + REDCapR::redcap_event_read( + redcap_uri = data_rv$uri, + token = input$api + )$data + }) + + output$fields <- shiny::renderUI({ + shiny::req(data_rv$dd_list) + shinyWidgets::virtualSelectInput( + inputId = ns("fields"), + label = "Select fields/variables to import:", + choices = purrr::pluck(data_rv$dd_list, "data") |> + dplyr::select(field_name, form_name) |> + (\(.x){ + split(.x$field_name, REDCapCAST::as_factor(.x$form_name)) + })(), + updateOn = "change", + multiple = TRUE, + search = TRUE, + showValueAsTags = TRUE, + width = "100%" + ) + }) + + output$data_type <- shiny::renderUI({ + shiny::req(data_rv$info) + if (isTRUE(data_rv$info$has_repeating_instruments_or_events)) { + vectorSelectInput( + inputId = ns("data_type"), + label = "Specify the data format", + choices = c( + "Wide data (One row for each subject)" = "wide", + "Long data for project with repeating instruments (default REDCap)" = "long" + ), + selected = "wide", + multiple = FALSE, + width = "100%" + ) + } + }) + + output$fill <- shiny::renderUI({ + shiny::req(data_rv$info) + shiny::req(input$data_type) + + ## Get repeated field + data_rv$rep_fields <- data_rv$dd_list$data$field_name[ + data_rv$dd_list$data$form_name %in% repeated_instruments( + uri = data_rv$uri, + token = input$api + ) + ] + + if (input$data_type == "long" && isTRUE(any(input$fields %in% data_rv$rep_fields))) { + vectorSelectInput( + inputId = ns("fill"), + label = "Fill missing values?", + choices = c( + "Yes, fill missing, non-repeated values" = "yes", + "No, leave the data as is" = "no" + ), + selected = "no", + multiple = FALSE, + width = "100%" + ) + } + }) + + shiny::observeEvent(input$fields, { + if (is.null(input$fields) | length(input$fields) == 0) { + shiny::updateActionButton(inputId = "data_import", disabled = TRUE) + } else { + shiny::updateActionButton(inputId = "data_import", disabled = FALSE) + } + }) + + output$arms <- shiny::renderUI({ + if (NROW(arms()) > 0) { + vectorSelectInput( + inputId = ns("arms"), + selected = NULL, + label = "Filter by events/arms", + choices = stats::setNames(arms()[[3]], arms()[[1]]), + multiple = TRUE, + width = "100%" + ) + } + }) + + shiny::observeEvent(input$data_import, { + shiny::req(input$fields) + + # browser() + record_id <- purrr::pluck(data_rv$dd_list, "data")[[1]][1] + + + parameters <- list( + uri = data_rv$uri, + token = input$api, + fields = unique(c(record_id, input$fields)), + events = input$arms, + raw_or_label = "both", + filter_logic = input$filter, + split_forms = ifelse( + input$data_type == "long" && !is.null(input$data_type), + "none", + "all" + ) + ) + + shiny::withProgress(message = "Downloading REDCap data. Hold on for a moment..", { + imported <- try(rlang::exec(REDCapCAST::read_redcap_tables, !!!parameters), silent = TRUE) + }) + + parameters_code <- parameters[c("uri", "fields", "events", "raw_or_label", "filter_logic")] + + code <- rlang::call2( + "easy_redcap", + !!!utils::modifyList( + parameters_code, + list( + data_format = ifelse( + input$data_type == "long" && !is.null(input$data_type), + "long", + "wide" + ), + project.name = simple_snake(data_rv$info$project_title) + ) + ), + .ns = "REDCapCAST" + ) + + if (inherits(imported, "try-error") || NROW(imported) < 1) { + data_rv$data_status <- "error" + data_rv$data_list <- NULL + data_rv$data_message <- imported$raw_text + } else { + data_rv$data_status <- "success" + data_rv$data_message <- "Requested data was retrieved!" + + ## The data management below should be separated to allow for changing + ## "wide"/"long" without re-importing data + + if (parameters$split_form == "all") { + # browser() + out <- imported |> + # redcap_wider() + REDCapCAST::redcap_wider() + } else { + if (input$fill == "yes") { + ## Repeated fields + + + ## Non-repeated fields in current dataset + inc_non_rep <- names(imported)[!names(imported) %in% data_rv$rep_fields] + + out <- imported |> + drop_empty_event() |> + dplyr::group_by(!!dplyr::sym(names(imported)[1])) |> + tidyr::fill(inc_non_rep) |> + dplyr::ungroup() + } else { + out <- imported |> + drop_empty_event() + } + } + + # browser() + in_data_check <- parameters$fields %in% names(out) | + sapply(names(out), \(.x) any(sapply(parameters$fields, \(.y) startsWith(.x, .y)))) + + if (!any(in_data_check[-1])) { + data_rv$data_status <- "warning" + data_rv$data_message <- "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." + } + + if (!all(in_data_check)) { + data_rv$data_status <- "warning" + data_rv$data_message <- "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_rv$code <- code + + data_rv$data <- out |> + dplyr::select(-dplyr::ends_with("_complete")) |> + # dplyr::select(-dplyr::any_of(record_id)) |> + REDCapCAST::suffix2label() + } + }) + + shiny::observeEvent( + data_rv$data_status, + { + # browser() + if (identical(data_rv$data_status, "error")) { + datamods:::insert_error(mssg = data_rv$data_message, selector = ns("retrieved")) + } else if (identical(data_rv$data_status, "success")) { + datamods:::insert_alert( + selector = ns("retrieved"), + status = data_rv$data_status, + # tags$p( + # tags$b(phosphoricons::ph("check", weight = "bold"), "Success!"), + # data_rv$data_message + # ), + include_data_alert( + see_data_text = "Click to see the imported data", + dataIdName = "see_data", + extra = tags$p( + tags$b(phosphoricons::ph("check", weight = "bold"), data_rv$data_message) + ), + btn_show_data = TRUE + ) + ) + } else { + datamods:::insert_alert( + selector = ns("retrieved"), + status = data_rv$data_status, + tags$p( + tags$b(phosphoricons::ph("warning", weight = "bold"), "Warning!"), + data_rv$data_message + ) + ) + } + } + ) + + return(list( + status = shiny::reactive(data_rv$data_status), + name = shiny::reactive(data_rv$info$project_title), + info = shiny::reactive(data_rv$info), + code = shiny::reactive(data_rv$code), + data = shiny::reactive(data_rv$data) + )) + } + + shiny::moduleServer( + id = id, + module = module + ) +} + +#' @importFrom htmltools tagList tags +#' @importFrom shiny icon getDefaultReactiveDomain +include_data_alert <- function(dataIdName = "see_data", + btn_show_data, + see_data_text = "Click to see data", + extra = NULL, + session = shiny::getDefaultReactiveDomain()) { + if (isTRUE(btn_show_data)) { + success_message <- tagList( + extra, + tags$br(), + shiny::actionLink( + inputId = session$ns(dataIdName), + label = tagList(phosphoricons::ph("book-open-text"), see_data_text) + ) + ) + } + return(success_message) +} + +# #' REDCap import teal data module +# #' +# #' @rdname redcap_read_shiny_module +# tdm_redcap_read <- teal::teal_data_module( +# ui <- function(id) { +# shiny::fluidPage( +# m_redcap_readUI(id) +# ) +# }, +# server = function(id) { +# m_redcap_readServer(id, output.format = "teal") +# } +# ) + + +#' Test if url is valid format for REDCap API +#' +#' @param url url +#' +#' @returns logical +#' @export +#' +#' @examples +#' url <- c( +#' "www.example.com", +#' "redcap.your.inst/api/", +#' "https://redcap.your.inst/api/", +#' "https://your.inst/redcap/api/", +#' "https://www.your.inst/redcap/api/" +#' ) +#' is_valid_redcap_url(url) +is_valid_redcap_url <- function(url) { + pattern <- "https://[^ /$.?#].[^\\s]*/api/$" + stringr::str_detect(url, pattern) +} + +#' Validate REDCap token +#' +#' @param token token +#' @param pattern_env pattern +#' +#' @returns logical +#' @export +#' +#' @examples +#' token <- paste(sample(c(1:9, LETTERS[1:6]), 32, TRUE), collapse = "") +#' is_valid_token(token) +is_valid_token <- function(token, pattern_env = NULL, nchar = 32) { + checkmate::assert_character(token, any.missing = TRUE, len = 1) + + if (!is.null(pattern_env)) { + checkmate::assert_character(pattern_env, + any.missing = FALSE, + len = 1 + ) + pattern <- pattern_env + } else { + pattern <- glue::glue("^([0-9A-Fa-f]{})(?:\\n)?$", + .open = "<", + .close = ">" + ) + } + + if (is.na(token)) { + out <- FALSE + } else if (is.null(token)) { + out <- FALSE + } else if (nchar(token) == 0L) { + out <- FALSE + } else if (!grepl(pattern, token, perl = TRUE)) { + out <- FALSE + } else { + out <- TRUE + } + out +} + +#' Get names of repeated instruments +#' +#' @param uri REDCap database uri +#' @param token database token +#' +#' @returns vector +#' @export +#' +repeated_instruments <- function(uri, token) { + instruments <- REDCapR::redcap_event_instruments(redcap_uri = uri, token = token) + unique(instruments$data$form[duplicated(instruments$data$form)]) +} + +#' Drop empty events from REDCap export +#' +#' @param data data +#' @param event "redcap_event_name", "redcap_repeat_instrument" or +#' "redcap_repeat_instance" +#' +#' @returns data.frame +#' @export +#' +drop_empty_event <- function(data, event = "redcap_event_name") { + generics <- c(names(data)[1], "redcap_event_name", "redcap_repeat_instrument", "redcap_repeat_instance") + + filt <- split(data, data[[event]]) |> + lapply(\(.x){ + dplyr::select(.x, -tidyselect::all_of(generics)) |> + REDCapCAST::all_na() + }) |> + unlist() + + data[data[[event]] %in% names(filt)[!filt], ] +} + + +#' Test app for the redcap_read_shiny_module +#' +#' @rdname redcap_read_shiny_module +#' +#' @examples +#' \dontrun{ +#' redcap_demo_app() +#' } +redcap_demo_app <- function() { + ui <- shiny::fluidPage( + m_redcap_readUI("data", url = NULL), + DT::DTOutput("data"), + shiny::tags$b("Code:"), + shiny::verbatimTextOutput(outputId = "code") + ) + server <- function(input, output, session) { + data_val <- m_redcap_readServer(id = "data") + + output$data <- DT::renderDataTable( + { + shiny::req(data_val$data) + data_val$data() + }, + options = list( + scrollX = TRUE, + pageLength = 5 + ), + ) + output$code <- shiny::renderPrint({ + shiny::req(data_val$code) + data_val$code() + }) + } + shiny::shinyApp(ui, server) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//regression_model.R +######## + +#' Create a regression model programatically +#' +#' @param data data set +#' @param fun Name of function as character vector or function to use for model creation. +#' @param vars character vector of variables to include +#' @param outcome.str Name of outcome variable. Character vector. +#' @param auto.mode Make assumptions on function dependent on outcome data format. Overwrites other arguments. +#' @param formula.str Formula as string. Passed through 'glue::glue'. If given, 'outcome.str' and 'vars' are ignored. Optional. +#' @param args.list List of arguments passed to 'fun' with 'do.call'. +#' @param ... ignored for now +#' +#' @importFrom stats as.formula +#' +#' @return object of standard class for fun +#' @export +#' @rdname regression_model +#' +#' @examples +#' gtsummary::trial |> +#' regression_model(outcome.str = "age") +#' gtsummary::trial |> +#' regression_model( +#' outcome.str = "age", +#' auto.mode = FALSE, +#' fun = "stats::lm", +#' formula.str = "{outcome.str}~.", +#' args.list = NULL +#' ) +#' gtsummary::trial |> +#' default_parsing() |> +#' regression_model( +#' outcome.str = "trt", +#' auto.mode = FALSE, +#' fun = "stats::glm", +#' args.list = list(family = binomial(link = "logit")) +#' ) +#' m <- mtcars |> +#' default_parsing() |> +#' regression_model( +#' outcome.str = "mpg", +#' auto.mode = FALSE, +#' fun = "stats::lm", +#' formula.str = "{outcome.str}~{paste(vars,collapse='+')}", +#' args.list = NULL, +#' vars = c("mpg", "cyl") +#' ) +#' broom::tidy(m) +regression_model <- function(data, + outcome.str = NULL, + auto.mode = FALSE, + formula.str = NULL, + args.list = NULL, + fun = NULL, + vars = NULL, + ...) { + if (!is.null(formula.str)) { + if (formula.str == "") { + formula.str <- NULL + } + } + + ## This will handle if outcome is not in data for nicer shiny behavior + if (isTRUE(!outcome.str %in% names(data))) { + outcome.str <- names(data)[1] + print("Outcome variable is not in data, first column is used") + } + + if (!is.null(formula.str)) { + formula.glue <- glue::glue(formula.str) + outcome.str <- NULL + } else { + assertthat::assert_that(outcome.str %in% names(data), + msg = "Outcome variable is not present in the provided dataset" + ) + formula.glue <- glue::glue("{outcome.str}~{paste(vars,collapse='+')}") + } + + if (is.null(vars)) { + vars <- names(data)[!names(data) %in% outcome.str] + } else if (!is.null(outcome.str)) { + if (outcome.str %in% vars) { + vars <- vars[!vars %in% outcome.str] + } + data <- data |> dplyr::select(dplyr::all_of(c(vars, outcome.str))) + } + + # Formatting character variables as factor + # Improvement should add a missing vector to format as NA + data <- data |> + purrr::map(\(.x){ + if (is.character(.x)) { + suppressWarnings(REDCapCAST::as_factor(.x)) + } else { + .x + } + }) |> + dplyr::bind_cols(.name_repair = "unique_quiet") + + if (is.null(fun)) auto.mode <- TRUE + + if (isTRUE(auto.mode)) { + if (is.numeric(data[[outcome.str]])) { + fun <- "stats::lm" + } else if (is.factor(data[[outcome.str]])) { + if (length(levels(data[[outcome.str]])) == 2) { + fun <- "stats::glm" + args.list <- list(family = stats::binomial(link = "logit")) + } else if (length(levels(data[[outcome.str]])) > 2) { + fun <- "MASS::polr" + args.list <- list( + Hess = TRUE, + method = "logistic" + ) + } else { + stop("The provided output variable only has one level") + } + } else { + stop("Output variable should be either numeric or factor for auto.mode") + } + } + + assertthat::assert_that("character" %in% class(fun), + msg = "Please provide the function as a character vector." + ) + + out <- do.call( + getfun(fun), + c( + list( + data = data, + formula = as.formula(formula.glue) + ), + args.list + ) + ) + + # out <- REDCapCAST::set_attr(out,label = fun,attr = "fun.call") + + # Recreating the call + # out$call <- match.call(definition=eval(parse(text=fun)), call(fun, data = 'data',formula = as.formula(formula.str),args.list)) + + return(out) +} + +#' Create a regression model programatically +#' +#' @param data data set +#' @param fun Name of function as character vector or function to use for model creation. +#' @param vars character vector of variables to include +#' @param outcome.str Name of outcome variable. Character vector. +#' @param args.list List of arguments passed to 'fun' with 'do.call'. +#' @param ... ignored for now +#' +#' @importFrom stats as.formula +#' @rdname regression_model +#' +#' @return object of standard class for fun +#' @export +#' +#' @examples +#' \dontrun{ +#' gtsummary::trial |> +#' regression_model_uv(outcome.str = "age") +#' gtsummary::trial |> +#' regression_model_uv( +#' outcome.str = "age", +#' fun = "stats::lm", +#' args.list = NULL +#' ) +#' m <- gtsummary::trial |> regression_model_uv( +#' outcome.str = "trt", +#' fun = "stats::glm", +#' args.list = list(family = stats::binomial(link = "logit")) +#' ) +#' lapply(m, broom::tidy) |> dplyr::bind_rows() +#' } +regression_model_uv <- function(data, + outcome.str, + args.list = NULL, + fun = NULL, + vars = NULL, + ...) { + ## This will handle if outcome is not in data for nicer shiny behavior + if (!outcome.str %in% names(data)) { + outcome.str <- names(data)[1] + print("outcome is not in data, first column is used") + } + + if (!is.null(vars)) { + data <- data |> + dplyr::select(dplyr::all_of( + unique(c(outcome.str, vars)) + )) + } + + if (is.null(args.list)) { + args.list <- list() + } + + if (is.null(fun)) { + if (is.numeric(data[[outcome.str]])) { + fun <- "stats::lm" + } else if (is.factor(data[[outcome.str]])) { + if (length(levels(data[[outcome.str]])) == 2) { + fun <- "stats::glm" + args.list <- list(family = stats::binomial(link = "logit")) + } else if (length(levels(data[[outcome.str]])) > 2) { + fun <- "MASS::polr" + args.list <- list( + Hess = TRUE, + method = "logistic" + ) + } else { + stop("The provided output variable only has one level") + } + } else { + stop("Output variable should be either numeric or factor for auto.mode") + } + } + + assertthat::assert_that("character" %in% class(fun), + msg = "Please provide the function as a character vector." + ) + + out <- names(data)[!names(data) %in% outcome.str] |> + purrr::map(\(.var){ + do.call( + regression_model, + c( + list( + data = data[match(c(outcome.str, .var), names(data))], + outcome.str = outcome.str + ), + args.list + ) + ) + }) + + return(out) +} + + +### HELPERS + +#' Data type assessment. +#' +#' @description +#' These are more overall than the native typeof. This is used to assess a more +#' meaningful "clinical" data type. +#' +#' @param data vector or data.frame. if data frame, each column is evaluated. +#' +#' @returns outcome type +#' @export +#' +#' @examples +#' mtcars |> +#' default_parsing() |> +#' lapply(data_type) +#' mtcars |> +#' default_parsing() |> +#' data_type() +#' c(1, 2) |> data_type() +#' 1 |> data_type() +#' c(rep(NA, 10)) |> data_type() +#' sample(1:100, 50) |> data_type() +#' factor(letters[1:20]) |> data_type() +#' as.Date(1:20) |> data_type() +data_type <- function(data) { + if (is.data.frame(data)) { + sapply(data, data_type) + } else { + cl_d <- class(data) + l_unique <- length(unique(na.omit(data))) + if (all(is.na(data))) { + out <- "empty" + } else if (l_unique < 2) { + out <- "monotone" + } else if (any(c("factor", "logical") %in% cl_d) | l_unique == 2) { + if (identical("logical", cl_d) | l_unique == 2) { + out <- "dichotomous" + } else { + # if (is.ordered(data)) { + # out <- "ordinal" + # } else { + out <- "categorical" + # } + } + } else if (identical(cl_d, "character")) { + out <- "text" + } else if (any(c("hms", "Date", "POSIXct", "POSIXt") %in% cl_d)) { + out <- "datetime" + } else if (l_unique > 2) { + ## Previously had all thinkable classes + ## Now just assumes the class has not been defined above + ## any(c("numeric", "integer", "hms", "Date", "timediff") %in% cl_d) & + out <- "continuous" + } else { + out <- "unknown" + } + + out + } +} + +#' Recognised data types from data_type +#' +#' @returns vector +#' @export +#' +#' @examples +#' data_types() +data_types <- function() { + list( + "empty" = list(descr="Variable of all NAs",classes="Any class"), + "monotone" = list(descr="Variable with only one unique value",classes="Any class"), + "dichotomous" = list(descr="Variable with only two unique values",classes="Any class"), + "categorical"= list(descr="Factor variable",classes="factor (ordered or unordered)"), + "text"= list(descr="Character variable",classes="character"), + "datetime"= list(descr="Variable of time, date or datetime values",classes="hms, Date, POSIXct and POSIXt"), + "continuous"= list(descr="Numeric variable",classes="numeric, integer or double"), + "unknown"= list(descr="Anything not falling within the previous",classes="Any other class") + ) +} + + +#' Implemented functions +#' +#' @description +#' Library of supported functions. The list name and "descr" element should be +#' unique for each element on list. +#' +#' +#' @returns list +#' @export +#' +#' @examples +#' supported_functions() +supported_functions <- function() { + list( + lm = list( + descr = "Linear regression model", + design = "cross-sectional", + out.type = "continuous", + fun = "stats::lm", + args.list = NULL, + formula.str = "{outcome.str}~{paste(vars,collapse='+')}", + table.fun = "gtsummary::tbl_regression", + table.args.list = list(exponentiate = FALSE) + ), + glm = list( + descr = "Logistic regression model", + design = "cross-sectional", + out.type = "dichotomous", + fun = "stats::glm", + args.list = list(family = "binomial"), + formula.str = "{outcome.str}~{paste(vars,collapse='+')}", + table.fun = "gtsummary::tbl_regression", + table.args.list = list() + ), + polr = list( + descr = "Ordinal logistic regression model", + design = "cross-sectional", + out.type = c("categorical"), + fun = "MASS::polr", + args.list = list( + Hess = TRUE, + method = "logistic" + ), + formula.str = "{outcome.str}~{paste(vars,collapse='+')}", + table.fun = "gtsummary::tbl_regression", + table.args.list = list() + ) + ) +} + + +#' Get possible regression models +#' +#' @param data data +#' +#' @returns character vector +#' @export +#' +#' @examples +#' mtcars |> +#' default_parsing() |> +#' dplyr::pull("cyl") |> +#' possible_functions(design = "cross-sectional") +#' +#' mtcars |> +#' default_parsing() |> +#' dplyr::select("cyl") |> +#' possible_functions(design = "cross-sectional") +possible_functions <- function(data, design = c("cross-sectional")) { + # + # data <- if (is.reactive(data)) data() else data + if (is.data.frame(data)) { + data <- data[[1]] + } + + design <- match.arg(design) + type <- data_type(data) + + design_ls <- supported_functions() |> + lapply(\(.x){ + if (design %in% .x$design) { + .x + } + }) + + if (type == "unknown") { + out <- type + } else { + out <- design_ls |> + lapply(\(.x){ + if (type %in% .x$out.type) { + .x$descr + } + }) |> + unlist() + } + unname(out) +} + + +#' Get the function options based on the selected function description +#' +#' @param data vector +#' +#' @returns list +#' @export +#' +#' @examples +#' mtcars |> +#' default_parsing() |> +#' dplyr::pull(mpg) |> +#' possible_functions(design = "cross-sectional") |> +#' (\(.x){ +#' .x[[1]] +#' })() |> +#' get_fun_options() +get_fun_options <- function(data) { + descrs <- supported_functions() |> + lapply(\(.x){ + .x$descr + }) |> + unlist() + supported_functions() |> + (\(.x){ + .x[match(data, descrs)] + })() +} + + +#' Wrapper to create regression model based on supported models +#' +#' @description +#' Output is a concatenated list of model information and model +#' +#' +#' @param data data +#' @param outcome.str name of outcome variable +#' @param fun.descr Description of chosen function matching description in +#' "supported_functions()" +#' @param fun name of custom function. Default is NULL. +#' @param formula.str custom formula glue string. Default is NULL. +#' @param args.list custom character string to be converted using +#' argsstring2list() or list of arguments. Default is NULL. +#' @param ... ignored +#' +#' @returns list +#' @export +#' @rdname regression_model +#' +#' @examples +#' \dontrun{ +#' gtsummary::trial |> +#' regression_model( +#' outcome.str = "age", +#' fun = "stats::lm", +#' formula.str = "{outcome.str}~.", +#' args.list = NULL +#' ) +#' ls <- regression_model_list(data = default_parsing(mtcars), outcome.str = "cyl", fun.descr = "Ordinal logistic regression model") +#' summary(ls$model) +#' ls <- regression_model_list(data = default_parsing(mtcars), outcome.str = "mpg", fun.descr = "Linear regression model") +#' +#' ls <- regression_model_list(data = default_parsing(gtsummary::trial), outcome.str = "trt", fun.descr = "Logistic regression model") +#' tbl <- gtsummary::tbl_regression(ls$model, exponentiate = TRUE) +#' m <- gtsummary::trial |> +#' default_parsing() |> +#' regression_model( +#' outcome.str = "trt", +#' fun = "stats::glm", +#' formula.str = "{outcome.str}~.", +#' args.list = list(family = "binomial") +#' ) +#' tbl2 <- gtsummary::tbl_regression(m, exponentiate = TRUE) +#' broom::tidy(ls$model) +#' broom::tidy(m) +#' } +regression_model_list <- function(data, + outcome.str, + fun.descr, + fun = NULL, + formula.str = NULL, + args.list = NULL, + vars = NULL, + ...) { + options <- get_fun_options(fun.descr) |> + (\(.x){ + .x[[1]] + })() + + ## Custom, specific fun, args and formula options + + if (is.null(formula.str)) { + formula.str.c <- options$formula.str + } else { + formula.str.c <- formula.str + } + + if (is.null(fun)) { + fun.c <- options$fun + } else { + fun.c <- fun + } + + if (is.null(args.list)) { + args.list.c <- options$args.list + } else { + args.list.c <- args.list + } + + if (is.character(args.list.c)) args.list.c <- argsstring2list(args.list.c) + + ## Handling vars to print code + + if (is.null(vars)) { + vars <- names(data)[!names(data) %in% outcome.str] + } else { + if (outcome.str %in% vars) { + vars <- vars[!vars %in% outcome.str] + } + } + + parameters <- list( + data = data, + fun = fun.c, + formula.str = glue::glue(formula.str.c), + args.list = args.list.c + ) + + model <- do.call( + regression_model, + parameters + ) + + parameters_code <- Filter( + length, + modifyList(parameters, list( + data = as.symbol("df"), + formula.str = as.character(glue::glue(formula.str.c)), + outcome.str = NULL + # args.list = NULL, + )) + ) + + ## The easiest solution was to simple paste as a string + ## The rlang::call2 or rlang::expr functions would probably work as well + # code <- glue::glue("FreesearchR::regression_model({parameters_print}, args.list=list({list2str(args.list.c)}))", .null = "NULL") + code <- rlang::call2("regression_model", !!!parameters_code, .ns = "FreesearchR") + + list( + options = options, + model = model, + code = expression_string(code) + ) +} + +list2str <- function(data) { + out <- purrr::imap(data, \(.x, .i){ + if (is.logical(.x)) { + arg <- .x + } else { + arg <- glue::glue("'{.x}'") + } + glue::glue("{.i} = {arg}") + }) |> + unlist() |> + paste(collapse = (", ")) + + if (out == "") { + return(NULL) + } else { + out + } +} + + +#' @returns list +#' @export +#' @rdname regression_model +#' +#' @examples +#' \dontrun{ +#' gtsummary::trial |> +#' regression_model_uv( +#' outcome.str = "trt", +#' fun = "stats::glm", +#' args.list = list(family = stats::binomial(link = "logit")) +#' ) |> +#' lapply(broom::tidy) |> +#' dplyr::bind_rows() +#' ms <- regression_model_uv_list(data = default_parsing(mtcars), outcome.str = "mpg", fun.descr = "Linear regression model") +#' ms$code +#' ls <- regression_model_uv_list(data = default_parsing(mtcars), outcome.str = "am", fun.descr = "Logistic regression model") +#' ls$code +#' lapply(ms$model, broom::tidy) |> dplyr::bind_rows() +#' } +regression_model_uv_list <- function(data, + outcome.str, + fun.descr, + fun = NULL, + formula.str = NULL, + args.list = NULL, + vars = NULL, + ...) { + options <- get_fun_options(fun.descr) |> + (\(.x){ + .x[[1]] + })() + + ## Custom, specific fun, args and formula options + + if (is.null(formula.str)) { + formula.str.c <- options$formula.str + } else { + formula.str.c <- formula.str + } + + if (is.null(fun)) { + fun.c <- options$fun + } else { + fun.c <- fun + } + + if (is.null(args.list)) { + args.list.c <- options$args.list + } else { + args.list.c <- args.list + } + + if (is.character(args.list.c)) args.list.c <- argsstring2list(args.list.c) + + ## Handling vars to print code + + if (is.null(vars)) { + vars <- names(data)[!names(data) %in% outcome.str] + } else { + if (outcome.str %in% vars) { + vars <- vars[!vars %in% outcome.str] + } + } + + # assertthat::assert_that("character" %in% class(fun), + # msg = "Please provide the function as a character vector." + # ) + + # model <- do.call( + # regression_model, + # c( + # list(data = data), + # list(outcome.str = outcome.str), + # list(fun = fun.c), + # list(formula.str = formula.str.c), + # args.list.c + # ) + # ) + + model <- vars |> + lapply(\(.var){ + parameters <- + list( + fun = fun.c, + data = data[c(outcome.str, .var)], + formula.str = as.character(glue::glue(gsub("vars", ".var", formula.str.c))), + args.list = args.list.c + ) + + out <- do.call( + regression_model, + parameters + ) + + ## This is the very long version + ## Handles deeply nested glue string + # code <- glue::glue("FreesearchR::regression_model(data=df,{list2str(modifyList(parameters,list(data=NULL,args.list=list2str(args.list.c))))})") + code <- rlang::call2("regression_model", !!!modifyList(parameters, list(data = as.symbol("df"), args.list = args.list.c)), .ns = "FreesearchR") + REDCapCAST::set_attr(out, code, "code") + }) + + code <- model |> + lapply(\(.x)REDCapCAST::get_attr(.x, "code")) |> + lapply(expression_string) |> + pipe_string(collapse = ",\n") |> + (\(.x){ + paste0("list(\n", .x, ")") + })() + + + list( + options = options, + model = model, + code = code + ) +} + + +# regression_model(mtcars, fun = "stats::lm", formula.str = "mpg~cyl") + + +######## +#### Current file: /Users/au301842/FreesearchR/R//regression_plot.R +######## + +#' Regression coef plot from gtsummary. Slightly modified to pass on arguments +#' +#' @param x (`tbl_regression`, `tbl_uvregression`)\cr +#' A 'tbl_regression' or 'tbl_uvregression' object +#' @param plot_ref (scalar `logical`)\cr +#' plot reference values +#' @param remove_header_rows (scalar `logical`)\cr +#' logical indicating whether to remove header rows +#' for categorical variables. Default is `TRUE` +#' @param remove_reference_rows (scalar `logical`)\cr +#' logical indicating whether to remove reference rows +#' for categorical variables. Default is `FALSE`. +#' @param ... arguments passed to `ggstats::ggcoef_plot(...)` +#' +#' @returns ggplot object +#' @export +#' +#' @examples +#' \dontrun{ +#' mod <- lm(mpg ~ ., default_parsing(mtcars)) +#' p <- mod |> +#' gtsummary::tbl_regression() |> +#' plot(colour = "variable") +#' } +#' +plot.tbl_regression <- function(x, + plot_ref = TRUE, + remove_header_rows = TRUE, + remove_reference_rows = FALSE, + ...) { + # check_dots_empty() + gtsummary:::check_pkg_installed("ggstats") + gtsummary:::check_not_missing(x) + # gtsummary:::check_scalar_logical(remove_header_rows) + # gtsummary:::check_scalar_logical(remove_reference_rows) + + df_coefs <- x$table_body + + if (isTRUE(remove_header_rows)) { + df_coefs <- df_coefs |> dplyr::filter(!header_row %in% TRUE) + } + if (isTRUE(remove_reference_rows)) { + df_coefs <- df_coefs |> dplyr::filter(!reference_row %in% TRUE) + } + + # Removes redundant label + df_coefs$label[df_coefs$row_type == "label"] <- "" + # browser() + # Add estimate value to reference level + if (plot_ref == TRUE) { + df_coefs[df_coefs$var_type %in% c("categorical", "dichotomous") & df_coefs$reference_row & !is.na(df_coefs$reference_row), "estimate"] <- if (x$inputs$exponentiate) 1 else 0 + } + + p <- df_coefs |> + ggstats::ggcoef_plot(exponentiate = x$inputs$exponentiate, ...) + + if (x$inputs$exponentiate) { + p <- symmetrical_scale_x_log10(p) + } + p +} + + +#' Wrapper to pivot gtsummary table data to long for plotting +#' +#' @param list a custom regression models list +#' @param model.names names of models to include +#' +#' @returns list +#' @export +#' +merge_long <- function(list, model.names) { + l_subset <- list$tables[model.names] + + l_merged <- l_subset |> tbl_merge() + + df_body <- l_merged$table_body + + sel_list <- lapply(seq_along(l_subset), \(.i){ + endsWith(names(df_body), paste0("_", .i)) + }) |> + setNames(names(l_subset)) + + common <- !Reduce(`|`, sel_list) + + df_body_long <- sel_list |> + purrr::imap(\(.l, .i){ + d <- dplyr::bind_cols( + df_body[common], + df_body[.l], + model = .i + ) + setNames(d, gsub("_[0-9]{,}$", "", names(d))) + }) |> + dplyr::bind_rows() |> + dplyr::mutate(model = REDCapCAST::as_factor(model)) + + l_merged$table_body <- df_body_long + + l_merged$inputs$exponentiate <- !identical(class(list$models$Multivariable$model), "lm") + + l_merged +} + + +#' Easily round log scale limits for nice plots +#' +#' @param data data +#' @param fun rounding function (floor/ceiling) +#' @param ... ignored +#' +#' @returns numeric vector +#' @export +#' +#' @examples +#' limit_log(-.1, floor) +#' limit_log(.1, ceiling) +#' limit_log(-2.1, ceiling) +#' limit_log(2.1, ceiling) +limit_log <- function(data, fun, ...) { + fun(10^-floor(data) * 10^data) / 10^-floor(data) +} + +#' Create summetric log ticks +#' +#' @param data numeric vector +#' +#' @returns numeric vector +#' @export +#' +#' @examples +#' c(sample(seq(.1, 1, .1), 3), sample(1:10, 3)) |> create_log_tics() +create_log_tics <- function(data) { + sort(round(unique(c(1 / data, data, 1)), 2)) +} + +#' Ensure symmetrical plot around 1 on a logarithmic x scale for ratio plots +#' +#' @param plot ggplot2 plot +#' @param breaks breaks used and mirrored +#' @param ... ignored +#' +#' @returns ggplot2 object +#' @export +#' +symmetrical_scale_x_log10 <- function(plot, breaks = c(1, 2, 3, 5, 10), ...) { + rx <- ggplot2::layer_scales(plot)$x$get_limits() + + x_min <- floor(10 * rx[1]) / 10 + x_max <- ceiling(10 * rx[2]) / 10 + + rx_min <- limit_log(rx[1], floor) + rx_max <- limit_log(rx[2], ceiling) + + max_abs_x <- max(abs(c(x_min, x_max))) + + ticks <- log10(breaks) + (ceiling(max_abs_x) - 1) + + plot + ggplot2::scale_x_log10(limits = c(rx_min, rx_max), breaks = create_log_tics(10^ticks[ticks <= max_abs_x])) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//regression_table.R +######## + +#' Create table of regression model +#' +#' @param x regression model +#' @param args.list list of arguments passed to 'fun'. +#' @param fun function to use for table creation. Default is "gtsummary::tbl_regression". +#' @param ... passed to methods +#' +#' @return object of standard class for fun +#' @export +#' @name regression_table +#' +#' @examples +#' \dontrun{ +#' tbl <- gtsummary::trial |> +#' regression_model( +#' outcome.str = "stage", +#' fun = "MASS::polr" +#' ) |> +#' regression_table(args.list = list("exponentiate" = TRUE)) +#' gtsummary::trial |> +#' regression_model( +#' outcome.str = "age", +#' fun = "stats::lm", +#' formula.str = "{outcome.str}~.", +#' args.list = NULL +#' ) |> +#' regression_table() |> +#' plot() +#' gtsummary::trial |> +#' regression_model( +#' outcome.str = "trt", +#' fun = "stats::glm", +#' args.list = list(family = binomial(link = "logit")) +#' ) |> +#' regression_table() +#' gtsummary::trial |> +#' regression_model_uv( +#' outcome.str = "trt", +#' fun = "stats::glm", +#' args.list = list(family = stats::binomial(link = "logit")) +#' ) |> +#' regression_table() +#' gtsummary::trial |> +#' regression_model_uv( +#' outcome.str = "stage", +#' args.list = list(family = stats::binomial(link = "logit")) +#' ) |> +#' regression_table() +#' mtcars|> +#' regression_model( +#' outcome.str = "mpg", +#' args.list = NULL) +#' ) |> +#' regression_table() +#' +#' +#' list( +#' "Univariable" = regression_model_uv, +#' "Multivariable" = regression_model +#' ) |> +#' lapply(\(.fun){ +#' do.call( +#' .fun, +#' c( +#' list(data = gtsummary::trial), +#' list(outcome.str = "stage") +#' ) +#' ) +#' }) |> +#' purrr::map(regression_table) |> +#' tbl_merge() +#' } +#' regression_table <- function(x, ...) { +#' UseMethod("regression_table") +#' } +#' +#' #' @rdname regression_table +#' #' @export +#' regression_table.list <- function(x, ...) { +#' x |> +#' purrr::map(\(.m){ +#' regression_table(x = .m, ...) |> +#' gtsummary::add_n() +#' }) |> +#' gtsummary::tbl_stack() +#' } +#' +#' #' @rdname regression_table +#' #' @export +#' regression_table.default <- function(x, ..., args.list = NULL, fun = "gtsummary::tbl_regression") { +#' # Stripping custom class +#' class(x) <- class(x)[class(x) != "freesearchr_model"] +#' +#' if (any(c(length(class(x)) != 1, class(x) != "lm"))) { +#' if (!"exponentiate" %in% names(args.list)) { +#' args.list <- c(args.list, list(exponentiate = TRUE)) +#' } +#' } +#' +#' out <- do.call(getfun(fun), c(list(x = x), args.list)) +#' out |> +#' gtsummary::add_glance_source_note() # |> +#' # gtsummary::bold_p() +#' } +regression_table <- function(x, ...) { + args <- list(...) + + if ("list" %in% class(x)) { + x |> + purrr::map(\(.m){ + regression_table_create(x = .m, args.list = args) |> + gtsummary::add_n() + }) |> + gtsummary::tbl_stack() + } else { + regression_table_create(x, args.list = args) + } +} + +#' Create regression summary table +#' +#' @param x (list of) regression model +#' @param ... ignored for now +#' @param args.list args.list for the summary function +#' @param fun table summary function. Default is "gtsummary::tbl_regression" +#' @param theme summary table theme +#' +#' @returns gtsummary list object +#' @export +#' +regression_table_create <- function(x, ..., args.list = NULL, fun = "gtsummary::tbl_regression", theme = c("jama", "lancet", "nejm", "qjecon")) { + # Stripping custom class + class(x) <- class(x)[class(x) != "freesearchr_model"] + + theme <- match.arg(theme) + + if (any(c(length(class(x)) != 1, class(x) != "lm"))) { + if (!"exponentiate" %in% names(args.list)) { + args.list <- c(args.list, list(exponentiate = TRUE, p.values = TRUE)) + } + } + + gtsummary::theme_gtsummary_journal(journal = theme) + if (inherits(x, "polr")) { + # browser() + out <- do.call(getfun(fun), c(list(x = x), args.list)) + # out <- do.call(getfun(fun), c(list(x = x, tidy_fun = list(residual_type = "normal")), args.list)) + # out <- do.call(what = getfun(fun), + # args = c( + # list( + # x = x, + # tidy_fun = list( + # conf.int = TRUE, + # conf.level = 0.95, + # residual_type = "normal")), + # args.list) + # ) + } else { + out <- do.call(getfun(fun), c(list(x = x), args.list)) + } + + out +} + + +#' A substitue to gtsummary::tbl_merge, that will use list names for the tab +#' spanner names. +#' +#' @param data gtsummary list object +#' +#' @return gt summary list object +#' @export +#' +tbl_merge <- function(data) { + if (is.null(names(data))) { + data |> gtsummary::tbl_merge() + } else { + data |> gtsummary::tbl_merge(tab_spanner = names(data)) + } +} + +# as_kable(tbl) |> write_lines(file=here::here("inst/apps/data_analysis_modules/www/_table1.md")) +# as_kable_extra(tbl)|> write_lines(file=here::here("inst/apps/data_analysis_modules/www/table1.md")) + + +######## +#### Current file: /Users/au301842/FreesearchR/R//regression-module.R +######## + +### On rewriting this module +### +### This module (and the plotting module) should be rewritten to allow for +### dynamically defining variable-selection for model evaluation. +### The principle of having a library of supported functions is fine, but should +### be expanded. +### +### + +# list( +# lm = list( +# descr = "Linear regression model", +# design = "cross-sectional", +# parameters=list( +# fun = "stats::lm", +# args.list = NULL +# ), +# variables = list( +# outcome.str = list( +# fun = "columnSelectInput", +# multiple = FALSE, +# label = "Select the dependent/outcome variable." +# ) +# ), +# out.type = "continuous", +# formula.str = "{outcome.str}~{paste(vars,collapse='+')}", +# table.fun = "gtsummary::tbl_regression", +# table.args.list = list(exponentiate = FALSE) +# )) +# +# Regarding the regression model, it really should be the design selection, +# that holds the input selection information, as this is what is deciding +# the number and type of primary inputs. +# +# Cross-sectional: outcome +# MMRM: outcome, random effect (id, time) +# Survival: time, status, strata(?) +# +# + + + +regression_ui <- function(id, ...) { + ns <- shiny::NS(id) + + shiny::tagList( + title = "", + sidebar = bslib::sidebar( + shiny::uiOutput(outputId = ns("data_info"), inline = TRUE), + bslib::accordion( + open = "acc_reg", + multiple = FALSE, + bslib::accordion_panel( + value = "acc_reg", + title = "Regression", + icon = bsicons::bs_icon("calculator"), + shiny::uiOutput(outputId = ns("outcome_var")), + # shiny::selectInput( + # inputId = "design", + # label = "Study design", + # selected = "no", + # inline = TRUE, + # choices = list( + # "Cross-sectional" = "cross-sectional" + # ) + # ), + shiny::uiOutput(outputId = ns("regression_type")), + shiny::radioButtons( + inputId = ns("all"), + label = "Specify covariables", + inline = TRUE, selected = 2, + choiceNames = c( + "Yes", + "No" + ), + choiceValues = c(1, 2) + ), + shiny::conditionalPanel( + condition = "input.all==1", + shiny::uiOutput(outputId = ns("regression_vars")), + shiny::helpText("If none are selected, all are included."), + shiny::tags$br(), + ns = ns + ), + bslib::input_task_button( + id = ns("load"), + label = "Analyse", + icon = bsicons::bs_icon("pencil"), + label_busy = "Working...", + icon_busy = fontawesome::fa_i("arrows-rotate", + class = "fa-spin", + "aria-hidden" = "true" + ), + type = "secondary", + auto_reset = TRUE + ), + shiny::helpText("Press 'Analyse' to create the regression model and after changing parameters."), + shiny::tags$br(), + shiny::radioButtons( + inputId = ns("add_regression_p"), + label = "Show p-value", + inline = TRUE, + selected = "yes", + choices = list( + "Yes" = "yes", + "No" = "no" + ) + ), + # shiny::tags$br(), + # shiny::radioButtons( + # inputId = ns("tbl_theme"), + # label = "Show p-value", + # inline = TRUE, + # selected = "jama", + # choices = list( + # "JAMA" = "jama", + # "Lancet" = "lancet", + # "NEJM" = "nejm" + # ) + # ), + shiny::tags$br() + ), + do.call( + bslib::accordion_panel, + c( + list( + value = "acc_plot", + title = "Coefficient plot", + icon = bsicons::bs_icon("bar-chart-steps"), + shiny::tags$br(), + shiny::uiOutput(outputId = ns("plot_model")) + ), + # plot_download_ui(ns("reg_plot_download")) + shiny::tagList( + shinyWidgets::noUiSliderInput( + inputId = ns("plot_height"), + label = "Plot height (mm)", + min = 50, + max = 300, + value = 100, + step = 1, + format = shinyWidgets::wNumbFormat(decimals = 0), + color = datamods:::get_primary_color() + ), + shinyWidgets::noUiSliderInput( + inputId = ns("plot_width"), + label = "Plot width (mm)", + min = 50, + max = 300, + value = 100, + step = 1, + format = shinyWidgets::wNumbFormat(decimals = 0), + color = datamods:::get_primary_color() + ), + shiny::selectInput( + inputId = ns("plot_type"), + label = "File format", + choices = list( + "png", + "tiff", + "eps", + "pdf", + "jpeg", + "svg" + ) + ), + shiny::br(), + # Button + shiny::downloadButton( + outputId = ns("download_plot"), + label = "Download plot", + icon = shiny::icon("download") + ) + ) + ) + ), + bslib::accordion_panel( + value = "acc_checks", + title = "Checks", + icon = bsicons::bs_icon("clipboard-check"), + shiny::uiOutput(outputId = ns("plot_checks")) + ) + ) + ), + bslib::nav_panel( + title = "Regression table", + gt::gt_output(outputId = ns("table2")) + ), + bslib::nav_panel( + title = "Coefficient plot", + shiny::plotOutput(outputId = ns("regression_plot"), height = "80vh") + ), + bslib::nav_panel( + title = "Model checks", + shiny::plotOutput(outputId = ns("check"), height = "90vh") + ) + ) +} + + +regression_server <- function(id, + data, + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + ns <- session$ns + + rv <- shiny::reactiveValues( + data = NULL, + plot = NULL, + check = NULL, + list = list() + ) + + data_r <- shiny::reactive({ + if (shiny::is.reactive(data)) { + data() + } else { + data + } + }) + + output$data_info <- shiny::renderUI({ + shiny::req(regression_vars()) + shiny::req(data_r()) + data_description(data_r()[regression_vars()]) + }) + + ############################################################################## + ######### + ######### Input fields + ######### + ############################################################################## + + ## Keep these "old" selection options as a simple alternative to the modification pane + + + output$regression_vars <- shiny::renderUI({ + columnSelectInput( + inputId = ns("regression_vars"), + selected = NULL, + label = "Covariables to include", + data = data_r(), + multiple = TRUE + ) + }) + + output$outcome_var <- shiny::renderUI({ + columnSelectInput( + inputId = ns("outcome_var"), + selected = NULL, + label = "Select outcome variable", + data = data_r(), + multiple = FALSE + ) + }) + + output$regression_type <- shiny::renderUI({ + shiny::req(input$outcome_var) + shiny::selectizeInput( + inputId = ns("regression_type"), + label = "Choose regression analysis", + ## The below ifelse statement handles the case of loading a new dataset + choices = possible_functions( + data = dplyr::select( + data_r(), + ifelse(input$outcome_var %in% names(data_r()), + input$outcome_var, + names(data_r())[1] + ) + ), design = "cross-sectional" + ), + multiple = FALSE + ) + }) + + output$factor_vars <- shiny::renderUI({ + shiny::selectizeInput( + inputId = ns("factor_vars"), + selected = colnames(data_r())[sapply(data_r(), is.factor)], + label = "Covariables to format as categorical", + choices = colnames(data_r()), + multiple = TRUE + ) + }) + + ## Collected regression variables + regression_vars <- shiny::reactive({ + if (is.null(input$regression_vars)) { + out <- colnames(data_r()) + } else { + out <- unique(c(input$regression_vars, input$outcome_var)) + } + return(out) + }) + + output$strat_var <- shiny::renderUI({ + columnSelectInput( + inputId = ns("strat_var"), + selected = "none", + label = "Select variable to stratify baseline", + data = data_r(), + col_subset = c( + "none", + names(data_r())[unlist(lapply(data_r(), data_type)) %in% c("dichotomous", "categorical", "ordinal")] + ) + ) + }) + + + output$plot_model <- shiny::renderUI({ + shiny::req(rv$list$regression$tables) + shiny::selectInput( + inputId = ns("plot_model"), + selected = 1, + label = "Select models to plot", + choices = names(rv$list$regression$tables), + multiple = TRUE + ) + }) + + ############################################################################## + ######### + ######### Regression models + ######### + ############################################################################## + + shiny::observeEvent( + input$load, + { + shiny::req(input$outcome_var) + + rv$list$regression$models <- NULL + + tryCatch( + { + ## Which models to create should be decided by input + ## Could also include + ## imputed or + ## minimally adjusted + model_lists <- list( + "Univariable" = "regression_model_uv_list", + "Multivariable" = "regression_model_list" + ) |> + lapply(\(.fun){ + parameters <- list( + data = data_r()[regression_vars()], + outcome.str = input$outcome_var, + fun.descr = input$regression_type + ) + + do.call( + .fun, + parameters + ) + }) + + rv$list$regression$params <- get_fun_options(input$regression_type) |> + (\(.x){ + .x[[1]] + })() + + rv$list$regression$models <- model_lists + }, + error = function(err) { + showNotification(paste0("Creating regression models failed with the following error: ", err), type = "err") + } + ) + } + ) + + + + shiny::observeEvent( + list( + data_r(), + regression_vars() + ), + { + rv$list$regression$tables <- NULL + } + ) + + ############################################################################## + ######### + ######### Regression table + ######### + ############################################################################## + + ### Creating the regression table + shiny::observeEvent( + input$load, + { + shiny::req(rv$list$regression$models) + ## To avoid plotting old models on fail/error + rv$list$regression$tables <- NULL + + # browser() + tryCatch( + { + parameters <- list( + p.values = input$add_regression_p == "no" + ) + + out <- lapply(rv$list$regression$models, \(.x){ + .x$model + }) |> + purrr::map(\(.x){ + do.call( + regression_table, + append_list(.x, parameters, "x") + ) + }) + + rv$list$regression$models |> + purrr::imap(\(.x, .i){ + rv$list$regression$models[[.i]][["code_table"]] <- paste( + .x$code, + expression_string(rlang::call2(.fn = "regression_table", !!!parameters, .ns = "FreesearchR"), assign.str = NULL), + sep = "|>\n" + ) + }) + + rv$list$regression$tables <- out + rv$list$input <- input + }, + warning = function(warn) { + showNotification(paste0(warn), type = "warning") + }, + error = function(err) { + showNotification(paste0("Creating a regression table failed with the following error: ", err), type = "err") + } + ) + } + ) + + ## Consider creating merged table with theming and then passing object + ## to render. + + output$table2 <- gt::render_gt({ + ## Print checks if a regression table is present + if (!is.null(rv$list$regression$tables)) { + # gtsummary::theme_gtsummary_journal(journal = "jama") + merged <- rv$list$regression$tables |> + tbl_merge() + + if (input$add_regression_p == "no") { + merged <- merged |> + gtsummary::modify_column_hide(column = dplyr::starts_with("p.value")) + } + + out <- merged |> + gtsummary::as_gt() |> + gt::tab_header(gt::md(glue::glue("**Table 2: {rv$list$regression$params$descr}**"))) + + # rv$list$regression$table_merged <- out + + out + } else { + return(NULL) + } + }) + + ############################################################################## + ######### + ######### Coefficients plot + ######### + ############################################################################## + + shiny::observeEvent(list( + input$plot_model, + rv$list$regression + ), { + shiny::req(input$plot_model) + + tryCatch( + { + p <- merge_long( + rv$list$regression, + sort_by( + input$plot_model, + c("Univariable", "Minimal", "Multivariable"), + na.rm = TRUE + ) + ) |> + (\(.x){ + if (length(input$plot_model) > 1) { + plot.tbl_regression( + x = .x, + colour = "model", + dodged = TRUE + ) + + ggplot2::theme(legend.position = "bottom") + + ggplot2::guides(color = ggplot2::guide_legend(reverse = TRUE)) + } else { + plot.tbl_regression( + x = .x, + colour = "variable" + ) + + ggplot2::theme(legend.position = "none") + } + })() + + rv$plot <- p + + ggplot2::scale_y_discrete(labels = scales::label_wrap(15)) + + gg_theme_shiny() + }, + error = function(err) { + showNotification(paste0(err), type = "err") + } + ) + }) + + + output$regression_plot <- shiny::renderPlot( + { + shiny::req(input$plot_model) + + rv$plot + }, + alt = "Regression coefficient plot" + ) + + # plot_download_server( + # id = ns("reg_plot_download"), + # data = shiny::reactive(rv$plot) + # ) + + output$download_plot <- shiny::downloadHandler( + filename = paste0("regression_plot.", input$plot_type), + content = function(file) { + shiny::withProgress(message = "Saving the plot. Hold on for a moment..", { + ggplot2::ggsave( + filename = file, + plot = rv$plot, + width = input$plot_width, + height = input$plot_height, + dpi = 300, + units = "mm", scale = 2 + ) + }) + } + ) + + ############################################################################## + ######### + ######### Model checks + ######### + ############################################################################## + + shiny::observeEvent( + list( + rv$list$regression$models + ), + { + shiny::req(rv$list$regression$models) + tryCatch( + { + rv$check <- lapply(rv$list$regression$models, \(.x){ + .x$model + }) |> + purrr::pluck("Multivariable") |> + performance::check_model() + }, + # warning = function(warn) { + # showNotification(paste0(warn), type = "warning") + # }, + error = function(err) { + showNotification(paste0("Running model assumptions checks failed with the following error: ", err), type = "err") + } + ) + } + ) + + rv$check_plot <- shiny::reactive(plot(rv$check)) + + output$plot_checks <- shiny::renderUI({ + shiny::req(rv$list$regression$models) + shiny::req(rv$check_plot) + + ## Implement correct plotting + names <- sapply(rv$check_plot(), \(.i){ + # .i$labels$title + get_ggplot_label(.i, "title") + }) + + vectorSelectInput( + inputId = ns("plot_checks"), + selected = 1, + label = "Select checks to plot", + choices = names, + multiple = TRUE + ) + }) + + output$check <- shiny::renderPlot( + { + shiny::req(rv$check_plot) + shiny::req(input$plot_checks) + + ## Print checks if a regression table is present + if (!is.null(rv$list$regression$tables)) { + p <- rv$check_plot() + + # patchwork::wrap_plots() + + patchwork::plot_annotation(title = "Multivariable regression model checks") + + + layout <- sapply(seq_len(length(p)), \(.x){ + patchwork::area(.x, 1) + }) + + p_list <- p + patchwork::plot_layout(design = Reduce(c, layout)) + + index <- match( + input$plot_checks, + sapply(rv$check_plot(), \(.i){ + get_ggplot_label(.i, "title") + }) + ) + + ls <- list() + + for (i in index) { + p <- p_list[[i]] + + ggplot2::theme( + axis.text = ggplot2::element_text(size = 10), + axis.title = ggplot2::element_text(size = 12), + legend.text = ggplot2::element_text(size = 12), + plot.subtitle = ggplot2::element_text(size = 12), + plot.title = ggplot2::element_text(size = 18) + ) + ls <- c(ls, list(p)) + } + # browser() + tryCatch( + { + out <- patchwork::wrap_plots(ls, ncol = if (length(ls) == 1) 1 else 2) + }, + error = function(err) { + showNotification(err, type = "err") + } + ) + + out + } else { + return(NULL) + } + }, + alt = "Assumptions testing of the multivariable regression model" + ) + + ############################################################################## + ######### + ######### Output + ######### + ############################################################################## + + return(shiny::reactive({ + rv$list + })) + } + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//report.R +######## + +#' Split vector by an index and embed addition +#' +#' @param data vector +#' @param index split index +#' @param add addition +#' +#' @return vector +#' @export +#' +index_embed <- function(data, index, add = NULL) { + start <- seq_len(index) + end <- seq_along(data)[-start] + c( + data[start], + add, + data[end] + ) +} + +#' Specify format arguments to include in qmd header/frontmatter +#' +#' @param data vector +#' @param fileformat format to include +#' +#' @return vector +#' @export +#' +specify_qmd_format <- function(data, fileformat = c("docx", "odt", "pdf", "all")) { + fileformat <- match.arg(fileformat) + args_list <- default_format_arguments() |> purrr::imap(format_writer) + + if (fileformat == "all") { + out <- data |> index_embed(index = 4, add = Reduce(c, args_list)) + } else { + out <- data |> index_embed(index = 4, add = args_list[[fileformat]]) + } + out +} + +#' Merges list of named arguments for qmd header generation +#' +#' @param data vector +#' @param name name +#' +#' @return vector +#' @export +#' +format_writer <- function(data, name) { + if (data == "default") { + glue::glue(" {name}: {data}") + } else { + warning("Not implemented") + } +} + +#' Defaults qmd formats +#' +#' @return list +#' @export +#' +default_format_arguments <- function() { + list( + docx = list("default"), + odt = list("default"), + pdf = list("default") + ) +} + +#' Wrapper to modify quarto file to render specific formats +#' +#' @param file filename +#' @param format desired output +#' +#' @return none +#' @export +#' +modify_qmd <- function(file, format) { + readLines(file) |> + specify_qmd_format(fileformat = "all") |> + writeLines(paste0(tools::file_path_sans_ext(file), "_format.", tools::file_ext(file))) +} + + + +######## +#### Current file: /Users/au301842/FreesearchR/R//syntax_highlight.R +######## + +## Inpiration: +## +## https://stackoverflow.com/questions/47445260/how-to-enable-syntax-highlighting-in-r-shiny-app-with-htmloutput + +prismCodeBlock <- function(code) { + tagList( + HTML(html_code_wrap(code)), + tags$script("Prism.highlightAll()") + ) +} + +prismDependencies <- tags$head( + tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.8.4/prism.min.js"), + tags$link(rel = "stylesheet", type = "text/css", + href = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.8.4/themes/prism.min.css") +) + +prismRDependency <- tags$head( + tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/prism/1.8.4/components/prism-r.min.js") +) + +html_code_wrap <- function(string,lang="r"){ + glue::glue("
{string}
+  
") +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//theme.R +######## + +#' Custom theme based on unity +#' +#' @param ... everything passed on to bslib::bs_theme() +#' +#' @returns theme list +#' @export +custom_theme <- function(..., + version = 5, + primary = FreesearchR_colors("primary"), + secondary = FreesearchR_colors("secondary"), + bootswatch = "united", + base_font = bslib::font_google("Montserrat"), + heading_font = bslib::font_google("Public Sans", wght = "700"), + code_font = bslib::font_google("Open Sans"), + success = FreesearchR_colors("success"), + info = FreesearchR_colors("info"), + warning = FreesearchR_colors("warning"), + danger = FreesearchR_colors("danger") + # fg = "#000", + # bg="#fff", + # base_font = bslib::font_google("Alice"), + # heading_font = bslib::font_google("Jost", wght = "800"), + # heading_font = bslib::font_google("Noto Serif"), + # heading_font = bslib::font_google("Alice"), +) { + bslib::bs_theme( + ..., + "navbar-bg" = primary, + version = version, + primary = primary, + secondary = secondary, + bootswatch = bootswatch, + base_font = base_font, + heading_font = heading_font, + code_font = code_font, + success=success, + info=info, + warning=warning, + danger=danger + ) +} + +FreesearchR_colors <- function(choose = NULL) { + out <- c( + primary = "#1E4A8F", + secondary = "#FF6F61", + success = "#00C896", + warning = "#FFB100", + danger = "#CC2E25", + extra = "#8A4FFF", + info = "#11A0EC", + bg = "#FFFFFF", + dark = "#2D2D42", + fg = "#000000" + ) + if (!is.null(choose)) { + unname(out[choose]) + } else { + out + } +} + +#' Use the FreesearchR colors +#' +#' @param n number of colors +#' +#' @returns character vector +#' @export +#' +#' @examples +#' FreesearchR_palette(n=7) +FreesearchR_palette <- function(n){ + rep_len(FreesearchR_colors(),n) +} + + + +#' GGplot default theme for plotting in Shiny +#' +#' @param data ggplot object +#' +#' @returns ggplot object +#' @export +#' +gg_theme_shiny <- function() { + ggplot2::theme( + axis.title = ggplot2::element_text(size = 18), + axis.text = ggplot2::element_text(size = 14), + strip.text = ggplot2::element_text(size = 14), + legend.title = ggplot2::element_text(size = 18), + legend.text = ggplot2::element_text(size = 14), + plot.title = ggplot2::element_text(size = 24), + plot.subtitle = ggplot2::element_text(size = 18) + ) +} + + +#' GGplot default theme for plotting export objects +#' +#' @param data ggplot object +#' +#' @returns ggplot object +#' @export +#' +gg_theme_export <- function() { + ggplot2::theme( + axis.title = ggplot2::element_text(size = 18), + axis.text.x = ggplot2::element_text(size = 14), + legend.title = ggplot2::element_text(size = 18), + legend.text = ggplot2::element_text(size = 14), + plot.title = ggplot2::element_text(size = 24) + ) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//update-factor-ext.R +######## + + +## Works, but not implemented +## +## These edits mainly allows for + + +#' @title Module to Reorder the Levels of a Factor Variable +#' +#' @description +#' This module contain an interface to reorder the levels of a factor variable. +#' +#' +#' @param id Module ID. +#' +#' @return A [shiny::reactive()] function returning the data. +#' @export +#' +#' @importFrom shiny NS fluidRow tagList column actionButton +#' @importFrom shinyWidgets virtualSelectInput prettyCheckbox +#' @importFrom toastui datagridOutput +#' @importFrom htmltools tags +#' +#' @name update-factor +#' +update_factor_ui <- function(id) { + ns <- NS(id) + tagList( + tags$style( + ".tui-grid-row-header-draggable span {width: 3px !important; height: 3px !important;}" + ), + fluidRow( + column( + width = 6, + shinyWidgets::virtualSelectInput( + inputId = ns("variable"), + label = i18n("Factor variable to reorder:"), + choices = NULL, + width = "100%", + zIndex = 50 + ) + ), + column( + width = 3, + class = "d-flex align-items-end", + actionButton( + inputId = ns("sort_levels"), + label = tagList( + phosphoricons::ph("sort-ascending"), + datamods:::i18n("Sort by levels") + ), + class = "btn-outline-primary mb-3", + width = "100%" + ) + ), + column( + width = 3, + class = "d-flex align-items-end", + actionButton( + inputId = ns("sort_occurrences"), + label = tagList( + phosphoricons::ph("sort-ascending"), + datamods:::i18n("Sort by count") + ), + class = "btn-outline-primary mb-3", + width = "100%" + ) + ) + ), + toastui::datagridOutput(ns("grid")), + tags$div( + class = "float-end", + shinyWidgets::prettyCheckbox( + inputId = ns("new_var"), + label = datamods:::i18n("Create a new variable (otherwise replaces the one selected)"), + value = FALSE, + status = "primary", + outline = TRUE, + inline = TRUE + ), + actionButton( + inputId = ns("create"), + label = tagList(phosphoricons::ph("arrow-clockwise"), datamods:::i18n("Update factor variable")), + class = "btn-outline-primary" + ) + ), + tags$div(class = "clearfix") + ) +} + + +#' @param data_r A [shiny::reactive()] function returning a `data.frame`. +#' +#' @export +#' +#' @importFrom shiny moduleServer observeEvent reactive reactiveValues req bindEvent isTruthy updateActionButton +#' @importFrom shinyWidgets updateVirtualSelect +#' @importFrom toastui renderDatagrid datagrid grid_columns grid_colorbar +#' +#' @rdname update-factor +update_factor_server <- function(id, data_r = reactive(NULL)) { + moduleServer( + id, + function(input, output, session) { + + rv <- reactiveValues(data = NULL, data_grid = NULL) + + bindEvent(observe({ + data <- data_r() + rv$data <- data + vars_factor <- vapply(data, is.factor, logical(1)) + vars_factor <- names(vars_factor)[vars_factor] + updateVirtualSelect( + inputId = "variable", + choices = vars_factor, + selected = if (isTruthy(input$variable)) input$variable else vars_factor[1] + ) + }), data_r(), input$hidden) + + observeEvent(input$variable, { + data <- req(data_r()) + variable <- req(input$variable) + grid <- as.data.frame(table(data[[variable]])) + rv$data_grid <- grid + }) + + observeEvent(input$sort_levels, { + if (input$sort_levels %% 2 == 1) { + decreasing <- FALSE + label <- tagList( + phosphoricons::ph("sort-descending"), + "Sort Levels" + ) + } else { + decreasing <- TRUE + label <- tagList( + phosphoricons::ph("sort-ascending"), + "Sort Levels" + ) + } + updateActionButton(inputId = "sort_levels", label = as.character(label)) + rv$data_grid <- rv$data_grid[order(rv$data_grid[[1]], decreasing = decreasing), ] + }) + + observeEvent(input$sort_occurrences, { + if (input$sort_occurrences %% 2 == 1) { + decreasing <- FALSE + label <- tagList( + phosphoricons::ph("sort-descending"), + datamods:::i18n("Sort count") + ) + } else { + decreasing <- TRUE + label <- tagList( + phosphoricons::ph("sort-ascending"), + datamods:::i18n("Sort count") + ) + } + updateActionButton(inputId = "sort_occurrences", label = as.character(label)) + rv$data_grid <- rv$data_grid[order(rv$data_grid[[2]], decreasing = decreasing), ] + }) + + + output$grid <- renderDatagrid({ + req(rv$data_grid) + gridTheme <- getOption("datagrid.theme") + if (length(gridTheme) < 1) { + datamods:::apply_grid_theme() + } + on.exit(toastui::reset_grid_theme()) + data <- rv$data_grid + data <- add_var_toset(data, "Var1", "New label") + + grid <- datagrid( + data = data, + draggable = TRUE, + sortable = FALSE, + data_as_input = TRUE + ) + grid <- grid_columns( + grid, + columns = c("Var1", "Var1_toset", "Freq"), + header = c(datamods:::i18n("Levels"), "New label", datamods:::i18n("Count")) + ) + grid <- grid_colorbar( + grid, + column = "Freq", + label_outside = TRUE, + label_width = "30px", + background = "#D8DEE9", + bar_bg = datamods:::get_primary_color(), + from = c(0, max(rv$data_grid$Freq) + 1) + ) + grid <- toastui::grid_style_column( + grid = grid, + column = "Var1_toset", + fontStyle = "italic" + ) + grid <- toastui::grid_editor( + grid = grid, + column = "Var1_toset", + type = "text" + ) + grid + }) + + data_updated_r <- reactive({ + data <- req(data_r()) + variable <- req(input$variable) + grid <- req(input$grid_data) + name_var <- if (isTRUE(input$new_var)) { + paste0(variable, "_updated") + } else { + variable + } + data[[name_var]] <- factor( + as.character(data[[variable]]), + levels = grid[["Var1"]] + ) + data[[name_var]] <- factor( + data[[variable]], + labels = ifelse(grid[["Var1_toset"]]=="New label",grid[["Var1"]],grid[["Var1_toset"]]) + ) + data + }) + + data_returned_r <- observeEvent(input$create, { + rv$data <- data_updated_r() + }) + return(reactive(rv$data)) + } + ) +} + + + +#' @inheritParams shiny::modalDialog +#' @export +#' +#' @importFrom shiny showModal modalDialog textInput +#' @importFrom htmltools tagList +#' +#' @rdname update-factor +modal_update_factor <- function(id, + title = i18n("Update levels of a factor"), + easyClose = TRUE, + size = "l", + footer = NULL) { + ns <- NS(id) + showModal(modalDialog( + title = tagList(title, datamods:::button_close_modal()), + update_factor_ui(id), + tags$div( + style = "display: none;", + textInput(inputId = ns("hidden"), label = NULL, value = datamods:::genId()) + ), + easyClose = easyClose, + size = size, + footer = footer + )) +} + + +#' @inheritParams shinyWidgets::WinBox +#' @export +#' +#' @importFrom shinyWidgets WinBox wbOptions wbControls +#' @importFrom htmltools tagList +#' @rdname update-factor +winbox_update_factor <- function(id, + title = i18n("Update levels of a factor"), + options = shinyWidgets::wbOptions(), + controls = shinyWidgets::wbControls()) { + ns <- NS(id) + WinBox( + title = title, + ui = tagList( + update_factor_ui(id), + tags$div( + style = "display: none;", + textInput(inputId = ns("hidden"), label = NULL, value = genId()) + ) + ), + options = modifyList( + shinyWidgets::wbOptions(height = "615px", modal = TRUE), + options + ), + controls = controls, + auto_height = FALSE + ) +} + + + +######## +#### Current file: /Users/au301842/FreesearchR/R//update-variables-ext.R +######## + +#' Select, rename and convert variables +#' +#' @param id Module id. See [shiny::moduleServer()]. +#' @param title Module's title, if `TRUE` use the default title, +#' use \code{NULL} for no title or a `shiny.tag` for a custom one. +#' +#' @return A [shiny::reactive()] function returning the updated data. +#' @export +#' +#' @name update-variables +#' +update_variables_ui <- function(id, title = "") { + ns <- NS(id) + if (isTRUE(title)) { + title <- htmltools::tags$h4( + i18n("Update & select variables"), + class = "datamods-title" + ) + } + htmltools::tags$div( + class = "datamods-update", + shinyWidgets::html_dependency_pretty(), + title, + htmltools::tags$div( + style = "min-height: 25px;", + htmltools::tags$div( + shiny::uiOutput(outputId = ns("data_info"), inline = TRUE), + shiny::tagAppendAttributes( + shinyWidgets::dropMenu( + placement = "bottom-end", + shiny::actionButton( + inputId = ns("settings"), + label = phosphoricons::ph("gear"), + class = "pull-right float-right" + ), + shinyWidgets::textInputIcon( + inputId = ns("format"), + label = i18n("Date format:"), + value = "%Y-%m-%d", + icon = list(phosphoricons::ph("clock")) + ), + shinyWidgets::textInputIcon( + inputId = ns("origin"), + label = i18n("Date to use as origin to convert date/datetime:"), + value = "1970-01-01", + icon = list(phosphoricons::ph("calendar")) + ), + shinyWidgets::textInputIcon( + inputId = ns("dec"), + label = i18n("Decimal separator:"), + value = ".", + icon = list("0.00") + ) + ), + style = "display: inline;" + ) + ), + htmltools::tags$br(), + toastui::datagridOutput(outputId = ns("table")) + ), + htmltools::tags$br(), + htmltools::tags$div( + id = ns("update-placeholder"), + shinyWidgets::alert( + id = ns("update-result"), + status = "info", + phosphoricons::ph("info"), + paste( + "Select variables to keep (if none selected, all are kept), rename", + "variables and labels, and convert variable type/class in the table", + "above. Apply changes by clicking the button below." + ) + ) + ), + shiny::actionButton( + inputId = ns("validate"), + label = htmltools::tagList( + phosphoricons::ph("arrow-circle-right", title = datamods::i18n("Apply changes")), + datamods::i18n("Apply changes") + ), + width = "100%" + ) + ) +} + +#' @export +#' +#' @param id Module's ID +#' @param data a \code{data.frame} or a \code{reactive} function returning a \code{data.frame}. +#' @param height Height for the table. +#' @param return_data_on_init Return initial data when module is called. +#' @param try_silent logical: should the report of error messages be suppressed? +#' +#' @rdname update-variables +#' +update_variables_server <- function(id, + data, + height = NULL, + return_data_on_init = FALSE, + try_silent = FALSE) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + ns <- session$ns + updated_data <- shiny::reactiveValues(x = NULL) + + data_r <- shiny::reactive({ + if (shiny::is.reactive(data)) { + data() + } else { + data + } + }) + + output$data_info <- shiny::renderUI({ + shiny::req(data_r()) + data_description(data_r()) + # sprintf(i18n("Data has %s observations and %s variables."), nrow(data), ncol(data)) + }) + + variables_r <- shiny::reactive({ + shiny::validate( + shiny::need(data(), i18n("No data to display.")) + ) + data <- data_r() + if (isTRUE(return_data_on_init)) { + updated_data$x <- data + } else { + updated_data$x <- NULL + } + summary_vars(data) + }) + + output$table <- toastui::renderDatagrid({ + shiny::req(variables_r()) + + variables <- variables_r() + + update_variables_datagrid( + variables, + height = height, + selectionId = ns("row_selected"), + buttonId = "validate" + ) + }) + + shiny::observeEvent(input$validate, + { + updated_data$list_rename <- NULL + updated_data$list_select <- NULL + updated_data$list_mutate <- NULL + updated_data$list_relabel <- NULL + # shiny::req(updated_data$x) + data <- data_r() + new_selections <- input$row_selected + if (length(new_selections) < 1) { + new_selections <- seq_along(data) + } + + data_inputs <- data.table::as.data.table(input$table_data) + data.table::setorderv(data_inputs, "rowKey") + + old_names <- data_inputs$name + new_names <- data_inputs$name_toset + new_names[new_names == "New name"] <- NA + new_names[is.na(new_names)] <- old_names[is.na(new_names)] + new_names[new_names == ""] <- old_names[new_names == ""] + + # browser() + + old_label <- data_inputs$label + new_label <- data_inputs$label_toset + + new_label[new_label == "New label"] <- old_label[new_label == "New label"] + + ## Later, "" will be interpreted as NA/empty and removed + new_label[is.na(new_label) | new_label %in% c('""',"''"," ")] <- "" + + # new_label[is.na(new_label)] <- old_label[is.na(new_label)] + new_label <- setNames(new_label, new_names) + + new_classes <- data_inputs$class_toset + new_classes[new_classes == "Select"] <- NA + + data_sv <- variables_r() + vars_to_change <- get_vars_to_convert(data_sv, setNames(as.list(new_classes), old_names)) + + res_update <- try( + { + # convert + if (nrow(vars_to_change) > 0) { + data <- convert_to( + data = data, + variable = vars_to_change$name, + new_class = vars_to_change$class_to_set, + origin = input$origin, + format = input$format, + dec = input$dec + ) + } + list_mutate <- attr(data, "code_03_convert") + + # rename + list_rename <- setNames( + as.list(old_names), + unlist(new_names, use.names = FALSE) + ) + list_rename <- list_rename[names(list_rename) != unlist(list_rename, use.names = FALSE)] + names(data) <- unlist(new_names, use.names = FALSE) + + # relabel + list_relabel <- as.list(new_label) + data <- set_column_label(data, list_relabel) + + # select + list_select <- setdiff(names(data), names(data)[new_selections]) + data <- data[, new_selections, drop = FALSE] + }, + silent = try_silent + ) + + if (inherits(res_update, "try-error")) { + datamods:::insert_error(selector = "update") + } else { + datamods:::insert_alert( + selector = ns("update"), + status = "success", + tags$b(phosphoricons::ph("check"), datamods::i18n("Data successfully updated!")) + ) + updated_data$x <- data + updated_data$list_rename <- list_rename + updated_data$list_select <- list_select + updated_data$list_mutate <- list_mutate + updated_data$list_relabel <- list_relabel + } + }, + ignoreNULL = TRUE, + ignoreInit = TRUE + ) + + # shiny::observeEvent(input$close, + # { + return(shiny::reactive({ + shiny::req(updated_data$x) + # browser() + data <- updated_data$x + code <- list() + if (!is.null(data) && shiny::isTruthy(updated_data$list_mutate) && length(updated_data$list_mutate) > 0) { + code <- c(code, list(rlang::call2("mutate", !!!updated_data$list_mutate,.ns="dplyr"))) + } + if (!is.null(data) && shiny::isTruthy(updated_data$list_rename) && length(updated_data$list_rename) > 0) { + code <- c(code, list(rlang::call2("rename", !!!updated_data$list_rename,.ns="dplyr"))) + } + if (!is.null(data) && shiny::isTruthy(updated_data$list_select) && length(updated_data$list_select) > 0) { + code <- c(code, list(rlang::expr(dplyr::select(-dplyr::any_of(c(!!!updated_data$list_select)))))) + } + if (!is.null(data) && shiny::isTruthy(updated_data$list_relabel) && length(updated_data$list_relabel) > 0) { + code <- c(code,list(rlang::call2("set_column_label",label=updated_data$list_relabel,.ns="FreesearchR"))) + } + if (length(code) > 0) { + attr(data, "code") <- Reduce( + f = function(x, y) rlang::expr(!!x %>% !!y), + x = code + ) + } + return(data) + })) + # }) + + # shiny::reactive({ + # data <- updated_data$x + # code <- list() + # if (!is.null(data) && shiny::isTruthy(updated_data$list_mutate) && length(updated_data$list_mutate) > 0) { + # code <- c(code, list(rlang::call2("mutate", !!!updated_data$list_mutate))) + # } + # if (!is.null(data) && shiny::isTruthy(updated_data$list_rename) && length(updated_data$list_rename) > 0) { + # code <- c(code, list(rlang::call2("rename", !!!updated_data$list_rename))) + # } + # if (!is.null(data) && shiny::isTruthy(updated_data$list_select) && length(updated_data$list_select) > 0) { + # code <- c(code, list(rlang::expr(select(-any_of(c(!!!updated_data$list_select)))))) + # } + # if (!is.null(data) && shiny::isTruthy(updated_data$list_relabel) && length(updated_data$list_relabel) > 0) { + # code <- c(code, list(rlang::call2("purrr::map2(list_relabel, + # function(.data,.label){ + # REDCapCAST::set_attr(.data,.label,attr = 'label') + # }) |> dplyr::bind_cols(.name_repair = 'unique_quiet')"))) + # } + # if (length(code) > 0) { + # attr(data, "code") <- Reduce( + # f = function(x, y) rlang::expr(!!x %>% !!y), + # x = code + # ) + # } + # updated_data$return_data <- data + # }) + + # shiny::observeEvent(input$close, + # { + # shiny::req(input$close) + # return(shiny::reactive({ + # data <- updated_data$return_data + # return(data) + # })) + # }) + } + ) +} + + +modal_update_variables <- function(id, + title = "Select, rename and reclass variables", + easyClose = TRUE, + size = "xl", + footer = NULL) { + ns <- NS(id) + showModal(modalDialog( + title = tagList(title, datamods:::button_close_modal()), + update_variables_ui(id), + # tags$div( + # style = "display: none;", + # textInput(inputId = ns("hidden"), label = NULL, value = datamods:::genId()) + # ), + easyClose = easyClose, + size = size, + footer = footer + )) +} + + + +# utils ------------------------------------------------------------------- + + +#' Get variables classes from a \code{data.frame} +#' +#' @param data a \code{data.frame} +#' +#' @return a \code{character} vector as same length as number of variables +#' @noRd +#' +#' @examples +#' +#' get_classes(mtcars) +get_classes <- function(data) { + classes <- lapply( + X = data, + FUN = function(x) { + paste(class(x), collapse = ", ") + } + ) + unlist(classes, use.names = FALSE) +} + + +#' Get count of unique values in variables of \code{data.frame} +#' +#' @param data a \code{data.frame} +#' +#' @return a \code{numeric} vector as same length as number of variables +#' @noRd +#' +#' +#' @examples +#' get_n_unique(mtcars) +get_n_unique <- function(data) { + u <- lapply(data, FUN = function(x) { + if (is.atomic(x)) { + data.table::uniqueN(x) + } else { + NA_integer_ + } + }) + unlist(u, use.names = FALSE) +} + + + +#' Add padding 0 to a vector +#' +#' @param x a \code{vector} +#' +#' @return a \code{character} vector +#' @noRd +#' +#' @examples +#' +#' pad0(1:10) +#' pad0(c(1, 15, 150, NA)) +pad0 <- function(x) { + NAs <- which(is.na(x)) + x <- formatC(x, width = max(nchar(as.character(x)), na.rm = TRUE), flag = "0") + x[NAs] <- NA + x +} + +#' Variables summary +#' +#' @param data a \code{data.frame} +#' +#' @return a \code{data.frame} +#' @noRd +#' +#' @examples +#' +#' summary_vars(iris) +#' summary_vars(mtcars) +summary_vars <- function(data) { + data <- as.data.frame(data) + datsum <- dplyr::tibble( + name = names(data), + label = lapply(data, \(.x) REDCapCAST::get_attr(.x, "label")) |> unlist(), + class = get_classes(data), + n_missing = unname(colSums(is.na(data))), + p_complete = 1 - n_missing / nrow(data), + n_unique = get_n_unique(data) + ) + + datsum +} + +add_var_toset <- function(data, var_name, default = "") { + datanames <- names(data) + datanames <- append( + x = datanames, + values = paste0(var_name, "_toset"), + after = which(datanames == var_name) + ) + data[[paste0(var_name, "_toset")]] <- default + data[, datanames] +} + +#' Modified from the datamods pacakge +#' +#' @param data data +#' +#' @param height height +#' @param selectionId selectionId +#' @param buttonId buttonId +#' +#' @examples +#' mtcars |> +#' summary_vars() |> +#' update_variables_datagrid() +#' +update_variables_datagrid <- function(data, height = NULL, selectionId = NULL, buttonId = NULL) { + # browser() + data <- add_var_toset(data, "name", "New name") + data <- add_var_toset(data, "class", "Select") + data <- add_var_toset(data, "label", "New label") + + gridTheme <- getOption("datagrid.theme") + if (length(gridTheme) < 1) { + datamods:::apply_grid_theme() + } + on.exit(toastui::reset_grid_theme()) + + col.names <- names(data) + + std_names <- c( + "name", "name_toset", "label", "label_toset", "class", "class_toset", "n_missing", "p_complete", "n_unique" + ) |> + setNames(c( + "Name", "New name", "Label", "New label", "Class", "New class", "Missing", "Complete", "Unique" + )) + + headers <- lapply(col.names, \(.x){ + if (.x %in% std_names) { + names(std_names)[match(.x, std_names)] + } else { + .x + } + }) |> unlist() + + grid <- toastui::datagrid( + data = data, + theme = "default", + colwidths = NULL + ) + grid <- toastui::grid_columns( + grid = grid, + columns = col.names, + header = headers, + minWidth = 100 + ) + + grid <- toastui::grid_format( + grid = grid, + "p_complete", + formatter = toastui::JS("function(obj) {return (obj.value*100).toFixed(0) + '%';}") + ) + grid <- toastui::grid_style_column( + grid = grid, + column = "name_toset", + fontStyle = "italic" + ) + grid <- toastui::grid_style_column( + grid = grid, + column = "label_toset", + fontStyle = "italic" + ) + grid <- toastui::grid_style_column( + grid = grid, + column = "class_toset", + fontStyle = "italic" + ) + + grid <- toastui::grid_filters( + grid = grid, + column = "name", + # columns = unname(std_names[std_names!="vals"]), + showApplyBtn = FALSE, + showClearBtn = TRUE, + type = "text" + ) + + # grid <- toastui::grid_columns( + # grid = grid, + # columns = "name_toset", + # editor = list(type = "text"), + # validation = toastui::validateOpts() + # ) + # + # grid <- toastui::grid_columns( + # grid = grid, + # columns = "label_toset", + # editor = list(type = "text"), + # validation = toastui::validateOpts() + # ) + # + # grid <- toastui::grid_columns( + # grid = grid, + # columns = "class_toset", + # editor = list( + # type = "radio", + # options = list( + # instantApply = TRUE, + # listItems = lapply( + # X = c("Select", "character", "factor", "numeric", "integer", "date", "datetime", "hms"), + # FUN = function(x) { + # list(text = x, value = x) + # } + # ) + # ) + # ), + # validation = toastui::validateOpts() + # ) + + grid <- toastui::grid_editor( + grid = grid, + column = "name_toset", + type = "text" + ) + grid <- toastui::grid_editor( + grid = grid, + column = "label_toset", + type = "text" + ) + grid <- toastui::grid_editor( + grid = grid, + column = "class_toset", + type = "select", + choices = c("Select", "character", "factor", "numeric", "integer", "date", "datetime", "hms") + ) + grid <- toastui::grid_editor_opts( + grid = grid, + editingEvent = "click", + actionButtonId = NULL, + session = NULL + ) + grid <- toastui::grid_selection_row( + grid = grid, + inputId = selectionId, + type = "checkbox", + return = "index" + ) + + return(grid) +} + + + +#' Convert a variable to specific new class +#' +#' @param data A \code{data.frame} +#' @param variable Name of the variable to convert +#' @param new_class Class to set +#' @param ... Other arguments passed on to methods. +#' +#' @return A \code{data.frame} +#' @noRd +#' +#' @importFrom utils type.convert +#' @importFrom rlang sym expr +#' +#' @examples +#' dat <- data.frame( +#' v1 = month.name, +#' v2 = month.abb, +#' v3 = 1:12, +#' v4 = as.numeric(Sys.Date() + 0:11), +#' v5 = as.character(Sys.Date() + 0:11), +#' v6 = as.factor(c("a", "a", "b", "a", "b", "a", "a", "b", "a", "b", "b", "a")), +#' v7 = as.character(11:22), +#' stringsAsFactors = FALSE +#' ) +#' +#' str(dat) +#' +#' str(convert_to(dat, "v3", "character")) +#' str(convert_to(dat, "v6", "character")) +#' str(convert_to(dat, "v7", "numeric")) +#' str(convert_to(dat, "v4", "date", origin = "1970-01-01")) +#' str(convert_to(dat, "v5", "date")) +#' +#' str(convert_to(dat, c("v1", "v3"), c("factor", "character"))) +#' +#' str(convert_to(dat, c("v1", "v3", "v4"), c("factor", "character", "date"), origin = "1970-01-01")) +#' +convert_to <- function(data, + variable, + new_class = c("character", "factor", "numeric", "integer", "date", "datetime", "hms"), + ...) { + new_class <- match.arg(new_class, several.ok = TRUE) + stopifnot(length(new_class) == length(variable)) + args <- list(...) + args$format <- clean_sep(args$format) + if (length(variable) > 1) { + for (i in seq_along(variable)) { + data <- convert_to(data, variable[i], new_class[i], ...) + } + return(data) + } + if (identical(new_class, "character")) { + data[[variable]] <- as.character(x = data[[variable]], ...) + attr(data, "code_03_convert") <- c( + attr(data, "code_03_convert"), + setNames(list(expr(as.character(!!sym(variable)))), variable) + ) + } else if (identical(new_class, "factor")) { + data[[variable]] <- REDCapCAST::as_factor(x = data[[variable]]) + attr(data, "code_03_convert") <- c( + attr(data, "code_03_convert"), + setNames(list(expr(REDCapCAST::as_factor(!!sym(variable)))), variable) + ) + } else if (identical(new_class, "numeric")) { + data[[variable]] <- as.numeric(data[[variable]], ...) + # This is the original, that would convert to character and then to numeric + # resulting in all NAs, setting as.is = FALSE would result in a numeric + # vector in order of appearance. Now it is acting like integer conversion + # data[[variable]] <- as.numeric(type.convert(data[[variable]], as.is = TRUE, ...)) + attr(data, "code_03_convert") <- c( + attr(data, "code_03_convert"), + setNames(list(expr(as.numeric(!!sym(variable)))), variable) + ) + } else if (identical(new_class, "integer")) { + data[[variable]] <- as.integer(x = data[[variable]], ...) + attr(data, "code_03_convert") <- c( + attr(data, "code_03_convert"), + setNames(list(expr(as.integer(!!sym(variable)))), variable) + ) + } else if (identical(new_class, "date")) { + data[[variable]] <- as.Date(x = clean_date(data[[variable]]), ...) + attr(data, "code_03_convert") <- c( + attr(data, "code_03_convert"), + setNames(list(expr(as.Date(clean_date(!!sym(variable)), origin = !!args$origin, format = clean_sep(!!args$format)))), variable) + ) + } else if (identical(new_class, "datetime")) { + data[[variable]] <- as.POSIXct(x = data[[variable]], ...) + attr(data, "code_03_convert") <- c( + attr(data, "code_03_convert"), + setNames(list(expr(as.POSIXct(!!sym(variable)))), variable) + ) + } else if (identical(new_class, "hms")) { + data[[variable]] <- hms::as_hms(x = data[[variable]]) + attr(data, "code_03_convert") <- c( + attr(data, "code_03_convert"), + setNames(list(expr(hms::as_hms(!!sym(variable)))), variable) + ) + } + return(data) +} + + + + + + + + +#' Get variable(s) to convert +#' +#' @param vars Output of [summary_vars()] +#' @param classes_input List of inputs containing new classes +#' +#' @return a `data.table`. +#' @noRd +#' +#' @importFrom data.table data.table as.data.table +#' +#' @examples +#' # 2 variables to convert +#' new_classes <- list( +#' "Sepal.Length" = "numeric", +#' "Sepal.Width" = "numeric", +#' "Petal.Length" = "character", +#' "Petal.Width" = "numeric", +#' "Species" = "character" +#' ) +#' get_vars_to_convert(summary_vars(iris), new_classes) +#' +#' +#' # No changes +#' new_classes <- list( +#' "Sepal.Length" = "numeric", +#' "Sepal.Width" = "numeric", +#' "Petal.Length" = "numeric", +#' "Petal.Width" = "numeric", +#' "Species" = "factor" +#' ) +#' get_vars_to_convert(summary_vars(iris), new_classes) +#' +#' # Not set = NA or "" +#' new_classes <- list( +#' "Sepal.Length" = NA, +#' "Sepal.Width" = NA, +#' "Petal.Length" = NA, +#' "Petal.Width" = NA, +#' "Species" = NA +#' ) +#' get_vars_to_convert(summary_vars(iris), new_classes) +#' +#' # Set for one var +#' new_classes <- list( +#' "Sepal.Length" = "", +#' "Sepal.Width" = "", +#' "Petal.Length" = "", +#' "Petal.Width" = "", +#' "Species" = "character" +#' ) +#' get_vars_to_convert(summary_vars(iris), new_classes) +#' +#' new_classes <- list( +#' "mpg" = "character", +#' "cyl" = "numeric", +#' "disp" = "character", +#' "hp" = "numeric", +#' "drat" = "character", +#' "wt" = "character", +#' "qsec" = "numeric", +#' "vs" = "character", +#' "am" = "numeric", +#' "gear" = "character", +#' "carb" = "integer" +#' ) +#' get_vars_to_convert(summary_vars(mtcars), new_classes) +get_vars_to_convert <- function(vars, classes_input) { + vars <- data.table::as.data.table(vars) + classes_input <- data.table::data.table( + name = names(classes_input), + class_to_set = unlist(classes_input, use.names = FALSE), + stringsAsFactors = FALSE + ) + classes_input <- classes_input[!is.na(class_to_set) & class_to_set != ""] + classes_df <- merge(x = vars, y = classes_input, by = "name") + classes_df <- classes_df[!is.na(class_to_set)] + classes_df[class != class_to_set] +} + + +#' gsub wrapper for piping with default values for separator substituting +#' +#' @param data character vector +#' @param old.sep old separator +#' @param new.sep new separator +#' +#' @returns character vector +#' @export +#' +clean_sep <- function(data, old.sep = "[-.,/]", new.sep = "-") { + gsub(old.sep, new.sep, data) +} + +#' Attempts at applying uniform date format +#' +#' @param data character string vector of possible dates +#' +#' @returns character string +#' @export +#' +clean_date <- function(data) { + data |> + clean_sep() |> + sapply(\(.x){ + if (is.na(.x)) { + .x + } else { + strsplit(.x, "-") |> + unlist() |> + lapply(\(.y){ + if (nchar(.y) == 1) paste0("0", .y) else .y + }) |> + paste(collapse = "-") + } + }) |> + unname() +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//visual_summary.R +######## + +#' Data correlations evaluation module +#' +#' @param id Module id +#' +#' @name data-missings +#' @returns Shiny ui module +#' @export +visual_summary_ui <- function(id) { + ns <- shiny::NS(id) + + shiny::tagList( + shiny::plotOutput(outputId = ns("visual_plot"), height = "70vh") + ) +} + +visual_summary_server <- function(id, + data_r=shiny::reactive(NULL), + ...) { + shiny::moduleServer( + id = id, + module = function(input, output, session) { + # ns <- session$ns + rv <- shiny::reactiveValues(data = NULL) + + shiny::bindEvent(shiny::observe({ + data <- data_r() + rv$data <- data + # vars_num <- vapply(data, \(.x){ + # is.numeric(.x) || is_datetime(.x) + # }, logical(1)) + # vars_num <- names(vars_num)[vars_num] + # shinyWidgets::updateVirtualSelect( + # inputId = "variable", + # choices = vars_num, + # selected = if (isTruthy(input$variable)) input$variable else vars_num[1] + # ) + }), data_r(), input$hidden) + + # datar <- if (is.reactive(data)) data else reactive(data) + + + # apexcharter::renderApexchart({ + # missings_apex_plot(datar(), ...) + # }) + output$visual_plot <- shiny::renderPlot(expr = { + visual_summary(data = rv$data,...) + }) + } + ) +} + +visual_summary_demo_app <- function() { + ui <- shiny::fluidPage( + shiny::actionButton( + inputId = "modal_missings", + label = "Visual summary", + width = "100%", + disabled = FALSE + ) + ) + server <- function(input, output, session) { + data_demo <- mtcars + data_demo[sample(1:32, 10), "cyl"] <- NA + data_demo[sample(1:32, 8), "vs"] <- NA + + visual_summary_server(id = "data", data = shiny::reactive(data_demo)) + + observeEvent(input$modal_missings, { + tryCatch( + { + modal_visual_summary(id = "data") + }, + error = function(err) { + showNotification(paste0("We encountered the following error browsing your data: ", err), type = "err") + } + ) + }) + } + shiny::shinyApp(ui, server) +} + +visual_summary_demo_app() + + +modal_visual_summary <- function(id, + title = "Visual overview of data classes and missing observations", + easyClose = TRUE, + size = "xl", + footer = NULL, + ...) { + showModal(modalDialog( + title = tagList(title, datamods:::button_close_modal()), + visual_summary_ui(id = id), + easyClose = easyClose, + size = size, + footer = footer + )) +} + + +## Slow with many observations... + +#' Plot missings and class with apexcharter +#' +#' @param data data frame +#' +#' @returns An [apexchart()] `htmlwidget` object. +#' @export +#' +#' @examples +#' data_demo <- mtcars +#' data_demo[2:4, "cyl"] <- NA +#' rbind(data_demo, data_demo, data_demo, data_demo) |> missings_apex_plot() +#' data_demo |> missings_apex_plot() +#' mtcars |> missings_apex_plot(animation = TRUE) +#' # dplyr::storms |> missings_apex_plot() +#' visdat::vis_dat(dplyr::storms) +missings_apex_plot <- function(data, animation = FALSE, ...) { + l <- data_summary_gather(data, ...) + + df_plot <- l$data + + out <- apexcharter::apex( + data = df_plot, + type = "heatmap", + mapping = apexcharter::aes(x = variable, y = rows, fill = valueType_num), + ... + ) |> + apexcharter::ax_stroke(width = NULL) |> + apexcharter::ax_plotOptions( + heatmap = apexcharter::heatmap_opts( + radius = 0, + enableShades = FALSE, + colorScale = list( + ranges = l$labels + ), + useFillColorAsStroke = TRUE + ) + ) |> + apexcharter::ax_dataLabels(enabled = FALSE) |> + apexcharter::ax_tooltip( + enabled = FALSE, + intersect = FALSE + ) + + if (!isTRUE(animation)) { + out <- out |> + apexcharter::ax_chart(animations = list(enabled = FALSE)) + } + + out +} + + + +#' Ggplot2 data summary visualisation based on visdat::vis_dat. +#' +#' @param data data +#' @param ... optional arguments passed to data_summary_gather() +#' +#' @returns ggplot2 object +#' @export +#' +#' @examples +#' data_demo <- mtcars +#' data_demo[sample(1:32, 10), "cyl"] <- NA +#' data_demo[sample(1:32, 8), "vs"] <- NA +#' visual_summary(data_demo) +#' visual_summary(data_demo, palette.fun = scales::hue_pal()) +#' visual_summary(dplyr::storms) +#' visual_summary(dplyr::storms, summary.fun = data_type) +visual_summary <- function(data, legend.title = "Data class", ...) { + l <- data_summary_gather(data, ...) + + df <- l$data + + df$valueType <- factor(df$valueType, levels = names(l$colors)) + df$variable <- factor(df$variable, levels = unique_short(names(data))) + + ggplot2::ggplot(data = df, ggplot2::aes(x = variable, y = rows)) + + ggplot2::geom_raster(ggplot2::aes(fill = valueType)) + + ggplot2::theme_minimal() + + ggplot2::theme(axis.text.x = ggplot2::element_text( + angle = 45, + vjust = 1, hjust = 1 + )) + + ggplot2::scale_fill_manual(values = l$colors) + + ggplot2::labs(x = "", y = "Observations") + + ggplot2::scale_y_reverse() + + ggplot2::theme(axis.text.x = ggplot2::element_text(hjust = 0.5)) + + ggplot2::guides(colour = "none") + + ggplot2::guides(fill = ggplot2::guide_legend(title = legend.title)) + + # change the limits etc. + ggplot2::guides(fill = ggplot2::guide_legend(title = "Type")) + + # add info about the axes + ggplot2::scale_x_discrete(position = "top") + + ggplot2::theme(axis.text.x = ggplot2::element_text(hjust = 0)) + + ggplot2::theme( + panel.grid.major = ggplot2::element_blank(), + panel.grid.minor = ggplot2::element_blank(), + text = ggplot2::element_text(size = 18), + plot.title = ggplot2::element_blank() + ) +} + +#' Data summary for printing visual summary +#' +#' @param data data.frame +#' @param fun summary function. Default is "class" +#' @param palette.fun optionally use specific palette functions. First argument +#' has to be the length. +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' mtcars |> data_summary_gather() +data_summary_gather <- function(data, summary.fun = class, palette.fun = viridisLite::viridis) { + df_plot <- setNames(data, unique_short(names(data))) |> + purrr::map_df(\(x){ + ifelse(is.na(x), + yes = NA, + no = glue::glue_collapse(summary.fun(x), + sep = "\n" + ) + ) + }) |> + dplyr::mutate(rows = dplyr::row_number()) |> + tidyr::pivot_longer( + cols = -rows, + names_to = "variable", values_to = "valueType", values_transform = list(valueType = as.character) + ) |> + dplyr::arrange(rows, variable, valueType) + + + df_plot$valueType_num <- df_plot$valueType |> + forcats::as_factor() |> + as.numeric() + + df_plot$valueType[is.na(df_plot$valueType)] <- "NA" + df_plot$valueType_num[is.na(df_plot$valueType_num)] <- max(df_plot$valueType_num, na.rm = TRUE) + 1 + + labels <- setNames(unique(df_plot$valueType_num), unique(df_plot$valueType)) |> sort() + + if (any(df_plot$valueType == "NA")) { + colors <- setNames(c(palette.fun(length(labels) - 1), "#999999"), names(labels)) + } else { + colors <- setNames(palette.fun(length(labels)), names(labels)) + } + + + label_list <- labels |> + purrr::imap(\(.x, .i){ + list( + from = .x, + to = .x, + color = colors[[.i]], + name = .i + ) + }) |> + setNames(NULL) + + list(data = df_plot, colors = colors, labels = label_list) +} + + + +#' Create unique short names of character vector items based on index +#' +#' @description +#' The function will prefer original names, and only append index to long +#' strings. +#' +#' +#' @param data character vector +#' @param max maximum final name length +#' +#' @returns character vector +#' @export +#' +#' @examples +#' c("kahdleidnsallskdj", "hej") |> unique_short() +unique_short <- function(data, max = 15) { + purrr::imap(data, \(.x, .i){ + if (nchar(.x) > max) { + glue::glue("{substr(.x,1,(max-(nchar(.i)+1)))}_{.i}") + } else { + .x + } + }) |> unlist() +} + + +######## +#### Current file: /Users/au301842/FreesearchR/R//wide2long.R +######## + +#' Alternative pivoting method for easily pivoting based on name pattern +#' +#' @description +#' This function requires and assumes a systematic naming of variables. +#' For now only supports one level pivoting. Adding more levels would require +#' an added "ignore" string pattern or similarly. Example 2. +#' +#' +#' @param data data +#' @param pattern pattern(s) to match. Character vector of length 1 or more. +#' @param type type of match. can be one of "prefix","infix" or "suffix". +#' @param id.col ID column. Will fill ID for all. Column name or numeric index. +#' Default is "1", first column. +#' @param instance.name +#' +#' @returns data.frame +#' @export +#' +#' @examples +#' data.frame( +#' 1:20, sample(70:80, 20, TRUE), +#' sample(70:100, 20, TRUE), +#' sample(70:100, 20, TRUE), +#' sample(170:200, 20, TRUE) +#' ) |> +#' setNames(c("id", "age", "weight_0", "weight_1", "height_1")) |> +#' wide2long(pattern = c("_0", "_1"), type = "suffix") +#' data.frame( +#' 1:20, sample(70:80, 20, TRUE), +#' sample(70:100, 20, TRUE), +#' sample(70:100, 20, TRUE), +#' sample(170:200, 20, TRUE) +#' ) |> +#' setNames(c("id", "age", "weight_0", "weight_a_1", "height_b_1")) |> +#' wide2long(pattern = c("_0", "_1"), type = "suffix") +#' # Optional filling of missing values by last observation carried forward +#' # Needed for mmrm analyses +#' long_missings |> +#' # Fills record ID assuming none are missing +#' tidyr::fill(record_id) |> +#' # Grouping by ID for the last step +#' dplyr::group_by(record_id) |> +#' # Filling missing data by ID +#' tidyr::fill(names(long_missings)[!names(long_missings) %in% new_names]) |> +#' # Remove grouping +#' dplyr::ungroup() +wide2long <- function( + data, + pattern, + type = c("prefix", "infix", "suffix"), + id.col = 1, + instance.name = "instance") { + type <- match.arg(type) + + ## Give the unique suffix names to use for identifying repeated measures + # suffixes <- c("_0", "_1") + + ## If no ID column is present, one is added + if (id.col == "none" | is.null(id.col)) { + data <- stats::setNames( + data.frame(seq_len(nrow(data)), data), + make.names(c("id", names(data)), unique = TRUE) + ) + id.col <- 1 + } +# browser() + ## Relevant columns are determined based on suffixes + cols <- names(data)[grepl_fix(names(data), pattern = pattern, type = type)] + + ## New colnames are created by removing suffixes + new_names <- unique(gsub(paste(pattern, collapse = "|"), "", cols)) + + out <- split(data, seq_len(nrow(data))) |> # Splits dataset by row + # Starts data modifications for each subject + lapply(\(.x){ + ## Pivots data with repeated measures as determined by the defined suffixes + long_ls <- split.default( + # Subset only repeated data + .x[cols], + # ... and split by meassure + gsub(paste(new_names, collapse = "|"), "", cols) + ) |> + # Sort data by order of given suffixes to ensure chronology + sort_by(pattern) |> + # New colnames are applied + lapply(\(.y){ + setNames( + .y, + gsub(paste(pattern, collapse = "|"), "", names(.y)) + ) + }) + + # Subsets non-pivotted data (this is assumed to belong to same ) + single <- .x[-match(cols, names(.x))] + + # Extends with empty rows to get same dimensions as long data + single[(nrow(single) + 1):length(long_ls), ] <- NA + + # Fills ID col + single[id.col] <- single[1, id.col] + + # Everything is merged together + merged <- dplyr::bind_cols( + single, + # Instance names are defined as suffixes without leading non-characters + REDCapCAST::as_factor(data.frame(gsub( + "^[^[:alnum:]]+", "", + names(long_ls) + ))), + dplyr::bind_rows(long_ls) + ) + + # Ensure unique new names based on supplied + colnames(merged) <- make.names( + c( + names(single), + instance.name, + names(merged)[(NCOL(single) + 2):NCOL(merged)] + ), + unique = TRUE + ) + + merged + }) |> dplyr::bind_rows() + + rownames(out) <- NULL + + out +} + + +#' Matches pattern to vector based on match type +#' +#' @param data vector +#' @param pattern pattern(s) to match. Character vector of length 1 or more. +#' @param type type of match. can be one of "prefix","infix" or "suffix". +#' +#' @returns logical vector +#' @export +#' +#' @examples +#' c("id", "age", "weight_0", "weight_1") |> grepl_fix(pattern = c("_0", "_1"), type = "suffix") +grepl_fix <- function(data, pattern, type = c("prefix", "infix", "suffix")) { + type <- match.arg(type) + + if (type == "prefix") { + grepl(paste0("^(", paste(pattern, collapse = "|"), ")*"), data) + } else if (type == "suffix") { + grepl(paste0("*(", paste(pattern, collapse = "|"), ")$"), data) + } else if (type == "infix") { + grepl(paste0("*(", paste(pattern, collapse = "|"), ")*"), data) + } +} + + +######## +#### Current file: /Users/au301842/FreesearchR/dev/header_include.R +######## + +header_include <- function(){ + shiny::tags$head( + includeHTML("www/umami-app.html"), + tags$link(rel = "stylesheet", type = "text/css", href = "style.css")) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/dev/dev_banner.R +######## + +dev_banner <- function(){ + NULL + } + + +######## +#### Current file: /Users/au301842/FreesearchR/app/ui.R +######## + +# ns <- NS(id) + + + +ui_elements <- list( + ############################################################################## + ######### + ######### Home panel + ######### + ############################################################################## + "home" = bslib::nav_panel( + title = "FreesearchR", + shiny::fluidRow( + ## On building the dev-version for shinyapps.io, the dev_banner() is redefined + ## Default just output "NULL" + ## This could probably be achieved more legantly, but this works. + dev_banner(), + shiny::column(width = 2), + shiny::column( + width = 8, + shiny::markdown(readLines("www/intro.md")), + shiny::column(width = 2) + ) + ), + icon = shiny::icon("home") + ), + ############################################################################## + ######### + ######### Import panel + ######### + ############################################################################## + "import" = bslib::nav_panel( + title = "Import", + shiny::fluidRow( + shiny::column(width = 2), + shiny::column( + width = 8, + shiny::h4("Choose your data source"), + shiny::br(), + # shiny::uiOutput(outputId = "source"), + shinyWidgets::radioGroupButtons( + inputId = "source", + selected = "file", + choices = c( + "File upload" = "file", + "REDCap server export" = "redcap", + "Local or sample data" = "env" + ), + size = "lg" + ), + shiny::tags$script('document.querySelector("#source div").style.width = "100%"'), + shiny::helpText("Upload a file from your device, get data directly from REDCap or select a sample data set for testing from the app."), + shiny::br(), + shiny::br(), + shiny::conditionalPanel( + condition = "input.source=='file'", + import_file_ui( + id = "file_import", + layout_params = "dropdown", + # title = "Choose a datafile to upload", + file_extensions = c(".csv", ".tsv", ".txt", ".xls", ".xlsx", ".rds", ".ods", ".dta") + ) + ), + shiny::conditionalPanel( + condition = "input.source=='redcap'", + shinyWidgets::alert( + id = "redcap-warning", + status = "info", + shiny::tags$h2(shiny::markdown("Careful with sensitive data")), + shiny::tags$p("The", shiny::tags$i(shiny::tags$b("FreesearchR")), "app only stores data for analyses, but please only use with sensitive data when running locally.", "", shiny::tags$a("Read more here", href = "https://agdamsbo.github.io/FreesearchR/#run-locally-on-your-own-machine"), "."), + dismissible = TRUE + ), + m_redcap_readUI( + id = "redcap_import", + title = "" + ) + ), + shiny::conditionalPanel( + condition = "input.source=='env'", + import_globalenv_ui(id = "env", title = NULL) + ), + # shiny::conditionalPanel( + # condition = "input.source=='redcap'", + # DT::DTOutput(outputId = "redcap_prev") + # ), + shiny::conditionalPanel( + condition = "output.data_loaded == true", + shiny::br(), + shiny::actionButton( + inputId = "modal_initial_view", + label = "Quick overview", + width = "100%", + icon = shiny::icon("binoculars"), + disabled = FALSE + ), + shiny::br(), + shiny::br(), + shiny::h5("Select variables for final import"), + shiny::fluidRow( + shiny::column( + width = 6, + shiny::p("Exclude incomplete variables:"), + shiny::br(), + shinyWidgets::noUiSliderInput( + inputId = "complete_cutoff", + label = NULL, + update_on = "end", + min = 0, + max = 100, + step = 5, + value = 30, + format = shinyWidgets::wNumbFormat(decimals = 0), + color = datamods:::get_primary_color() + ), + shiny::helpText("Only include variables missing less observations than the specified percentage."), + shiny::br() + ), + shiny::column( + width = 6, + shiny::p("Manual selection:"), + shiny::br(), + shiny::uiOutput(outputId = "import_var"), + shiny::br() + ) + ), + shiny::uiOutput(outputId = "data_info_import", inline = TRUE), + shiny::br(), + shiny::br(), + shiny::actionButton( + inputId = "act_start", + label = "Start", + width = "100%", + icon = shiny::icon("play"), + disabled = TRUE + ), + shiny::helpText('After importing, hit "Start" or navigate to the desired tab.'), + shiny::br(), + shiny::br() + ), + shiny::column(width = 2) + ), + shiny::br(), + shiny::br() + ) + ), + ############################################################################## + ######### + ######### Data overview panel + ######### + ############################################################################## + "overview" = + # bslib::nav_panel_hidden( + bslib::nav_panel( + # value = "overview", + title = "Data", + bslib::navset_bar( + fillable = TRUE, + bslib::nav_panel( + title = "Overview", + tags$h3("Overview and filtering"), + fluidRow( + shiny::column( + width = 9, + shiny::uiOutput(outputId = "data_info", inline = TRUE), + shiny::tags$p( + "Below is a short summary table, on the right you can click to visualise data classes or browse data and create different data filters." + ) + ), + shiny::column( + width = 3, + shiny::actionButton( + inputId = "modal_visual_overview", + label = "Visual overview", + width = "100%", + disabled = TRUE + ), + shiny::br(), + shiny::br(), + shiny::actionButton( + inputId = "modal_browse", + label = "Browse data", + width = "100%", + disabled = TRUE + ), + shiny::br(), + shiny::br() + ) + ), + fluidRow( + shiny::column( + width = 9, + data_summary_ui(id = "data_summary"), + shiny::br(), + shiny::br(), + shiny::br(), + shiny::br(), + shiny::br() + ), + shiny::column( + width = 3, + # shiny::actionButton( + # inputId = "modal_missings", + # label = "Visual overview", + # width = "100%", + # disabled = TRUE + # ), + # shiny::br(), + # shiny::br(), + # shiny::actionButton( + # inputId = "modal_browse", + # label = "Browse data", + # width = "100%", + # disabled = TRUE + # ), + # shiny::br(), + # shiny::br(), + shiny::tags$h6("Filter data types"), + shiny::uiOutput( + outputId = "column_filter" + ), + shiny::helpText("Read more on how ", tags$a( + "data types", + href = "https://agdamsbo.github.io/FreesearchR/articles/data-types.html", + target = "_blank", + rel = "noopener noreferrer" + ), " are defined."), + shiny::br(), + shiny::br(), + shiny::tags$h6("Filter observations"), + shiny::tags$p("Filter on observation level"), + IDEAFilter::IDEAFilter_ui("data_filter"), + shiny::br(), + shiny::br() + ) + ), + shiny::br(), + shiny::br(), + # shiny::br(), + # shiny::br(), + shiny::br() + ), + bslib::nav_panel( + title = "Modify", + tags$h3("Subset, rename and convert variables"), + fluidRow( + shiny::column( + width = 9, + shiny::tags$p( + shiny::markdown("Below, are several options for simple data manipulation like update variables by renaming, creating new labels (for nicer tables in the report) and changing variable classes (numeric, factor/categorical etc.)."), + shiny::markdown("There are more advanced options to modify factor/categorical variables as well as create new factor from a continous variable or new variables with *R* code. At the bottom you can restore the original data."), + shiny::markdown("Please note that data modifications are applied before any filtering.") + ) + ) + ), + # shiny::tags$br(), + update_variables_ui("modal_variables"), + shiny::tags$br(), + shiny::tags$br(), + shiny::tags$h4("Advanced data manipulation"), + shiny::tags$p("Below options allow more advanced varaible manipulations."), + shiny::tags$br(), + shiny::tags$br(), + shiny::fluidRow( + shiny::column( + width = 4, + shiny::actionButton( + inputId = "modal_update", + label = "Reorder factor levels", + width = "100%" + ), + shiny::tags$br(), + shiny::helpText("Reorder the levels of factor/categorical variables."), + shiny::tags$br(), + shiny::tags$br() + ), + shiny::column( + width = 4, + shiny::actionButton( + inputId = "modal_cut", + label = "New factor", + width = "100%" + ), + shiny::tags$br(), + shiny::helpText("Create factor/categorical variable from a continous variable (number/date/time)."), + shiny::tags$br(), + shiny::tags$br() + ), + shiny::column( + width = 4, + shiny::actionButton( + inputId = "modal_column", + label = "New variable", + width = "100%" + ), + shiny::tags$br(), + shiny::helpText(shiny::markdown("Create a new variable/column based on an *R*-expression.")), + shiny::tags$br(), + shiny::tags$br() + ) + ), + tags$h4("Compare modified data to original"), + shiny::tags$br(), + shiny::tags$p( + "Raw print of the original vs the modified data." + ), + shiny::tags$br(), + shiny::fluidRow( + shiny::column( + width = 6, + shiny::tags$b("Original data:"), + # verbatimTextOutput("original"), + shiny::verbatimTextOutput("original_str") + ), + shiny::column( + width = 6, + shiny::tags$b("Modified data:"), + # verbatimTextOutput("modified"), + shiny::verbatimTextOutput("modified_str") + ) + ), + shiny::tags$br(), + shiny::actionButton( + inputId = "data_reset", + label = "Restore original data", + width = "100%" + ), + shiny::tags$br(), + shiny::helpText("Reset to original imported dataset. Careful! There is no un-doing."), + shiny::tags$br() + ) + ) + ), + ############################################################################## + ######### + ######### Descriptive analyses panel + ######### + ############################################################################## + "describe" = + bslib::nav_panel( + title = "Evaluate", + id = "navdescribe", + bslib::navset_bar( + title = "", + sidebar = bslib::sidebar( + shiny::uiOutput(outputId = "data_info_nochar", inline = TRUE), + bslib::accordion( + open = "acc_chars", + multiple = FALSE, + bslib::accordion_panel( + value = "acc_chars", + title = "Characteristics", + icon = bsicons::bs_icon("table"), + shiny::uiOutput("strat_var"), + shiny::helpText("Only factor/categorical variables are available for stratification. Go back to the 'Data' tab to reclass a variable if it's not on the list."), + shiny::conditionalPanel( + condition = "input.strat_var!='none'", + shiny::radioButtons( + inputId = "add_p", + label = "Compare strata?", + selected = "no", + inline = TRUE, + choices = list( + "No" = "no", + "Yes" = "yes" + ) + ), + shiny::helpText("Option to perform statistical comparisons between strata in baseline table.") + ), + shiny::br(), + shiny::br(), + shiny::actionButton( + inputId = "act_eval", + label = "Evaluate", + width = "100%", + icon = shiny::icon("calculator"), + disabled = TRUE + ) + ), + bslib::accordion_panel( + vlaue = "acc_cor", + title = "Correlations", + icon = bsicons::bs_icon("bounding-box"), + shiny::uiOutput("outcome_var_cor"), + shiny::helpText("To avoid evaluating the correlation of the outcome variable, this can be excluded from the plot or select 'none'."), + shiny::br(), + shinyWidgets::noUiSliderInput( + inputId = "cor_cutoff", + label = "Correlation cut-off", + min = 0, + max = 1, + step = .01, + value = .8, + format = shinyWidgets::wNumbFormat(decimals = 2), + color = datamods:::get_primary_color() + ), + shiny::helpText("Set the cut-off for considered 'highly correlated'.") + ), + bslib::accordion_panel( + vlaue = "acc_mis", + title = "Missings", + icon = bsicons::bs_icon("x-circle"), + shiny::uiOutput("missings_var"), + shiny::helpText("To consider if daata is missing by random, choose the outcome/dependent variable, if it has any missings to evaluate if there is a significant difference across other variables depending on missing data or not.") + ) + ) + ), + bslib::nav_panel( + title = "Characteristics", + gt::gt_output(outputId = "table1") + ), + bslib::nav_panel( + title = "Correlations", + data_correlations_ui(id = "correlations", height = 600) + ), + bslib::nav_panel( + title = "Missings", + data_missings_ui(id = "missingness") + ) + ) + ), + ############################################################################## + ######### + ######### Download panel + ######### + ############################################################################## + "visuals" = bslib::nav_panel( + title = "Visuals", + id = "navvisuals", + do.call( + bslib::navset_bar, + c( + data_visuals_ui("visuals"), + shiny::tagList( + bslib::nav_spacer(), + bslib::nav_item( + # shiny::img(shiny::icon("book")), + shiny::tags$a( + href = "https://agdamsbo.github.io/FreesearchR/articles/visuals.html", + "Notes (external)", + target = "_blank", + rel = "noopener noreferrer" + ) + ) + ) + ) + ) + ), + ############################################################################## + ######### + ######### Regression analyses panel + ######### + ############################################################################## + "analyze" = + bslib::nav_panel( + title = "Regression", + id = "navanalyses", + do.call( + bslib::navset_bar, + regression_ui("regression") + ) + ), + ############################################################################## + ######### + ######### Download panel + ######### + ############################################################################## + "download" = + bslib::nav_panel( + title = "Download", + id = "navdownload", + shiny::fluidRow( + shiny::column(width = 2), + shiny::column( + width = 8, + shiny::fluidRow( + shiny::column( + width = 6, + shiny::h4("Report"), + shiny::helpText("Choose your favourite output file format for further work, and download, when the analyses are done."), + shiny::br(), + shiny::br(), + shiny::selectInput( + inputId = "output_type", + label = "Output format", + selected = NULL, + choices = list( + "MS Word" = "docx", + "LibreOffice" = "odt" + # , + # "PDF" = "pdf", + # "All the above" = "all" + ) + ), + shiny::br(), + # Button + shiny::downloadButton( + outputId = "report", + label = "Download report", + icon = shiny::icon("download") + ) + # 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."), + ), + shiny::column( + width = 6, + shiny::h4("Data"), + shiny::helpText("Choose your favourite output data format to download the modified data."), + shiny::br(), + shiny::br(), + shiny::selectInput( + inputId = "data_type", + label = "Data format", + selected = NULL, + choices = list( + "R" = "rds", + "stata" = "dta", + "CSV" = "csv" + ) + ), + shiny::helpText("No metadata is saved when exporting to csv."), + shiny::br(), + shiny::br(), + # Button + shiny::downloadButton( + outputId = "data_modified", + label = "Download data", + icon = shiny::icon("download") + ) + ) + ), + shiny::br(), + shiny::br(), + shiny::h4("Code snippets"), + shiny::tags$p("Below are the code bits used to create the final data set and the main analyses."), + shiny::tags$p("This can be used as a starting point for learning to code and for reproducibility."), + shiny::tagList( + lapply( + paste0("code_", c( + "import", "format", "data", "variables", "filter", "table1", "univariable", "multivariable" + )), + \(.x)shiny::htmlOutput(outputId = .x) + ) + ), + shiny::tags$br(), + shiny::br() + ), + shiny::column(width = 2) + ) + ), + ############################################################################## + ######### + ######### Feedback link + ######### + ############################################################################## + "feedback" = bslib::nav_item( + # shiny::img(shiny::icon("book")), + shiny::tags$a( + href = "https://redcap.au.dk/surveys/?s=JPCLPTXYDKFA8DA8", + "Feedback", shiny::icon("arrow-up-right-from-square"), + target = "_blank", + rel = "noopener noreferrer" + ) + ), + ############################################################################## + ######### + ######### Documentation link + ######### + ############################################################################## + "docs" = bslib::nav_item( + # shiny::img(shiny::icon("book")), + shiny::tags$a( + href = "https://agdamsbo.github.io/FreesearchR/", + "Docs", shiny::icon("arrow-up-right-from-square"), + target = "_blank", + rel = "noopener noreferrer" + ) + ) + # bslib::nav_panel( + # title = "Documentation", + # # shiny::tags$iframe("www/docs.html", height=600, width=535), + # shiny::htmlOutput("docs_file"), + # shiny::br() + # ) +) +# Initial attempt at creating light and dark versions +light <- custom_theme() +dark <- custom_theme( + bg = "#000", + fg = "#fff" +) + +# Fonts to consider: +# https://webdesignerdepot.com/17-open-source-fonts-youll-actually-love/ + +ui <- bslib::page_fixed( + prismDependencies, + prismRDependency, + header_include(), + ## This adds the actual favicon + ## png and ico versions are kept for compatibility + shiny::tags$head(tags$link(rel = "shortcut icon", href = "favicon.svg")), + title = "FreesearchR", + theme = light, + shiny::useBusyIndicators(), + shinyjs::useShinyjs(), + shiny::div( + id = "loading_page", + # shiny::h1("Loading the FreesearchR app..."), + shinybusy::add_busy_spinner(position = "full-page") + ), + shinyjs::hidden( + shiny::div( + id = "main_content", + bslib::page_navbar( + id = "main_panel", + ui_elements$home, + ui_elements$import, + ui_elements$overview, + ui_elements$describe, + ui_elements$visuals, + ui_elements$analyze, + ui_elements$download, + bslib::nav_spacer(), + ui_elements$feedback, + ui_elements$docs, + fillable = FALSE, + footer = shiny::tags$footer( + style = "background-color: #14131326; padding: 4px; text-align: center; bottom: 0; width: 100%;", + shiny::p( + style = "margin: 1", + "Data is only stored for analyses and deleted when the app is closed.", shiny::markdown("Consider [running ***FreesearchR*** locally](https://agdamsbo.github.io/FreesearchR/#run-locally-on-your-own-machine) if working with sensitive data.") + ), + shiny::p( + style = "margin: 1; color: #888;", + shiny::tags$a("Docs", href = "https://agdamsbo.github.io/FreesearchR/", target = "_blank", rel = "noopener noreferrer"), " | ", hosted_version(), " | ", shiny::tags$a("License: AGPLv3", href = "https://github.com/agdamsbo/FreesearchR/blob/main/LICENSE.md", target = "_blank", rel = "noopener noreferrer"), " | ", shiny::tags$a("Source", href = "https://github.com/agdamsbo/FreesearchR/", target = "_blank", rel = "noopener noreferrer"), " | ", shiny::tags$a("Share feedback", href = "https://redcap.au.dk/surveys/?s=JPCLPTXYDKFA8DA8", target = "_blank", rel = "noopener noreferrer") + ), + ) + ) + ) + ) +) + + +######## +#### Current file: /Users/au301842/FreesearchR/app/server.R +######## + +data(mtcars) + +# trial <- gtsummary::trial +# starwars <- dplyr::starwars +# +# mtcars_na <- rbind(mtcars,NA,NA) + +# thematic::thematic_shiny() + +load_data <- function() { + Sys.sleep(1) + shinyjs::hide("loading_page") + shinyjs::show("main_content") +} + +# is_local = is.na(Sys.getenv('SHINY_SERVER_VERSION', NA)) + +server <- function(input, output, session) { + ## Listing files in www in session start to keep when ending and removing + ## everything else. + files.to.keep <- list.files("www/") + + load_data() + + ############################################################################## + ######### + ######### Night mode (just very popular, not really needed) + ######### + ############################################################################## + + # observeEvent(input$dark_mode,{ + # session$setCurrentTheme( + # if (isTRUE(input$dark_mode)) dark else light + # )}) + + # observe({ + # if(input$dark_mode==TRUE) + # session$setCurrentTheme(bs_theme_update(theme = custom_theme(version = 5))) + # if(input$dark_mode==FALSE) + # session$setCurrentTheme(bs_theme_update(theme = custom_theme(version = 5, bg = "#000",fg="#fff"))) + # }) + + + ############################################################################## + ######### + ######### Setting reactive values + ######### + ############################################################################## + + rv <- shiny::reactiveValues( + list = list(), + regression = NULL, + missings = NULL, + ds = NULL, + local_temp = NULL, + ready = NULL, + test = "no", + data_original = NULL, + data_temp = NULL, + data = NULL, + data_variables = NULL, + data_filtered = NULL, + models = NULL, + code = list() + ) + + ############################################################################## + ######### + ######### Data import section + ######### + ############################################################################## + + data_file <- import_file_server( + id = "file_import", + show_data_in = "popup", + trigger_return = "change", + return_class = "data.frame" + ) + + shiny::observeEvent(data_file$data(), { + shiny::req(data_file$data()) + rv$data_temp <- data_file$data() + rv$code <- modifyList(x = rv$code, list(import = data_file$code())) + }) + + from_redcap <- m_redcap_readServer( + id = "redcap_import" + ) + + shiny::observeEvent(from_redcap$data(), { + rv$data_temp <- from_redcap$data() + rv$code <- modifyList(x = rv$code, list(import = from_redcap$code())) + }) + + from_env <- datamods::import_globalenv_server( + id = "env", + trigger_return = "change", + btn_show_data = FALSE, + reset = reactive(input$hidden) + ) + + shiny::observeEvent(from_env$data(), { + shiny::req(from_env$data()) + + rv$data_temp <- from_env$data() + rv$code <- modifyList(x = rv$code, list(import = from_env$name())) + }) + + visual_summary_server( + id = "initial_summary", + data_r = shiny::reactive({ + shiny::req(rv$data_temp) + default_parsing(rv$data_temp) + }), + palette.fun = FreesearchR_palette + ) + + observeEvent(input$modal_initial_view, { + tryCatch( + { + modal_visual_summary( + id = "initial_summary", + footer = NULL, + size = "xl" + ) + }, + error = function(err) { + showNotification(paste0("We encountered the following error showing missingness: ", err), type = "err") + } + ) + }) + + output$import_var <- shiny::renderUI({ + shiny::req(rv$data_temp) + + preselect <- names(rv$data_temp)[sapply(rv$data_temp, missing_fraction) <= (input$complete_cutoff / 100)] + + shinyWidgets::virtualSelectInput( + inputId = "import_var", + label = "Select variables to include", + selected = preselect, + choices = names(rv$data_temp), + updateOn = "change", + multiple = TRUE, + search = TRUE, + showValueAsTags = TRUE + ) + }) + + output$data_loaded <- shiny::reactive({ + !is.null(rv$data_temp) + }) + + shiny::observeEvent(input$source, { + rv$data_temp <- NULL + }) + + shiny::outputOptions(output, "data_loaded", suspendWhenHidden = FALSE) + + shiny::observeEvent( + eventExpr = list( + input$import_var, + input$complete_cutoff, + rv$data_temp + ), + handlerExpr = { + shiny::req(rv$data_temp) + shiny::req(input$import_var) + # browser() + temp_data <- rv$data_temp + if (all(input$import_var %in% names(temp_data))) { + temp_data <- temp_data |> dplyr::select(input$import_var) + } + + rv$data_original <- temp_data |> + default_parsing() + + rv$code$import <- rv$code$import |> + expression_string(assign.str = "df <-") + + rv$code$format <- list( + "df", + rlang::expr(dplyr::select(dplyr::all_of(!!input$import_var))), + rlang::call2(.fn = "default_parsing", .ns = "FreesearchR") + ) |> + lapply(expression_string) |> + pipe_string() |> + expression_string(assign.str = "df <-") + + rv$code$filter <- NULL + rv$code$modify <- NULL + }, ignoreNULL = FALSE + ) + + output$data_info_import <- shiny::renderUI({ + shiny::req(rv$data_original) + data_description(rv$data_original) + }) + + ## Activating action buttons on data imported + shiny::observeEvent(rv$data_original, { + if (is.null(rv$data_original) | NROW(rv$data_original) == 0) { + shiny::updateActionButton(inputId = "act_start", disabled = TRUE) + shiny::updateActionButton(inputId = "modal_browse", disabled = TRUE) + shiny::updateActionButton(inputId = "modal_visual_overview", disabled = TRUE) + shiny::updateActionButton(inputId = "act_eval", disabled = TRUE) + } else { + shiny::updateActionButton(inputId = "act_start", disabled = FALSE) + shiny::updateActionButton(inputId = "modal_browse", disabled = FALSE) + shiny::updateActionButton(inputId = "modal_visual_overview", disabled = FALSE) + shiny::updateActionButton(inputId = "act_eval", disabled = FALSE) + } + }) + + ############################################################################## + ######### + ######### Data modification section + ######### + ############################################################################## + + shiny::observeEvent( + eventExpr = list( + rv$data_original + ), + handlerExpr = { + shiny::req(rv$data_original) + + rv$data <- rv$data_original + } + ) + + ## For now this solution work, but I would prefer to solve this with the above + shiny::observeEvent(input$reset_confirm, + { + if (isTRUE(input$reset_confirm)) { + shiny::req(rv$data_original) + rv$data <- rv$data_original + rv$code$filter <- NULL + rv$code$variables <- NULL + rv$code$modify <- NULL + } + }, + ignoreNULL = TRUE + ) + + + shiny::observeEvent(input$data_reset, { + shinyWidgets::ask_confirmation( + cancelOnDismiss = TRUE, + inputId = "reset_confirm", + title = "Please confirm data reset?", + type = "warning" + ) + }) + + ######### + ######### Modifications + ######### + + ## Using modified version of the datamods::cut_variable_server function + ## Further modifications are needed to have cut/bin options based on class of variable + ## Could be defined server-side + + output$data_info <- shiny::renderUI({ + shiny::req(data_filter()) + data_description(data_filter(), "The filtered data") + }) + + ######### Create factor + + shiny::observeEvent( + input$modal_cut, + modal_cut_variable("modal_cut", title = "Create new factor") + ) + + data_modal_cut <- cut_variable_server( + id = "modal_cut", + data_r = shiny::reactive(rv$data) + ) + + shiny::observeEvent(data_modal_cut(), { + rv$data <- data_modal_cut() + rv$code$modify[[length(rv$code$modify) + 1]] <- attr(rv$data, "code") + }) + + ######### Modify factor + + shiny::observeEvent( + input$modal_update, + datamods::modal_update_factor(id = "modal_update", title = "Reorder factor levels") + ) + + data_modal_update <- datamods::update_factor_server( + id = "modal_update", + data_r = reactive(rv$data) + ) + + shiny::observeEvent(data_modal_update(), { + shiny::removeModal() + rv$data <- data_modal_update() + rv$code$modify[[length(rv$code$modify) + 1]] <- attr(rv$data, "code") + }) + + ######### Create column + + shiny::observeEvent( + input$modal_column, + modal_create_column( + id = "modal_column", + footer = shiny::markdown("This window is aimed at advanced users and require some *R*-experience!"), + title = "Create new variables" + ) + ) + data_modal_r <- create_column_server( + id = "modal_column", + data_r = reactive(rv$data) + ) + shiny::observeEvent( + data_modal_r(), + { + rv$data <- data_modal_r() + rv$code$modify[[length(rv$code$modify) + 1]] <- attr(rv$data, "code") + } + ) + + ######### Subset, rename, reclass + + updated_data <- update_variables_server( + id = "modal_variables", + data = shiny::reactive(rv$data), + return_data_on_init = FALSE + ) + + shiny::observeEvent(updated_data(), { + rv$data <- updated_data() + rv$code$modify[[length(rv$code$modify) + 1]] <- attr(rv$data, "code") + }) + + ### Column filter + ### Completely implemented, but it takes a little considering where in the + ### data flow to implement, as it will act destructively on previous + ### manipulations + + output$column_filter <- shiny::renderUI({ + shiny::req(rv$data) + # c("dichotomous", "ordinal", "categorical", "datatime", "continuous") + shinyWidgets::virtualSelectInput( + inputId = "column_filter", + label = "Select data types to include", + selected = unique(data_type(rv$data)), + choices = unique(data_type(rv$data)), + updateOn = "change", + multiple = TRUE, + search = FALSE, + showValueAsTags = TRUE + ) + }) + + shiny::observe({ + # shiny::req(input$column_filter) + out <- data_type_filter(rv$data, input$column_filter) + rv$data_variables <- out + if (!is.null(input$column_filter)) { + rv$code$variables <- attr(out, "code") + } + # rv$code$modify[[length(rv$code$modify) + 1]] <- attr(rv$data, "code") + }) + + + ######### Data filter + # IDEAFilter has the least cluttered UI, but might have a License issue + # Consider using shinyDataFilter, though not on CRAN + data_filter <- IDEAFilter::IDEAFilter("data_filter", + data = shiny::reactive(rv$data_variables), + verbose = TRUE + ) + + shiny::observeEvent( + list( + shiny::reactive(rv$data_variables), + shiny::reactive(rv$data_original), + data_filter(), + # regression_vars(), + input$complete_cutoff + ), + { + ### Save filtered data + rv$data_filtered <- data_filter() + + ### Save filtered data + ### without empty factor levels + rv$list$data <- data_filter() |> + REDCapCAST::fct_drop() |> + (\(.x){ + .x[!sapply(.x, is.character)] + })() + + ## This looks messy!! But it works as intended for now + + out <- gsub( + "filter", "dplyr::filter", + gsub( + "\\s{2,}", " ", + paste0( + capture.output(attr(rv$data_filtered, "code")), + collapse = " " + ) + ) + ) + + out <- strsplit(out, "%>%") |> + unlist() |> + (\(.x){ + paste(c("df <- df", .x[-1], "REDCapCAST::fct_drop()"), + collapse = "|> \n " + ) + })() + + rv$code <- append_list(data = out, list = rv$code, index = "filter") + } + ) + + ######### Data preview + + ### Overview + + data_summary_server( + id = "data_summary", + data = shiny::reactive({ + rv$data_filtered + }), + color.main = "#2A004E", + color.sec = "#C62300", + pagination = 10 + ) + + observeEvent(input$modal_browse, { + tryCatch( + { + show_data(REDCapCAST::fct_drop(rv$data_filtered), title = "Uploaded data overview", type = "modal") + }, + error = function(err) { + showNotification(paste0("We encountered the following error browsing your data: ", err), type = "err") + } + ) + }) + + visual_summary_server( + id = "visual_overview", + data_r = shiny::reactive({ + shiny::req(rv$data_filtered) + REDCapCAST::fct_drop(rv$data_filtered) + }), + palette.fun = FreesearchR_palette + ) + + observeEvent(input$modal_visual_overview, { + tryCatch( + { + modal_visual_summary( + id = "visual_overview", + footer = "Here is an overview of how your data is interpreted, and where data is missing. Use this information to consider if data is missing at random or if some observations are missing systematically wich may be caused by an observation bias.", + size = "xl" + ) + }, + error = function(err) { + showNotification(paste0("We encountered the following error showing missingness: ", err), type = "err") + } + ) + }) + + output$original_str <- renderPrint({ + str(rv$data_original) + }) + + output$modified_str <- renderPrint({ + str(as.data.frame(rv$data_filtered) |> + REDCapCAST::set_attr( + label = NULL, + attr = "code" + )) + }) + + ## Evaluation table/plots reset on data change + ## This does not work (!?) + shiny::observeEvent( + list( + rv$data_filtered + ), + { + shiny::req(rv$data_filtered) + + rv$list$table1 <- NULL + } + ) + + + ############################################################################## + ######### + ######### Code export + ######### + ############################################################################## + + ## This really should be collapsed to only one call, but I'll leave it for now + ## as a working example of dynamically defining outputs and rendering. + + # output$code_import <- shiny::renderPrint({ + # shiny::req(rv$code$import) + # cat(c("#Data import\n", rv$code$import)) + # }) + + output$code_import <- shiny::renderUI({ + shiny::req(rv$code$import) + prismCodeBlock(paste0("#Data import\n", rv$code$import)) + }) + + output$code_format <- shiny::renderUI({ + shiny::req(rv$code$format) + prismCodeBlock(paste0("#Data import formatting\n", rv$code$format)) + }) + + output$code_data <- shiny::renderUI({ + shiny::req(rv$code$modify) + # browser() + ## This will create three lines for each modification + # ls <- rv$code$modify + ## This will remove all non-unique entries + # ls <- rv$code$modify |> unique() + ## This will only remove all non-repeating entries + ls <- rv$code$modify[!is_identical_to_previous(rv$code$modify)] + + out <- ls |> + lapply(expression_string) |> + pipe_string() |> + expression_string(assign.str = "df <- df |>\n") + + prismCodeBlock(paste0("#Data modifications\n", out)) + }) + + output$code_variables <- shiny::renderUI({ + shiny::req(rv$code$variables) + out <- expression_string(rv$code$variables, assign.str = "df <- df |>\n") + prismCodeBlock(paste0("#Variables filter\n", out)) + }) + + output$code_filter <- shiny::renderUI({ + shiny::req(rv$code$filter) + prismCodeBlock(paste0("#Data filter\n", rv$code$filter)) + }) + + output$code_table1 <- shiny::renderUI({ + shiny::req(rv$code$table1) + prismCodeBlock(paste0("#Data characteristics table\n", rv$code$table1)) + }) + + + ## Just a note to self + ## This is a very rewarding couple of lines marking new insights to dynamically rendering code + shiny::observe({ + shiny::req(rv$regression) + rv$regression()$regression$models |> purrr::imap(\(.x, .i){ + output[[paste0("code_", tolower(.i))]] <- shiny::renderUI({ + prismCodeBlock(paste0(paste("#", .i, "regression model\n"), .x$code_table)) + }) + }) + }) + + + ############################################################################## + ######### + ######### Data analyses Inputs + ######### + ############################################################################## + + output$strat_var <- shiny::renderUI({ + columnSelectInput( + inputId = "strat_var", + selected = "none", + label = "Select variable to stratify baseline", + data = shiny::reactive(rv$data_filtered)(), + col_subset = c( + "none", + names(rv$data_filtered)[unlist(lapply(rv$data_filtered, data_type)) %in% c("dichotomous", "categorical", "ordinal")] + ) + ) + }) + + ############################################################################## + ######### + ######### Descriptive evaluations + ######### + ############################################################################## + + + output$data_info_nochar <- shiny::renderUI({ + shiny::req(rv$list$data) + data_description(rv$list$data, data_text = "The dataset without text variables") + }) + + shiny::observeEvent( + list( + input$act_eval + ), + { + shiny::req(input$strat_var) + shiny::req(rv$list$data) + + parameters <- list( + by.var = input$strat_var, + add.p = input$add_p == "yes", + add.overall = TRUE + ) + + shiny::withProgress(message = "Creating the table. Hold on for a moment..", { + rv$list$table1 <- rlang::exec(create_baseline, !!!append_list(rv$list$data, parameters, "data")) + }) + + rv$code$table1 <- glue::glue("FreesearchR::create_baseline(df,{list2str(parameters)})") + } + ) + + output$table1 <- gt::render_gt({ + if (!is.null(rv$list$table1)) { + rv$list$table1 |> + gtsummary::as_gt() |> + gt::tab_header(gt::md("**Table 1: Baseline Characteristics**")) + } else { + return(NULL) + } + }) + + output$outcome_var_cor <- shiny::renderUI({ + columnSelectInput( + inputId = "outcome_var_cor", + selected = "none", + data = rv$list$data, + label = "Select outcome variable", + col_subset = c( + "none", + colnames(rv$list$data) + ), + multiple = FALSE + ) + }) + + data_correlations_server( + id = "correlations", + data = shiny::reactive({ + shiny::req(rv$list$data) + out <- rv$list$data + if (!is.null(input$outcome_var_cor) && input$outcome_var_cor != "none") { + out <- out[!names(out) %in% input$outcome_var_cor] + } + out + }), + cutoff = shiny::reactive(input$cor_cutoff) + ) + + output$missings_var <- shiny::renderUI({ + columnSelectInput( + inputId = "missings_var", + label = "Select variable to stratify analysis", + data = shiny::reactive({ + shiny::req(rv$data_filtered) + rv$data_filtered[apply(rv$data_filtered, 2, anyNA)] + })() + ) + }) + + rv$missings <- data_missings_server( + id = "missingness", + data = shiny::reactive(rv$data_filtered), + variable = shiny::reactive(input$missings_var) + ) + + + ############################################################################## + ######### + ######### Data visuals + ######### + ############################################################################## + + pl <- data_visuals_server("visuals", data = shiny::reactive(rv$list$data)) + + ############################################################################## + ######### + ######### Regression model analyses + ######### + ############################################################################## + + rv$regression <- regression_server("regression", data = shiny::reactive(rv$list$data)) + + ############################################################################## + ######### + ######### Page navigation + ######### + ############################################################################## + + shiny::observeEvent(input$act_start, { + bslib::nav_select(id = "main_panel", selected = "Data") + }) + + ############################################################################## + ######### + ######### Reactivity + ######### + ############################################################################## + + output$uploaded <- shiny::reactive({ + if (is.null(rv$ds)) { + "no" + } else { + "yes" + } + }) + + shiny::outputOptions(output, "uploaded", suspendWhenHidden = FALSE) + + output$ready <- shiny::reactive({ + if (is.null(rv$ready)) { + "no" + } else { + "yes" + } + }) + + shiny::outputOptions(output, "ready", suspendWhenHidden = FALSE) + + ############################################################################## + ######### + ######### Downloads + ######### + ############################################################################## + + # Could be rendered with other tables or should show progress + # Investigate quarto render problems + # On temp file handling: https://github.com/quarto-dev/quarto-cli/issues/3992 + output$report <- downloadHandler( + filename = shiny::reactive({ + paste0("report.", input$output_type) + }), + content = function(file, type = input$output_type) { + ## Notification is not progressing + ## Presumably due to missing + # Simplified for .rmd output attempt + format <- ifelse(type == "docx", "word_document", "odt_document") + + rv$list$regression <- rv$regression() + rv$list$missings <- rv$missings() + + shiny::withProgress(message = "Generating the report. Hold on for a moment..", { + tryCatch( + { + rv$list |> + write_rmd( + params.args = list( + regression.p = rv$list$regression$input$add_regression_p + ), + output_format = format, + input = file.path(getwd(), "www/report.rmd") + ) + }, + error = function(err) { + showNotification(paste0("We encountered the following error creating your report: ", err), type = "err") + } + ) + }) + file.rename(paste0("www/report.", type), file) + } + ) + + output$data_modified <- downloadHandler( + filename = shiny::reactive({ + paste0("modified_data.", input$data_type) + }), + content = function(file, type = input$data_type) { + if (type == "rds") { + readr::write_rds(rv$list$data, file = file) + } else if (type == "dta") { + haven::write_dta(as.data.frame(rv$list$data), path = file) + } else if (type == "csv") { + readr::write_csv(rv$list$data, file = file) + } + } + ) + + ############################################################################## + ######### + ######### Clearing the session on end + ######### + ############################################################################## + + session$onSessionEnded(function() { + cat("Session Ended\n") + files <- list.files("www/") + lapply(files[!files %in% files.to.keep], \(.x){ + unlink(paste0("www/", .x), recursive = FALSE) + print(paste(.x, "deleted")) + }) + }) +} + + +######## +#### Current file: /Users/au301842/FreesearchR/app/launch.R +######## + +shinyApp(ui, server) diff --git a/app_docker/www/FreesearchR-logo.png b/app_docker/www/FreesearchR-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..e0f9f99ce3a8c12f5e079e7b0696b62e1bb28787 GIT binary patch literal 22712 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 I2hT(Q3)77O+DL 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 diff --git a/app_docker/www/intro.html b/app_docker/www/intro.html new file mode 100644 index 00000000..f61794b9 --- /dev/null +++ b/app_docker/www/intro.html @@ -0,0 +1,438 @@ + + + + + + + + + + + + + +intro + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app_docker/www/intro.md b/app_docker/www/intro.md new file mode 100644 index 00000000..0b644dcf --- /dev/null +++ b/app_docker/www/intro.md @@ -0,0 +1,31 @@ +# Welcome + +This is the ***FreesearchR*** data analysis tool. We intend ***FreesearchR*** to be a free tool for easy data evaluation and analysis. If you need more advanced tools, start with ***FreesearchR*** and then you'll probably be better off using *R* or similar directly. + +Here is a brief summary of the functions: + +1. **Import data** from a spreadsheet/file on your machine, direct export from a REDCap server, sample data or data from a your local environment if run locally. + +1. **Data inspection** and **modification** like modifying variables or creating new (categorical from numeric or time data, or completely new variables from the data) + +1. **Evaluate data** using descriptive analyses methods and inspect cross-correlations + +1. **Create and export simple, clean plots** for data overview and insights + +1. **Create regression simple models** for even more advanced data analyses + + - Linear, dichotomous or ordinal logistic regression will be used depending on specified outcome variable + + - Plot regression analysis coefficients + + - Evaluate model assumptions + +1. **Export results** + + - Descriptive and regression analyses results for MS Word or [LibreOffice](https://www.libreoffice.org/) + + - Modified data with preserved metadata + + - Code to recreate all steps locally + +The full [project documentation is here](https://agdamsbo.github.io/FreesearchR/) where you'll find detailed description of the app and link to the source code! If you want to [share feedback, please follow this link to a simple survey](https://redcap.au.dk/surveys/?s=JPCLPTXYDKFA8DA8). diff --git a/app_docker/www/references.bib b/app_docker/www/references.bib new file mode 100644 index 00000000..ab4b8b80 --- /dev/null +++ b/app_docker/www/references.bib @@ -0,0 +1,11 @@ + +@book{andreasgammelgaarddamsbo2025, + title = {agdamsbo/FreesearchR: FreesearchR 25.4.3}, + author = {Damsbo, Andreas Gammelgaard}, + year = {2025}, + month = {04}, + date = {2025-04-24}, + publisher = {Zenodo}, + doi = {10.5281/ZENODO.14527429}, + url = {https://zenodo.org/doi/10.5281/zenodo.14527429} +} diff --git a/app_docker/www/report.rmd b/app_docker/www/report.rmd new file mode 100644 index 00000000..fcc6d4d3 --- /dev/null +++ b/app_docker/www/report.rmd @@ -0,0 +1,83 @@ +--- +title: "FreesearchR data report" +date: "Report generated `r gsub('(\\D)0', '\\1', format(Sys.time(), '%A, %d.%m.%Y'))`" +format: docx +author: FreesearchR data analysis tool +toc: false +params: + data.file: NA + version: NA + regression.p: NA +--- + +```{r setup, echo = FALSE} +knitr::opts_chunk$set(echo = FALSE, message = FALSE, warning = FALSE) +# glue::glue("{format(lubridate::today(),'%A')}, {lubridate::day(lubridate::today())}.{lubridate::month(lubridate::today())}.{lubridate::year(lubridate::today())}") +``` + +```{r} +web_data <- readr::read_rds(file = params$data.file) +# web_data <- readr::read_rds(file = "~/FreesearchR/inst/apps/FreesearchR/www/web_data.rds") +library(gtsummary) +library(gt) + +tbl_merge <- function(data) { + if (is.null(names(data))) { + data |> gtsummary::tbl_merge() + } else { + data |> gtsummary::tbl_merge(tab_spanner = names(data)) + } +} + +vec2sentence <- function(data, sep.word = "and") { + sep.word <- paste0(" ", gsub(" ", "", sep.word), " ") + if (length(data) < 2) { + out <- data + } else if (length(data) == 2) { + out <- paste(data, collapse = sep.word) + } else { + out <- paste(paste(data[-length(data)], collapse = ","), data[length(data)], sep = sep.word) + } + return(out) +} +``` + +## Introduction + +Research should be free and open with easy access for all. The *FreesearchR* tool attempts to help lower the bar to participate in research by making basic data exploration and analyses easily accessible. + +## Methods + +Analyses were conducted using the *FreesearchR* data analysis web-tool version `r params$version` based on *R* version 4.4.1. + +## Results + +Below are the baseline characteristics. + +```{r, results = 'asis'} +if ("table1" %in% names(web_data)) { + tbl <- gtsummary::as_gt(web_data$table1) + knitr::knit_print(tbl) +} +``` + +`r if (length(web_data$regression) > 0) glue::glue("Below are the results from the { tolower(vec2sentence(names(web_data$regression$regression$tables)))} {web_data$regression$regression$params$descr}.")` + +```{r, results = 'asis'} +if ("regression" %in% names(web_data) && length(web_data$regression) > 0) { + reg_tbl <- web_data$regression$regression$tables + + merged <- tbl_merge(reg_tbl) + + if (params$regression.p == "no") { + merged <- merged |> + gtsummary::modify_column_hide(column = dplyr::starts_with("p.value")) + } + + knitr::knit_print(merged) +} +``` + +## Discussion + +Good luck on your further work! diff --git a/app_docker/www/style.css b/app_docker/www/style.css new file mode 100644 index 00000000..fedcd1f7 --- /dev/null +++ b/app_docker/www/style.css @@ -0,0 +1,125 @@ + +/*! + * Copyright (c) 2025 FreesearchR + * + * FreesearchR, CSS styles + * https://github.com/agdamsbo/FreesearchR + * + * @version 0.0.1 + */ + +.container-fluid > .nav > li > + a[data-value='FreesearchR'] {font-size: 28px} + + +/* from datamods */ +.show-block { + display: block !important; +} +.show-inline { + display: inline !important; +} +.hidden { + display: none !important; +} +.invisible { + visibility: hidden; +} + +.container-rule { + position: relative; + text-align: center; + height: 25px; + margin-bottom: 5px; +} + +.horizontal-rule { + position: absolute; + top: 11px; + right: 0; + left: 0; + background-color: #d0cfcf; + height: 1px; + z-index: 100; + margin: 0; + border: none; +} + +.label-rule { + background: #FFF; + opacity: 1; + z-index: 101; + background-color: #FFF; + position: relative; + padding: 0 10px 0 10px; +} + +.datamods-table-container { + overflow: auto; + word-break: keep-all; + white-space: nowrap; +} + +.datamods-table-container > .table { + margin-bottom: 0 !important; +} + +.datamods-file-import { + display: grid; + grid-template-columns: auto 50px; + grid-column-gap: 10px; +} + +.datamods-dt-nowrap { + word-break: keep-all; + white-space: nowrap; +} + + + +/* validation */ +.datamods-validation-results { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: 1fr; + height: 50px; + line-height: 50px; + font-size: large; +} + +.datamods-validation-summary { + font-weight: bold; + text-align: center; +} + +.datamods-validation-item { + font-size: larger; +} + + + +/* modified from esquisse for data types */ +.btn-column-categorical { + background-color: #00C896; + color: #FFFFFF; +} +.btn-column-continuous { + background-color: #FFB100; + color: #FFFFFF; +} +.btn-column-dichotomous { + background-color: #8A4FFF; + color: #FFFFFF; +} +.btn-column-datetime { + background-color: #11A0EC; + color: #FFFFFF; +} +.btn-column-id { + background-color: #848484; + color: #FFFFFF; +} +.btn-column-text { + background-color: #2E2E2E; + color: #FFFFFF; +} diff --git a/app_docker/www/umami-app.html b/app_docker/www/umami-app.html new file mode 100644 index 00000000..05820534 --- /dev/null +++ b/app_docker/www/umami-app.html @@ -0,0 +1 @@ + diff --git a/app_docker/www/web_data.rds b/app_docker/www/web_data.rds new file mode 100644 index 0000000000000000000000000000000000000000..d81c8b24c3dbdb079353ec4940d2ce756a9ac1e0 GIT binary patch literal 1737943 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"x!M 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 U?ua#hW$whv9Ei3=hWYXT4@bvznE(I) literal 0 HcmV?d00001 diff --git a/renv.lock b/renv.lock index 442e69c8..074b3f4f 100644 --- a/renv.lock +++ b/renv.lock @@ -8917,54 +8917,6 @@ "Author": "Simon Garnier [aut, cre], Noam Ross [ctb, cph], Bob Rudis [ctb, cph], Marco Sciaini [ctb, cph], Antônio Pedro Camargo [ctb, cph], Cédric Scherer [ctb, cph]", "Repository": "CRAN" }, - "visdat": { - "Package": "visdat", - "Version": "0.6.0", - "Source": "Repository", - "Title": "Preliminary Visualisation of Data", - "Authors@R": "c( person(\"Nicholas\", \"Tierney\", role = c(\"aut\", \"cre\"), email = \"nicholas.tierney@gmail.com\", comment = c(ORCID = \"https://orcid.org/0000-0003-1460-8722\")), person(\"Sean\", \"Hughes\", role = \"rev\", comment =c(ORCID = \"https://orcid.org/0000-0002-9409-9405\", \"Sean Hughes reviewed the package for rOpenSci, see https://github.com/ropensci/onboarding/issues/87\")), person(\"Mara\", \"Averick\", role = \"rev\", comment = \"Mara Averick reviewed the package for rOpenSci, see https://github.com/ropensci/onboarding/issues/87\"), person(\"Stuart\", \"Lee\", role = c(\"ctb\")), person(\"Earo\", \"Wang\", role = c(\"ctb\")), person(\"Nic\", \"Crane\", role = c(\"ctb\")), person(\"Christophe\", \"Regouby\", role=c(\"ctb\")) )", - "Description": "Create preliminary exploratory data visualisations of an entire dataset to identify problems or unexpected features using 'ggplot2'.", - "Depends": [ - "R (>= 3.2.2)" - ], - "License": "MIT + file LICENSE", - "LazyData": "true", - "RoxygenNote": "7.2.3", - "Imports": [ - "ggplot2", - "tidyr", - "dplyr", - "purrr", - "readr", - "magrittr", - "stats", - "tibble", - "glue", - "forcats", - "cli", - "scales" - ], - "URL": "https://docs.ropensci.org/visdat/, https://github.com/ropensci/visdat", - "BugReports": "https://github.com/ropensci/visdat/issues", - "Suggests": [ - "testthat (>= 3.0.0)", - "plotly (>= 4.5.6)", - "knitr", - "rmarkdown", - "vdiffr", - "spelling", - "covr", - "stringr" - ], - "VignetteBuilder": "knitr", - "Encoding": "UTF-8", - "Language": "en-US", - "Config/testthat/edition": "3", - "NeedsCompilation": "no", - "Author": "Nicholas Tierney [aut, cre] (), Sean Hughes [rev] (, Sean Hughes reviewed the package for rOpenSci, see https://github.com/ropensci/onboarding/issues/87), Mara Averick [rev] (Mara Averick reviewed the package for rOpenSci, see https://github.com/ropensci/onboarding/issues/87), Stuart Lee [ctb], Earo Wang [ctb], Nic Crane [ctb], Christophe Regouby [ctb]", - "Maintainer": "Nicholas Tierney ", - "Repository": "CRAN" - }, "vroom": { "Package": "vroom", "Version": "1.6.5", From 6b1a8af175176cd8d2b037ded40a5cf4de3d2596 Mon Sep 17 00:00:00 2001 From: Andreas Gammelgaard Damsbo Date: Thu, 26 Jun 2025 10:42:26 +0200 Subject: [PATCH 7/7] new attempt --- .dockerignore | 6 + .github/workflows/docker-build.yml | 2 +- app_docker/Dockerfile | 4 +- app_docker/renv.lock | 7170 ++++++++++++++++++++++++++++ 4 files changed, 7179 insertions(+), 3 deletions(-) create mode 100644 .dockerignore create mode 100644 app_docker/renv.lock diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..aab0653a --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +.Rhistory +.git +.gitignore +manifest.json +rsconnect/ +.Rproj.user diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 3cd45b8b..de40ad7c 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -41,7 +41,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@v4 with: - context: . + context: app_docker/ file: app_docker/Dockerfile push: true tags: | diff --git a/app_docker/Dockerfile b/app_docker/Dockerfile index 201620ab..47eaca46 100644 --- a/app_docker/Dockerfile +++ b/app_docker/Dockerfile @@ -1,9 +1,9 @@ FROM rocker/geospatial:4.4.1 -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 libfftw3-dev libsodium-dev && rm -rf /var/lib/apt/lists/* +RUN apt-get update -y && apt-get install -y make pandoc zlib1g-dev libicu-dev libcurl4-openssl-dev libsecret-1-dev libxml2-dev libssl-dev libx11-dev libfontconfig1-dev libfreetype6-dev git libsodium-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.4")' +RUN R -e 'remotes::install_version("renv", version = "1.0.3")' 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/ diff --git a/app_docker/renv.lock b/app_docker/renv.lock new file mode 100644 index 00000000..be472d7e --- /dev/null +++ b/app_docker/renv.lock @@ -0,0 +1,7170 @@ +{ + "R": { + "Version": "4.4.1", + "Repositories": [ + { + "Name": "CRAN", + "URL": "https://cloud.r-project.org" + } + ] + }, + "Packages": { + "DT": { + "Package": "DT", + "Version": "0.33", + "Source": "Repository", + "Type": "Package", + "Title": "A Wrapper of the JavaScript Library 'DataTables'", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = \"aut\"), person(\"Joe\", \"Cheng\", email = \"joe@posit.co\", role = c(\"aut\", \"cre\")), person(\"Xianying\", \"Tan\", role = \"aut\"), person(\"JJ\", \"Allaire\", role = \"ctb\"), person(\"Maximilian\", \"Girlich\", role = \"ctb\"), person(\"Greg\", \"Freedman Ellis\", role = \"ctb\"), person(\"Johannes\", \"Rauh\", role = \"ctb\"), person(\"SpryMedia Limited\", role = c(\"ctb\", \"cph\"), comment = \"DataTables in htmlwidgets/lib\"), person(\"Brian\", \"Reavis\", role = c(\"ctb\", \"cph\"), comment = \"selectize.js in htmlwidgets/lib\"), person(\"Leon\", \"Gersen\", role = c(\"ctb\", \"cph\"), comment = \"noUiSlider in htmlwidgets/lib\"), person(\"Bartek\", \"Szopka\", role = c(\"ctb\", \"cph\"), comment = \"jquery.highlight.js in htmlwidgets/lib\"), person(\"Alex\", \"Pickering\", role = c(\"ctb\")), person(\"William\", \"Holmes\", role = c(\"ctb\")), person(\"Mikko\", \"Marttila\", role = c(\"ctb\")), person(\"Andres\", \"Quintero\", role = c(\"ctb\")), person(\"Stéphane\", \"Laurent\", role = c(\"ctb\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Data objects in R can be rendered as HTML tables using the JavaScript library 'DataTables' (typically via R Markdown or Shiny). The 'DataTables' library has been included in this R package. The package name 'DT' is an abbreviation of 'DataTables'.", + "URL": "https://github.com/rstudio/DT", + "BugReports": "https://github.com/rstudio/DT/issues", + "License": "GPL-3 | file LICENSE", + "Imports": [ + "htmltools (>= 0.3.6)", + "htmlwidgets (>= 1.3)", + "httpuv", + "jsonlite (>= 0.9.16)", + "magrittr", + "crosstalk", + "jquerylib", + "promises" + ], + "Suggests": [ + "knitr (>= 1.8)", + "rmarkdown", + "shiny (>= 1.6)", + "bslib", + "future", + "testit", + "tibble" + ], + "VignetteBuilder": "knitr", + "RoxygenNote": "7.3.1", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut], Joe Cheng [aut, cre], Xianying Tan [aut], JJ Allaire [ctb], Maximilian Girlich [ctb], Greg Freedman Ellis [ctb], Johannes Rauh [ctb], SpryMedia Limited [ctb, cph] (DataTables in htmlwidgets/lib), Brian Reavis [ctb, cph] (selectize.js in htmlwidgets/lib), Leon Gersen [ctb, cph] (noUiSlider in htmlwidgets/lib), Bartek Szopka [ctb, cph] (jquery.highlight.js in htmlwidgets/lib), Alex Pickering [ctb], William Holmes [ctb], Mikko Marttila [ctb], Andres Quintero [ctb], Stéphane Laurent [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Joe Cheng ", + "Repository": "CRAN" + }, + "Formula": { + "Package": "Formula", + "Version": "1.2-5", + "Source": "Repository", + "Date": "2023-02-23", + "Title": "Extended Model Formulas", + "Description": "Infrastructure for extended formulas with multiple parts on the right-hand side and/or multiple responses on the left-hand side (see ).", + "Authors@R": "c(person(given = \"Achim\", family = \"Zeileis\", role = c(\"aut\", \"cre\"), email = \"Achim.Zeileis@R-project.org\", comment = c(ORCID = \"0000-0003-0918-3766\")), person(given = \"Yves\", family = \"Croissant\", role = \"aut\", email = \"Yves.Croissant@univ-reunion.fr\"))", + "Depends": [ + "R (>= 2.0.0)", + "stats" + ], + "License": "GPL-2 | GPL-3", + "NeedsCompilation": "no", + "Author": "Achim Zeileis [aut, cre] (), Yves Croissant [aut]", + "Maintainer": "Achim Zeileis ", + "Repository": "CRAN" + }, + "GenSA": { + "Package": "GenSA", + "Version": "1.1.14.1", + "Source": "Repository", + "Type": "Package", + "Title": "R Functions for Generalized Simulated Annealing", + "Date": "2024-01-22", + "Author": "Sylvain Gubian, Yang Xiang, Brian Suomela, Julia Hoeng, PMP SA.", + "Maintainer": "Sylvain Gubian ", + "Depends": [ + "R (>= 2.12.0)" + ], + "Description": "Performs search for global minimum of a very complex non-linear objective function with a very large number of optima.", + "License": "GPL-2", + "LazyLoad": "yes", + "NeedsCompilation": "yes", + "Repository": "CRAN", + "RoxygenNote": "7.2.3" + }, + "Hmisc": { + "Package": "Hmisc", + "Version": "5.2-3", + "Source": "Repository", + "Date": "2025-03-16", + "Title": "Harrell Miscellaneous", + "Authors@R": "c(person(given = \"Frank E\", family = \"Harrell Jr\", role = c(\"aut\", \"cre\"), email = \"fh@fharrell.com\", comment = c(ORCID = \"0000-0002-8271-5493\")), person(given = \"Charles\", family = \"Dupont\", role = \"ctb\", email = \"charles.dupont@vumc.org\", comment = \"contributed several functions and maintains latex functions\"))", + "Maintainer": "Frank E Harrell Jr ", + "Depends": [ + "R (>= 4.2.0)" + ], + "Imports": [ + "methods", + "ggplot2", + "cluster", + "rpart", + "nnet", + "foreign", + "gtable", + "grid", + "gridExtra", + "data.table", + "htmlTable (>= 1.11.0)", + "viridis", + "htmltools", + "base64enc", + "colorspace", + "rmarkdown", + "knitr", + "Formula" + ], + "Suggests": [ + "survival", + "qreport", + "acepack", + "chron", + "rms", + "mice", + "rstudioapi", + "tables", + "plotly (>= 4.5.6)", + "rlang", + "plyr", + "VGAM", + "leaps", + "pcaPP", + "digest", + "parallel", + "polspline", + "abind", + "kableExtra", + "rio", + "lattice", + "latticeExtra", + "gt", + "sparkline", + "jsonlite", + "htmlwidgets", + "qs", + "getPass", + "keyring", + "safer", + "htm2txt" + ], + "Description": "Contains many functions useful for data analysis, high-level graphics, utility operations, functions for computing sample size and power, simulation, importing and annotating datasets, imputing missing values, advanced table making, variable clustering, character string manipulation, conversion of R objects to LaTeX and html code, recoding variables, caching, simplified parallel computing, encrypting and decrypting data using a safe workflow, general moving window statistical estimation, and assistance in interpreting principal component analysis.", + "License": "GPL (>= 2)", + "LazyLoad": "Yes", + "URL": "https://hbiostat.org/R/Hmisc/", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Frank E Harrell Jr [aut, cre] (), Charles Dupont [ctb] (contributed several functions and maintains latex functions)", + "Repository": "CRAN" + }, + "IDEAFilter": { + "Package": "IDEAFilter", + "Version": "0.2.0", + "Source": "Repository", + "Type": "Package", + "Title": "Agnostic, Idiomatic Data Filter Module for Shiny", + "Description": "When added to an existing shiny app, users may subset any developer-chosen R data.frame on the fly. That is, users are empowered to slice & dice data by applying multiple (order specific) filters using the AND (&) operator between each, and getting real-time updates on the number of rows effected/available along the way. Thus, any downstream processes that leverage this data source (like tables, plots, or statistical procedures) will re-render after new filters are applied. The shiny module’s user interface has a 'minimalist' aesthetic so that the focus can be on the data & other visuals. In addition to returning a reactive (filtered) data.frame, 'IDEAFilter' as also returns 'dplyr' filter statements used to actually slice the data.", + "Authors@R": "c( person( given = \"Aaron\", family = \"Clark\", email = \"clark.aaronchris@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-0123-0970\")), person( given = \"Jeff\", family = \"Thompson\", email = \"jeff.thompson51317@gmail.com\", role = \"aut\"), person( given = \"Doug\", family = \"Kelkhoff\", email = \"doug.kelkhoff@gmail.com\", role = c(\"ctb\", \"cph\"), comment = \"Author of shinyDataFilter\"), person( given = \"Maya\", family = \"Gans\", email = \"maya.gans@biogen.com\", role = \"ctb\"), person(family = \"SortableJS contributors\", role = \"ctb\", comment = \"SortableJS library\"), person(given = \"Biogen\", role = \"cph\"))", + "License": "MIT + file LICENSE", + "URL": "https://biogen-inc.github.io/IDEAFilter/, https://github.com/Biogen-Inc/IDEAFilter", + "BugReports": "https://github.com/Biogen-Inc/IDEAFilter/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Imports": [ + "crayon", + "ggplot2", + "pillar (>= 1.5.0)", + "purrr", + "RColorBrewer", + "shiny", + "shinyTime" + ], + "Suggests": [ + "dplyr", + "knitr", + "rmarkdown", + "shinytest", + "shinytest2", + "spelling", + "testthat" + ], + "Language": "en-US", + "VignetteBuilder": "knitr", + "Depends": [ + "R (>= 2.10)" + ], + "NeedsCompilation": "no", + "Author": "Aaron Clark [aut, cre] (), Jeff Thompson [aut], Doug Kelkhoff [ctb, cph] (Author of shinyDataFilter), Maya Gans [ctb], SortableJS contributors [ctb] (SortableJS library), Biogen [cph]", + "Maintainer": "Aaron Clark ", + "Repository": "CRAN" + }, + "KernSmooth": { + "Package": "KernSmooth", + "Version": "2.23-26", + "Source": "Repository", + "Priority": "recommended", + "Date": "2024-12-10", + "Title": "Functions for Kernel Smoothing Supporting Wand & Jones (1995)", + "Authors@R": "c(person(\"Matt\", \"Wand\", role = \"aut\", email = \"Matt.Wand@uts.edu.au\"), person(\"Cleve\", \"Moler\", role = \"ctb\", comment = \"LINPACK routines in src/d*\"), person(\"Brian\", \"Ripley\", role = c(\"trl\", \"cre\", \"ctb\"), email = \"Brian.Ripley@R-project.org\", comment = \"R port and updates\"))", + "Note": "Maintainers are not available to give advice on using a package they did not author.", + "Depends": [ + "R (>= 2.5.0)", + "stats" + ], + "Suggests": [ + "MASS", + "carData" + ], + "Description": "Functions for kernel smoothing (and density estimation) corresponding to the book: Wand, M.P. and Jones, M.C. (1995) \"Kernel Smoothing\".", + "License": "Unlimited", + "ByteCompile": "yes", + "NeedsCompilation": "yes", + "Author": "Matt Wand [aut], Cleve Moler [ctb] (LINPACK routines in src/d*), Brian Ripley [trl, cre, ctb] (R port and updates)", + "Maintainer": "Brian Ripley ", + "Repository": "CRAN" + }, + "MASS": { + "Package": "MASS", + "Version": "7.3-65", + "Source": "Repository", + "Priority": "recommended", + "Date": "2025-02-19", + "Revision": "$Rev: 3681 $", + "Depends": [ + "R (>= 4.4.0)", + "grDevices", + "graphics", + "stats", + "utils" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "lattice", + "nlme", + "nnet", + "survival" + ], + "Authors@R": "c(person(\"Brian\", \"Ripley\", role = c(\"aut\", \"cre\", \"cph\"), email = \"Brian.Ripley@R-project.org\"), person(\"Bill\", \"Venables\", role = c(\"aut\", \"cph\")), person(c(\"Douglas\", \"M.\"), \"Bates\", role = \"ctb\"), person(\"Kurt\", \"Hornik\", role = \"trl\", comment = \"partial port ca 1998\"), person(\"Albrecht\", \"Gebhardt\", role = \"trl\", comment = \"partial port ca 1998\"), person(\"David\", \"Firth\", role = \"ctb\", comment = \"support functions for polr\"))", + "Description": "Functions and datasets to support Venables and Ripley, \"Modern Applied Statistics with S\" (4th edition, 2002).", + "Title": "Support Functions and Datasets for Venables and Ripley's MASS", + "LazyData": "yes", + "ByteCompile": "yes", + "License": "GPL-2 | GPL-3", + "URL": "http://www.stats.ox.ac.uk/pub/MASS4/", + "Contact": "", + "NeedsCompilation": "yes", + "Author": "Brian Ripley [aut, cre, cph], Bill Venables [aut, cph], Douglas M. Bates [ctb], Kurt Hornik [trl] (partial port ca 1998), Albrecht Gebhardt [trl] (partial port ca 1998), David Firth [ctb] (support functions for polr)", + "Maintainer": "Brian Ripley ", + "Repository": "CRAN" + }, + "Matrix": { + "Package": "Matrix", + "Version": "1.7-3", + "Source": "Repository", + "VersionNote": "do also bump src/version.h, inst/include/Matrix/version.h", + "Date": "2025-03-05", + "Priority": "recommended", + "Title": "Sparse and Dense Matrix Classes and Methods", + "Description": "A rich hierarchy of sparse and dense matrix classes, including general, symmetric, triangular, and diagonal matrices with numeric, logical, or pattern entries. Efficient methods for operating on such matrices, often wrapping the 'BLAS', 'LAPACK', and 'SuiteSparse' libraries.", + "License": "GPL (>= 2) | file LICENCE", + "URL": "https://Matrix.R-forge.R-project.org", + "BugReports": "https://R-forge.R-project.org/tracker/?atid=294&group_id=61", + "Contact": "Matrix-authors@R-project.org", + "Authors@R": "c(person(\"Douglas\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Martin\", \"Maechler\", role = c(\"aut\", \"cre\"), email = \"mmaechler+Matrix@gmail.com\", comment = c(ORCID = \"0000-0002-8685-9910\")), person(\"Mikael\", \"Jagan\", role = \"aut\", comment = c(ORCID = \"0000-0002-3542-2938\")), person(\"Timothy A.\", \"Davis\", role = \"ctb\", comment = c(ORCID = \"0000-0001-7614-6899\", \"SuiteSparse libraries\", \"collaborators listed in dir(system.file(\\\"doc\\\", \\\"SuiteSparse\\\", package=\\\"Matrix\\\"), pattern=\\\"License\\\", full.names=TRUE, recursive=TRUE)\")), person(\"George\", \"Karypis\", role = \"ctb\", comment = c(ORCID = \"0000-0003-2753-1437\", \"METIS library\", \"Copyright: Regents of the University of Minnesota\")), person(\"Jason\", \"Riedy\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4345-4200\", \"GNU Octave's condest() and onenormest()\", \"Copyright: Regents of the University of California\")), person(\"Jens\", \"Oehlschlägel\", role = \"ctb\", comment = \"initial nearPD()\"), person(\"R Core Team\", role = \"ctb\", comment = c(ROR = \"02zz1nj61\", \"base R's matrix implementation\")))", + "Depends": [ + "R (>= 4.4)", + "methods" + ], + "Imports": [ + "grDevices", + "graphics", + "grid", + "lattice", + "stats", + "utils" + ], + "Suggests": [ + "MASS", + "datasets", + "sfsmisc", + "tools" + ], + "Enhances": [ + "SparseM", + "graph" + ], + "LazyData": "no", + "LazyDataNote": "not possible, since we use data/*.R and our S4 classes", + "BuildResaveData": "no", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Douglas Bates [aut] (), Martin Maechler [aut, cre] (), Mikael Jagan [aut] (), Timothy A. Davis [ctb] (, SuiteSparse libraries, collaborators listed in dir(system.file(\"doc\", \"SuiteSparse\", package=\"Matrix\"), pattern=\"License\", full.names=TRUE, recursive=TRUE)), George Karypis [ctb] (, METIS library, Copyright: Regents of the University of Minnesota), Jason Riedy [ctb] (, GNU Octave's condest() and onenormest(), Copyright: Regents of the University of California), Jens Oehlschlägel [ctb] (initial nearPD()), R Core Team [ctb] (02zz1nj61, base R's matrix implementation)", + "Maintainer": "Martin Maechler ", + "Repository": "CRAN" + }, + "R.methodsS3": { + "Package": "R.methodsS3", + "Version": "1.8.2", + "Source": "Repository", + "Depends": [ + "R (>= 2.13.0)" + ], + "Imports": [ + "utils" + ], + "Suggests": [ + "codetools" + ], + "Title": "S3 Methods Simplified", + "Authors@R": "c(person(\"Henrik\", \"Bengtsson\", role=c(\"aut\", \"cre\", \"cph\"), email = \"henrikb@braju.com\"))", + "Author": "Henrik Bengtsson [aut, cre, cph]", + "Maintainer": "Henrik Bengtsson ", + "Description": "Methods that simplify the setup of S3 generic functions and S3 methods. Major effort has been made in making definition of methods as simple as possible with a minimum of maintenance for package developers. For example, generic functions are created automatically, if missing, and naming conflict are automatically solved, if possible. The method setMethodS3() is a good start for those who in the future may want to migrate to S4. This is a cross-platform package implemented in pure R that generates standard S3 methods.", + "License": "LGPL (>= 2.1)", + "LazyLoad": "TRUE", + "URL": "https://github.com/HenrikBengtsson/R.methodsS3", + "BugReports": "https://github.com/HenrikBengtsson/R.methodsS3/issues", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "R.oo": { + "Package": "R.oo", + "Version": "1.27.0", + "Source": "Repository", + "Depends": [ + "R (>= 2.13.0)", + "R.methodsS3 (>= 1.8.2)" + ], + "Imports": [ + "methods", + "utils" + ], + "Suggests": [ + "tools" + ], + "Title": "R Object-Oriented Programming with or without References", + "Authors@R": "c(person(\"Henrik\", \"Bengtsson\", role=c(\"aut\", \"cre\", \"cph\"), email = \"henrikb@braju.com\"))", + "Author": "Henrik Bengtsson [aut, cre, cph]", + "Maintainer": "Henrik Bengtsson ", + "Description": "Methods and classes for object-oriented programming in R with or without references. Large effort has been made on making definition of methods as simple as possible with a minimum of maintenance for package developers. The package has been developed since 2001 and is now considered very stable. This is a cross-platform package implemented in pure R that defines standard S3 classes without any tricks.", + "License": "LGPL (>= 2.1)", + "LazyLoad": "TRUE", + "URL": "https://github.com/HenrikBengtsson/R.oo", + "BugReports": "https://github.com/HenrikBengtsson/R.oo/issues", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "R.utils": { + "Package": "R.utils", + "Version": "2.13.0", + "Source": "Repository", + "Depends": [ + "R (>= 2.14.0)", + "R.oo" + ], + "Imports": [ + "methods", + "utils", + "tools", + "R.methodsS3" + ], + "Suggests": [ + "datasets", + "digest (>= 0.6.10)" + ], + "Title": "Various Programming Utilities", + "Authors@R": "c(person(\"Henrik\", \"Bengtsson\", role=c(\"aut\", \"cre\", \"cph\"), email = \"henrikb@braju.com\"))", + "Author": "Henrik Bengtsson [aut, cre, cph]", + "Maintainer": "Henrik Bengtsson ", + "Description": "Utility functions useful when programming and developing R packages.", + "License": "LGPL (>= 2.1)", + "LazyLoad": "TRUE", + "URL": "https://henrikbengtsson.github.io/R.utils/, https://github.com/HenrikBengtsson/R.utils", + "BugReports": "https://github.com/HenrikBengtsson/R.utils/issues", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "R6": { + "Package": "R6", + "Version": "2.6.1", + "Source": "Repository", + "Title": "Encapsulated Classes with Reference Semantics", + "Authors@R": "c( person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Creates classes with reference semantics, similar to R's built-in reference classes. Compared to reference classes, R6 classes are simpler and lighter-weight, and they are not built on S4 classes so they do not require the methods package. These classes allow public and private members, and they support inheritance, even when the classes are defined in different packages.", + "License": "MIT + file LICENSE", + "URL": "https://r6.r-lib.org, https://github.com/r-lib/R6", + "BugReports": "https://github.com/r-lib/R6/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Suggests": [ + "lobstr", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate, ggplot2, microbenchmark, scales", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "RColorBrewer": { + "Package": "RColorBrewer", + "Version": "1.1-3", + "Source": "Repository", + "Date": "2022-04-03", + "Title": "ColorBrewer Palettes", + "Authors@R": "c(person(given = \"Erich\", family = \"Neuwirth\", role = c(\"aut\", \"cre\"), email = \"erich.neuwirth@univie.ac.at\"))", + "Author": "Erich Neuwirth [aut, cre]", + "Maintainer": "Erich Neuwirth ", + "Depends": [ + "R (>= 2.0.0)" + ], + "Description": "Provides color schemes for maps (and other graphics) designed by Cynthia Brewer as described at http://colorbrewer2.org.", + "License": "Apache License 2.0", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "REDCapCAST": { + "Package": "REDCapCAST", + "Version": "25.3.2", + "Source": "Repository", + "Title": "REDCap Metadata Casting and Castellated Data Handling", + "Authors@R": "c( person(\"Andreas Gammelgaard\", \"Damsbo\", email = \"agdamsbo@clin.au.dk\", role = c(\"aut\", \"cre\"),comment = c(ORCID = \"0000-0002-7559-1154\")), person(\"Paul\", \"Egeler\", email = \"paulegeler@gmail.com\", role = c(\"aut\"), comment = c(ORCID = \"0000-0001-6948-9498\")))", + "Description": "Casting metadata for REDCap database creation and handling of castellated data using repeated instruments and longitudinal projects in 'REDCap'. Keeps a focused data export approach, by allowing to only export required data from the database. Also for casting new REDCap databases based on datasets from other sources. Originally forked from the R part of 'REDCapRITS' by Paul Egeler. See . 'REDCap' (Research Electronic Data Capture) is a secure, web-based software platform designed to support data capture for research studies, providing 1) an intuitive interface for validated data capture; 2) audit trails for tracking data manipulation and export procedures; 3) automated export procedures for seamless data downloads to common statistical packages; and 4) procedures for data integration and interoperability with external sources (Harris et al (2009) ; Harris et al (2019) ).", + "Depends": [ + "R (>= 4.1.0)" + ], + "Suggests": [ + "httr", + "jsonlite", + "testthat", + "Hmisc", + "knitr", + "rmarkdown", + "styler", + "devtools", + "roxygen2", + "spelling", + "rhub", + "rsconnect", + "pkgconfig" + ], + "License": "GPL (>= 3)", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "URL": "https://github.com/agdamsbo/REDCapCAST, https://agdamsbo.github.io/REDCapCAST/", + "BugReports": "https://github.com/agdamsbo/REDCapCAST/issues", + "Imports": [ + "dplyr", + "REDCapR", + "tidyr", + "tidyselect", + "keyring", + "purrr", + "readr", + "stats", + "zip", + "assertthat", + "forcats", + "vctrs", + "gt", + "bslib", + "here", + "glue", + "gtsummary", + "shiny", + "haven", + "openxlsx2", + "readODS" + ], + "Language": "en-US", + "VignetteBuilder": "knitr", + "Collate": "'REDCapCAST-package.R' 'utils.r' 'process_user_input.r' 'REDCap_split.r' 'as_factor.R' 'as_logical.R' 'doc2dd.R' 'ds2dd_detailed.R' 'easy_redcap.R' 'export_redcap_instrument.R' 'fct_drop.R' 'html_styling.R' 'mtcars_redcap.R' 'read_redcap_instrument.R' 'read_redcap_tables.R' 'redcap_wider.R' 'redcapcast_data.R' 'redcapcast_meta.R' 'shiny_cast.R'", + "NeedsCompilation": "no", + "Author": "Andreas Gammelgaard Damsbo [aut, cre] (), Paul Egeler [aut] ()", + "Maintainer": "Andreas Gammelgaard Damsbo ", + "Repository": "CRAN" + }, + "REDCapR": { + "Package": "REDCapR", + "Version": "1.4.0", + "Source": "Repository", + "Title": "Interaction Between R and REDCap", + "Description": "Encapsulates functions to streamline calls from R to the REDCap API. REDCap (Research Electronic Data CAPture) is a web application for building and managing online surveys and databases developed at Vanderbilt University. The Application Programming Interface (API) offers an avenue to access and modify data programmatically, improving the capacity for literate and reproducible programming.", + "Authors@R": "c(person(\"Will\", \"Beasley\", role = c(\"aut\", \"cre\"), email = \"wibeasley@hotmail.com\", comment = c(ORCID = \"0000-0002-5613-5006\")), person(\"David\", \"Bard\", role = \"ctb\", comment = c(ORCID = \"0000-0002-3922-8489\")), person(\"Thomas\", \"Wilson\", role = \"ctb\"), person(given=\"John J\", family=\"Aponte\", role = \"ctb\", email=\"john.aponte@isglobal.org\"), person(\"Rollie\", \"Parrish\", role = \"ctb\", email = \"rparrish@flightweb.com\", comment = c(ORCID = \"0000-0001-8858-6381\")), person(\"Benjamin\", \"Nutter\", role = \"ctb\"), person(\"Andrew\", \"Peters\", role = \"ctb\", comment = c(ORCID = \"0000-0003-2487-1268\")), person(\"Hao\", \"Zhu\", role = \"ctb\", comment = c(ORCID = \"0000-0002-3386-6076\")), person(\"Janosch\", \"Linkersdörfer\", role = \"ctb\", comment = c(ORCID = \"0000-0002-1577-1233\")), person(\"Jonathan\", \"Mang\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0518-4710\")), person(\"Felix\", \"Torres\", role = \"ctb\", email = \"fetorres@ucsd.edu\"), person(\"Philip\", \"Chase\", role = \"ctb\", email = \"pbc@ufl.edu\", comment = c(ORCID = \"0000-0002-5318-9420\")), person(\"Victor\", \"Castro\", role = \"ctb\", email = \"vcastro@mgh.harvard.edu\", comment = c(ORCID = \"0000-0001-7390-6354\")), person(\"Greg\", \"Botwin\", role = \"ctb\"), person(\"Stephan\", \"Kadauke\", role = \"ctb\", comment = c(ORCID = \"0000-0003-2996-8034\")), person(\"Ezra\", \"Porter\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4690-8343\")), person(\"Matthew\", \"Schuelke\", role = \"ctb\", email=\"matt@themadstatter.com\", comment = c(ORCID = \"0000-0001-5755-1725\")))", + "URL": "https://ouhscbbmc.github.io/REDCapR/, https://github.com/OuhscBbmc/REDCapR, https://www.ouhsc.edu/bbmc/, https://projectredcap.org", + "BugReports": "https://github.com/OuhscBbmc/REDCapR/issues", + "Depends": [ + "R(>= 3.5.0)" + ], + "Imports": [ + "checkmate (>= 2.0)", + "dplyr (>= 1.0)", + "httr (>= 1.4.0)", + "jsonlite", + "magrittr (>= 1.5)", + "methods", + "readr (>= 2.0)", + "rlang (>= 0.4)", + "tibble (>= 2.0)", + "tidyr (>= 1.0)" + ], + "Suggests": [ + "spelling", + "covr (>= 3.4)", + "DBI (>= 1.1)", + "kableExtra (>= 1.0)", + "knitr", + "odbc (>= 1.1.1)", + "purrr (>= 0.3.4)", + "rmarkdown", + "sessioninfo (>= 1.1.1)", + "testthat (>= 3.0)", + "tidyselect", + "yaml" + ], + "License": "MIT + file LICENSE", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Language": "en-US", + "NeedsCompilation": "no", + "Author": "Will Beasley [aut, cre] (), David Bard [ctb] (), Thomas Wilson [ctb], John J Aponte [ctb], Rollie Parrish [ctb] (), Benjamin Nutter [ctb], Andrew Peters [ctb] (), Hao Zhu [ctb] (), Janosch Linkersdörfer [ctb] (), Jonathan Mang [ctb] (), Felix Torres [ctb], Philip Chase [ctb] (), Victor Castro [ctb] (), Greg Botwin [ctb], Stephan Kadauke [ctb] (), Ezra Porter [ctb] (), Matthew Schuelke [ctb] ()", + "Maintainer": "Will Beasley ", + "Repository": "CRAN" + }, + "Rcpp": { + "Package": "Rcpp", + "Version": "1.0.14", + "Source": "Repository", + "Title": "Seamless R and C++ Integration", + "Date": "2025-01-11", + "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Romain\", \"Francois\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"JJ\", \"Allaire\", role = \"aut\", comment = c(ORCID = \"0000-0003-0174-9868\")), person(\"Kevin\", \"Ushey\", role = \"aut\", comment = c(ORCID = \"0000-0003-2880-7407\")), person(\"Qiang\", \"Kou\", role = \"aut\", comment = c(ORCID = \"0000-0001-6786-5453\")), person(\"Nathan\", \"Russell\", role = \"aut\"), person(\"Iñaki\", \"Ucar\", role = \"aut\", comment = c(ORCID = \"0000-0001-6403-5550\")), person(\"Doug\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"John\", \"Chambers\", role = \"aut\"))", + "Description": "The 'Rcpp' package provides R functions as well as C++ classes which offer a seamless integration of R and C++. Many R data types and objects can be mapped back and forth to C++ equivalents which facilitates both writing of new code as well as easier integration of third-party libraries. Documentation about 'Rcpp' is provided by several vignettes included in this package, via the 'Rcpp Gallery' site at , the paper by Eddelbuettel and Francois (2011, ), the book by Eddelbuettel (2013, ) and the paper by Eddelbuettel and Balamuta (2018, ); see 'citation(\"Rcpp\")' for details.", + "Imports": [ + "methods", + "utils" + ], + "Suggests": [ + "tinytest", + "inline", + "rbenchmark", + "pkgKitten (>= 0.1.2)" + ], + "URL": "https://www.rcpp.org, https://dirk.eddelbuettel.com/code/rcpp.html, https://github.com/RcppCore/Rcpp", + "License": "GPL (>= 2)", + "BugReports": "https://github.com/RcppCore/Rcpp/issues", + "MailingList": "rcpp-devel@lists.r-forge.r-project.org", + "RoxygenNote": "6.1.1", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Dirk Eddelbuettel [aut, cre] (), Romain Francois [aut] (), JJ Allaire [aut] (), Kevin Ushey [aut] (), Qiang Kou [aut] (), Nathan Russell [aut], Iñaki Ucar [aut] (), Doug Bates [aut] (), John Chambers [aut]", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" + }, + "RcppArmadillo": { + "Package": "RcppArmadillo", + "Version": "14.4.2-1", + "Source": "Repository", + "Type": "Package", + "Title": "'Rcpp' Integration for the 'Armadillo' Templated Linear Algebra Library", + "Date": "2025-04-25", + "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Romain\", \"Francois\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Doug\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Binxiang\", \"Ni\", role = \"aut\"), person(\"Conrad\", \"Sanderson\", role = \"aut\", comment = c(ORCID = \"0000-0002-0049-4501\")))", + "Description": "'Armadillo' is a templated C++ linear algebra library (by Conrad Sanderson) that aims towards a good balance between speed and ease of use. Integer, floating point and complex numbers are supported, as well as a subset of trigonometric and statistics functions. Various matrix decompositions are provided through optional integration with LAPACK and ATLAS libraries. The 'RcppArmadillo' package includes the header files from the templated 'Armadillo' library. Thus users do not need to install 'Armadillo' itself in order to use 'RcppArmadillo'. From release 7.800.0 on, 'Armadillo' is licensed under Apache License 2; previous releases were under licensed as MPL 2.0 from version 3.800.0 onwards and LGPL-3 prior to that; 'RcppArmadillo' (the 'Rcpp' bindings/bridge to Armadillo) is licensed under the GNU GPL version 2 or later, as is the rest of 'Rcpp'.", + "License": "GPL (>= 2)", + "LazyLoad": "yes", + "Depends": [ + "R (>= 3.3.0)" + ], + "LinkingTo": [ + "Rcpp" + ], + "Imports": [ + "Rcpp (>= 1.0.12)", + "stats", + "utils", + "methods" + ], + "Suggests": [ + "tinytest", + "Matrix (>= 1.3.0)", + "pkgKitten", + "reticulate", + "slam" + ], + "URL": "https://github.com/RcppCore/RcppArmadillo, https://dirk.eddelbuettel.com/code/rcpp.armadillo.html", + "BugReports": "https://github.com/RcppCore/RcppArmadillo/issues", + "RoxygenNote": "6.0.1", + "NeedsCompilation": "yes", + "Author": "Dirk Eddelbuettel [aut, cre] (), Romain Francois [aut] (), Doug Bates [aut] (), Binxiang Ni [aut], Conrad Sanderson [aut] ()", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" + }, + "RcppEigen": { + "Package": "RcppEigen", + "Version": "0.3.4.0.2", + "Source": "Repository", + "Type": "Package", + "Title": "'Rcpp' Integration for the 'Eigen' Templated Linear Algebra Library", + "Date": "2024-08-23", + "Authors@R": "c(person(\"Doug\", \"Bates\", role = \"aut\", comment = c(ORCID = \"0000-0001-8316-9503\")), person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Romain\", \"Francois\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Yixuan\", \"Qiu\", role = \"aut\", comment = c(ORCID = \"0000-0003-0109-6692\")), person(\"Authors of\", \"Eigen\", role = \"cph\", comment = \"Authorship and copyright in included Eigen library as detailed in inst/COPYRIGHTS\"))", + "Copyright": "See the file COPYRIGHTS for various Eigen copyright details", + "Description": "R and 'Eigen' integration using 'Rcpp'. 'Eigen' is a C++ template library for linear algebra: matrices, vectors, numerical solvers and related algorithms. It supports dense and sparse matrices on integer, floating point and complex numbers, decompositions of such matrices, and solutions of linear systems. Its performance on many algorithms is comparable with some of the best implementations based on 'Lapack' and level-3 'BLAS'. The 'RcppEigen' package includes the header files from the 'Eigen' C++ template library. Thus users do not need to install 'Eigen' itself in order to use 'RcppEigen'. Since version 3.1.1, 'Eigen' is licensed under the Mozilla Public License (version 2); earlier version were licensed under the GNU LGPL version 3 or later. 'RcppEigen' (the 'Rcpp' bindings/bridge to 'Eigen') is licensed under the GNU GPL version 2 or later, as is the rest of 'Rcpp'.", + "License": "GPL (>= 2) | file LICENSE", + "LazyLoad": "yes", + "Depends": [ + "R (>= 3.6.0)" + ], + "LinkingTo": [ + "Rcpp" + ], + "Imports": [ + "Rcpp (>= 0.11.0)", + "stats", + "utils" + ], + "Suggests": [ + "Matrix", + "inline", + "tinytest", + "pkgKitten", + "microbenchmark" + ], + "URL": "https://github.com/RcppCore/RcppEigen, https://dirk.eddelbuettel.com/code/rcpp.eigen.html", + "BugReports": "https://github.com/RcppCore/RcppEigen/issues", + "NeedsCompilation": "yes", + "Author": "Doug Bates [aut] (), Dirk Eddelbuettel [aut, cre] (), Romain Francois [aut] (), Yixuan Qiu [aut] (), Authors of Eigen [cph] (Authorship and copyright in included Eigen library as detailed in inst/COPYRIGHTS)", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" + }, + "V8": { + "Package": "V8", + "Version": "6.0.3", + "Source": "Repository", + "Type": "Package", + "Title": "Embedded JavaScript and WebAssembly Engine for R", + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Jan Marvin\", \"Garbuszus\", role = \"ctb\"))", + "Description": "An R interface to V8 : Google's open source JavaScript and WebAssembly engine. This package can be compiled either with V8 version 6 and up or NodeJS when built as a shared library.", + "License": "MIT + file LICENSE", + "URL": "https://jeroen.r-universe.dev/V8", + "BugReports": "https://github.com/jeroen/v8/issues", + "SystemRequirements": "V8 engine version 6+ is needed for ES6 and WASM support. On Linux you can build against libv8-dev (Debian) or v8-devel (Fedora). We also provide static libv8 binaries for most platforms, see the README for details.", + "NeedsCompilation": "yes", + "VignetteBuilder": "knitr", + "Imports": [ + "Rcpp (>= 0.12.12)", + "jsonlite (>= 1.0)", + "curl (>= 1.0)", + "utils" + ], + "LinkingTo": [ + "Rcpp" + ], + "Suggests": [ + "testthat", + "knitr", + "rmarkdown" + ], + "RoxygenNote": "7.3.1", + "Language": "en-US", + "Encoding": "UTF-8", + "Biarch": "true", + "Author": "Jeroen Ooms [aut, cre] (), Jan Marvin Garbuszus [ctb]", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "apexcharter": { + "Package": "apexcharter", + "Version": "0.4.4", + "Source": "Repository", + "Title": "Create Interactive Chart with the JavaScript 'ApexCharts' Library", + "Description": "Provides an 'htmlwidgets' interface to 'apexcharts.js'. 'Apexcharts' is a modern JavaScript charting library to build interactive charts and visualizations with simple API. 'Apexcharts' examples and documentation are available here: .", + "Authors@R": "c( person(\"Victor\", \"Perrier\", email = \"victor.perrier@dreamrs.fr\", role = c(\"aut\", \"cre\")), person(\"Fanny\", \"Meyer\", role = \"aut\"), person(\"Juned\", \"Chhipa\", role = \"cph\", comment = \"apexcharts.js library\"), person(\"Mike\", \"Bostock\", role = \"cph\", comment = \"d3.format library\"))", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "LazyData": "true", + "ByteCompile": "true", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "htmltools", + "htmlwidgets (>= 1.5.3)", + "magrittr", + "rlang", + "ggplot2", + "jsonlite", + "shiny (>= 1.1.0)" + ], + "Suggests": [ + "testthat", + "knitr", + "scales", + "rmarkdown", + "covr" + ], + "RoxygenNote": "7.3.2", + "URL": "https://github.com/dreamRs/apexcharter, https://dreamrs.github.io/apexcharter/", + "BugReports": "https://github.com/dreamRs/apexcharter/issues", + "VignetteBuilder": "knitr", + "NeedsCompilation": "no", + "Author": "Victor Perrier [aut, cre], Fanny Meyer [aut], Juned Chhipa [cph] (apexcharts.js library), Mike Bostock [cph] (d3.format library)", + "Maintainer": "Victor Perrier ", + "Repository": "CRAN" + }, + "askpass": { + "Package": "askpass", + "Version": "1.2.1", + "Source": "Repository", + "Type": "Package", + "Title": "Password Entry Utilities for R, Git, and SSH", + "Authors@R": "person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\"))", + "Description": "Cross-platform utilities for prompting the user for credentials or a passphrase, for example to authenticate with a server or read a protected key. Includes native programs for MacOS and Windows, hence no 'tcltk' is required. Password entry can be invoked in two different ways: directly from R via the askpass() function, or indirectly as password-entry back-end for 'ssh-agent' or 'git-credential' via the SSH_ASKPASS and GIT_ASKPASS environment variables. Thereby the user can be prompted for credentials or a passphrase if needed when R calls out to git or ssh.", + "License": "MIT + file LICENSE", + "URL": "https://r-lib.r-universe.dev/askpass", + "BugReports": "https://github.com/r-lib/askpass/issues", + "Encoding": "UTF-8", + "Imports": [ + "sys (>= 2.1)" + ], + "RoxygenNote": "7.2.3", + "Suggests": [ + "testthat" + ], + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] ()", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "assertthat": { + "Package": "assertthat", + "Version": "0.2.1", + "Source": "Repository", + "Title": "Easy Pre and Post Assertions", + "Authors@R": "person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", c(\"aut\", \"cre\"))", + "Description": "An extension to stopifnot() that makes it easy to declare the pre and post conditions that you code should satisfy, while also producing friendly error messages so that your users know what's gone wrong.", + "License": "GPL-3", + "Imports": [ + "tools" + ], + "Suggests": [ + "testthat", + "covr" + ], + "RoxygenNote": "6.0.1", + "Collate": "'assert-that.r' 'on-failure.r' 'assertions-file.r' 'assertions-scalar.R' 'assertions.r' 'base.r' 'base-comparison.r' 'base-is.r' 'base-logical.r' 'base-misc.r' 'utils.r' 'validate-that.R'", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "backports": { + "Package": "backports", + "Version": "1.5.0", + "Source": "Repository", + "Type": "Package", + "Title": "Reimplementations of Functions Introduced Since R-3.0.0", + "Authors@R": "c( person(\"Michel\", \"Lang\", NULL, \"michellang@gmail.com\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0001-9754-0393\")), person(\"Duncan\", \"Murdoch\", NULL, \"murdoch.duncan@gmail.com\", role = c(\"aut\")), person(\"R Core Team\", role = \"aut\"))", + "Maintainer": "Michel Lang ", + "Description": "Functions introduced or changed since R v3.0.0 are re-implemented in this package. The backports are conditionally exported in order to let R resolve the function name to either the implemented backport, or the respective base version, if available. Package developers can make use of new functions or arguments by selectively importing specific backports to support older installations.", + "URL": "https://github.com/r-lib/backports", + "BugReports": "https://github.com/r-lib/backports/issues", + "License": "GPL-2 | GPL-3", + "NeedsCompilation": "yes", + "ByteCompile": "yes", + "Depends": [ + "R (>= 3.0.0)" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Author": "Michel Lang [cre, aut] (), Duncan Murdoch [aut], R Core Team [aut]", + "Repository": "CRAN" + }, + "base64enc": { + "Package": "base64enc", + "Version": "0.1-3", + "Source": "Repository", + "Title": "Tools for base64 encoding", + "Author": "Simon Urbanek ", + "Maintainer": "Simon Urbanek ", + "Depends": [ + "R (>= 2.9.0)" + ], + "Enhances": [ + "png" + ], + "Description": "This package provides tools for handling base64 encoding. It is more flexible than the orphaned base64 package.", + "License": "GPL-2 | GPL-3", + "URL": "http://www.rforge.net/base64enc", + "NeedsCompilation": "yes", + "Repository": "CRAN" + }, + "bayestestR": { + "Package": "bayestestR", + "Version": "0.15.3", + "Source": "Repository", + "Type": "Package", + "Title": "Understand and Describe Bayesian Models and Posterior Distributions", + "Authors@R": "c(person(given = \"Dominique\", family = \"Makowski\", role = c(\"aut\", \"cre\"), email = \"officialeasystats@gmail.com\", comment = c(ORCID = \"0000-0001-5375-9967\")), person(given = \"Daniel\", family = \"Lüdecke\", role = \"aut\", email = \"d.luedecke@uke.de\", comment = c(ORCID = \"0000-0002-8895-3206\")), person(given = \"Mattan S.\", family = \"Ben-Shachar\", role = \"aut\", email = \"matanshm@post.bgu.ac.il\", comment = c(ORCID = \"0000-0002-4287-4801\")), person(given = \"Indrajeet\", family = \"Patil\", role = \"aut\", email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\")), person(given = \"Micah K.\", family = \"Wilson\", role = \"aut\", email = \"micah.k.wilson@curtin.edu.au\", comment = c(ORCID = \"0000-0003-4143-7308\")), person(given = \"Brenton M.\", family = \"Wiernik\", role = \"aut\", email = \"brenton@wiernik.org\", comment = c(ORCID = \"0000-0001-9560-6336\")), person(given = \"Paul-Christian\", family = \"Bürkner\", role = \"rev\", email = \"paul.buerkner@gmail.com\"), person(given = \"Tristan\", family = \"Mahr\", role = \"rev\", email = \"tristan.mahr@wisc.edu\", comment = c(ORCID = \"0000-0002-8890-5116\")), person(given = \"Henrik\", family = \"Singmann\", role = \"ctb\", email = \"singmann@gmail.com\", comment = c(ORCID = \"0000-0002-4842-3657\")), person(given = \"Quentin F.\", family = \"Gronau\", role = \"ctb\", comment = c(ORCID = \"0000-0001-5510-6943\")), person(given = \"Sam\", family = \"Crawley\", role = \"ctb\", email = \"sam@crawley.nz\", comment = c(ORCID = \"0000-0002-7847-0411\")))", + "Maintainer": "Dominique Makowski ", + "Description": "Provides utilities to describe posterior distributions and Bayesian models. It includes point-estimates such as Maximum A Posteriori (MAP), measures of dispersion (Highest Density Interval - HDI; Kruschke, 2015 ) and indices used for null-hypothesis testing (such as ROPE percentage, pd and Bayes factors). References: Makowski et al. (2021) .", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "insight (>= 1.1.0)", + "datawizard (>= 1.0.2)", + "graphics", + "methods", + "stats", + "utils" + ], + "Suggests": [ + "BayesFactor (>= 0.9.12-4.4)", + "bayesQR", + "bayesplot", + "betareg", + "BH", + "blavaan", + "bridgesampling", + "brms", + "collapse", + "curl", + "effectsize", + "emmeans", + "gamm4", + "ggdist", + "ggplot2", + "glmmTMB", + "httr2", + "KernSmooth", + "knitr", + "lavaan", + "lme4", + "logspline (>= 2.1.21)", + "marginaleffects (>= 0.25.0)", + "MASS", + "mclust", + "mediation", + "modelbased", + "ordbetareg", + "parameters", + "patchwork", + "performance", + "posterior", + "quadprog", + "RcppEigen", + "rmarkdown", + "rstan", + "rstanarm", + "see (>= 0.8.5)", + "testthat", + "tweedie", + "withr" + ], + "License": "GPL-3", + "URL": "https://easystats.github.io/bayestestR/", + "BugReports": "https://github.com/easystats/bayestestR/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/rcmdcheck/ignore-inconsequential-notes": "true", + "Config/Needs/website": "easystats/easystatstemplate", + "Config/Needs/check": "stan-dev/cmdstanr", + "NeedsCompilation": "no", + "Author": "Dominique Makowski [aut, cre] (), Daniel Lüdecke [aut] (), Mattan S. Ben-Shachar [aut] (), Indrajeet Patil [aut] (), Micah K. Wilson [aut] (), Brenton M. Wiernik [aut] (), Paul-Christian Bürkner [rev], Tristan Mahr [rev] (), Henrik Singmann [ctb] (), Quentin F. Gronau [ctb] (), Sam Crawley [ctb] ()", + "Repository": "CRAN" + }, + "bigD": { + "Package": "bigD", + "Version": "0.3.1", + "Source": "Repository", + "Type": "Package", + "Title": "Flexibly Format Dates and Times to a Given Locale", + "Description": "Format dates and times flexibly and to whichever locales make sense. Parses dates, times, and date-times in various formats (including string-based ISO 8601 constructions). The formatting syntax gives the user many options for formatting the date and time output in a precise manner. Time zones in the input can be expressed in multiple ways and there are many options for formatting time zones in the output as well. Several of the provided helper functions allow for automatic generation of locale-aware formatting patterns based on date/time skeleton formats and standardized date/time formats with varying specificity.", + "Authors@R": "c( person(\"Richard\", \"Iannone\", , \"rich@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Olivier\", \"Roy\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/bigD/, https://github.com/rstudio/bigD", + "BugReports": "https://github.com/rstudio/bigD/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Depends": [ + "R (>= 3.6.0)" + ], + "Suggests": [ + "testthat (>= 3.0.0)", + "vctrs (>= 0.5.0)" + ], + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "NeedsCompilation": "no", + "Author": "Richard Iannone [aut, cre] (), Olivier Roy [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Richard Iannone ", + "Repository": "CRAN" + }, + "bit": { + "Package": "bit", + "Version": "4.6.0", + "Source": "Repository", + "Title": "Classes and Methods for Fast Memory-Efficient Boolean Selections", + "Authors@R": "c( person(\"Michael\", \"Chirico\", email = \"MichaelChirico4@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Jens\", \"Oehlschlägel\", role = \"aut\"), person(\"Brian\", \"Ripley\", role = \"ctb\") )", + "Depends": [ + "R (>= 3.4.0)" + ], + "Suggests": [ + "testthat (>= 3.0.0)", + "roxygen2", + "knitr", + "markdown", + "rmarkdown", + "microbenchmark", + "bit64 (>= 4.0.0)", + "ff (>= 4.0.0)" + ], + "Description": "Provided are classes for boolean and skewed boolean vectors, fast boolean methods, fast unique and non-unique integer sorting, fast set operations on sorted and unsorted sets of integers, and foundations for ff (range index, compression, chunked processing).", + "License": "GPL-2 | GPL-3", + "LazyLoad": "yes", + "ByteCompile": "yes", + "Encoding": "UTF-8", + "URL": "https://github.com/r-lib/bit", + "VignetteBuilder": "knitr, rmarkdown", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Michael Chirico [aut, cre], Jens Oehlschlägel [aut], Brian Ripley [ctb]", + "Maintainer": "Michael Chirico ", + "Repository": "CRAN" + }, + "bit64": { + "Package": "bit64", + "Version": "4.6.0-1", + "Source": "Repository", + "Title": "A S3 Class for Vectors of 64bit Integers", + "Authors@R": "c( person(\"Michael\", \"Chirico\", email = \"michaelchirico4@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Jens\", \"Oehlschlägel\", role = \"aut\"), person(\"Leonardo\", \"Silvestri\", role = \"ctb\"), person(\"Ofek\", \"Shilon\", role = \"ctb\") )", + "Depends": [ + "R (>= 3.4.0)", + "bit (>= 4.0.0)" + ], + "Description": "Package 'bit64' provides serializable S3 atomic 64bit (signed) integers. These are useful for handling database keys and exact counting in +-2^63. WARNING: do not use them as replacement for 32bit integers, integer64 are not supported for subscripting by R-core and they have different semantics when combined with double, e.g. integer64 + double => integer64. Class integer64 can be used in vectors, matrices, arrays and data.frames. Methods are available for coercion from and to logicals, integers, doubles, characters and factors as well as many elementwise and summary functions. Many fast algorithmic operations such as 'match' and 'order' support inter- active data exploration and manipulation and optionally leverage caching.", + "License": "GPL-2 | GPL-3", + "LazyLoad": "yes", + "ByteCompile": "yes", + "URL": "https://github.com/r-lib/bit64", + "Encoding": "UTF-8", + "Imports": [ + "graphics", + "methods", + "stats", + "utils" + ], + "Suggests": [ + "testthat (>= 3.0.3)", + "withr" + ], + "Config/testthat/edition": "3", + "Config/needs/development": "testthat", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Michael Chirico [aut, cre], Jens Oehlschlägel [aut], Leonardo Silvestri [ctb], Ofek Shilon [ctb]", + "Maintainer": "Michael Chirico ", + "Repository": "CRAN" + }, + "bitops": { + "Package": "bitops", + "Version": "1.0-9", + "Source": "Repository", + "Date": "2024-10-03", + "Authors@R": "c( person(\"Steve\", \"Dutky\", role = \"aut\", email = \"sdutky@terpalum.umd.edu\", comment = \"S original; then (after MM's port) revised and modified\"), person(\"Martin\", \"Maechler\", role = c(\"cre\", \"aut\"), email = \"maechler@stat.math.ethz.ch\", comment = c(\"Initial R port; tweaks\", ORCID = \"0000-0002-8685-9910\")))", + "Title": "Bitwise Operations", + "Description": "Functions for bitwise operations on integer vectors.", + "License": "GPL (>= 2)", + "URL": "https://github.com/mmaechler/R-bitops", + "BugReports": "https://github.com/mmaechler/R-bitops/issues", + "NeedsCompilation": "yes", + "Author": "Steve Dutky [aut] (S original; then (after MM's port) revised and modified), Martin Maechler [cre, aut] (Initial R port; tweaks, )", + "Maintainer": "Martin Maechler ", + "Repository": "CRAN" + }, + "broom": { + "Package": "broom", + "Version": "1.0.8", + "Source": "Repository", + "Type": "Package", + "Title": "Convert Statistical Objects into Tidy Tibbles", + "Authors@R": "c(person(given = \"David\", family = \"Robinson\", role = \"aut\", email = \"admiral.david@gmail.com\"), person(given = \"Alex\", family = \"Hayes\", role = \"aut\", email = \"alexpghayes@gmail.com\", comment = c(ORCID = \"0000-0002-4985-5160\")), person(given = \"Simon\", family = \"Couch\", role = c(\"aut\", \"cre\"), email = \"simon.couch@posit.co\", comment = c(ORCID = \"0000-0001-5676-5107\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(given = \"Indrajeet\", family = \"Patil\", role = \"ctb\", email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\")), person(given = \"Derek\", family = \"Chiu\", role = \"ctb\", email = \"dchiu@bccrc.ca\"), person(given = \"Matthieu\", family = \"Gomez\", role = \"ctb\", email = \"mattg@princeton.edu\"), person(given = \"Boris\", family = \"Demeshev\", role = \"ctb\", email = \"boris.demeshev@gmail.com\"), person(given = \"Dieter\", family = \"Menne\", role = \"ctb\", email = \"dieter.menne@menne-biomed.de\"), person(given = \"Benjamin\", family = \"Nutter\", role = \"ctb\", email = \"nutter@battelle.org\"), person(given = \"Luke\", family = \"Johnston\", role = \"ctb\", email = \"luke.johnston@mail.utoronto.ca\"), person(given = \"Ben\", family = \"Bolker\", role = \"ctb\", email = \"bolker@mcmaster.ca\"), person(given = \"Francois\", family = \"Briatte\", role = \"ctb\", email = \"f.briatte@gmail.com\"), person(given = \"Jeffrey\", family = \"Arnold\", role = \"ctb\", email = \"jeffrey.arnold@gmail.com\"), person(given = \"Jonah\", family = \"Gabry\", role = \"ctb\", email = \"jsg2201@columbia.edu\"), person(given = \"Luciano\", family = \"Selzer\", role = \"ctb\", email = \"luciano.selzer@gmail.com\"), person(given = \"Gavin\", family = \"Simpson\", role = \"ctb\", email = \"ucfagls@gmail.com\"), person(given = \"Jens\", family = \"Preussner\", role = \"ctb\", email = \" jens.preussner@mpi-bn.mpg.de\"), person(given = \"Jay\", family = \"Hesselberth\", role = \"ctb\", email = \"jay.hesselberth@gmail.com\"), person(given = \"Hadley\", family = \"Wickham\", role = \"ctb\", email = \"hadley@posit.co\"), person(given = \"Matthew\", family = \"Lincoln\", role = \"ctb\", email = \"matthew.d.lincoln@gmail.com\"), person(given = \"Alessandro\", family = \"Gasparini\", role = \"ctb\", email = \"ag475@leicester.ac.uk\"), person(given = \"Lukasz\", family = \"Komsta\", role = \"ctb\", email = \"lukasz.komsta@umlub.pl\"), person(given = \"Frederick\", family = \"Novometsky\", role = \"ctb\"), person(given = \"Wilson\", family = \"Freitas\", role = \"ctb\"), person(given = \"Michelle\", family = \"Evans\", role = \"ctb\"), person(given = \"Jason Cory\", family = \"Brunson\", role = \"ctb\", email = \"cornelioid@gmail.com\"), person(given = \"Simon\", family = \"Jackson\", role = \"ctb\", email = \"drsimonjackson@gmail.com\"), person(given = \"Ben\", family = \"Whalley\", role = \"ctb\", email = \"ben.whalley@plymouth.ac.uk\"), person(given = \"Karissa\", family = \"Whiting\", role = \"ctb\", email = \"karissa.whiting@gmail.com\"), person(given = \"Yves\", family = \"Rosseel\", role = \"ctb\", email = \"yrosseel@gmail.com\"), person(given = \"Michael\", family = \"Kuehn\", role = \"ctb\", email = \"mkuehn10@gmail.com\"), person(given = \"Jorge\", family = \"Cimentada\", role = \"ctb\", email = \"cimentadaj@gmail.com\"), person(given = \"Erle\", family = \"Holgersen\", role = \"ctb\", email = \"erle.holgersen@gmail.com\"), person(given = \"Karl\", family = \"Dunkle Werner\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0523-7309\")), person(given = \"Ethan\", family = \"Christensen\", role = \"ctb\", email = \"christensen.ej@gmail.com\"), person(given = \"Steven\", family = \"Pav\", role = \"ctb\", email = \"shabbychef@gmail.com\"), person(given = \"Paul\", family = \"PJ\", role = \"ctb\", email = \"pjpaul.stephens@gmail.com\"), person(given = \"Ben\", family = \"Schneider\", role = \"ctb\", email = \"benjamin.julius.schneider@gmail.com\"), person(given = \"Patrick\", family = \"Kennedy\", role = \"ctb\", email = \"pkqstr@protonmail.com\"), person(given = \"Lily\", family = \"Medina\", role = \"ctb\", email = \"lilymiru@gmail.com\"), person(given = \"Brian\", family = \"Fannin\", role = \"ctb\", email = \"captain@pirategrunt.com\"), person(given = \"Jason\", family = \"Muhlenkamp\", role = \"ctb\", email = \"jason.muhlenkamp@gmail.com\"), person(given = \"Matt\", family = \"Lehman\", role = \"ctb\"), person(given = \"Bill\", family = \"Denney\", role = \"ctb\", email = \"wdenney@humanpredictions.com\", comment = c(ORCID = \"0000-0002-5759-428X\")), person(given = \"Nic\", family = \"Crane\", role = \"ctb\"), person(given = \"Andrew\", family = \"Bates\", role = \"ctb\"), person(given = \"Vincent\", family = \"Arel-Bundock\", role = \"ctb\", email = \"vincent.arel-bundock@umontreal.ca\", comment = c(ORCID = \"0000-0003-2042-7063\")), person(given = \"Hideaki\", family = \"Hayashi\", role = \"ctb\"), person(given = \"Luis\", family = \"Tobalina\", role = \"ctb\"), person(given = \"Annie\", family = \"Wang\", role = \"ctb\", email = \"anniewang.uc@gmail.com\"), person(given = \"Wei Yang\", family = \"Tham\", role = \"ctb\", email = \"weiyang.tham@gmail.com\"), person(given = \"Clara\", family = \"Wang\", role = \"ctb\", email = \"clara.wang.94@gmail.com\"), person(given = \"Abby\", family = \"Smith\", role = \"ctb\", email = \"als1@u.northwestern.edu\", comment = c(ORCID = \"0000-0002-3207-0375\")), person(given = \"Jasper\", family = \"Cooper\", role = \"ctb\", email = \"jaspercooper@gmail.com\", comment = c(ORCID = \"0000-0002-8639-3188\")), person(given = \"E Auden\", family = \"Krauska\", role = \"ctb\", email = \"krauskae@gmail.com\", comment = c(ORCID = \"0000-0002-1466-5850\")), person(given = \"Alex\", family = \"Wang\", role = \"ctb\", email = \"x249wang@uwaterloo.ca\"), person(given = \"Malcolm\", family = \"Barrett\", role = \"ctb\", email = \"malcolmbarrett@gmail.com\", comment = c(ORCID = \"0000-0003-0299-5825\")), person(given = \"Charles\", family = \"Gray\", role = \"ctb\", email = \"charlestigray@gmail.com\", comment = c(ORCID = \"0000-0002-9978-011X\")), person(given = \"Jared\", family = \"Wilber\", role = \"ctb\"), person(given = \"Vilmantas\", family = \"Gegzna\", role = \"ctb\", email = \"GegznaV@gmail.com\", comment = c(ORCID = \"0000-0002-9500-5167\")), person(given = \"Eduard\", family = \"Szoecs\", role = \"ctb\", email = \"eduardszoecs@gmail.com\"), person(given = \"Frederik\", family = \"Aust\", role = \"ctb\", email = \"frederik.aust@uni-koeln.de\", comment = c(ORCID = \"0000-0003-4900-788X\")), person(given = \"Angus\", family = \"Moore\", role = \"ctb\", email = \"angusmoore9@gmail.com\"), person(given = \"Nick\", family = \"Williams\", role = \"ctb\", email = \"ntwilliams.personal@gmail.com\"), person(given = \"Marius\", family = \"Barth\", role = \"ctb\", email = \"marius.barth.uni.koeln@gmail.com\", comment = c(ORCID = \"0000-0002-3421-6665\")), person(given = \"Bruna\", family = \"Wundervald\", role = \"ctb\", email = \"brunadaviesw@gmail.com\", comment = c(ORCID = \"0000-0001-8163-220X\")), person(given = \"Joyce\", family = \"Cahoon\", role = \"ctb\", email = \"joyceyu48@gmail.com\", comment = c(ORCID = \"0000-0001-7217-4702\")), person(given = \"Grant\", family = \"McDermott\", role = \"ctb\", email = \"grantmcd@uoregon.edu\", comment = c(ORCID = \"0000-0001-7883-8573\")), person(given = \"Kevin\", family = \"Zarca\", role = \"ctb\", email = \"kevin.zarca@gmail.com\"), person(given = \"Shiro\", family = \"Kuriwaki\", role = \"ctb\", email = \"shirokuriwaki@gmail.com\", comment = c(ORCID = \"0000-0002-5687-2647\")), person(given = \"Lukas\", family = \"Wallrich\", role = \"ctb\", email = \"lukas.wallrich@gmail.com\", comment = c(ORCID = \"0000-0003-2121-5177\")), person(given = \"James\", family = \"Martherus\", role = \"ctb\", email = \"james@martherus.com\", comment = c(ORCID = \"0000-0002-8285-3300\")), person(given = \"Chuliang\", family = \"Xiao\", role = \"ctb\", email = \"cxiao@umich.edu\", comment = c(ORCID = \"0000-0002-8466-9398\")), person(given = \"Joseph\", family = \"Larmarange\", role = \"ctb\", email = \"joseph@larmarange.net\"), person(given = \"Max\", family = \"Kuhn\", role = \"ctb\", email = \"max@posit.co\"), person(given = \"Michal\", family = \"Bojanowski\", role = \"ctb\", email = \"michal2992@gmail.com\"), person(given = \"Hakon\", family = \"Malmedal\", role = \"ctb\", email = \"hmalmedal@gmail.com\"), person(given = \"Clara\", family = \"Wang\", role = \"ctb\"), person(given = \"Sergio\", family = \"Oller\", role = \"ctb\", email = \"sergioller@gmail.com\"), person(given = \"Luke\", family = \"Sonnet\", role = \"ctb\", email = \"luke.sonnet@gmail.com\"), person(given = \"Jim\", family = \"Hester\", role = \"ctb\", email = \"jim.hester@posit.co\"), person(given = \"Ben\", family = \"Schneider\", role = \"ctb\", email = \"benjamin.julius.schneider@gmail.com\"), person(given = \"Bernie\", family = \"Gray\", role = \"ctb\", email = \"bfgray3@gmail.com\", comment = c(ORCID = \"0000-0001-9190-6032\")), person(given = \"Mara\", family = \"Averick\", role = \"ctb\", email = \"mara@posit.co\"), person(given = \"Aaron\", family = \"Jacobs\", role = \"ctb\", email = \"atheriel@gmail.com\"), person(given = \"Andreas\", family = \"Bender\", role = \"ctb\", email = \"bender.at.R@gmail.com\"), person(given = \"Sven\", family = \"Templer\", role = \"ctb\", email = \"sven.templer@gmail.com\"), person(given = \"Paul-Christian\", family = \"Buerkner\", role = \"ctb\", email = \"paul.buerkner@gmail.com\"), person(given = \"Matthew\", family = \"Kay\", role = \"ctb\", email = \"mjskay@umich.edu\"), person(given = \"Erwan\", family = \"Le Pennec\", role = \"ctb\", email = \"lepennec@gmail.com\"), person(given = \"Johan\", family = \"Junkka\", role = \"ctb\", email = \"johan.junkka@umu.se\"), person(given = \"Hao\", family = \"Zhu\", role = \"ctb\", email = \"haozhu233@gmail.com\"), person(given = \"Benjamin\", family = \"Soltoff\", role = \"ctb\", email = \"soltoffbc@uchicago.edu\"), person(given = \"Zoe\", family = \"Wilkinson Saldana\", role = \"ctb\", email = \"zoewsaldana@gmail.com\"), person(given = \"Tyler\", family = \"Littlefield\", role = \"ctb\", email = \"tylurp1@gmail.com\"), person(given = \"Charles T.\", family = \"Gray\", role = \"ctb\", email = \"charlestigray@gmail.com\"), person(given = \"Shabbh E.\", family = \"Banks\", role = \"ctb\"), person(given = \"Serina\", family = \"Robinson\", role = \"ctb\", email = \"robi0916@umn.edu\"), person(given = \"Roger\", family = \"Bivand\", role = \"ctb\", email = \"Roger.Bivand@nhh.no\"), person(given = \"Riinu\", family = \"Ots\", role = \"ctb\", email = \"riinuots@gmail.com\"), person(given = \"Nicholas\", family = \"Williams\", role = \"ctb\", email = \"ntwilliams.personal@gmail.com\"), person(given = \"Nina\", family = \"Jakobsen\", role = \"ctb\"), person(given = \"Michael\", family = \"Weylandt\", role = \"ctb\", email = \"michael.weylandt@gmail.com\"), person(given = \"Lisa\", family = \"Lendway\", role = \"ctb\", email = \"llendway@macalester.edu\"), person(given = \"Karl\", family = \"Hailperin\", role = \"ctb\", email = \"khailper@gmail.com\"), person(given = \"Josue\", family = \"Rodriguez\", role = \"ctb\", email = \"jerrodriguez@ucdavis.edu\"), person(given = \"Jenny\", family = \"Bryan\", role = \"ctb\", email = \"jenny@posit.co\"), person(given = \"Chris\", family = \"Jarvis\", role = \"ctb\", email = \"Christopher1.jarvis@gmail.com\"), person(given = \"Greg\", family = \"Macfarlane\", role = \"ctb\", email = \"gregmacfarlane@gmail.com\"), person(given = \"Brian\", family = \"Mannakee\", role = \"ctb\", email = \"bmannakee@gmail.com\"), person(given = \"Drew\", family = \"Tyre\", role = \"ctb\", email = \"atyre2@unl.edu\"), person(given = \"Shreyas\", family = \"Singh\", role = \"ctb\", email = \"shreyas.singh.298@gmail.com\"), person(given = \"Laurens\", family = \"Geffert\", role = \"ctb\", email = \"laurensgeffert@gmail.com\"), person(given = \"Hong\", family = \"Ooi\", role = \"ctb\", email = \"hongooi@microsoft.com\"), person(given = \"Henrik\", family = \"Bengtsson\", role = \"ctb\", email = \"henrikb@braju.com\"), person(given = \"Eduard\", family = \"Szocs\", role = \"ctb\", email = \"eduardszoecs@gmail.com\"), person(given = \"David\", family = \"Hugh-Jones\", role = \"ctb\", email = \"davidhughjones@gmail.com\"), person(given = \"Matthieu\", family = \"Stigler\", role = \"ctb\", email = \"Matthieu.Stigler@gmail.com\"), person(given = \"Hugo\", family = \"Tavares\", role = \"ctb\", email = \"hm533@cam.ac.uk\", comment = c(ORCID = \"0000-0001-9373-2726\")), person(given = \"R. Willem\", family = \"Vervoort\", role = \"ctb\", email = \"Willemvervoort@gmail.com\"), person(given = \"Brenton M.\", family = \"Wiernik\", role = \"ctb\", email = \"brenton@wiernik.org\"), person(given = \"Josh\", family = \"Yamamoto\", role = \"ctb\", email = \"joshuayamamoto5@gmail.com\"), person(given = \"Jasme\", family = \"Lee\", role = \"ctb\"), person(given = \"Taren\", family = \"Sanders\", role = \"ctb\", email = \"taren.sanders@acu.edu.au\", comment = c(ORCID = \"0000-0002-4504-6008\")), person(given = \"Ilaria\", family = \"Prosdocimi\", role = \"ctb\", email = \"prosdocimi.ilaria@gmail.com\", comment = c(ORCID = \"0000-0001-8565-094X\")), person(given = \"Daniel D.\", family = \"Sjoberg\", role = \"ctb\", email = \"danield.sjoberg@gmail.com\", comment = c(ORCID = \"0000-0003-0862-2018\")), person(given = \"Alex\", family = \"Reinhart\", role = \"ctb\", email = \"areinhar@stat.cmu.edu\", comment = c(ORCID = \"0000-0002-6658-514X\")))", + "Description": "Summarizes key information about statistical objects in tidy tibbles. This makes it easy to report results, create plots and consistently work with large numbers of models at once. Broom provides three verbs that each provide different types of information about a model. tidy() summarizes information about model components such as coefficients of a regression. glance() reports information about an entire model, such as goodness of fit measures like AIC and BIC. augment() adds information about individual observations to a dataset, such as fitted values or influence measures.", + "License": "MIT + file LICENSE", + "URL": "https://broom.tidymodels.org/, https://github.com/tidymodels/broom", + "BugReports": "https://github.com/tidymodels/broom/issues", + "Depends": [ + "R (>= 3.5)" + ], + "Imports": [ + "backports", + "cli", + "dplyr (>= 1.0.0)", + "generics (>= 0.0.2)", + "glue", + "lifecycle", + "purrr", + "rlang (>= 1.1.0)", + "stringr", + "tibble (>= 3.0.0)", + "tidyr (>= 1.0.0)" + ], + "Suggests": [ + "AER", + "AUC", + "bbmle", + "betareg (>= 3.2-1)", + "biglm", + "binGroup", + "boot", + "btergm (>= 1.10.6)", + "car (>= 3.1-2)", + "carData", + "caret", + "cluster", + "cmprsk", + "coda", + "covr", + "drc", + "e1071", + "emmeans", + "epiR", + "ergm (>= 3.10.4)", + "fixest (>= 0.9.0)", + "gam (>= 1.15)", + "gee", + "geepack", + "ggplot2", + "glmnet", + "glmnetUtils", + "gmm", + "Hmisc", + "irlba", + "interp", + "joineRML", + "Kendall", + "knitr", + "ks", + "Lahman", + "lavaan (>= 0.6.18)", + "leaps", + "lfe", + "lm.beta", + "lme4", + "lmodel2", + "lmtest (>= 0.9.38)", + "lsmeans", + "maps", + "margins", + "MASS", + "mclust", + "mediation", + "metafor", + "mfx", + "mgcv", + "mlogit", + "modeldata", + "modeltests (>= 0.1.6)", + "muhaz", + "multcomp", + "network", + "nnet", + "ordinal", + "plm", + "poLCA", + "psych", + "quantreg", + "rmarkdown", + "robust", + "robustbase", + "rsample", + "sandwich", + "spdep (>= 1.1)", + "spatialreg", + "speedglm", + "spelling", + "survey", + "survival (>= 3.6-4)", + "systemfit", + "testthat (>= 3.0.0)", + "tseries", + "vars", + "zoo" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Language": "en-US", + "Collate": "'aaa-documentation-helper.R' 'null-and-default.R' 'aer.R' 'auc.R' 'base.R' 'bbmle.R' 'betareg.R' 'biglm.R' 'bingroup.R' 'boot.R' 'broom-package.R' 'broom.R' 'btergm.R' 'car.R' 'caret.R' 'cluster.R' 'cmprsk.R' 'data-frame.R' 'deprecated-0-7-0.R' 'drc.R' 'emmeans.R' 'epiR.R' 'ergm.R' 'fixest.R' 'gam.R' 'geepack.R' 'glmnet-cv-glmnet.R' 'glmnet-glmnet.R' 'gmm.R' 'hmisc.R' 'import-standalone-obj-type.R' 'import-standalone-types-check.R' 'joinerml.R' 'kendall.R' 'ks.R' 'lavaan.R' 'leaps.R' 'lfe.R' 'list-irlba.R' 'list-optim.R' 'list-svd.R' 'list-xyz.R' 'list.R' 'lm-beta.R' 'lmodel2.R' 'lmtest.R' 'maps.R' 'margins.R' 'mass-fitdistr.R' 'mass-negbin.R' 'mass-polr.R' 'mass-ridgelm.R' 'stats-lm.R' 'mass-rlm.R' 'mclust.R' 'mediation.R' 'metafor.R' 'mfx.R' 'mgcv.R' 'mlogit.R' 'muhaz.R' 'multcomp.R' 'nnet.R' 'nobs.R' 'ordinal-clm.R' 'ordinal-clmm.R' 'plm.R' 'polca.R' 'psych.R' 'stats-nls.R' 'quantreg-nlrq.R' 'quantreg-rq.R' 'quantreg-rqs.R' 'robust-glmrob.R' 'robust-lmrob.R' 'robustbase-glmrob.R' 'robustbase-lmrob.R' 'sp.R' 'spdep.R' 'speedglm-speedglm.R' 'speedglm-speedlm.R' 'stats-anova.R' 'stats-arima.R' 'stats-decompose.R' 'stats-factanal.R' 'stats-glm.R' 'stats-htest.R' 'stats-kmeans.R' 'stats-loess.R' 'stats-mlm.R' 'stats-prcomp.R' 'stats-smooth.spline.R' 'stats-summary-lm.R' 'stats-time-series.R' 'survey.R' 'survival-aareg.R' 'survival-cch.R' 'survival-coxph.R' 'survival-pyears.R' 'survival-survdiff.R' 'survival-survexp.R' 'survival-survfit.R' 'survival-survreg.R' 'systemfit.R' 'tseries.R' 'utilities.R' 'vars.R' 'zoo.R' 'zzz.R'", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "David Robinson [aut], Alex Hayes [aut] (), Simon Couch [aut, cre] (), Posit Software, PBC [cph, fnd], Indrajeet Patil [ctb] (), Derek Chiu [ctb], Matthieu Gomez [ctb], Boris Demeshev [ctb], Dieter Menne [ctb], Benjamin Nutter [ctb], Luke Johnston [ctb], Ben Bolker [ctb], Francois Briatte [ctb], Jeffrey Arnold [ctb], Jonah Gabry [ctb], Luciano Selzer [ctb], Gavin Simpson [ctb], Jens Preussner [ctb], Jay Hesselberth [ctb], Hadley Wickham [ctb], Matthew Lincoln [ctb], Alessandro Gasparini [ctb], Lukasz Komsta [ctb], Frederick Novometsky [ctb], Wilson Freitas [ctb], Michelle Evans [ctb], Jason Cory Brunson [ctb], Simon Jackson [ctb], Ben Whalley [ctb], Karissa Whiting [ctb], Yves Rosseel [ctb], Michael Kuehn [ctb], Jorge Cimentada [ctb], Erle Holgersen [ctb], Karl Dunkle Werner [ctb] (), Ethan Christensen [ctb], Steven Pav [ctb], Paul PJ [ctb], Ben Schneider [ctb], Patrick Kennedy [ctb], Lily Medina [ctb], Brian Fannin [ctb], Jason Muhlenkamp [ctb], Matt Lehman [ctb], Bill Denney [ctb] (), Nic Crane [ctb], Andrew Bates [ctb], Vincent Arel-Bundock [ctb] (), Hideaki Hayashi [ctb], Luis Tobalina [ctb], Annie Wang [ctb], Wei Yang Tham [ctb], Clara Wang [ctb], Abby Smith [ctb] (), Jasper Cooper [ctb] (), E Auden Krauska [ctb] (), Alex Wang [ctb], Malcolm Barrett [ctb] (), Charles Gray [ctb] (), Jared Wilber [ctb], Vilmantas Gegzna [ctb] (), Eduard Szoecs [ctb], Frederik Aust [ctb] (), Angus Moore [ctb], Nick Williams [ctb], Marius Barth [ctb] (), Bruna Wundervald [ctb] (), Joyce Cahoon [ctb] (), Grant McDermott [ctb] (), Kevin Zarca [ctb], Shiro Kuriwaki [ctb] (), Lukas Wallrich [ctb] (), James Martherus [ctb] (), Chuliang Xiao [ctb] (), Joseph Larmarange [ctb], Max Kuhn [ctb], Michal Bojanowski [ctb], Hakon Malmedal [ctb], Clara Wang [ctb], Sergio Oller [ctb], Luke Sonnet [ctb], Jim Hester [ctb], Ben Schneider [ctb], Bernie Gray [ctb] (), Mara Averick [ctb], Aaron Jacobs [ctb], Andreas Bender [ctb], Sven Templer [ctb], Paul-Christian Buerkner [ctb], Matthew Kay [ctb], Erwan Le Pennec [ctb], Johan Junkka [ctb], Hao Zhu [ctb], Benjamin Soltoff [ctb], Zoe Wilkinson Saldana [ctb], Tyler Littlefield [ctb], Charles T. Gray [ctb], Shabbh E. Banks [ctb], Serina Robinson [ctb], Roger Bivand [ctb], Riinu Ots [ctb], Nicholas Williams [ctb], Nina Jakobsen [ctb], Michael Weylandt [ctb], Lisa Lendway [ctb], Karl Hailperin [ctb], Josue Rodriguez [ctb], Jenny Bryan [ctb], Chris Jarvis [ctb], Greg Macfarlane [ctb], Brian Mannakee [ctb], Drew Tyre [ctb], Shreyas Singh [ctb], Laurens Geffert [ctb], Hong Ooi [ctb], Henrik Bengtsson [ctb], Eduard Szocs [ctb], David Hugh-Jones [ctb], Matthieu Stigler [ctb], Hugo Tavares [ctb] (), R. Willem Vervoort [ctb], Brenton M. Wiernik [ctb], Josh Yamamoto [ctb], Jasme Lee [ctb], Taren Sanders [ctb] (), Ilaria Prosdocimi [ctb] (), Daniel D. Sjoberg [ctb] (), Alex Reinhart [ctb] ()", + "Maintainer": "Simon Couch ", + "Repository": "CRAN" + }, + "broom.helpers": { + "Package": "broom.helpers", + "Version": "1.21.0", + "Source": "Repository", + "Title": "Helpers for Model Coefficients Tibbles", + "Authors@R": "c( person(\"Joseph\", \"Larmarange\", , \"joseph@larmarange.net\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0001-7097-700X\")), person(\"Daniel D.\", \"Sjoberg\", , \"danield.sjoberg@gmail.com\", role = \"aut\", comment = c(ORCID = \"0000-0003-0862-2018\")) )", + "Description": "Provides suite of functions to work with regression model 'broom::tidy()' tibbles. The suite includes functions to group regression model terms by variable, insert reference and header rows for categorical variables, add variable labels, and more.", + "License": "GPL (>= 3)", + "URL": "https://larmarange.github.io/broom.helpers/, https://github.com/larmarange/broom.helpers", + "BugReports": "https://github.com/larmarange/broom.helpers/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "broom (>= 0.8)", + "cards", + "cli", + "dplyr (>= 1.1.0)", + "labelled", + "lifecycle", + "purrr", + "rlang (>= 1.0.1)", + "stats", + "stringr", + "tibble", + "tidyr", + "tidyselect" + ], + "Suggests": [ + "betareg", + "biglm", + "brms (>= 2.13.0)", + "broom.mixed", + "cmprsk", + "covr", + "datasets", + "effects", + "emmeans", + "fixest (>= 0.10.0)", + "forcats", + "gam", + "gee", + "geepack", + "ggplot2", + "ggeffects (>= 1.3.2)", + "ggstats (>= 0.2.1)", + "glmmTMB", + "glmtoolbox", + "glue", + "gt", + "gtsummary (>= 2.0.0)", + "knitr", + "lavaan", + "lfe", + "lme4 (>= 1.1.28)", + "logitr (>= 0.8.0)", + "marginaleffects (>= 0.21.0)", + "margins", + "MASS", + "mgcv", + "mice", + "mmrm (>= 0.3.6)", + "multgee", + "nnet", + "ordinal", + "parameters", + "parsnip", + "patchwork", + "plm", + "pscl", + "rmarkdown", + "rstanarm", + "scales", + "spelling", + "survey", + "survival", + "testthat (>= 3.0.0)", + "tidycmprsk", + "VGAM", + "svyVGAM" + ], + "VignetteBuilder": "knitr", + "RdMacros": "lifecycle", + "Encoding": "UTF-8", + "Language": "en-US", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Joseph Larmarange [aut, cre] (), Daniel D. Sjoberg [aut] ()", + "Maintainer": "Joseph Larmarange ", + "Repository": "CRAN" + }, + "bsicons": { + "Package": "bsicons", + "Version": "0.1.2", + "Source": "Repository", + "Title": "Easily Work with 'Bootstrap' Icons", + "Authors@R": "c( person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"Mark\", \"Otto\", role = \"cph\", comment = \"Bootstrap icons maintainer\") )", + "Description": "Easily use 'Bootstrap' icons inside 'Shiny' apps and 'R Markdown' documents. More generally, icons can be inserted in any 'htmltools' document through inline 'SVG'.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/bsicons", + "BugReports": "https://github.com/rstudio/bsicons/issues", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "cli", + "htmltools", + "rlang", + "utils" + ], + "Suggests": [ + "bslib", + "processx", + "testthat", + "webshot2", + "withr" + ], + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Carson Sievert [cre, aut] (), Posit Software, PBC [cph, fnd], Mark Otto [cph] (Bootstrap icons maintainer)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "bslib": { + "Package": "bslib", + "Version": "0.9.0", + "Source": "Repository", + "Title": "Custom 'Bootstrap' 'Sass' Themes for 'shiny' and 'rmarkdown'", + "Authors@R": "c( person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Garrick\", \"Aden-Buie\", , \"garrick@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0002-7111-0077\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Javi\", \"Aguilar\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap colorpicker library\"), person(\"Thomas\", \"Park\", role = c(\"ctb\", \"cph\"), comment = \"Bootswatch library\"), person(, \"PayPal\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap accessibility plugin\") )", + "Description": "Simplifies custom 'CSS' styling of both 'shiny' and 'rmarkdown' via 'Bootstrap' 'Sass'. Supports 'Bootstrap' 3, 4 and 5 as well as their various 'Bootswatch' themes. An interactive widget is also provided for previewing themes in real time.", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/bslib/, https://github.com/rstudio/bslib", + "BugReports": "https://github.com/rstudio/bslib/issues", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "base64enc", + "cachem", + "fastmap (>= 1.1.1)", + "grDevices", + "htmltools (>= 0.5.8)", + "jquerylib (>= 0.1.3)", + "jsonlite", + "lifecycle", + "memoise (>= 2.0.1)", + "mime", + "rlang", + "sass (>= 0.4.9)" + ], + "Suggests": [ + "bsicons", + "curl", + "fontawesome", + "future", + "ggplot2", + "knitr", + "magrittr", + "rappdirs", + "rmarkdown (>= 2.7)", + "shiny (> 1.8.1)", + "testthat", + "thematic", + "tools", + "utils", + "withr", + "yaml" + ], + "Config/Needs/deploy": "BH, chiflights22, colourpicker, commonmark, cpp11, cpsievert/chiflights22, cpsievert/histoslider, dplyr, DT, ggplot2, ggridges, gt, hexbin, histoslider, htmlwidgets, lattice, leaflet, lubridate, markdown, modelr, plotly, reactable, reshape2, rprojroot, rsconnect, rstudio/shiny, scales, styler, tibble", + "Config/Needs/routine": "chromote, desc, renv", + "Config/Needs/website": "brio, crosstalk, dplyr, DT, ggplot2, glue, htmlwidgets, leaflet, lorem, palmerpenguins, plotly, purrr, rprojroot, rstudio/htmltools, scales, stringr, tidyr, webshot2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "zzzz-bs-sass, fonts, zzz-precompile, theme-*, rmd-*", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Collate": "'accordion.R' 'breakpoints.R' 'bs-current-theme.R' 'bs-dependencies.R' 'bs-global.R' 'bs-remove.R' 'bs-theme-layers.R' 'bs-theme-preset-bootswatch.R' 'bs-theme-preset-brand.R' 'bs-theme-preset-builtin.R' 'bs-theme-preset.R' 'utils.R' 'bs-theme-preview.R' 'bs-theme-update.R' 'bs-theme.R' 'bslib-package.R' 'buttons.R' 'card.R' 'deprecated.R' 'files.R' 'fill.R' 'imports.R' 'input-dark-mode.R' 'input-switch.R' 'layout.R' 'nav-items.R' 'nav-update.R' 'navbar_options.R' 'navs-legacy.R' 'navs.R' 'onLoad.R' 'page.R' 'popover.R' 'precompiled.R' 'print.R' 'shiny-devmode.R' 'sidebar.R' 'staticimports.R' 'tooltip.R' 'utils-deps.R' 'utils-shiny.R' 'utils-tags.R' 'value-box.R' 'version-default.R' 'versions.R'", + "NeedsCompilation": "no", + "Author": "Carson Sievert [aut, cre] (), Joe Cheng [aut], Garrick Aden-Buie [aut] (), Posit Software, PBC [cph, fnd], Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Javi Aguilar [ctb, cph] (Bootstrap colorpicker library), Thomas Park [ctb, cph] (Bootswatch library), PayPal [ctb, cph] (Bootstrap accessibility plugin)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "cachem": { + "Package": "cachem", + "Version": "1.1.0", + "Source": "Repository", + "Title": "Cache R Objects with Automatic Pruning", + "Description": "Key-value stores with automatic pruning. Caches can limit either their total size or the age of the oldest object (or both), automatically pruning objects to maintain the constraints.", + "Authors@R": "c( person(\"Winston\", \"Chang\", , \"winston@posit.co\", c(\"aut\", \"cre\")), person(family = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")))", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "ByteCompile": "true", + "URL": "https://cachem.r-lib.org/, https://github.com/r-lib/cachem", + "Imports": [ + "rlang", + "fastmap (>= 1.2.0)" + ], + "Suggests": [ + "testthat" + ], + "RoxygenNote": "7.2.3", + "Config/Needs/routine": "lobstr", + "Config/Needs/website": "pkgdown", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "cards": { + "Package": "cards", + "Version": "0.6.0", + "Source": "Repository", + "Title": "Analysis Results Data", + "Authors@R": "c( person(\"Daniel D.\", \"Sjoberg\", , \"danield.sjoberg@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0862-2018\")), person(\"Becca\", \"Krouse\", , \"becca.z.krouse@gsk.com\", role = \"aut\"), person(\"Emily\", \"de la Rua\", , \"emily.de_la_rua@contractors.roche.com\", role = \"aut\"), person(\"F. Hoffmann-La Roche AG\", role = c(\"cph\", \"fnd\")), person(\"GlaxoSmithKline Research & Development Limited\", role = \"cph\") )", + "Description": "Construct CDISC (Clinical Data Interchange Standards Consortium) compliant Analysis Results Data objects. These objects are used and re-used to construct summary tables, visualizations, and written reports. The package also exports utilities for working with these objects and creating new Analysis Results Data objects.", + "License": "Apache License 2.0", + "URL": "https://github.com/insightsengineering/cards, https://insightsengineering.github.io/cards/", + "BugReports": "https://github.com/insightsengineering/cards/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "cli (>= 3.6.1)", + "dplyr (>= 1.1.2)", + "glue (>= 1.6.2)", + "lifecycle (>= 1.0.3)", + "rlang (>= 1.1.1)", + "tidyr (>= 1.3.0)", + "tidyselect (>= 1.2.0)" + ], + "Suggests": [ + "testthat (>= 3.2.0)", + "withr (>= 3.0.0)" + ], + "Config/Needs/coverage": "hms", + "Config/Needs/website": "rmarkdown, jsonlite, yaml, gtsummary, tfrmt, cardx, gt, fontawesome, insightsengineering/nesttemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Encoding": "UTF-8", + "Language": "en-US", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Daniel D. Sjoberg [aut, cre] (), Becca Krouse [aut], Emily de la Rua [aut], F. Hoffmann-La Roche AG [cph, fnd], GlaxoSmithKline Research & Development Limited [cph]", + "Maintainer": "Daniel D. Sjoberg ", + "Repository": "CRAN" + }, + "cardx": { + "Package": "cardx", + "Version": "0.2.4", + "Source": "Repository", + "Title": "Extra Analysis Results Data Utilities", + "Authors@R": "c( person(\"Daniel D.\", \"Sjoberg\", , \"danield.sjoberg@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0862-2018\")), person(\"Abinaya\", \"Yogasekaram\", , \"abinaya.yogasekaram@contractors.roche.com\", role = \"aut\"), person(\"Emily\", \"de la Rua\", , \"emily.de_la_rua@contractors.roche.com\", role = \"aut\"), person(\"F. Hoffmann-La Roche AG\", role = c(\"cph\", \"fnd\")) )", + "Description": "Create extra Analysis Results Data (ARD) summary objects. The package supplements the simple ARD functions from the 'cards' package, exporting functions to put statistical results in the ARD format. These objects are used and re-used to construct summary tables, visualizations, and written reports.", + "License": "Apache License 2.0", + "URL": "https://github.com/insightsengineering/cardx, https://insightsengineering.github.io/cardx/", + "BugReports": "https://github.com/insightsengineering/cardx/issues", + "Depends": [ + "R (>= 4.2)" + ], + "Imports": [ + "cards (>= 0.5.1)", + "cli (>= 3.6.1)", + "dplyr (>= 1.1.2)", + "glue (>= 1.6.2)", + "lifecycle (>= 1.0.3)", + "rlang (>= 1.1.1)", + "tidyr (>= 1.3.0)" + ], + "Suggests": [ + "aod (>= 1.3.3)", + "broom (>= 1.0.8)", + "broom.helpers (>= 1.17.0)", + "broom.mixed (>= 0.2.9)", + "car (>= 3.1-2)", + "effectsize (>= 0.8.8)", + "emmeans (>= 1.7.3)", + "geepack (>= 1.3.2)", + "ggsurvfit (>= 1.1.0)", + "lme4 (>= 1.1-37)", + "parameters (>= 0.20.2)", + "smd (>= 0.6.6)", + "survey (>= 4.2)", + "survival (>= 3.6-4)", + "testthat (>= 3.2.0)", + "withr (>= 2.5.0)" + ], + "Config/Needs/website": "insightsengineering/nesttemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Daniel D. Sjoberg [aut, cre] (), Abinaya Yogasekaram [aut], Emily de la Rua [aut], F. Hoffmann-La Roche AG [cph, fnd]", + "Maintainer": "Daniel D. Sjoberg ", + "Repository": "CRAN" + }, + "cellranger": { + "Package": "cellranger", + "Version": "1.1.0", + "Source": "Repository", + "Title": "Translate Spreadsheet Cell Ranges to Rows and Columns", + "Authors@R": "c( person(\"Jennifer\", \"Bryan\", , \"jenny@stat.ubc.ca\", c(\"cre\", \"aut\")), person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", \"ctb\") )", + "Description": "Helper functions to work with spreadsheets and the \"A1:D10\" style of cell range specification.", + "Depends": [ + "R (>= 3.0.0)" + ], + "License": "MIT + file LICENSE", + "LazyData": "true", + "URL": "https://github.com/rsheets/cellranger", + "BugReports": "https://github.com/rsheets/cellranger/issues", + "Suggests": [ + "covr", + "testthat (>= 1.0.0)", + "knitr", + "rmarkdown" + ], + "RoxygenNote": "5.0.1.9000", + "VignetteBuilder": "knitr", + "Imports": [ + "rematch", + "tibble" + ], + "NeedsCompilation": "no", + "Author": "Jennifer Bryan [cre, aut], Hadley Wickham [ctb]", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN" + }, + "checkmate": { + "Package": "checkmate", + "Version": "2.3.2", + "Source": "Repository", + "Type": "Package", + "Title": "Fast and Versatile Argument Checks", + "Description": "Tests and assertions to perform frequent argument checks. A substantial part of the package was written in C to minimize any worries about execution time overhead.", + "Authors@R": "c( person(\"Michel\", \"Lang\", NULL, \"michellang@gmail.com\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0001-9754-0393\")), person(\"Bernd\", \"Bischl\", NULL, \"bernd_bischl@gmx.net\", role = \"ctb\"), person(\"Dénes\", \"Tóth\", NULL, \"toth.denes@kogentum.hu\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4262-3217\")) )", + "URL": "https://mllg.github.io/checkmate/, https://github.com/mllg/checkmate", + "URLNote": "https://github.com/mllg/checkmate", + "BugReports": "https://github.com/mllg/checkmate/issues", + "NeedsCompilation": "yes", + "ByteCompile": "yes", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 3.0.0)" + ], + "Imports": [ + "backports (>= 1.1.0)", + "utils" + ], + "Suggests": [ + "R6", + "fastmatch", + "data.table (>= 1.9.8)", + "devtools", + "ggplot2", + "knitr", + "magrittr", + "microbenchmark", + "rmarkdown", + "testthat (>= 3.0.4)", + "tinytest (>= 1.1.0)", + "tibble" + ], + "License": "BSD_3_clause + file LICENSE", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.3.2", + "Collate": "'AssertCollection.R' 'allMissing.R' 'anyInfinite.R' 'anyMissing.R' 'anyNaN.R' 'asInteger.R' 'assert.R' 'helper.R' 'makeExpectation.R' 'makeTest.R' 'makeAssertion.R' 'checkAccess.R' 'checkArray.R' 'checkAtomic.R' 'checkAtomicVector.R' 'checkCharacter.R' 'checkChoice.R' 'checkClass.R' 'checkComplex.R' 'checkCount.R' 'checkDataFrame.R' 'checkDataTable.R' 'checkDate.R' 'checkDirectoryExists.R' 'checkDisjunct.R' 'checkDouble.R' 'checkEnvironment.R' 'checkFALSE.R' 'checkFactor.R' 'checkFileExists.R' 'checkFlag.R' 'checkFormula.R' 'checkFunction.R' 'checkInt.R' 'checkInteger.R' 'checkIntegerish.R' 'checkList.R' 'checkLogical.R' 'checkMatrix.R' 'checkMultiClass.R' 'checkNamed.R' 'checkNames.R' 'checkNull.R' 'checkNumber.R' 'checkNumeric.R' 'checkOS.R' 'checkPOSIXct.R' 'checkPathForOutput.R' 'checkPermutation.R' 'checkR6.R' 'checkRaw.R' 'checkScalar.R' 'checkScalarNA.R' 'checkSetEqual.R' 'checkString.R' 'checkSubset.R' 'checkTRUE.R' 'checkTibble.R' 'checkVector.R' 'coalesce.R' 'isIntegerish.R' 'matchArg.R' 'qassert.R' 'qassertr.R' 'vname.R' 'wfwl.R' 'zzz.R'", + "Author": "Michel Lang [cre, aut] (), Bernd Bischl [ctb], Dénes Tóth [ctb] ()", + "Maintainer": "Michel Lang ", + "Repository": "CRAN" + }, + "class": { + "Package": "class", + "Version": "7.3-23", + "Source": "Repository", + "Priority": "recommended", + "Date": "2025-01-01", + "Depends": [ + "R (>= 3.0.0)", + "stats", + "utils" + ], + "Imports": [ + "MASS" + ], + "Authors@R": "c(person(\"Brian\", \"Ripley\", role = c(\"aut\", \"cre\", \"cph\"), email = \"Brian.Ripley@R-project.org\"), person(\"William\", \"Venables\", role = \"cph\"))", + "Description": "Various functions for classification, including k-nearest neighbour, Learning Vector Quantization and Self-Organizing Maps.", + "Title": "Functions for Classification", + "ByteCompile": "yes", + "License": "GPL-2 | GPL-3", + "URL": "http://www.stats.ox.ac.uk/pub/MASS4/", + "NeedsCompilation": "yes", + "Author": "Brian Ripley [aut, cre, cph], William Venables [cph]", + "Maintainer": "Brian Ripley ", + "Repository": "CRAN" + }, + "classInt": { + "Package": "classInt", + "Version": "0.4-11", + "Source": "Repository", + "Date": "2025-01-06", + "Title": "Choose Univariate Class Intervals", + "Authors@R": "c( person(\"Roger\", \"Bivand\", role=c(\"aut\", \"cre\"), email=\"Roger.Bivand@nhh.no\", comment=c(ORCID=\"0000-0003-2392-6140\")), person(\"Bill\", \"Denney\", role=\"ctb\", comment=c(ORCID=\"0000-0002-5759-428X\")), person(\"Richard\", \"Dunlap\", role=\"ctb\"), person(\"Diego\", \"Hernangómez\", role=\"ctb\", comment=c(ORCID=\"0000-0001-8457-4658\")), person(\"Hisaji\", \"Ono\", role=\"ctb\"), person(\"Josiah\", \"Parry\", role = \"ctb\", comment = c(ORCID = \"0000-0001-9910-865X\")), person(\"Matthieu\", \"Stigler\", role=\"ctb\", comment =c(ORCID=\"0000-0002-6802-4290\")))", + "Depends": [ + "R (>= 2.2)" + ], + "Imports": [ + "grDevices", + "stats", + "graphics", + "e1071", + "class", + "KernSmooth" + ], + "Suggests": [ + "spData (>= 0.2.6.2)", + "units", + "knitr", + "rmarkdown", + "tinytest" + ], + "NeedsCompilation": "yes", + "Description": "Selected commonly used methods for choosing univariate class intervals for mapping or other graphics purposes.", + "License": "GPL (>= 2)", + "URL": "https://r-spatial.github.io/classInt/, https://github.com/r-spatial/classInt/", + "BugReports": "https://github.com/r-spatial/classInt/issues/", + "RoxygenNote": "6.1.1", + "Encoding": "UTF-8", + "VignetteBuilder": "knitr", + "Author": "Roger Bivand [aut, cre] (), Bill Denney [ctb] (), Richard Dunlap [ctb], Diego Hernangómez [ctb] (), Hisaji Ono [ctb], Josiah Parry [ctb] (), Matthieu Stigler [ctb] ()", + "Maintainer": "Roger Bivand ", + "Repository": "CRAN" + }, + "cli": { + "Package": "cli", + "Version": "3.6.5", + "Source": "Repository", + "Title": "Helpers for Developing Command Line Interfaces", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"gabor@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Kirill\", \"Müller\", role = \"ctb\"), person(\"Salim\", \"Brüggemann\", , \"salim-b@pm.me\", role = \"ctb\", comment = c(ORCID = \"0000-0002-5329-5987\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A suite of tools to build attractive command line interfaces ('CLIs'), from semantic elements: headings, lists, alerts, paragraphs, etc. Supports custom themes via a 'CSS'-like language. It also contains a number of lower level 'CLI' elements: rules, boxes, trees, and 'Unicode' symbols with 'ASCII' alternatives. It support ANSI colors and text styles as well.", + "License": "MIT + file LICENSE", + "URL": "https://cli.r-lib.org, https://github.com/r-lib/cli", + "BugReports": "https://github.com/r-lib/cli/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "utils" + ], + "Suggests": [ + "callr", + "covr", + "crayon", + "digest", + "glue (>= 1.6.0)", + "grDevices", + "htmltools", + "htmlwidgets", + "knitr", + "methods", + "processx", + "ps (>= 1.3.4.9000)", + "rlang (>= 1.0.2.9003)", + "rmarkdown", + "rprojroot", + "rstudioapi", + "testthat (>= 3.2.0)", + "tibble", + "whoami", + "withr" + ], + "Config/Needs/website": "r-lib/asciicast, bench, brio, cpp11, decor, desc, fansi, prettyunits, sessioninfo, tidyverse/tidytemplate, usethis, vctrs", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre], Hadley Wickham [ctb], Kirill Müller [ctb], Salim Brüggemann [ctb] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "clipr": { + "Package": "clipr", + "Version": "0.8.0", + "Source": "Repository", + "Type": "Package", + "Title": "Read and Write from the System Clipboard", + "Authors@R": "c( person(\"Matthew\", \"Lincoln\", , \"matthew.d.lincoln@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4387-3384\")), person(\"Louis\", \"Maddox\", role = \"ctb\"), person(\"Steve\", \"Simpson\", role = \"ctb\"), person(\"Jennifer\", \"Bryan\", role = \"ctb\") )", + "Description": "Simple utility functions to read from and write to the Windows, OS X, and X11 clipboards.", + "License": "GPL-3", + "URL": "https://github.com/mdlincoln/clipr, http://matthewlincoln.net/clipr/", + "BugReports": "https://github.com/mdlincoln/clipr/issues", + "Imports": [ + "utils" + ], + "Suggests": [ + "covr", + "knitr", + "rmarkdown", + "rstudioapi (>= 0.5)", + "testthat (>= 2.0.0)" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.1.2", + "SystemRequirements": "xclip (https://github.com/astrand/xclip) or xsel (http://www.vergenet.net/~conrad/software/xsel/) for accessing the X11 clipboard, or wl-clipboard (https://github.com/bugaevc/wl-clipboard) for systems using Wayland.", + "NeedsCompilation": "no", + "Author": "Matthew Lincoln [aut, cre] (), Louis Maddox [ctb], Steve Simpson [ctb], Jennifer Bryan [ctb]", + "Maintainer": "Matthew Lincoln ", + "Repository": "CRAN" + }, + "cluster": { + "Package": "cluster", + "Version": "2.1.8.1", + "Source": "Repository", + "VersionNote": "Last CRAN: 2.1.8 on 2024-12-10; 2.1.7 on 2024-12-06; 2.1.6 on 2023-11-30; 2.1.5 on 2023-11-27", + "Date": "2025-03-11", + "Priority": "recommended", + "Title": "\"Finding Groups in Data\": Cluster Analysis Extended Rousseeuw et al.", + "Description": "Methods for Cluster analysis. Much extended the original from Peter Rousseeuw, Anja Struyf and Mia Hubert, based on Kaufman and Rousseeuw (1990) \"Finding Groups in Data\".", + "Maintainer": "Martin Maechler ", + "Authors@R": "c(person(\"Martin\",\"Maechler\", role = c(\"aut\",\"cre\"), email=\"maechler@stat.math.ethz.ch\", comment = c(ORCID = \"0000-0002-8685-9910\")) ,person(\"Peter\", \"Rousseeuw\", role=\"aut\", email=\"peter.rousseeuw@kuleuven.be\", comment = c(\"Fortran original\", ORCID = \"0000-0002-3807-5353\")) ,person(\"Anja\", \"Struyf\", role=\"aut\", comment= \"S original\") ,person(\"Mia\", \"Hubert\", role=\"aut\", email= \"Mia.Hubert@uia.ua.ac.be\", comment = c(\"S original\", ORCID = \"0000-0001-6398-4850\")) ,person(\"Kurt\", \"Hornik\", role=c(\"trl\", \"ctb\"), email=\"Kurt.Hornik@R-project.org\", comment=c(\"port to R; maintenance(1999-2000)\", ORCID=\"0000-0003-4198-9911\")) ,person(\"Matthias\", \"Studer\", role=\"ctb\") ,person(\"Pierre\", \"Roudier\", role=\"ctb\") ,person(\"Juan\", \"Gonzalez\", role=\"ctb\") ,person(\"Kamil\", \"Kozlowski\", role=\"ctb\") ,person(\"Erich\", \"Schubert\", role=\"ctb\", comment = c(\"fastpam options for pam()\", ORCID = \"0000-0001-9143-4880\")) ,person(\"Keefe\", \"Murphy\", role=\"ctb\", comment = \"volume.ellipsoid({d >= 3})\") #not yet ,person(\"Fischer-Rasmussen\", \"Kasper\", role = \"ctb\", comment = \"Gower distance for CLARA\") )", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "graphics", + "grDevices", + "stats", + "utils" + ], + "Suggests": [ + "MASS", + "Matrix" + ], + "SuggestsNote": "MASS: two examples using cov.rob() and mvrnorm(); Matrix tools for testing", + "Enhances": [ + "mvoutlier", + "fpc", + "ellipse", + "sfsmisc" + ], + "EnhancesNote": "xref-ed in man/*.Rd", + "LazyLoad": "yes", + "LazyData": "yes", + "ByteCompile": "yes", + "BuildResaveData": "no", + "License": "GPL (>= 2)", + "URL": "https://svn.r-project.org/R-packages/trunk/cluster/", + "NeedsCompilation": "yes", + "Author": "Martin Maechler [aut, cre] (), Peter Rousseeuw [aut] (Fortran original, ), Anja Struyf [aut] (S original), Mia Hubert [aut] (S original, ), Kurt Hornik [trl, ctb] (port to R; maintenance(1999-2000), ), Matthias Studer [ctb], Pierre Roudier [ctb], Juan Gonzalez [ctb], Kamil Kozlowski [ctb], Erich Schubert [ctb] (fastpam options for pam(), ), Keefe Murphy [ctb] (volume.ellipsoid({d >= 3}))", + "Repository": "CRAN" + }, + "colorspace": { + "Package": "colorspace", + "Version": "2.1-1", + "Source": "Repository", + "Date": "2024-07-26", + "Title": "A Toolbox for Manipulating and Assessing Colors and Palettes", + "Authors@R": "c(person(given = \"Ross\", family = \"Ihaka\", role = \"aut\", email = \"ihaka@stat.auckland.ac.nz\"), person(given = \"Paul\", family = \"Murrell\", role = \"aut\", email = \"paul@stat.auckland.ac.nz\", comment = c(ORCID = \"0000-0002-3224-8858\")), person(given = \"Kurt\", family = \"Hornik\", role = \"aut\", email = \"Kurt.Hornik@R-project.org\", comment = c(ORCID = \"0000-0003-4198-9911\")), person(given = c(\"Jason\", \"C.\"), family = \"Fisher\", role = \"aut\", email = \"jfisher@usgs.gov\", comment = c(ORCID = \"0000-0001-9032-8912\")), person(given = \"Reto\", family = \"Stauffer\", role = \"aut\", email = \"Reto.Stauffer@uibk.ac.at\", comment = c(ORCID = \"0000-0002-3798-5507\")), person(given = c(\"Claus\", \"O.\"), family = \"Wilke\", role = \"aut\", email = \"wilke@austin.utexas.edu\", comment = c(ORCID = \"0000-0002-7470-9261\")), person(given = c(\"Claire\", \"D.\"), family = \"McWhite\", role = \"aut\", email = \"claire.mcwhite@utmail.utexas.edu\", comment = c(ORCID = \"0000-0001-7346-3047\")), person(given = \"Achim\", family = \"Zeileis\", role = c(\"aut\", \"cre\"), email = \"Achim.Zeileis@R-project.org\", comment = c(ORCID = \"0000-0003-0918-3766\")))", + "Description": "Carries out mapping between assorted color spaces including RGB, HSV, HLS, CIEXYZ, CIELUV, HCL (polar CIELUV), CIELAB, and polar CIELAB. Qualitative, sequential, and diverging color palettes based on HCL colors are provided along with corresponding ggplot2 color scales. Color palette choice is aided by an interactive app (with either a Tcl/Tk or a shiny graphical user interface) and shiny apps with an HCL color picker and a color vision deficiency emulator. Plotting functions for displaying and assessing palettes include color swatches, visualizations of the HCL space, and trajectories in HCL and/or RGB spectrum. Color manipulation functions include: desaturation, lightening/darkening, mixing, and simulation of color vision deficiencies (deutanomaly, protanomaly, tritanomaly). Details can be found on the project web page at and in the accompanying scientific paper: Zeileis et al. (2020, Journal of Statistical Software, ).", + "Depends": [ + "R (>= 3.0.0)", + "methods" + ], + "Imports": [ + "graphics", + "grDevices", + "stats" + ], + "Suggests": [ + "datasets", + "utils", + "KernSmooth", + "MASS", + "kernlab", + "mvtnorm", + "vcd", + "tcltk", + "shiny", + "shinyjs", + "ggplot2", + "dplyr", + "scales", + "grid", + "png", + "jpeg", + "knitr", + "rmarkdown", + "RColorBrewer", + "rcartocolor", + "scico", + "viridis", + "wesanderson" + ], + "VignetteBuilder": "knitr", + "License": "BSD_3_clause + file LICENSE", + "URL": "https://colorspace.R-Forge.R-project.org/, https://hclwizard.org/", + "BugReports": "https://colorspace.R-Forge.R-project.org/contact.html", + "LazyData": "yes", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "NeedsCompilation": "yes", + "Author": "Ross Ihaka [aut], Paul Murrell [aut] (), Kurt Hornik [aut] (), Jason C. Fisher [aut] (), Reto Stauffer [aut] (), Claus O. Wilke [aut] (), Claire D. McWhite [aut] (), Achim Zeileis [aut, cre] ()", + "Maintainer": "Achim Zeileis ", + "Repository": "CRAN" + }, + "commonmark": { + "Package": "commonmark", + "Version": "1.9.5", + "Source": "Repository", + "Type": "Package", + "Title": "High Performance CommonMark and Github Markdown Rendering in R", + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", ,\"jeroenooms@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"John MacFarlane\", role = \"cph\", comment = \"Author of cmark\"))", + "Description": "The CommonMark specification defines a rationalized version of markdown syntax. This package uses the 'cmark' reference implementation for converting markdown text into various formats including html, latex and groff man. In addition it exposes the markdown parse tree in xml format. Also includes opt-in support for GFM extensions including tables, autolinks, and strikethrough text.", + "License": "BSD_2_clause + file LICENSE", + "URL": "https://docs.ropensci.org/commonmark/ https://ropensci.r-universe.dev/commonmark", + "BugReports": "https://github.com/r-lib/commonmark/issues", + "Suggests": [ + "curl", + "testthat", + "xml2" + ], + "RoxygenNote": "7.3.2", + "Language": "en-US", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), John MacFarlane [cph] (Author of cmark)", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "cpp11": { + "Package": "cpp11", + "Version": "0.5.2", + "Source": "Repository", + "Title": "A C++11 Interface for R's C Interface", + "Authors@R": "c( person(\"Davis\", \"Vaughan\", email = \"davis@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4777-038X\")), person(\"Jim\",\"Hester\", role = \"aut\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Romain\", \"François\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Benjamin\", \"Kietzman\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a header only, C++11 interface to R's C interface. Compared to other approaches 'cpp11' strives to be safe against long jumps from the C API as well as C++ exceptions, conform to normal R function semantics and supports interaction with 'ALTREP' vectors.", + "License": "MIT + file LICENSE", + "URL": "https://cpp11.r-lib.org, https://github.com/r-lib/cpp11", + "BugReports": "https://github.com/r-lib/cpp11/issues", + "Depends": [ + "R (>= 4.0.0)" + ], + "Suggests": [ + "bench", + "brio", + "callr", + "cli", + "covr", + "decor", + "desc", + "ggplot2", + "glue", + "knitr", + "lobstr", + "mockery", + "progress", + "rmarkdown", + "scales", + "Rcpp", + "testthat (>= 3.2.0)", + "tibble", + "utils", + "vctrs", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/Needs/cpp11/cpp_register": "brio, cli, decor, desc, glue, tibble, vctrs", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Davis Vaughan [aut, cre] (), Jim Hester [aut] (), Romain François [aut] (), Benjamin Kietzman [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN" + }, + "crayon": { + "Package": "crayon", + "Version": "1.5.3", + "Source": "Repository", + "Title": "Colored Terminal Output", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Brodie\", \"Gaslam\", , \"brodie.gaslam@yahoo.com\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "The crayon package is now superseded. Please use the 'cli' package for new projects. Colored terminal output on terminals that support 'ANSI' color and highlight codes. It also works in 'Emacs' 'ESS'. 'ANSI' color support is automatically detected. Colors and highlighting can be combined and nested. New styles can also be created easily. This package was inspired by the 'chalk' 'JavaScript' project.", + "License": "MIT + file LICENSE", + "URL": "https://r-lib.github.io/crayon/, https://github.com/r-lib/crayon", + "BugReports": "https://github.com/r-lib/crayon/issues", + "Imports": [ + "grDevices", + "methods", + "utils" + ], + "Suggests": [ + "mockery", + "rstudioapi", + "testthat", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Collate": "'aaa-rstudio-detect.R' 'aaaa-rematch2.R' 'aab-num-ansi-colors.R' 'aac-num-ansi-colors.R' 'ansi-256.R' 'ansi-palette.R' 'combine.R' 'string.R' 'utils.R' 'crayon-package.R' 'disposable.R' 'enc-utils.R' 'has_ansi.R' 'has_color.R' 'link.R' 'styles.R' 'machinery.R' 'parts.R' 'print.R' 'style-var.R' 'show.R' 'string_operations.R'", + "NeedsCompilation": "no", + "Author": "Gábor Csárdi [aut, cre], Brodie Gaslam [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "crosstalk": { + "Package": "crosstalk", + "Version": "1.2.1", + "Source": "Repository", + "Type": "Package", + "Title": "Inter-Widget Interactivity for HTML Widgets", + "Authors@R": "c( person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@posit.co\"), person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@posit.co\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(family = \"jQuery Foundation\", role = \"cph\", comment = \"jQuery library and jQuery UI library\"), person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt\"), person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"), person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"), person(family = \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(family = \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Brian\", \"Reavis\", role = c(\"ctb\", \"cph\"), comment = \"selectize.js library\"), person(\"Kristopher Michael\", \"Kowal\", role = c(\"ctb\", \"cph\"), comment = \"es5-shim library\"), person(family = \"es5-shim contributors\", role = c(\"ctb\", \"cph\"), comment = \"es5-shim library\"), person(\"Denis\", \"Ineshin\", role = c(\"ctb\", \"cph\"), comment = \"ion.rangeSlider library\"), person(\"Sami\", \"Samhuri\", role = c(\"ctb\", \"cph\"), comment = \"Javascript strftime library\") )", + "Description": "Provides building blocks for allowing HTML widgets to communicate with each other, with Shiny or without (i.e. static .html files). Currently supports linked brushing and filtering.", + "License": "MIT + file LICENSE", + "Imports": [ + "htmltools (>= 0.3.6)", + "jsonlite", + "lazyeval", + "R6" + ], + "Suggests": [ + "shiny", + "ggplot2", + "testthat (>= 2.1.0)", + "sass", + "bslib" + ], + "URL": "https://rstudio.github.io/crosstalk/, https://github.com/rstudio/crosstalk", + "BugReports": "https://github.com/rstudio/crosstalk/issues", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Joe Cheng [aut], Carson Sievert [aut, cre] (), Posit Software, PBC [cph, fnd], jQuery Foundation [cph] (jQuery library and jQuery UI library), jQuery contributors [ctb, cph] (jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt), Mark Otto [ctb] (Bootstrap library), Jacob Thornton [ctb] (Bootstrap library), Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Brian Reavis [ctb, cph] (selectize.js library), Kristopher Michael Kowal [ctb, cph] (es5-shim library), es5-shim contributors [ctb, cph] (es5-shim library), Denis Ineshin [ctb, cph] (ion.rangeSlider library), Sami Samhuri [ctb, cph] (Javascript strftime library)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "curl": { + "Package": "curl", + "Version": "6.2.2", + "Source": "Repository", + "Type": "Package", + "Title": "A Modern and Flexible Web Client for R", + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Posit Software, PBC\", role = \"cph\"))", + "Description": "Bindings to 'libcurl' for performing fully configurable HTTP/FTP requests where responses can be processed in memory, on disk, or streaming via the callback or connection interfaces. Some knowledge of 'libcurl' is recommended; for a more-user-friendly web client see the 'httr2' package which builds on this package with http specific tools and logic.", + "License": "MIT + file LICENSE", + "SystemRequirements": "libcurl (>= 7.62): libcurl-devel (rpm) or libcurl4-openssl-dev (deb)", + "URL": "https://jeroen.r-universe.dev/curl", + "BugReports": "https://github.com/jeroen/curl/issues", + "Suggests": [ + "spelling", + "testthat (>= 1.0.0)", + "knitr", + "jsonlite", + "later", + "rmarkdown", + "httpuv (>= 1.4.4)", + "webutils" + ], + "VignetteBuilder": "knitr", + "Depends": [ + "R (>= 3.0.0)" + ], + "RoxygenNote": "7.3.2.9000", + "Encoding": "UTF-8", + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), Hadley Wickham [ctb], Posit Software, PBC [cph]", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "data.table": { + "Package": "data.table", + "Version": "1.17.0", + "Source": "Repository", + "Title": "Extension of `data.frame`", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "bit64 (>= 4.0.0)", + "bit (>= 4.0.4)", + "R.utils", + "xts", + "zoo (>= 1.8-1)", + "yaml", + "knitr", + "markdown" + ], + "Description": "Fast aggregation of large data (e.g. 100GB in RAM), fast ordered joins, fast add/modify/delete of columns by group using no copies at all, list columns, friendly and fast character-separated-value read/write. Offers a natural and flexible syntax, for faster development.", + "License": "MPL-2.0 | file LICENSE", + "URL": "https://r-datatable.com, https://Rdatatable.gitlab.io/data.table, https://github.com/Rdatatable/data.table", + "BugReports": "https://github.com/Rdatatable/data.table/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "ByteCompile": "TRUE", + "Authors@R": "c( person(\"Tyson\",\"Barrett\", role=c(\"aut\",\"cre\"), email=\"t.barrett88@gmail.com\", comment = c(ORCID=\"0000-0002-2137-1391\")), person(\"Matt\",\"Dowle\", role=\"aut\", email=\"mattjdowle@gmail.com\"), person(\"Arun\",\"Srinivasan\", role=\"aut\", email=\"asrini@pm.me\"), person(\"Jan\",\"Gorecki\", role=\"aut\"), person(\"Michael\",\"Chirico\", role=\"aut\", comment = c(ORCID=\"0000-0003-0787-087X\")), person(\"Toby\",\"Hocking\", role=\"aut\", comment = c(ORCID=\"0000-0002-3146-0865\")), person(\"Benjamin\",\"Schwendinger\",role=\"aut\", comment = c(ORCID=\"0000-0003-3315-8114\")), person(\"Ivan\", \"Krylov\", role=\"aut\", email=\"ikrylov@disroot.org\", comment = c(ORCID=\"0000-0002-0172-3812\")), person(\"Pasha\",\"Stetsenko\", role=\"ctb\"), person(\"Tom\",\"Short\", role=\"ctb\"), person(\"Steve\",\"Lianoglou\", role=\"ctb\"), person(\"Eduard\",\"Antonyan\", role=\"ctb\"), person(\"Markus\",\"Bonsch\", role=\"ctb\"), person(\"Hugh\",\"Parsonage\", role=\"ctb\"), person(\"Scott\",\"Ritchie\", role=\"ctb\"), person(\"Kun\",\"Ren\", role=\"ctb\"), person(\"Xianying\",\"Tan\", role=\"ctb\"), person(\"Rick\",\"Saporta\", role=\"ctb\"), person(\"Otto\",\"Seiskari\", role=\"ctb\"), person(\"Xianghui\",\"Dong\", role=\"ctb\"), person(\"Michel\",\"Lang\", role=\"ctb\"), person(\"Watal\",\"Iwasaki\", role=\"ctb\"), person(\"Seth\",\"Wenchel\", role=\"ctb\"), person(\"Karl\",\"Broman\", role=\"ctb\"), person(\"Tobias\",\"Schmidt\", role=\"ctb\"), person(\"David\",\"Arenburg\", role=\"ctb\"), person(\"Ethan\",\"Smith\", role=\"ctb\"), person(\"Francois\",\"Cocquemas\", role=\"ctb\"), person(\"Matthieu\",\"Gomez\", role=\"ctb\"), person(\"Philippe\",\"Chataignon\", role=\"ctb\"), person(\"Nello\",\"Blaser\", role=\"ctb\"), person(\"Dmitry\",\"Selivanov\", role=\"ctb\"), person(\"Andrey\",\"Riabushenko\", role=\"ctb\"), person(\"Cheng\",\"Lee\", role=\"ctb\"), person(\"Declan\",\"Groves\", role=\"ctb\"), person(\"Daniel\",\"Possenriede\", role=\"ctb\"), person(\"Felipe\",\"Parages\", role=\"ctb\"), person(\"Denes\",\"Toth\", role=\"ctb\"), person(\"Mus\",\"Yaramaz-David\", role=\"ctb\"), person(\"Ayappan\",\"Perumal\", role=\"ctb\"), person(\"James\",\"Sams\", role=\"ctb\"), person(\"Martin\",\"Morgan\", role=\"ctb\"), person(\"Michael\",\"Quinn\", role=\"ctb\"), person(\"@javrucebo\",\"\", role=\"ctb\"), person(\"@marc-outins\",\"\", role=\"ctb\"), person(\"Roy\",\"Storey\", role=\"ctb\"), person(\"Manish\",\"Saraswat\", role=\"ctb\"), person(\"Morgan\",\"Jacob\", role=\"ctb\"), person(\"Michael\",\"Schubmehl\", role=\"ctb\"), person(\"Davis\",\"Vaughan\", role=\"ctb\"), person(\"Leonardo\",\"Silvestri\", role=\"ctb\"), person(\"Jim\",\"Hester\", role=\"ctb\"), person(\"Anthony\",\"Damico\", role=\"ctb\"), person(\"Sebastian\",\"Freundt\", role=\"ctb\"), person(\"David\",\"Simons\", role=\"ctb\"), person(\"Elliott\",\"Sales de Andrade\", role=\"ctb\"), person(\"Cole\",\"Miller\", role=\"ctb\"), person(\"Jens Peder\",\"Meldgaard\", role=\"ctb\"), person(\"Vaclav\",\"Tlapak\", role=\"ctb\"), person(\"Kevin\",\"Ushey\", role=\"ctb\"), person(\"Dirk\",\"Eddelbuettel\", role=\"ctb\"), person(\"Tony\",\"Fischetti\", role=\"ctb\"), person(\"Ofek\",\"Shilon\", role=\"ctb\"), person(\"Vadim\",\"Khotilovich\", role=\"ctb\"), person(\"Hadley\",\"Wickham\", role=\"ctb\"), person(\"Bennet\",\"Becker\", role=\"ctb\"), person(\"Kyle\",\"Haynes\", role=\"ctb\"), person(\"Boniface Christian\",\"Kamgang\", role=\"ctb\"), person(\"Olivier\",\"Delmarcell\", role=\"ctb\"), person(\"Josh\",\"O'Brien\", role=\"ctb\"), person(\"Dereck\",\"de Mezquita\", role=\"ctb\"), person(\"Michael\",\"Czekanski\", role=\"ctb\"), person(\"Dmitry\", \"Shemetov\", role=\"ctb\"), person(\"Nitish\", \"Jha\", role=\"ctb\"), person(\"Joshua\", \"Wu\", role=\"ctb\"), person(\"Iago\", \"Giné-Vázquez\", role=\"ctb\"), person(\"Anirban\", \"Chetia\", role=\"ctb\"), person(\"Doris\", \"Amoakohene\", role=\"ctb\"), person(\"Angel\", \"Feliz\", role=\"ctb\"), person(\"Michael\",\"Young\", role=\"ctb\"), person(\"Mark\", \"Seeto\", role=\"ctb\"), person(\"Philippe\", \"Grosjean\", role=\"ctb\"), person(\"Vincent\", \"Runge\", role=\"ctb\"), person(\"Christian\", \"Wia\", role=\"ctb\"), person(\"Elise\", \"Maigné\", role=\"ctb\"), person(\"Vincent\", \"Rocher\", role=\"ctb\"), person(\"Vijay\", \"Lulla\", role=\"ctb\"), person(\"Aljaž\", \"Sluga\", role=\"ctb\"), person(\"Bill\", \"Evans\", role=\"ctb\") )", + "NeedsCompilation": "yes", + "Author": "Tyson Barrett [aut, cre] (), Matt Dowle [aut], Arun Srinivasan [aut], Jan Gorecki [aut], Michael Chirico [aut] (), Toby Hocking [aut] (), Benjamin Schwendinger [aut] (), Ivan Krylov [aut] (), Pasha Stetsenko [ctb], Tom Short [ctb], Steve Lianoglou [ctb], Eduard Antonyan [ctb], Markus Bonsch [ctb], Hugh Parsonage [ctb], Scott Ritchie [ctb], Kun Ren [ctb], Xianying Tan [ctb], Rick Saporta [ctb], Otto Seiskari [ctb], Xianghui Dong [ctb], Michel Lang [ctb], Watal Iwasaki [ctb], Seth Wenchel [ctb], Karl Broman [ctb], Tobias Schmidt [ctb], David Arenburg [ctb], Ethan Smith [ctb], Francois Cocquemas [ctb], Matthieu Gomez [ctb], Philippe Chataignon [ctb], Nello Blaser [ctb], Dmitry Selivanov [ctb], Andrey Riabushenko [ctb], Cheng Lee [ctb], Declan Groves [ctb], Daniel Possenriede [ctb], Felipe Parages [ctb], Denes Toth [ctb], Mus Yaramaz-David [ctb], Ayappan Perumal [ctb], James Sams [ctb], Martin Morgan [ctb], Michael Quinn [ctb], @javrucebo [ctb], @marc-outins [ctb], Roy Storey [ctb], Manish Saraswat [ctb], Morgan Jacob [ctb], Michael Schubmehl [ctb], Davis Vaughan [ctb], Leonardo Silvestri [ctb], Jim Hester [ctb], Anthony Damico [ctb], Sebastian Freundt [ctb], David Simons [ctb], Elliott Sales de Andrade [ctb], Cole Miller [ctb], Jens Peder Meldgaard [ctb], Vaclav Tlapak [ctb], Kevin Ushey [ctb], Dirk Eddelbuettel [ctb], Tony Fischetti [ctb], Ofek Shilon [ctb], Vadim Khotilovich [ctb], Hadley Wickham [ctb], Bennet Becker [ctb], Kyle Haynes [ctb], Boniface Christian Kamgang [ctb], Olivier Delmarcell [ctb], Josh O'Brien [ctb], Dereck de Mezquita [ctb], Michael Czekanski [ctb], Dmitry Shemetov [ctb], Nitish Jha [ctb], Joshua Wu [ctb], Iago Giné-Vázquez [ctb], Anirban Chetia [ctb], Doris Amoakohene [ctb], Angel Feliz [ctb], Michael Young [ctb], Mark Seeto [ctb], Philippe Grosjean [ctb], Vincent Runge [ctb], Christian Wia [ctb], Elise Maigné [ctb], Vincent Rocher [ctb], Vijay Lulla [ctb], Aljaž Sluga [ctb], Bill Evans [ctb]", + "Maintainer": "Tyson Barrett ", + "Repository": "CRAN" + }, + "datamods": { + "Package": "datamods", + "Version": "1.5.3", + "Source": "Repository", + "Title": "Modules to Import and Manipulate Data in 'Shiny'", + "Authors@R": "c(person(given = \"Victor\", family = \"Perrier\", role = c(\"aut\", \"cre\", \"cph\"), email = \"victor.perrier@dreamrs.fr\"), person(given = \"Fanny\", family = \"Meyer\", role = \"aut\"), person(given = \"Samra\", family = \"Goumri\", role = \"aut\"), person(given = \"Zauad Shahreer\", family = \"Abeer\", role = \"aut\", email = \"shahreyar.abeer@gmail.com\"), person(given = \"Eduard\", family = \"Szöcs\", role = \"ctb\", email = \"eduardszoecs@gmail.com\") )", + "Description": "'Shiny' modules to import data into an application or 'addin' from various sources, and to manipulate them after that.", + "License": "GPL-3", + "URL": "https://github.com/dreamRs/datamods, https://dreamrs.github.io/datamods/", + "BugReports": "https://github.com/dreamRs/datamods/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Imports": [ + "bslib", + "classInt", + "data.table", + "htmltools", + "phosphoricons", + "reactable", + "readxl", + "rio", + "rlang", + "shiny (>= 1.5.0)", + "shinyWidgets (>= 0.8.4)", + "tibble", + "toastui (>= 0.3.3)", + "tools", + "shinybusy", + "writexl" + ], + "Suggests": [ + "ggplot2", + "jsonlite", + "knitr", + "MASS", + "rmarkdown", + "testthat", + "validate" + ], + "VignetteBuilder": "knitr", + "Depends": [ + "R (>= 2.10)" + ], + "LazyData": "true", + "NeedsCompilation": "no", + "Author": "Victor Perrier [aut, cre, cph], Fanny Meyer [aut], Samra Goumri [aut], Zauad Shahreer Abeer [aut], Eduard Szöcs [ctb]", + "Maintainer": "Victor Perrier ", + "Repository": "CRAN" + }, + "datawizard": { + "Package": "datawizard", + "Version": "1.0.2", + "Source": "Repository", + "Type": "Package", + "Title": "Easy Data Wrangling and Statistical Transformations", + "Authors@R": "c( person(\"Indrajeet\", \"Patil\", , \"patilindrajeet.science@gmail.com\", role = \"aut\", comment = c(ORCID = \"0000-0003-1995-6531\")), person(\"Etienne\", \"Bacher\", , \"etienne.bacher@protonmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-9271-5075\")), person(\"Dominique\", \"Makowski\", , \"dom.makowski@gmail.com\", role = \"aut\", comment = c(ORCID = \"0000-0001-5375-9967\")), person(\"Daniel\", \"Lüdecke\", , \"d.luedecke@uke.de\", role = \"aut\", comment = c(ORCID = \"0000-0002-8895-3206\")), person(\"Mattan S.\", \"Ben-Shachar\", , \"matanshm@post.bgu.ac.il\", role = \"aut\", comment = c(ORCID = \"0000-0002-4287-4801\")), person(\"Brenton M.\", \"Wiernik\", , \"brenton@wiernik.org\", role = \"aut\", comment = c(ORCID = \"0000-0001-9560-6336\")), person(\"Rémi\", \"Thériault\", , \"remi.theriault@mail.mcgill.ca\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4315-6788\")), person(\"Thomas J.\", \"Faulkenberry\", , \"faulkenberry@tarleton.edu\", role = \"rev\"), person(\"Robert\", \"Garrett\", , \"rcg4@illinois.edu\", role = \"rev\") )", + "Maintainer": "Etienne Bacher ", + "Description": "A lightweight package to assist in key steps involved in any data analysis workflow: (1) wrangling the raw data to get it in the needed form, (2) applying preprocessing steps and statistical transformations, and (3) compute statistical summaries of data properties and distributions. It is also the data wrangling backend for packages in 'easystats' ecosystem. References: Patil et al. (2022) .", + "License": "MIT + file LICENSE", + "URL": "https://easystats.github.io/datawizard/", + "BugReports": "https://github.com/easystats/datawizard/issues", + "Depends": [ + "R (>= 4.0)" + ], + "Imports": [ + "insight (>= 1.0.2)", + "stats", + "utils" + ], + "Suggests": [ + "bayestestR", + "boot", + "brms", + "curl", + "data.table", + "dplyr (>= 1.1)", + "effectsize", + "emmeans", + "gamm4", + "ggplot2 (>= 3.5.0)", + "gt", + "haven", + "httr", + "knitr", + "lme4", + "mediation", + "modelbased", + "parameters (>= 0.21.7)", + "poorman (>= 0.2.7)", + "psych", + "readxl", + "readr", + "rio", + "rmarkdown", + "rstanarm", + "see", + "testthat (>= 3.2.1)", + "tibble", + "tidyr", + "withr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/Needs/website": "easystats/easystatstemplate", + "NeedsCompilation": "no", + "Author": "Indrajeet Patil [aut] (), Etienne Bacher [aut, cre] (), Dominique Makowski [aut] (), Daniel Lüdecke [aut] (), Mattan S. Ben-Shachar [aut] (), Brenton M. Wiernik [aut] (), Rémi Thériault [ctb] (), Thomas J. Faulkenberry [rev], Robert Garrett [rev]", + "Repository": "CRAN" + }, + "digest": { + "Package": "digest", + "Version": "0.6.37", + "Source": "Repository", + "Authors@R": "c(person(\"Dirk\", \"Eddelbuettel\", role = c(\"aut\", \"cre\"), email = \"edd@debian.org\", comment = c(ORCID = \"0000-0001-6419-907X\")), person(\"Antoine\", \"Lucas\", role=\"ctb\"), person(\"Jarek\", \"Tuszynski\", role=\"ctb\"), person(\"Henrik\", \"Bengtsson\", role=\"ctb\", comment = c(ORCID = \"0000-0002-7579-5165\")), person(\"Simon\", \"Urbanek\", role=\"ctb\", comment = c(ORCID = \"0000-0003-2297-1732\")), person(\"Mario\", \"Frasca\", role=\"ctb\"), person(\"Bryan\", \"Lewis\", role=\"ctb\"), person(\"Murray\", \"Stokely\", role=\"ctb\"), person(\"Hannes\", \"Muehleisen\", role=\"ctb\"), person(\"Duncan\", \"Murdoch\", role=\"ctb\"), person(\"Jim\", \"Hester\", role=\"ctb\"), person(\"Wush\", \"Wu\", role=\"ctb\", comment = c(ORCID = \"0000-0001-5180-0567\")), person(\"Qiang\", \"Kou\", role=\"ctb\", comment = c(ORCID = \"0000-0001-6786-5453\")), person(\"Thierry\", \"Onkelinx\", role=\"ctb\", comment = c(ORCID = \"0000-0001-8804-4216\")), person(\"Michel\", \"Lang\", role=\"ctb\", comment = c(ORCID = \"0000-0001-9754-0393\")), person(\"Viliam\", \"Simko\", role=\"ctb\"), person(\"Kurt\", \"Hornik\", role=\"ctb\", comment = c(ORCID = \"0000-0003-4198-9911\")), person(\"Radford\", \"Neal\", role=\"ctb\", comment = c(ORCID = \"0000-0002-2473-3407\")), person(\"Kendon\", \"Bell\", role=\"ctb\", comment = c(ORCID = \"0000-0002-9093-8312\")), person(\"Matthew\", \"de Queljoe\", role=\"ctb\"), person(\"Dmitry\", \"Selivanov\", role=\"ctb\"), person(\"Ion\", \"Suruceanu\", role=\"ctb\"), person(\"Bill\", \"Denney\", role=\"ctb\"), person(\"Dirk\", \"Schumacher\", role=\"ctb\"), person(\"András\", \"Svraka\", role=\"ctb\"), person(\"Sergey\", \"Fedorov\", role=\"ctb\"), person(\"Will\", \"Landau\", role=\"ctb\", comment = c(ORCID = \"0000-0003-1878-3253\")), person(\"Floris\", \"Vanderhaeghe\", role=\"ctb\", comment = c(ORCID = \"0000-0002-6378-6229\")), person(\"Kevin\", \"Tappe\", role=\"ctb\"), person(\"Harris\", \"McGehee\", role=\"ctb\"), person(\"Tim\", \"Mastny\", role=\"ctb\"), person(\"Aaron\", \"Peikert\", role=\"ctb\", comment = c(ORCID = \"0000-0001-7813-818X\")), person(\"Mark\", \"van der Loo\", role=\"ctb\", comment = c(ORCID = \"0000-0002-9807-4686\")), person(\"Chris\", \"Muir\", role=\"ctb\", comment = c(ORCID = \"0000-0003-2555-3878\")), person(\"Moritz\", \"Beller\", role=\"ctb\", comment = c(ORCID = \"0000-0003-4852-0526\")), person(\"Sebastian\", \"Campbell\", role=\"ctb\"), person(\"Winston\", \"Chang\", role=\"ctb\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Dean\", \"Attali\", role=\"ctb\", comment = c(ORCID = \"0000-0002-5645-3493\")), person(\"Michael\", \"Chirico\", role=\"ctb\", comment = c(ORCID = \"0000-0003-0787-087X\")), person(\"Kevin\", \"Ushey\", role=\"ctb\"))", + "Date": "2024-08-19", + "Title": "Create Compact Hash Digests of R Objects", + "Description": "Implementation of a function 'digest()' for the creation of hash digests of arbitrary R objects (using the 'md5', 'sha-1', 'sha-256', 'crc32', 'xxhash', 'murmurhash', 'spookyhash', 'blake3', 'crc32c', 'xxh3_64', and 'xxh3_128' algorithms) permitting easy comparison of R language objects, as well as functions such as'hmac()' to create hash-based message authentication code. Please note that this package is not meant to be deployed for cryptographic purposes for which more comprehensive (and widely tested) libraries such as 'OpenSSL' should be used.", + "URL": "https://github.com/eddelbuettel/digest, https://dirk.eddelbuettel.com/code/digest.html", + "BugReports": "https://github.com/eddelbuettel/digest/issues", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "utils" + ], + "License": "GPL (>= 2)", + "Suggests": [ + "tinytest", + "simplermarkdown" + ], + "VignetteBuilder": "simplermarkdown", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Dirk Eddelbuettel [aut, cre] (), Antoine Lucas [ctb], Jarek Tuszynski [ctb], Henrik Bengtsson [ctb] (), Simon Urbanek [ctb] (), Mario Frasca [ctb], Bryan Lewis [ctb], Murray Stokely [ctb], Hannes Muehleisen [ctb], Duncan Murdoch [ctb], Jim Hester [ctb], Wush Wu [ctb] (), Qiang Kou [ctb] (), Thierry Onkelinx [ctb] (), Michel Lang [ctb] (), Viliam Simko [ctb], Kurt Hornik [ctb] (), Radford Neal [ctb] (), Kendon Bell [ctb] (), Matthew de Queljoe [ctb], Dmitry Selivanov [ctb], Ion Suruceanu [ctb], Bill Denney [ctb], Dirk Schumacher [ctb], András Svraka [ctb], Sergey Fedorov [ctb], Will Landau [ctb] (), Floris Vanderhaeghe [ctb] (), Kevin Tappe [ctb], Harris McGehee [ctb], Tim Mastny [ctb], Aaron Peikert [ctb] (), Mark van der Loo [ctb] (), Chris Muir [ctb] (), Moritz Beller [ctb] (), Sebastian Campbell [ctb], Winston Chang [ctb] (), Dean Attali [ctb] (), Michael Chirico [ctb] (), Kevin Ushey [ctb]", + "Maintainer": "Dirk Eddelbuettel ", + "Repository": "CRAN" + }, + "dplyr": { + "Package": "dplyr", + "Version": "1.1.4", + "Source": "Repository", + "Type": "Package", + "Title": "A Grammar of Data Manipulation", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Romain\", \"François\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Lionel\", \"Henry\", role = \"aut\"), person(\"Kirill\", \"Müller\", role = \"aut\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4777-038X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A fast, consistent tool for working with data frame like objects, both in memory and out of memory.", + "License": "MIT + file LICENSE", + "URL": "https://dplyr.tidyverse.org, https://github.com/tidyverse/dplyr", + "BugReports": "https://github.com/tidyverse/dplyr/issues", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "generics", + "glue (>= 1.3.2)", + "lifecycle (>= 1.0.3)", + "magrittr (>= 1.5)", + "methods", + "pillar (>= 1.9.0)", + "R6", + "rlang (>= 1.1.0)", + "tibble (>= 3.2.0)", + "tidyselect (>= 1.2.0)", + "utils", + "vctrs (>= 0.6.4)" + ], + "Suggests": [ + "bench", + "broom", + "callr", + "covr", + "DBI", + "dbplyr (>= 2.2.1)", + "ggplot2", + "knitr", + "Lahman", + "lobstr", + "microbenchmark", + "nycflights13", + "purrr", + "rmarkdown", + "RMySQL", + "RPostgreSQL", + "RSQLite", + "stringi (>= 1.7.6)", + "testthat (>= 3.1.5)", + "tidyr (>= 1.3.0)", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse, shiny, pkgdown, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre] (), Romain François [aut] (), Lionel Henry [aut], Kirill Müller [aut] (), Davis Vaughan [aut] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "e1071": { + "Package": "e1071", + "Version": "1.7-16", + "Source": "Repository", + "Title": "Misc Functions of the Department of Statistics, Probability Theory Group (Formerly: E1071), TU Wien", + "Imports": [ + "graphics", + "grDevices", + "class", + "stats", + "methods", + "utils", + "proxy" + ], + "Suggests": [ + "cluster", + "mlbench", + "nnet", + "randomForest", + "rpart", + "SparseM", + "xtable", + "Matrix", + "MASS", + "slam" + ], + "Authors@R": "c(person(given = \"David\", family = \"Meyer\", role = c(\"aut\", \"cre\"), email = \"David.Meyer@R-project.org\", comment = c(ORCID = \"0000-0002-5196-3048\")), person(given = \"Evgenia\", family = \"Dimitriadou\", role = c(\"aut\",\"cph\")), person(given = \"Kurt\", family = \"Hornik\", role = \"aut\", email = \"Kurt.Hornik@R-project.org\", comment = c(ORCID = \"0000-0003-4198-9911\")), person(given = \"Andreas\", family = \"Weingessel\", role = \"aut\"), person(given = \"Friedrich\", family = \"Leisch\", role = \"aut\"), person(given = \"Chih-Chung\", family = \"Chang\", role = c(\"ctb\",\"cph\"), comment = \"libsvm C++-code\"), person(given = \"Chih-Chen\", family = \"Lin\", role = c(\"ctb\",\"cph\"), comment = \"libsvm C++-code\"))", + "Description": "Functions for latent class analysis, short time Fourier transform, fuzzy clustering, support vector machines, shortest path computation, bagged clustering, naive Bayes classifier, generalized k-nearest neighbour ...", + "License": "GPL-2 | GPL-3", + "LazyLoad": "yes", + "NeedsCompilation": "yes", + "Author": "David Meyer [aut, cre] (), Evgenia Dimitriadou [aut, cph], Kurt Hornik [aut] (), Andreas Weingessel [aut], Friedrich Leisch [aut], Chih-Chung Chang [ctb, cph] (libsvm C++-code), Chih-Chen Lin [ctb, cph] (libsvm C++-code)", + "Maintainer": "David Meyer ", + "Repository": "CRAN" + }, + "eulerr": { + "Package": "eulerr", + "Version": "7.0.2", + "Source": "Repository", + "Title": "Area-Proportional Euler and Venn Diagrams with Ellipses", + "Authors@R": "c(person(\"Johan\", \"Larsson\", email = \"johanlarsson@outlook.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4029-5945\")), person(\"A. Jonathan R.\", \"Godfrey\", role = \"ctb\"), person(\"Peter\", \"Gustafsson\", role = \"ctb\"), person(\"David H.\", \"Eberly\", role = \"ctb\", comment = \"geometric algorithms\"), person(\"Emanuel\", \"Huber\", role = \"ctb\", comment = \"root solver code\"), person(\"Florian\", \"Privé\", role = \"ctb\"))", + "Description": "Generate area-proportional Euler diagrams using numerical optimization. An Euler diagram is a generalization of a Venn diagram, relaxing the criterion that all interactions need to be represented. Diagrams may be fit with ellipses and circles via a wide range of inputs and can be visualized in numerous ways.", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "GenSA", + "graphics", + "grDevices", + "grid", + "polyclip", + "polylabelr", + "Rcpp", + "stats", + "utils" + ], + "Suggests": [ + "covr", + "knitr", + "lattice", + "pBrackets", + "RConics", + "rmarkdown", + "testthat", + "spelling" + ], + "LinkingTo": [ + "Rcpp (>= 0.12.12)", + "RcppArmadillo (>= 0.7.600.1.0)" + ], + "License": "GPL-3", + "Encoding": "UTF-8", + "LazyData": "true", + "VignetteBuilder": "knitr", + "URL": "https://github.com/jolars/eulerr, https://jolars.github.io/eulerr/", + "BugReports": "https://github.com/jolars/eulerr/issues", + "RoxygenNote": "7.2.3", + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Johan Larsson [aut, cre] (), A. Jonathan R. Godfrey [ctb], Peter Gustafsson [ctb], David H. Eberly [ctb] (geometric algorithms), Emanuel Huber [ctb] (root solver code), Florian Privé [ctb]", + "Maintainer": "Johan Larsson ", + "Repository": "CRAN" + }, + "evaluate": { + "Package": "evaluate", + "Version": "1.0.3", + "Source": "Repository", + "Type": "Package", + "Title": "Parsing and Evaluation Tools that Provide More Details than the Default", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Yihui\", \"Xie\", role = \"aut\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Michael\", \"Lawrence\", role = \"ctb\"), person(\"Thomas\", \"Kluyver\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\"), person(\"Barret\", \"Schloerke\", role = \"ctb\"), person(\"Adam\", \"Ryczkowski\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Michel\", \"Lang\", role = \"ctb\"), person(\"Karolis\", \"Koncevičius\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Parsing and evaluation tools that make it easy to recreate the command line behaviour of R.", + "License": "MIT + file LICENSE", + "URL": "https://evaluate.r-lib.org/, https://github.com/r-lib/evaluate", + "BugReports": "https://github.com/r-lib/evaluate/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Suggests": [ + "callr", + "covr", + "ggplot2 (>= 3.3.6)", + "lattice", + "methods", + "pkgload", + "rlang", + "knitr", + "testthat (>= 3.0.0)", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Yihui Xie [aut] (), Michael Lawrence [ctb], Thomas Kluyver [ctb], Jeroen Ooms [ctb], Barret Schloerke [ctb], Adam Ryczkowski [ctb], Hiroaki Yutani [ctb], Michel Lang [ctb], Karolis Koncevičius [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "fansi": { + "Package": "fansi", + "Version": "1.0.6", + "Source": "Repository", + "Title": "ANSI Control Sequence Aware String Functions", + "Description": "Counterparts to R string manipulation functions that account for the effects of ANSI text formatting control sequences.", + "Authors@R": "c( person(\"Brodie\", \"Gaslam\", email=\"brodie.gaslam@yahoo.com\", role=c(\"aut\", \"cre\")), person(\"Elliott\", \"Sales De Andrade\", role=\"ctb\"), person(family=\"R Core Team\", email=\"R-core@r-project.org\", role=\"cph\", comment=\"UTF8 byte length calcs from src/util.c\" ))", + "Depends": [ + "R (>= 3.1.0)" + ], + "License": "GPL-2 | GPL-3", + "URL": "https://github.com/brodieG/fansi", + "BugReports": "https://github.com/brodieG/fansi/issues", + "VignetteBuilder": "knitr", + "Suggests": [ + "unitizer", + "knitr", + "rmarkdown" + ], + "Imports": [ + "grDevices", + "utils" + ], + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "Collate": "'constants.R' 'fansi-package.R' 'internal.R' 'load.R' 'misc.R' 'nchar.R' 'strwrap.R' 'strtrim.R' 'strsplit.R' 'substr2.R' 'trimws.R' 'tohtml.R' 'unhandled.R' 'normalize.R' 'sgr.R'", + "NeedsCompilation": "yes", + "Author": "Brodie Gaslam [aut, cre], Elliott Sales De Andrade [ctb], R Core Team [cph] (UTF8 byte length calcs from src/util.c)", + "Maintainer": "Brodie Gaslam ", + "Repository": "CRAN" + }, + "farver": { + "Package": "farver", + "Version": "2.1.2", + "Source": "Repository", + "Type": "Package", + "Title": "High Performance Colour Space Manipulation", + "Authors@R": "c( person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Berendea\", \"Nicolae\", role = \"aut\", comment = \"Author of the ColorSpace C++ library\"), person(\"Romain\", \"François\", , \"romain@purrple.cat\", role = \"aut\", comment = c(ORCID = \"0000-0002-2444-4226\")), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "The encoding of colour can be handled in many different ways, using different colour spaces. As different colour spaces have different uses, efficient conversion between these representations are important. The 'farver' package provides a set of functions that gives access to very fast colour space conversion and comparisons implemented in C++, and offers speed improvements over the 'convertColor' function in the 'grDevices' package.", + "License": "MIT + file LICENSE", + "URL": "https://farver.data-imaginist.com, https://github.com/thomasp85/farver", + "BugReports": "https://github.com/thomasp85/farver/issues", + "Suggests": [ + "covr", + "testthat (>= 3.0.0)" + ], + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "NeedsCompilation": "yes", + "Author": "Thomas Lin Pedersen [cre, aut] (), Berendea Nicolae [aut] (Author of the ColorSpace C++ library), Romain François [aut] (), Posit, PBC [cph, fnd]", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "fastmap": { + "Package": "fastmap", + "Version": "1.2.0", + "Source": "Repository", + "Title": "Fast Data Structures", + "Authors@R": "c( person(\"Winston\", \"Chang\", email = \"winston@posit.co\", role = c(\"aut\", \"cre\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(given = \"Tessil\", role = \"cph\", comment = \"hopscotch_map library\") )", + "Description": "Fast implementation of data structures, including a key-value store, stack, and queue. Environments are commonly used as key-value stores in R, but every time a new key is used, it is added to R's global symbol table, causing a small amount of memory leakage. This can be problematic in cases where many different keys are used. Fastmap avoids this memory leak issue by implementing the map using data structures in C++.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Suggests": [ + "testthat (>= 2.1.1)" + ], + "URL": "https://r-lib.github.io/fastmap/, https://github.com/r-lib/fastmap", + "BugReports": "https://github.com/r-lib/fastmap/issues", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Posit Software, PBC [cph, fnd], Tessil [cph] (hopscotch_map library)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "filelock": { + "Package": "filelock", + "Version": "1.0.3", + "Source": "Repository", + "Title": "Portable File Locking", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Place an exclusive or shared lock on a file. It uses 'LockFile' on Windows and 'fcntl' locks on Unix-like systems.", + "License": "MIT + file LICENSE", + "URL": "https://r-lib.github.io/filelock/, https://github.com/r-lib/filelock", + "BugReports": "https://github.com/r-lib/filelock/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Suggests": [ + "callr (>= 2.0.0)", + "covr", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "fontawesome": { + "Package": "fontawesome", + "Version": "0.5.3", + "Source": "Repository", + "Type": "Package", + "Title": "Easily Work with 'Font Awesome' Icons", + "Description": "Easily and flexibly insert 'Font Awesome' icons into 'R Markdown' documents and 'Shiny' apps. These icons can be inserted into HTML content through inline 'SVG' tags or 'i' tags. There is also a utility function for exporting 'Font Awesome' icons as 'PNG' images for those situations where raster graphics are needed.", + "Authors@R": "c( person(\"Richard\", \"Iannone\", , \"rich@posit.co\", c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"ctb\"), person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome font\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/fontawesome, https://rstudio.github.io/fontawesome/", + "BugReports": "https://github.com/rstudio/fontawesome/issues", + "Encoding": "UTF-8", + "ByteCompile": "true", + "RoxygenNote": "7.3.2", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "rlang (>= 1.0.6)", + "htmltools (>= 0.5.1.1)" + ], + "Suggests": [ + "covr", + "dplyr (>= 1.0.8)", + "gt (>= 0.9.0)", + "knitr (>= 1.31)", + "testthat (>= 3.0.0)", + "rsvg" + ], + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Richard Iannone [aut, cre] (), Christophe Dervieux [ctb] (), Winston Chang [ctb], Dave Gandy [ctb, cph] (Font-Awesome font), Posit Software, PBC [cph, fnd]", + "Maintainer": "Richard Iannone ", + "Repository": "CRAN" + }, + "forcats": { + "Package": "forcats", + "Version": "1.0.0", + "Source": "Repository", + "Title": "Tools for Working with Categorical Variables (Factors)", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = c(\"aut\", \"cre\")), person(\"RStudio\", role = c(\"cph\", \"fnd\")) )", + "Description": "Helpers for reordering factor levels (including moving specified levels to front, ordering by first appearance, reversing, and randomly shuffling), and tools for modifying factor levels (including collapsing rare levels into other, 'anonymising', and manually 'recoding').", + "License": "MIT + file LICENSE", + "URL": "https://forcats.tidyverse.org/, https://github.com/tidyverse/forcats", + "BugReports": "https://github.com/tidyverse/forcats/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "glue", + "lifecycle", + "magrittr", + "rlang (>= 1.0.0)", + "tibble" + ], + "Suggests": [ + "covr", + "dplyr", + "ggplot2", + "knitr", + "readr", + "rmarkdown", + "testthat (>= 3.0.0)", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], RStudio [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "foreign": { + "Package": "foreign", + "Version": "0.8-90", + "Source": "Repository", + "Priority": "recommended", + "Date": "2025-03-31", + "Title": "Read Data Stored by 'Minitab', 'S', 'SAS', 'SPSS', 'Stata', 'Systat', 'Weka', 'dBase', ...", + "Depends": [ + "R (>= 4.0.0)" + ], + "Imports": [ + "methods", + "utils", + "stats" + ], + "Authors@R": "c( person(\"R Core Team\", email = \"R-core@R-project.org\", role = c(\"aut\", \"cph\", \"cre\"), comment = c(ROR = \"02zz1nj61\")), person(\"Roger\", \"Bivand\", role = c(\"ctb\", \"cph\")), person(c(\"Vincent\", \"J.\"), \"Carey\", role = c(\"ctb\", \"cph\")), person(\"Saikat\", \"DebRoy\", role = c(\"ctb\", \"cph\")), person(\"Stephen\", \"Eglen\", role = c(\"ctb\", \"cph\")), person(\"Rajarshi\", \"Guha\", role = c(\"ctb\", \"cph\")), person(\"Swetlana\", \"Herbrandt\", role = \"ctb\"), person(\"Nicholas\", \"Lewin-Koh\", role = c(\"ctb\", \"cph\")), person(\"Mark\", \"Myatt\", role = c(\"ctb\", \"cph\")), person(\"Michael\", \"Nelson\", role = \"ctb\"), person(\"Ben\", \"Pfaff\", role = \"ctb\"), person(\"Brian\", \"Quistorff\", role = \"ctb\"), person(\"Frank\", \"Warmerdam\", role = c(\"ctb\", \"cph\")), person(\"Stephen\", \"Weigand\", role = c(\"ctb\", \"cph\")), person(\"Free Software Foundation, Inc.\", role = \"cph\"))", + "Contact": "see 'MailingList'", + "Copyright": "see file COPYRIGHTS", + "Description": "Reading and writing data stored by some versions of 'Epi Info', 'Minitab', 'S', 'SAS', 'SPSS', 'Stata', 'Systat', 'Weka', and for reading and writing some 'dBase' files.", + "ByteCompile": "yes", + "Biarch": "yes", + "License": "GPL (>= 2)", + "BugReports": "https://bugs.r-project.org", + "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]", + "Maintainer": "R Core Team ", + "Repository": "CRAN" + }, + "fs": { + "Package": "fs", + "Version": "1.6.6", + "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\")) )", + "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)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "covr", + "crayon", + "knitr", + "pillar (>= 1.0.0)", + "rmarkdown", + "spelling", + "testthat (>= 3.0.0)", + "tibble (>= 1.1.0)", + "vctrs (>= 0.3.0)", + "withr" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Copyright": "file COPYRIGHTS", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.2.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 ", + "Repository": "CRAN" + }, + "generics": { + "Package": "generics", + "Version": "0.1.3", + "Source": "Repository", + "Title": "Common S3 Generics not Provided by Base R Methods Related to Model Fitting", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = c(\"aut\", \"cre\")), person(\"Max\", \"Kuhn\", , \"max@rstudio.com\", role = \"aut\"), person(\"Davis\", \"Vaughan\", , \"davis@rstudio.com\", role = \"aut\"), person(\"RStudio\", role = \"cph\") )", + "Description": "In order to reduce potential package dependencies and conflicts, generics provides a number of commonly used S3 generics.", + "License": "MIT + file LICENSE", + "URL": "https://generics.r-lib.org, https://github.com/r-lib/generics", + "BugReports": "https://github.com/r-lib/generics/issues", + "Depends": [ + "R (>= 3.2)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "covr", + "pkgload", + "testthat (>= 3.0.0)", + "tibble", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.0", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Max Kuhn [aut], Davis Vaughan [aut], RStudio [cph]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "ggalluvial": { + "Package": "ggalluvial", + "Version": "0.12.5", + "Source": "Repository", + "Type": "Package", + "Title": "Alluvial Plots in 'ggplot2'", + "Authors@R": "c( person(given = \"Jason Cory\", family = \"Brunson\", role = c(\"aut\", \"cre\"), email = \"cornelioid@gmail.com\"), person(given = \"Quentin D.\", family = \"Read\", role = 'aut'))", + "Maintainer": "Jason Cory Brunson ", + "Description": "Alluvial plots use variable-width ribbons and stacked bar plots to represent multi-dimensional or repeated-measures data with categorical or ordinal variables; see Riehmann, Hanfler, and Froehlich (2005) and Rosvall and Bergstrom (2010) . Alluvial plots are statistical graphics in the sense of Wilkinson (2006) ; they share elements with Sankey diagrams and parallel sets plots but are uniquely determined from the data and a small set of parameters. This package extends Wickham's (2010) layered grammar of graphics to generate alluvial plots from tidy data.", + "Depends": [ + "R (>= 3.6)", + "ggplot2 (>= 2.2)" + ], + "Imports": [ + "stats", + "dplyr (>= 0.7)", + "tidyr (>= 0.7)", + "lazyeval", + "rlang", + "tidyselect" + ], + "Suggests": [ + "grid", + "alluvial", + "testthat", + "knitr", + "rmarkdown", + "babynames", + "sessioninfo", + "ggrepel", + "shiny (>= 1.4.0.2)", + "htmltools", + "sp (>= 1.4-0)", + "ggfittext (>= 0.6)", + "vdiffr (>= 0.2)" + ], + "License": "GPL-3", + "LazyData": "true", + "URL": "http://corybrunson.github.io/ggalluvial/", + "BugReports": "https://github.com/corybrunson/ggalluvial/issues", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Jason Cory Brunson [aut, cre], Quentin D. Read [aut]", + "Repository": "CRAN" + }, + "ggcorrplot": { + "Package": "ggcorrplot", + "Version": "0.1.4.1", + "Source": "Repository", + "Type": "Package", + "Title": "Visualization of a Correlation Matrix using 'ggplot2'", + "Authors@R": "c(person(given = \"Alboukadel\", family = \"Kassambara\", role = c(\"aut\", \"cre\"), email = \"alboukadel.kassambara@gmail.com\"), person(given = \"Indrajeet\", family = \"Patil\", role = \"ctb\", email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\", Twitter = \"@patilindrajeets\")))", + "Description": "The 'ggcorrplot' package can be used to visualize easily a correlation matrix using 'ggplot2'. It provides a solution for reordering the correlation matrix and displays the significance level on the plot. It also includes a function for computing a matrix of correlation p-values.", + "License": "GPL-2", + "URL": "http://www.sthda.com/english/wiki/ggcorrplot-visualization-of-a-correlation-matrix-using-ggplot2", + "BugReports": "https://github.com/kassambara/ggcorrplot/issues", + "Depends": [ + "R (>= 3.3)", + "ggplot2 (>= 3.3.6)" + ], + "Imports": [ + "reshape2", + "stats" + ], + "Suggests": [ + "testthat (>= 3.0.0)", + "knitr", + "spelling", + "vdiffr (>= 1.0.0)" + ], + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.1.0", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Alboukadel Kassambara [aut, cre], Indrajeet Patil [ctb] (, @patilindrajeets)", + "Maintainer": "Alboukadel Kassambara ", + "Repository": "CRAN" + }, + "ggforce": { + "Package": "ggforce", + "Version": "0.4.2", + "Source": "Repository", + "Type": "Package", + "Title": "Accelerating 'ggplot2'", + "Authors@R": "c(person(given = \"Thomas Lin\", family = \"Pedersen\", role = c(\"cre\", \"aut\"), email = \"thomasp85@gmail.com\", comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"RStudio\", role = \"cph\"))", + "Maintainer": "Thomas Lin Pedersen ", + "Description": "The aim of 'ggplot2' is to aid in visual data investigations. This focus has led to a lack of facilities for composing specialised plots. 'ggforce' aims to be a collection of mainly new stats and geoms that fills this gap. All additional functionality is aimed to come through the official extension system so using 'ggforce' should be a stable experience.", + "URL": "https://ggforce.data-imaginist.com, https://github.com/thomasp85/ggforce", + "BugReports": "https://github.com/thomasp85/ggforce/issues", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Depends": [ + "ggplot2 (>= 3.3.6)", + "R (>= 3.3.0)" + ], + "Imports": [ + "Rcpp (>= 0.12.2)", + "grid", + "scales", + "MASS", + "tweenr (>= 0.1.5)", + "gtable", + "rlang", + "polyclip", + "stats", + "grDevices", + "tidyselect", + "withr", + "utils", + "lifecycle", + "cli", + "vctrs", + "systemfonts" + ], + "LinkingTo": [ + "Rcpp", + "RcppEigen" + ], + "RoxygenNote": "7.3.1", + "Suggests": [ + "sessioninfo", + "concaveman", + "deldir", + "latex2exp", + "reshape2", + "units (>= 0.4-6)", + "covr" + ], + "Collate": "'RcppExports.R' 'aaa.R' 'shape.R' 'arc_bar.R' 'arc.R' 'autodensity.R' 'autohistogram.R' 'autopoint.R' 'bezier.R' 'bspline.R' 'bspline_closed.R' 'circle.R' 'diagonal.R' 'diagonal_wide.R' 'ellipse.R' 'errorbar.R' 'facet_grid_paginate.R' 'facet_matrix.R' 'facet_row.R' 'facet_stereo.R' 'facet_wrap_paginate.R' 'facet_zoom.R' 'ggforce-package.R' 'ggproto-classes.R' 'interpolate.R' 'labeller.R' 'link.R' 'mark_circle.R' 'mark_ellipse.R' 'mark_hull.R' 'mark_label.R' 'mark_rect.R' 'parallel_sets.R' 'position-jitternormal.R' 'position_auto.R' 'position_floatstack.R' 'regon.R' 'scale-depth.R' 'scale-unit.R' 'sina.R' 'spiro.R' 'themes.R' 'trans.R' 'trans_linear.R' 'utilities.R' 'voronoi.R' 'zzz.R'", + "NeedsCompilation": "yes", + "Author": "Thomas Lin Pedersen [cre, aut] (), RStudio [cph]", + "Repository": "CRAN" + }, + "ggplot2": { + "Package": "ggplot2", + "Version": "3.5.2", + "Source": "Repository", + "Title": "Create Elegant Data Visualisations Using the Grammar of Graphics", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Winston\", \"Chang\", role = \"aut\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Lionel\", \"Henry\", role = \"aut\"), person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Kohske\", \"Takahashi\", role = \"aut\"), person(\"Claus\", \"Wilke\", role = \"aut\", comment = c(ORCID = \"0000-0002-7470-9261\")), person(\"Kara\", \"Woo\", role = \"aut\", comment = c(ORCID = \"0000-0002-5125-4188\")), person(\"Hiroaki\", \"Yutani\", role = \"aut\", comment = c(ORCID = \"0000-0002-3385-7233\")), person(\"Dewey\", \"Dunnington\", role = \"aut\", comment = c(ORCID = \"0000-0002-9415-4582\")), person(\"Teun\", \"van den Brand\", role = \"aut\", comment = c(ORCID = \"0000-0002-9335-7468\")), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A system for 'declaratively' creating graphics, based on \"The Grammar of Graphics\". You provide the data, tell 'ggplot2' how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details.", + "License": "MIT + file LICENSE", + "URL": "https://ggplot2.tidyverse.org, https://github.com/tidyverse/ggplot2", + "BugReports": "https://github.com/tidyverse/ggplot2/issues", + "Depends": [ + "R (>= 3.5)" + ], + "Imports": [ + "cli", + "glue", + "grDevices", + "grid", + "gtable (>= 0.1.1)", + "isoband", + "lifecycle (> 1.0.1)", + "MASS", + "mgcv", + "rlang (>= 1.1.0)", + "scales (>= 1.3.0)", + "stats", + "tibble", + "vctrs (>= 0.6.0)", + "withr (>= 2.5.0)" + ], + "Suggests": [ + "covr", + "dplyr", + "ggplot2movies", + "hexbin", + "Hmisc", + "knitr", + "mapproj", + "maps", + "multcomp", + "munsell", + "nlme", + "profvis", + "quantreg", + "ragg (>= 1.2.6)", + "RColorBrewer", + "rmarkdown", + "rpart", + "sf (>= 0.7-3)", + "svglite (>= 2.1.2)", + "testthat (>= 3.1.2)", + "vdiffr (>= 1.0.6)", + "xml2" + ], + "Enhances": [ + "sp" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "ggtext, tidyr, forcats, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "Collate": "'ggproto.R' 'ggplot-global.R' 'aaa-.R' 'aes-colour-fill-alpha.R' 'aes-evaluation.R' 'aes-group-order.R' 'aes-linetype-size-shape.R' 'aes-position.R' 'compat-plyr.R' 'utilities.R' 'aes.R' 'utilities-checks.R' 'legend-draw.R' 'geom-.R' 'annotation-custom.R' 'annotation-logticks.R' 'geom-polygon.R' 'geom-map.R' 'annotation-map.R' 'geom-raster.R' 'annotation-raster.R' 'annotation.R' 'autolayer.R' 'autoplot.R' 'axis-secondary.R' 'backports.R' 'bench.R' 'bin.R' 'coord-.R' 'coord-cartesian-.R' 'coord-fixed.R' 'coord-flip.R' 'coord-map.R' 'coord-munch.R' 'coord-polar.R' 'coord-quickmap.R' 'coord-radial.R' 'coord-sf.R' 'coord-transform.R' 'data.R' 'docs_layer.R' 'facet-.R' 'facet-grid-.R' 'facet-null.R' 'facet-wrap.R' 'fortify-lm.R' 'fortify-map.R' 'fortify-multcomp.R' 'fortify-spatial.R' 'fortify.R' 'stat-.R' 'geom-abline.R' 'geom-rect.R' 'geom-bar.R' 'geom-bin2d.R' 'geom-blank.R' 'geom-boxplot.R' 'geom-col.R' 'geom-path.R' 'geom-contour.R' 'geom-count.R' 'geom-crossbar.R' 'geom-segment.R' 'geom-curve.R' 'geom-defaults.R' 'geom-ribbon.R' 'geom-density.R' 'geom-density2d.R' 'geom-dotplot.R' 'geom-errorbar.R' 'geom-errorbarh.R' 'geom-freqpoly.R' 'geom-function.R' 'geom-hex.R' 'geom-histogram.R' 'geom-hline.R' 'geom-jitter.R' 'geom-label.R' 'geom-linerange.R' 'geom-point.R' 'geom-pointrange.R' 'geom-quantile.R' 'geom-rug.R' 'geom-sf.R' 'geom-smooth.R' 'geom-spoke.R' 'geom-text.R' 'geom-tile.R' 'geom-violin.R' 'geom-vline.R' 'ggplot2-package.R' 'grob-absolute.R' 'grob-dotstack.R' 'grob-null.R' 'grouping.R' 'theme-elements.R' 'guide-.R' 'guide-axis.R' 'guide-axis-logticks.R' 'guide-axis-stack.R' 'guide-axis-theta.R' 'guide-legend.R' 'guide-bins.R' 'guide-colorbar.R' 'guide-colorsteps.R' 'guide-custom.R' 'layer.R' 'guide-none.R' 'guide-old.R' 'guides-.R' 'guides-grid.R' 'hexbin.R' 'import-standalone-obj-type.R' 'import-standalone-types-check.R' 'labeller.R' 'labels.R' 'layer-sf.R' 'layout.R' 'limits.R' 'margins.R' 'performance.R' 'plot-build.R' 'plot-construction.R' 'plot-last.R' 'plot.R' 'position-.R' 'position-collide.R' 'position-dodge.R' 'position-dodge2.R' 'position-identity.R' 'position-jitter.R' 'position-jitterdodge.R' 'position-nudge.R' 'position-stack.R' 'quick-plot.R' 'reshape-add-margins.R' 'save.R' 'scale-.R' 'scale-alpha.R' 'scale-binned.R' 'scale-brewer.R' 'scale-colour.R' 'scale-continuous.R' 'scale-date.R' 'scale-discrete-.R' 'scale-expansion.R' 'scale-gradient.R' 'scale-grey.R' 'scale-hue.R' 'scale-identity.R' 'scale-linetype.R' 'scale-linewidth.R' 'scale-manual.R' 'scale-shape.R' 'scale-size.R' 'scale-steps.R' 'scale-type.R' 'scale-view.R' 'scale-viridis.R' 'scales-.R' 'stat-align.R' 'stat-bin.R' 'stat-bin2d.R' 'stat-bindot.R' 'stat-binhex.R' 'stat-boxplot.R' 'stat-contour.R' 'stat-count.R' 'stat-density-2d.R' 'stat-density.R' 'stat-ecdf.R' 'stat-ellipse.R' 'stat-function.R' 'stat-identity.R' 'stat-qq-line.R' 'stat-qq.R' 'stat-quantilemethods.R' 'stat-sf-coordinates.R' 'stat-sf.R' 'stat-smooth-methods.R' 'stat-smooth.R' 'stat-sum.R' 'stat-summary-2d.R' 'stat-summary-bin.R' 'stat-summary-hex.R' 'stat-summary.R' 'stat-unique.R' 'stat-ydensity.R' 'summarise-plot.R' 'summary.R' 'theme.R' 'theme-defaults.R' 'theme-current.R' 'utilities-break.R' 'utilities-grid.R' 'utilities-help.R' 'utilities-matrix.R' 'utilities-patterns.R' 'utilities-resolution.R' 'utilities-tidy-eval.R' 'zxx.R' 'zzz.R'", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut] (), Winston Chang [aut] (), Lionel Henry [aut], Thomas Lin Pedersen [aut, cre] (), Kohske Takahashi [aut], Claus Wilke [aut] (), Kara Woo [aut] (), Hiroaki Yutani [aut] (), Dewey Dunnington [aut] (), Teun van den Brand [aut] (), Posit, PBC [cph, fnd]", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "ggridges": { + "Package": "ggridges", + "Version": "0.5.6", + "Source": "Repository", + "Type": "Package", + "Title": "Ridgeline Plots in 'ggplot2'", + "Authors@R": "person( given = \"Claus O.\", family = \"Wilke\", role = c(\"aut\", \"cre\"), email = \"wilke@austin.utexas.edu\", comment = c(ORCID = \"0000-0002-7470-9261\") )", + "Description": "Ridgeline plots provide a convenient way of visualizing changes in distributions over time or space. This package enables the creation of such plots in 'ggplot2'.", + "URL": "https://wilkelab.org/ggridges/", + "BugReports": "https://github.com/wilkelab/ggridges/issues", + "Depends": [ + "R (>= 3.2)" + ], + "Imports": [ + "ggplot2 (>= 3.4.0)", + "grid (>= 3.0.0)", + "scales (>= 0.4.1)", + "withr (>= 2.1.1)" + ], + "License": "GPL-2 | file LICENSE", + "LazyData": "true", + "Suggests": [ + "covr", + "dplyr", + "patchwork", + "ggplot2movies", + "forcats", + "knitr", + "rmarkdown", + "testthat", + "vdiffr" + ], + "VignetteBuilder": "knitr", + "Collate": "'data.R' 'ggridges.R' 'geoms.R' 'geomsv.R' 'geoms-gradient.R' 'geom-density-line.R' 'position.R' 'scale-cyclical.R' 'scale-point.R' 'scale-vline.R' 'stats.R' 'theme.R' 'utils_ggplot2.R' 'utils.R'", + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Claus O. Wilke [aut, cre] ()", + "Maintainer": "Claus O. Wilke ", + "Repository": "CRAN" + }, + "ggstats": { + "Package": "ggstats", + "Version": "0.9.0", + "Source": "Repository", + "Type": "Package", + "Title": "Extension to 'ggplot2' for Plotting Stats", + "Authors@R": "c( person( \"Joseph\", \"Larmarange\", , \"joseph@larmarange.net\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0001-7097-700X\") ) )", + "Description": "Provides new statistics, new geometries and new positions for 'ggplot2' and a suite of functions to facilitate the creation of statistical plots.", + "License": "GPL (>= 3)", + "URL": "https://larmarange.github.io/ggstats/, https://github.com/larmarange/ggstats", + "BugReports": "https://github.com/larmarange/ggstats/issues", + "Depends": [ + "R (>= 4.2)" + ], + "Imports": [ + "cli", + "dplyr", + "forcats", + "ggplot2 (>= 3.4.0)", + "lifecycle", + "patchwork", + "purrr", + "rlang", + "scales", + "stats", + "stringr", + "utils", + "tidyr" + ], + "Suggests": [ + "betareg", + "broom", + "broom.helpers (>= 1.20.0)", + "emmeans", + "glue", + "gtsummary", + "knitr", + "labelled (>= 2.11.0)", + "reshape", + "rmarkdown", + "nnet", + "parameters", + "pscl", + "testthat (>= 3.0.0)", + "spelling", + "survey", + "survival", + "vdiffr" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Language": "en-US", + "VignetteBuilder": "knitr", + "NeedsCompilation": "no", + "Author": "Joseph Larmarange [aut, cre] ()", + "Maintainer": "Joseph Larmarange ", + "Repository": "CRAN" + }, + "glue": { + "Package": "glue", + "Version": "1.8.0", + "Source": "Repository", + "Title": "Interpreted String Literals", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Jennifer\", \"Bryan\", , \"jenny@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-6983-2759\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "An implementation of interpreted string literals, inspired by Python's Literal String Interpolation and Docstrings and Julia's Triple-Quoted String Literals .", + "License": "MIT + file LICENSE", + "URL": "https://glue.tidyverse.org/, https://github.com/tidyverse/glue", + "BugReports": "https://github.com/tidyverse/glue/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "methods" + ], + "Suggests": [ + "crayon", + "DBI (>= 1.2.0)", + "dplyr", + "knitr", + "magrittr", + "rlang", + "rmarkdown", + "RSQLite", + "testthat (>= 3.2.0)", + "vctrs (>= 0.3.0)", + "waldo (>= 0.5.3)", + "withr" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/Needs/website": "bench, forcats, ggbeeswarm, ggplot2, R.utils, rprintf, tidyr, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Jim Hester [aut] (), Jennifer Bryan [aut, cre] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN" + }, + "gridExtra": { + "Package": "gridExtra", + "Version": "2.3", + "Source": "Repository", + "Authors@R": "c(person(\"Baptiste\", \"Auguie\", email = \"baptiste.auguie@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Anton\", \"Antonov\", email = \"tonytonov@gmail.com\", role = c(\"ctb\")))", + "License": "GPL (>= 2)", + "Title": "Miscellaneous Functions for \"Grid\" Graphics", + "Type": "Package", + "Description": "Provides a number of user-level functions to work with \"grid\" graphics, notably to arrange multiple grid-based plots on a page, and draw tables.", + "VignetteBuilder": "knitr", + "Imports": [ + "gtable", + "grid", + "grDevices", + "graphics", + "utils" + ], + "Suggests": [ + "ggplot2", + "egg", + "lattice", + "knitr", + "testthat" + ], + "RoxygenNote": "6.0.1", + "NeedsCompilation": "no", + "Author": "Baptiste Auguie [aut, cre], Anton Antonov [ctb]", + "Maintainer": "Baptiste Auguie ", + "Repository": "CRAN" + }, + "gt": { + "Package": "gt", + "Version": "1.0.0", + "Source": "Repository", + "Type": "Package", + "Title": "Easily Create Presentation-Ready Display Tables", + "Authors@R": "c( person(\"Richard\", \"Iannone\", , \"rich@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Barret\", \"Schloerke\", , \"barret@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Ellis\", \"Hughes\", , \"ellis.h.hughes@gsk.com\", role = \"aut\", comment = c(ORCID = \"0000-0003-0637-4436\")), person(\"Alexandra\", \"Lauer\", , \"alexandralauer1@gmail.com\", role = \"aut\", comment = c(ORCID = \"0000-0002-4191-6301\")), person(\"JooYoung\", \"Seo\", , \"jseo1005@illinois.edu\", role = \"aut\", comment = c(ORCID = \"0000-0002-4064-6012\")), person(\"Ken\", \"Brevoort\", , \"ken@brevoort.com\", role = \"aut\", comment = c(ORCID = \"0000-0002-4001-8358\")), person(\"Olivier\", \"Roy\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Build display tables from tabular data with an easy-to-use set of functions. With its progressive approach, we can construct display tables with a cohesive set of table parts. Table values can be formatted using any of the included formatting functions. Footnotes and cell styles can be precisely added through a location targeting system. The way in which 'gt' handles things for you means that you don't often have to worry about the fine details.", + "License": "MIT + file LICENSE", + "URL": "https://gt.rstudio.com, https://github.com/rstudio/gt", + "BugReports": "https://github.com/rstudio/gt/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "base64enc (>= 0.1-3)", + "bigD (>= 0.2)", + "bitops (>= 1.0-7)", + "cli (>= 3.6.3)", + "commonmark (>= 1.9.1)", + "dplyr (>= 1.1.4)", + "fs (>= 1.6.4)", + "glue (>= 1.8.0)", + "htmltools (>= 0.5.8.1)", + "htmlwidgets (>= 1.6.4)", + "juicyjuice (>= 0.1.0)", + "magrittr (>= 2.0.3)", + "markdown (>= 1.13)", + "reactable (>= 0.4.4)", + "rlang (>= 1.1.4)", + "sass (>= 0.4.9)", + "scales (>= 1.3.0)", + "tidyselect (>= 1.2.1)", + "vctrs", + "xml2 (>= 1.3.6)" + ], + "Suggests": [ + "fontawesome (>= 0.5.2)", + "ggplot2", + "grid", + "gtable (>= 0.3.6)", + "katex (>= 1.4.1)", + "knitr", + "lubridate", + "magick", + "paletteer", + "RColorBrewer", + "rmarkdown (>= 2.20)", + "rsvg", + "rvest", + "shiny (>= 1.9.1)", + "testthat (>= 3.1.9)", + "tidyr (>= 1.0.0)", + "webshot2 (>= 0.1.0)", + "withr" + ], + "Config/Needs/coverage": "officer", + "Config/Needs/website": "quarto", + "ByteCompile": "true", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Richard Iannone [aut, cre] (), Joe Cheng [aut], Barret Schloerke [aut] (), Ellis Hughes [aut] (), Alexandra Lauer [aut] (), JooYoung Seo [aut] (), Ken Brevoort [aut] (), Olivier Roy [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Richard Iannone ", + "Repository": "CRAN" + }, + "gtable": { + "Package": "gtable", + "Version": "0.3.6", + "Source": "Repository", + "Title": "Arrange 'Grobs' in Tables", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools to make it easier to work with \"tables\" of 'grobs'. The 'gtable' package defines a 'gtable' grob class that specifies a grid along with a list of grobs and their placement in the grid. Further the package makes it easy to manipulate and combine 'gtable' objects so that complex compositions can be built up sequentially.", + "License": "MIT + file LICENSE", + "URL": "https://gtable.r-lib.org, https://github.com/r-lib/gtable", + "BugReports": "https://github.com/r-lib/gtable/issues", + "Depends": [ + "R (>= 4.0)" + ], + "Imports": [ + "cli", + "glue", + "grid", + "lifecycle", + "rlang (>= 1.1.0)", + "stats" + ], + "Suggests": [ + "covr", + "ggplot2", + "knitr", + "profvis", + "rmarkdown", + "testthat (>= 3.0.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2024-10-25", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Thomas Lin Pedersen [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "gtsummary": { + "Package": "gtsummary", + "Version": "2.2.0", + "Source": "Repository", + "Title": "Presentation-Ready Data Summary and Analytic Result Tables", + "Authors@R": "c( person(\"Daniel D.\", \"Sjoberg\", , \"danield.sjoberg@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0862-2018\")), person(\"Joseph\", \"Larmarange\", role = \"aut\", comment = c(ORCID = \"0000-0001-7097-700X\")), person(\"Michael\", \"Curry\", role = \"aut\", comment = c(ORCID = \"0000-0002-0261-4044\")), person(\"Emily\", \"de la Rua\", , role = \"aut\", comment = c(ORCID = \"0009-0000-8738-5561\")), person(\"Jessica\", \"Lavery\", role = \"aut\", comment = c(ORCID = \"0000-0002-2746-5647\")), person(\"Karissa\", \"Whiting\", role = \"aut\", comment = c(ORCID = \"0000-0002-4683-1868\")), person(\"Emily C.\", \"Zabor\", role = \"aut\", comment = c(ORCID = \"0000-0002-1402-4498\")), person(\"Xing\", \"Bai\", role = \"ctb\"), person(\"Esther\", \"Drill\", role = \"ctb\", comment = c(ORCID = \"0000-0002-3315-4538\")), person(\"Jessica\", \"Flynn\", role = \"ctb\", comment = c(ORCID = \"0000-0001-8310-6684\")), person(\"Margie\", \"Hannum\", role = \"ctb\", comment = c(ORCID = \"0000-0002-2953-0449\")), person(\"Stephanie\", \"Lobaugh\", role = \"ctb\"), person(\"Shannon\", \"Pileggi\", role = \"ctb\", comment = c(ORCID = \"0000-0002-7732-4164\")), person(\"Amy\", \"Tin\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8005-0694\")), person(\"Gustavo\", \"Zapata Wainberg\", role = \"ctb\", comment = c(ORCID = \"0000-0002-2524-3637\")) )", + "Description": "Creates presentation-ready tables summarizing data sets, regression models, and more. The code to create the tables is concise and highly customizable. Data frames can be summarized with any function, e.g. mean(), median(), even user-written functions. Regression models are summarized and include the reference rows for categorical variables. Common regression models, such as logistic regression and Cox proportional hazards regression, are automatically identified and the tables are pre-filled with appropriate column headers.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/ddsjoberg/gtsummary, https://www.danieldsjoberg.com/gtsummary/", + "BugReports": "https://github.com/ddsjoberg/gtsummary/issues", + "Depends": [ + "R (>= 4.2)" + ], + "Imports": [ + "cards (>= 0.6.0)", + "cli (>= 3.6.3)", + "dplyr (>= 1.1.3)", + "glue (>= 1.8.0)", + "gt (>= 0.11.1)", + "lifecycle (>= 1.0.3)", + "rlang (>= 1.1.1)", + "tidyr (>= 1.3.0)", + "vctrs (>= 0.6.4)" + ], + "Suggests": [ + "aod (>= 1.3.3)", + "broom (>= 1.0.5)", + "broom.helpers (>= 1.17.0)", + "broom.mixed (>= 0.2.9)", + "car (>= 3.0-11)", + "cardx (>= 0.2.4)", + "cmprsk", + "effectsize (>= 0.6.0)", + "emmeans (>= 1.7.3)", + "flextable (>= 0.8.1)", + "geepack (>= 1.3.10)", + "ggstats (>= 0.2.1)", + "huxtable (>= 5.4.0)", + "insight (>= 0.15.0)", + "kableExtra (>= 1.3.4)", + "knitr (>= 1.37)", + "lme4 (>= 1.1-31)", + "mice (>= 3.10.0)", + "nnet", + "officer", + "openxlsx", + "parameters (>= 0.20.2)", + "parsnip (>= 0.1.7)", + "rmarkdown", + "smd (>= 0.6.6)", + "spelling", + "survey (>= 4.2)", + "survival (>= 3.6-4)", + "testthat (>= 3.2.0)", + "withr (>= 2.5.0)", + "workflows (>= 0.2.4)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/check": "hms", + "Config/Needs/website": "forcats, sandwich, scales", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Encoding": "UTF-8", + "Language": "en-US", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Daniel D. Sjoberg [aut, cre] (), Joseph Larmarange [aut] (), Michael Curry [aut] (), Emily de la Rua [aut] (), Jessica Lavery [aut] (), Karissa Whiting [aut] (), Emily C. Zabor [aut] (), Xing Bai [ctb], Esther Drill [ctb] (), Jessica Flynn [ctb] (), Margie Hannum [ctb] (), Stephanie Lobaugh [ctb], Shannon Pileggi [ctb] (), Amy Tin [ctb] (), Gustavo Zapata Wainberg [ctb] ()", + "Maintainer": "Daniel D. Sjoberg ", + "Repository": "CRAN" + }, + "haven": { + "Package": "haven", + "Version": "2.5.4", + "Source": "Repository", + "Title": "Import and Export 'SPSS', 'Stata' and 'SAS' Files", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Evan\", \"Miller\", role = c(\"aut\", \"cph\"), comment = \"Author of included ReadStat code\"), person(\"Danny\", \"Smith\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Import foreign statistical formats into R via the embedded 'ReadStat' C library, .", + "License": "MIT + file LICENSE", + "URL": "https://haven.tidyverse.org, https://github.com/tidyverse/haven, https://github.com/WizardMac/ReadStat", + "BugReports": "https://github.com/tidyverse/haven/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli (>= 3.0.0)", + "forcats (>= 0.2.0)", + "hms", + "lifecycle", + "methods", + "readr (>= 0.1.0)", + "rlang (>= 0.4.0)", + "tibble", + "tidyselect", + "vctrs (>= 0.3.0)" + ], + "Suggests": [ + "covr", + "crayon", + "fs", + "knitr", + "pillar (>= 1.4.0)", + "rmarkdown", + "testthat (>= 3.0.0)", + "utf8" + ], + "LinkingTo": [ + "cpp11" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "GNU make, zlib: zlib1g-dev (deb), zlib-devel (rpm)", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre], Evan Miller [aut, cph] (Author of included ReadStat code), Danny Smith [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "here": { + "Package": "here", + "Version": "1.0.1", + "Source": "Repository", + "Title": "A Simpler Way to Find Your Files", + "Date": "2020-12-13", + "Authors@R": "c(person(given = \"Kirill\", family = \"M\\u00fcller\", role = c(\"aut\", \"cre\"), email = \"krlmlr+r@mailbox.org\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(given = \"Jennifer\", family = \"Bryan\", role = \"ctb\", email = \"jenny@rstudio.com\", comment = c(ORCID = \"0000-0002-6983-2759\")))", + "Description": "Constructs paths to your project's files. Declare the relative path of a file within your project with 'i_am()'. Use the 'here()' function as a drop-in replacement for 'file.path()', it will always locate the files relative to your project root.", + "License": "MIT + file LICENSE", + "URL": "https://here.r-lib.org/, https://github.com/r-lib/here", + "BugReports": "https://github.com/r-lib/here/issues", + "Imports": [ + "rprojroot (>= 2.0.2)" + ], + "Suggests": [ + "conflicted", + "covr", + "fs", + "knitr", + "palmerpenguins", + "plyr", + "readr", + "rlang", + "rmarkdown", + "testthat", + "uuid", + "withr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.1.1.9000", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Kirill Müller [aut, cre] (), Jennifer Bryan [ctb] ()", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "highr": { + "Package": "highr", + "Version": "0.11", + "Source": "Repository", + "Type": "Package", + "Title": "Syntax Highlighting for R Source Code", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Yixuan\", \"Qiu\", role = \"aut\"), person(\"Christopher\", \"Gandrud\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\") )", + "Description": "Provides syntax highlighting for R source code. Currently it supports LaTeX and HTML output. Source code of other languages is supported via Andre Simon's highlight package ().", + "Depends": [ + "R (>= 3.3.0)" + ], + "Imports": [ + "xfun (>= 0.18)" + ], + "Suggests": [ + "knitr", + "markdown", + "testit" + ], + "License": "GPL", + "URL": "https://github.com/yihui/highr", + "BugReports": "https://github.com/yihui/highr/issues", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (), Yixuan Qiu [aut], Christopher Gandrud [ctb], Qiang Li [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "hms": { + "Package": "hms", + "Version": "1.1.3", + "Source": "Repository", + "Title": "Pretty Time of Day", + "Date": "2023-03-21", + "Authors@R": "c( person(\"Kirill\", \"Müller\", role = c(\"aut\", \"cre\"), email = \"kirill@cynkra.com\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(\"R Consortium\", role = \"fnd\"), person(\"RStudio\", role = \"fnd\") )", + "Description": "Implements an S3 class for storing and formatting time-of-day values, based on the 'difftime' class.", + "Imports": [ + "lifecycle", + "methods", + "pkgconfig", + "rlang (>= 1.0.2)", + "vctrs (>= 0.3.8)" + ], + "Suggests": [ + "crayon", + "lubridate", + "pillar (>= 1.1.0)", + "testthat (>= 3.0.0)" + ], + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "URL": "https://hms.tidyverse.org/, https://github.com/tidyverse/hms", + "BugReports": "https://github.com/tidyverse/hms/issues", + "RoxygenNote": "7.2.3", + "Config/testthat/edition": "3", + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "false", + "Config/Needs/website": "tidyverse/tidytemplate", + "NeedsCompilation": "no", + "Author": "Kirill Müller [aut, cre] (), R Consortium [fnd], RStudio [fnd]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "htmlTable": { + "Package": "htmlTable", + "Version": "2.4.3", + "Source": "Repository", + "Title": "Advanced Tables for Markdown/HTML", + "Authors@R": "c( person(\"Max\", \"Gordon\", email = \"max@gforge.se\", role = c(\"aut\", \"cre\")), person(\"Stephen\", \"Gragg\", role=c(\"aut\")), person(\"Peter\", \"Konings\", role=c(\"aut\")))", + "Maintainer": "Max Gordon ", + "Description": "Tables with state-of-the-art layout elements such as row spanners, column spanners, table spanners, zebra striping, and more. While allowing advanced layout, the underlying css-structure is simple in order to maximize compatibility with common word processors. The package also contains a few text formatting functions that help outputting text compatible with HTML/LaTeX.", + "License": "GPL (>= 3)", + "URL": "https://gforge.se/packages/", + "BugReports": "https://github.com/gforge/htmlTable/issues", + "Biarch": "yes", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "stringr", + "knitr (>= 1.6)", + "magrittr (>= 1.5)", + "methods", + "checkmate", + "htmlwidgets", + "htmltools", + "rstudioapi (>= 0.6)" + ], + "Suggests": [ + "testthat", + "XML", + "xml2", + "Hmisc", + "rmarkdown", + "chron", + "lubridate", + "tibble", + "purrr", + "tidyselect", + "glue", + "rlang", + "tidyr (>= 0.7.2)", + "dplyr (>= 0.7.4)" + ], + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.2.2", + "Author": "Max Gordon [aut, cre], Stephen Gragg [aut], Peter Konings [aut]", + "Repository": "CRAN" + }, + "htmltools": { + "Package": "htmltools", + "Version": "0.5.8.1", + "Source": "Repository", + "Type": "Package", + "Title": "Tools for HTML", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Barret\", \"Schloerke\", , \"barret@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Yihui\", \"Xie\", , \"yihui@posit.co\", role = \"aut\"), person(\"Jeff\", \"Allen\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools for HTML generation and output.", + "License": "GPL (>= 2)", + "URL": "https://github.com/rstudio/htmltools, https://rstudio.github.io/htmltools/", + "BugReports": "https://github.com/rstudio/htmltools/issues", + "Depends": [ + "R (>= 2.14.1)" + ], + "Imports": [ + "base64enc", + "digest", + "fastmap (>= 1.1.0)", + "grDevices", + "rlang (>= 1.0.0)", + "utils" + ], + "Suggests": [ + "Cairo", + "markdown", + "ragg", + "shiny", + "testthat", + "withr" + ], + "Enhances": [ + "knitr" + ], + "Config/Needs/check": "knitr", + "Config/Needs/website": "rstudio/quillt, bench", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Collate": "'colors.R' 'fill.R' 'html_dependency.R' 'html_escape.R' 'html_print.R' 'htmltools-package.R' 'images.R' 'known_tags.R' 'selector.R' 'staticimports.R' 'tag_query.R' 'utils.R' 'tags.R' 'template.R'", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut], Carson Sievert [aut, cre] (), Barret Schloerke [aut] (), Winston Chang [aut] (), Yihui Xie [aut], Jeff Allen [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "htmlwidgets": { + "Package": "htmlwidgets", + "Version": "1.6.4", + "Source": "Repository", + "Type": "Package", + "Title": "HTML Widgets for R", + "Authors@R": "c( person(\"Ramnath\", \"Vaidyanathan\", role = c(\"aut\", \"cph\")), person(\"Yihui\", \"Xie\", role = \"aut\"), person(\"JJ\", \"Allaire\", role = \"aut\"), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Carson\", \"Sievert\", , \"carson@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Kenton\", \"Russell\", role = c(\"aut\", \"cph\")), person(\"Ellis\", \"Hughes\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A framework for creating HTML widgets that render in various contexts including the R console, 'R Markdown' documents, and 'Shiny' web applications.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/ramnathv/htmlwidgets", + "BugReports": "https://github.com/ramnathv/htmlwidgets/issues", + "Imports": [ + "grDevices", + "htmltools (>= 0.5.7)", + "jsonlite (>= 0.9.16)", + "knitr (>= 1.8)", + "rmarkdown", + "yaml" + ], + "Suggests": [ + "testthat" + ], + "Enhances": [ + "shiny (>= 1.1)" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Ramnath Vaidyanathan [aut, cph], Yihui Xie [aut], JJ Allaire [aut], Joe Cheng [aut], Carson Sievert [aut, cre] (), Kenton Russell [aut, cph], Ellis Hughes [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "httpuv": { + "Package": "httpuv", + "Version": "1.6.16", + "Source": "Repository", + "Type": "Package", + "Title": "HTTP and WebSocket Server Library", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit, PBC\", \"fnd\", role = \"cph\"), person(\"Hector\", \"Corrada Bravo\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\"), person(\"Andrzej\", \"Krzemienski\", role = \"cph\", comment = \"optional.hpp\"), person(\"libuv project contributors\", role = \"cph\", comment = \"libuv library, see src/libuv/AUTHORS file\"), person(\"Joyent, Inc. and other Node contributors\", role = \"cph\", comment = \"libuv library, see src/libuv/AUTHORS file; and http-parser library, see src/http-parser/AUTHORS file\"), person(\"Niels\", \"Provos\", role = \"cph\", comment = \"libuv subcomponent: tree.h\"), person(\"Internet Systems Consortium, Inc.\", role = \"cph\", comment = \"libuv subcomponent: inet_pton and inet_ntop, contained in src/libuv/src/inet.c\"), person(\"Alexander\", \"Chemeris\", role = \"cph\", comment = \"libuv subcomponent: stdint-msvc2008.h (from msinttypes)\"), person(\"Google, Inc.\", role = \"cph\", comment = \"libuv subcomponent: pthread-fixes.c\"), person(\"Sony Mobile Communcations AB\", role = \"cph\", comment = \"libuv subcomponent: pthread-fixes.c\"), person(\"Berkeley Software Design Inc.\", role = \"cph\", comment = \"libuv subcomponent: android-ifaddrs.h, android-ifaddrs.c\"), person(\"Kenneth\", \"MacKay\", role = \"cph\", comment = \"libuv subcomponent: android-ifaddrs.h, android-ifaddrs.c\"), person(\"Emergya (Cloud4all, FP7/2007-2013, grant agreement no 289016)\", role = \"cph\", comment = \"libuv subcomponent: android-ifaddrs.h, android-ifaddrs.c\"), person(\"Steve\", \"Reid\", role = \"aut\", comment = \"SHA-1 implementation\"), person(\"James\", \"Brown\", role = \"aut\", comment = \"SHA-1 implementation\"), person(\"Bob\", \"Trower\", role = \"aut\", comment = \"base64 implementation\"), person(\"Alexander\", \"Peslyak\", role = \"aut\", comment = \"MD5 implementation\"), person(\"Trantor Standard Systems\", role = \"cph\", comment = \"base64 implementation\"), person(\"Igor\", \"Sysoev\", role = \"cph\", comment = \"http-parser\") )", + "Description": "Provides low-level socket and protocol support for handling HTTP and WebSocket requests directly from within R. It is primarily intended as a building block for other packages, rather than making it particularly easy to create complete web applications using httpuv alone. httpuv is built on top of the libuv and http-parser C libraries, both of which were developed by Joyent, Inc. (See LICENSE file for libuv and http-parser license information.)", + "License": "GPL (>= 2) | file LICENSE", + "URL": "https://github.com/rstudio/httpuv", + "BugReports": "https://github.com/rstudio/httpuv/issues", + "Depends": [ + "R (>= 2.15.1)" + ], + "Imports": [ + "later (>= 0.8.0)", + "promises", + "R6", + "Rcpp (>= 1.0.7)", + "utils" + ], + "Suggests": [ + "callr", + "curl", + "jsonlite", + "testthat", + "websocket" + ], + "LinkingTo": [ + "later", + "Rcpp" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "GNU make, zlib", + "Collate": "'RcppExports.R' 'httpuv.R' 'random_port.R' 'server.R' 'staticServer.R' 'static_paths.R' 'utils.R'", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut], Winston Chang [aut, cre], Posit, PBC fnd [cph], Hector Corrada Bravo [ctb], Jeroen Ooms [ctb], Andrzej Krzemienski [cph] (optional.hpp), libuv project contributors [cph] (libuv library, see src/libuv/AUTHORS file), Joyent, Inc. and other Node contributors [cph] (libuv library, see src/libuv/AUTHORS file; and http-parser library, see src/http-parser/AUTHORS file), Niels Provos [cph] (libuv subcomponent: tree.h), Internet Systems Consortium, Inc. [cph] (libuv subcomponent: inet_pton and inet_ntop, contained in src/libuv/src/inet.c), Alexander Chemeris [cph] (libuv subcomponent: stdint-msvc2008.h (from msinttypes)), Google, Inc. [cph] (libuv subcomponent: pthread-fixes.c), Sony Mobile Communcations AB [cph] (libuv subcomponent: pthread-fixes.c), Berkeley Software Design Inc. [cph] (libuv subcomponent: android-ifaddrs.h, android-ifaddrs.c), Kenneth MacKay [cph] (libuv subcomponent: android-ifaddrs.h, android-ifaddrs.c), Emergya (Cloud4all, FP7/2007-2013, grant agreement no 289016) [cph] (libuv subcomponent: android-ifaddrs.h, android-ifaddrs.c), Steve Reid [aut] (SHA-1 implementation), James Brown [aut] (SHA-1 implementation), Bob Trower [aut] (base64 implementation), Alexander Peslyak [aut] (MD5 implementation), Trantor Standard Systems [cph] (base64 implementation), Igor Sysoev [cph] (http-parser)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "httr": { + "Package": "httr", + "Version": "1.4.7", + "Source": "Repository", + "Title": "Tools for Working with URLs and HTTP", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Useful tools for working with HTTP organised by HTTP verbs (GET(), POST(), etc). Configuration functions make it easy to control additional request components (authenticate(), add_headers() and so on).", + "License": "MIT + file LICENSE", + "URL": "https://httr.r-lib.org/, https://github.com/r-lib/httr", + "BugReports": "https://github.com/r-lib/httr/issues", + "Depends": [ + "R (>= 3.5)" + ], + "Imports": [ + "curl (>= 5.0.2)", + "jsonlite", + "mime", + "openssl (>= 0.8)", + "R6" + ], + "Suggests": [ + "covr", + "httpuv", + "jpeg", + "knitr", + "png", + "readr", + "rmarkdown", + "testthat (>= 0.8.0)", + "xml2" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre], Posit, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "insight": { + "Package": "insight", + "Version": "1.2.0", + "Source": "Repository", + "Type": "Package", + "Title": "Easy Access to Model Information for Various Model Objects", + "Authors@R": "c(person(given = \"Daniel\", family = \"Lüdecke\", role = c(\"aut\", \"cre\"), email = \"officialeasystats@gmail.com\", comment = c(ORCID = \"0000-0002-8895-3206\")), person(given = \"Dominique\", family = \"Makowski\", role = c(\"aut\", \"ctb\"), email = \"dom.makowski@gmail.com\", comment = c(ORCID = \"0000-0001-5375-9967\")), person(given = \"Indrajeet\", family = \"Patil\", role = c(\"aut\", \"ctb\"), email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\")), person(given = \"Philip\", family = \"Waggoner\", role = c(\"aut\", \"ctb\"), email = \"philip.waggoner@gmail.com\", comment = c(ORCID = \"0000-0002-7825-7573\")), person(given = \"Mattan S.\", family = \"Ben-Shachar\", role = c(\"aut\", \"ctb\"), email = \"matanshm@post.bgu.ac.il\", comment = c(ORCID = \"0000-0002-4287-4801\")), person(given = \"Brenton M.\", family = \"Wiernik\", role = c(\"aut\", \"ctb\"), email = \"brenton@wiernik.org\", comment = c(ORCID = \"0000-0001-9560-6336\")), person(given = \"Vincent\", family = \"Arel-Bundock\", email = \"vincent.arel-bundock@umontreal.ca\", role = c(\"aut\", \"ctb\"), comment = c(ORCID = \"0000-0003-2042-7063\")), person(given = \"Etienne\", family = \"Bacher\", email = \"etienne.bacher@protonmail.com\", role = c(\"aut\", \"ctb\"), comment = c(ORCID = \"0000-0002-9271-5075\")), person(given = \"Alex\", family = \"Hayes\", role = c(\"rev\"), email = \"alexpghayes@gmail.com\", comment = c(ORCID = \"0000-0002-4985-5160\")), person(given = \"Grant\", family = \"McDermott\", role = c(\"ctb\"), email = \"grantmcd@uoregon.edu\", comment = c(ORCID = \"0000-0001-7883-8573\")), person(given = \"Rémi\", family = \"Thériault\", role = \"ctb\", email = \"remi.theriault@mail.mcgill.ca\", comment = c(ORCID = \"0000-0003-4315-6788\")), person(given = \"Alex\", family = \"Reinhart\", role = \"ctb\", email = \"areinhar@stat.cmu.edu\", comment = c(ORCID = \"0000-0002-6658-514X\")))", + "Maintainer": "Daniel Lüdecke ", + "Description": "A tool to provide an easy, intuitive and consistent access to information contained in various R models, like model formulas, model terms, information about random effects, data that was used to fit the model or data from response variables. 'insight' mainly revolves around two types of functions: Functions that find (the names of) information, starting with 'find_', and functions that get the underlying data, starting with 'get_'. The package has a consistent syntax and works with many different model objects, where otherwise functions to access these information are missing.", + "License": "GPL-3", + "URL": "https://easystats.github.io/insight/", + "BugReports": "https://github.com/easystats/insight/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "methods", + "stats", + "utils" + ], + "Suggests": [ + "AER", + "afex", + "aod", + "ape", + "BayesFactor", + "bayestestR", + "bbmle", + "bdsmatrix", + "betareg", + "bife", + "biglm", + "BH", + "blavaan (>= 0.5-5)", + "blme", + "boot", + "brms", + "broom", + "car", + "carData", + "censReg", + "cgam", + "clubSandwich", + "cobalt", + "coxme", + "cplm", + "crch", + "curl", + "datawizard", + "effectsize", + "emmeans", + "epiR", + "estimatr", + "feisr", + "fixest (>= 0.11.2)", + "fungible", + "fwb", + "gam", + "gamlss", + "gamlss.data", + "gamm4", + "gbm", + "gee", + "geepack", + "geoR", + "GLMMadaptive", + "glmmTMB (>= 1.1.10)", + "glmtoolbox", + "gmnl", + "grDevices", + "gt", + "httptest2", + "httr2", + "interp", + "ivreg", + "JM", + "knitr", + "lavaan", + "lavaSearch2", + "lfe", + "lme4", + "lmerTest", + "lmtest", + "logistf", + "logitr", + "marginaleffects (>= 0.25.0)", + "MASS", + "Matrix", + "mclogit", + "mclust", + "MCMCglmm", + "merTools", + "metaBMA", + "metadat", + "metafor", + "metaplus", + "mgcv", + "mice (>= 3.17.0)", + "mlogit", + "mmrm", + "modelbased (>= 0.9.0)", + "multgee", + "MuMIn", + "nestedLogit", + "nlme", + "nnet", + "nonnest2", + "ordinal", + "panelr", + "parameters", + "parsnip", + "pbkrtest", + "performance", + "phylolm", + "plm", + "poorman", + "PROreg (>= 1.3.0)", + "pscl", + "psych", + "quantreg", + "Rcpp", + "RcppEigen", + "rmarkdown", + "rms", + "robustbase", + "robustlmm", + "rpart", + "rstanarm (>= 2.21.1)", + "rstantools (>= 2.1.0)", + "rstudioapi", + "RWiener", + "sandwich", + "serp", + "speedglm", + "splines", + "statmod", + "survey", + "survival", + "svylme", + "testthat", + "tinytable (>= 0.8.0)", + "TMB", + "truncreg", + "tune", + "tweedie", + "VGAM", + "WeightIt", + "withr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/Needs/website": "easystats/easystatstemplate", + "Config/Needs/check": "stan-dev/cmdstanr", + "NeedsCompilation": "no", + "Author": "Daniel Lüdecke [aut, cre] (), Dominique Makowski [aut, ctb] (), Indrajeet Patil [aut, ctb] (), Philip Waggoner [aut, ctb] (), Mattan S. Ben-Shachar [aut, ctb] (), Brenton M. Wiernik [aut, ctb] (), Vincent Arel-Bundock [aut, ctb] (), Etienne Bacher [aut, ctb] (), Alex Hayes [rev] (), Grant McDermott [ctb] (), Rémi Thériault [ctb] (), Alex Reinhart [ctb] ()", + "Repository": "CRAN" + }, + "isoband": { + "Package": "isoband", + "Version": "0.2.7", + "Source": "Repository", + "Title": "Generate Isolines and Isobands from Regularly Spaced Elevation Grids", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Claus O.\", \"Wilke\", , \"wilke@austin.utexas.edu\", role = \"aut\", comment = c(\"Original author\", ORCID = \"0000-0002-7470-9261\")), person(\"Thomas Lin\", \"Pedersen\", , \"thomasp85@gmail.com\", role = \"aut\", comment = c(ORCID = \"0000-0002-5147-4711\")) )", + "Description": "A fast C++ implementation to generate contour lines (isolines) and contour polygons (isobands) from regularly spaced grids containing elevation data.", + "License": "MIT + file LICENSE", + "URL": "https://isoband.r-lib.org", + "BugReports": "https://github.com/r-lib/isoband/issues", + "Imports": [ + "grid", + "utils" + ], + "Suggests": [ + "covr", + "ggplot2", + "knitr", + "magick", + "microbenchmark", + "rmarkdown", + "sf", + "testthat", + "xml2" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "C++11", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre] (), Claus O. Wilke [aut] (Original author, ), Thomas Lin Pedersen [aut] ()", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "jquerylib": { + "Package": "jquerylib", + "Version": "0.1.4", + "Source": "Repository", + "Title": "Obtain 'jQuery' as an HTML Dependency Object", + "Authors@R": "c( person(\"Carson\", \"Sievert\", role = c(\"aut\", \"cre\"), email = \"carson@rstudio.com\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@rstudio.com\"), person(family = \"RStudio\", role = \"cph\"), person(family = \"jQuery Foundation\", role = \"cph\", comment = \"jQuery library and jQuery UI library\"), person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt\") )", + "Description": "Obtain any major version of 'jQuery' () and use it in any webpage generated by 'htmltools' (e.g. 'shiny', 'htmlwidgets', and 'rmarkdown'). Most R users don't need to use this package directly, but other R packages (e.g. 'shiny', 'rmarkdown', etc.) depend on this package to avoid bundling redundant copies of 'jQuery'.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Config/testthat/edition": "3", + "RoxygenNote": "7.0.2", + "Imports": [ + "htmltools" + ], + "Suggests": [ + "testthat" + ], + "NeedsCompilation": "no", + "Author": "Carson Sievert [aut, cre] (), Joe Cheng [aut], RStudio [cph], jQuery Foundation [cph] (jQuery library and jQuery UI library), jQuery contributors [ctb, cph] (jQuery library; authors listed in inst/lib/jquery-AUTHORS.txt)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "jsonlite": { + "Package": "jsonlite", + "Version": "2.0.0", + "Source": "Repository", + "Title": "A Simple and Robust JSON Parser and Generator for R", + "License": "MIT + file LICENSE", + "Depends": [ + "methods" + ], + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Duncan\", \"Temple Lang\", role = \"ctb\"), person(\"Lloyd\", \"Hilaiel\", role = \"cph\", comment=\"author of bundled libyajl\"))", + "URL": "https://jeroen.r-universe.dev/jsonlite https://arxiv.org/abs/1403.2805", + "BugReports": "https://github.com/jeroen/jsonlite/issues", + "Maintainer": "Jeroen Ooms ", + "VignetteBuilder": "knitr, R.rsp", + "Description": "A reasonably fast JSON parser and generator, optimized for statistical data and the web. Offers simple, flexible tools for working with JSON in R, and is particularly powerful for building pipelines and interacting with a web API. The implementation is based on the mapping described in the vignette (Ooms, 2014). In addition to converting JSON data from/to R objects, 'jsonlite' contains functions to stream, validate, and prettify JSON data. The unit tests included with the package verify that all edge cases are encoded and decoded consistently for use with dynamic data in systems and applications.", + "Suggests": [ + "httr", + "vctrs", + "testthat", + "knitr", + "rmarkdown", + "R.rsp", + "sf" + ], + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), Duncan Temple Lang [ctb], Lloyd Hilaiel [cph] (author of bundled libyajl)", + "Repository": "CRAN" + }, + "juicyjuice": { + "Package": "juicyjuice", + "Version": "0.1.0", + "Source": "Repository", + "Title": "Inline CSS Properties into HTML Tags Using 'juice'", + "Authors@R": "c( person(\"Richard\", \"Iannone\", , \"riannone@me.com\", c(\"aut\", \"cre\", \"cph\"), comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Automattic\", role = c(\"cph\"), comment = \"juice library\"), person(\"juice contributors\", role = c(\"ctb\"), comment = \"juice library\") )", + "Description": "There are occasions where you need a piece of HTML with integrated styles. A prime example of this is HTML email. This transformation involves moving the CSS and associated formatting instructions from the style block in the head of your document into the body of the HTML. Many prominent email clients require integrated styles in HTML email; otherwise a received HTML email will be displayed without any styling. This package will quickly and precisely perform these CSS transformations when given HTML text and it does so by using the JavaScript 'juice' library.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/rich-iannone/juicyjuice", + "BugReports": "https://github.com/rich-iannone/juicyjuice/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1", + "Imports": [ + "V8 (>= 4.2.0)" + ], + "Suggests": [ + "testthat (>= 3.0.0)" + ], + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Richard Iannone [aut, cre, cph] (), Automattic [cph] (juice library), juice contributors [ctb] (juice library)", + "Maintainer": "Richard Iannone ", + "Repository": "CRAN" + }, + "keyring": { + "Package": "keyring", + "Version": "1.3.2", + "Source": "Repository", + "Title": "Access the System Credential Store from R", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Alec\", \"Wong\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Platform independent 'API' to access the operating system's credential store. Currently supports: 'Keychain' on 'macOS', Credential Store on 'Windows', the Secret Service 'API' on 'Linux', and simple, platform independent stores implemented with environment variables or encrypted files. Additional storage back-ends can be added easily.", + "License": "MIT + file LICENSE", + "URL": "https://keyring.r-lib.org/, https://github.com/r-lib/keyring", + "BugReports": "https://github.com/r-lib/keyring/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "askpass", + "assertthat", + "filelock", + "openssl", + "R6", + "rappdirs", + "sodium", + "tools", + "utils", + "yaml" + ], + "Suggests": [ + "callr", + "covr", + "mockery", + "testthat (>= 3.0.0)", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "Optional: libsecret on Linux (libsecret-1-dev on Debian/Ubuntu, libsecret-devel on Fedora/CentOS)", + "Collate": "'api.R' 'assertions.R' 'backend-class.R' 'backend-env.R' 'backend-file.R' 'backend-macos.R' 'backend-secret-service.R' 'backend-wincred.R' 'default_backend.R' 'keyring-package.R' 'package.R' 'pass.R' 'utils.R'", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre], Alec Wong [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "knitr": { + "Package": "knitr", + "Version": "1.50", + "Source": "Repository", + "Type": "Package", + "Title": "A General-Purpose Package for Dynamic Report Generation in R", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Abhraneel\", \"Sarma\", role = \"ctb\"), person(\"Adam\", \"Vogt\", role = \"ctb\"), person(\"Alastair\", \"Andrew\", role = \"ctb\"), person(\"Alex\", \"Zvoleff\", role = \"ctb\"), person(\"Amar\", \"Al-Zubaidi\", role = \"ctb\"), person(\"Andre\", \"Simon\", role = \"ctb\", comment = \"the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de\"), person(\"Aron\", \"Atkins\", role = \"ctb\"), person(\"Aaron\", \"Wolen\", role = \"ctb\"), person(\"Ashley\", \"Manton\", role = \"ctb\"), person(\"Atsushi\", \"Yasumoto\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8335-495X\")), person(\"Ben\", \"Baumer\", role = \"ctb\"), person(\"Brian\", \"Diggs\", role = \"ctb\"), person(\"Brian\", \"Zhang\", role = \"ctb\"), person(\"Bulat\", \"Yapparov\", role = \"ctb\"), person(\"Cassio\", \"Pereira\", role = \"ctb\"), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person(\"David\", \"Hall\", role = \"ctb\"), person(\"David\", \"Hugh-Jones\", role = \"ctb\"), person(\"David\", \"Robinson\", role = \"ctb\"), person(\"Doug\", \"Hemken\", role = \"ctb\"), person(\"Duncan\", \"Murdoch\", role = \"ctb\"), person(\"Elio\", \"Campitelli\", role = \"ctb\"), person(\"Ellis\", \"Hughes\", role = \"ctb\"), person(\"Emily\", \"Riederer\", role = \"ctb\"), person(\"Fabian\", \"Hirschmann\", role = \"ctb\"), person(\"Fitch\", \"Simeon\", role = \"ctb\"), person(\"Forest\", \"Fang\", role = \"ctb\"), person(c(\"Frank\", \"E\", \"Harrell\", \"Jr\"), role = \"ctb\", comment = \"the Sweavel package at inst/misc/Sweavel.sty\"), person(\"Garrick\", \"Aden-Buie\", role = \"ctb\"), person(\"Gregoire\", \"Detrez\", role = \"ctb\"), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Hao\", \"Zhu\", role = \"ctb\"), person(\"Heewon\", \"Jeon\", role = \"ctb\"), person(\"Henrik\", \"Bengtsson\", role = \"ctb\"), person(\"Hiroaki\", \"Yutani\", role = \"ctb\"), person(\"Ian\", \"Lyttle\", role = \"ctb\"), person(\"Hodges\", \"Daniel\", role = \"ctb\"), person(\"Jacob\", \"Bien\", role = \"ctb\"), person(\"Jake\", \"Burkhead\", role = \"ctb\"), person(\"James\", \"Manton\", role = \"ctb\"), person(\"Jared\", \"Lander\", role = \"ctb\"), person(\"Jason\", \"Punyon\", role = \"ctb\"), person(\"Javier\", \"Luraschi\", role = \"ctb\"), person(\"Jeff\", \"Arnold\", role = \"ctb\"), person(\"Jenny\", \"Bryan\", role = \"ctb\"), person(\"Jeremy\", \"Ashkenas\", role = c(\"ctb\", \"cph\"), comment = \"the CSS file at inst/misc/docco-classic.css\"), person(\"Jeremy\", \"Stephens\", role = \"ctb\"), person(\"Jim\", \"Hester\", role = \"ctb\"), person(\"Joe\", \"Cheng\", role = \"ctb\"), person(\"Johannes\", \"Ranke\", role = \"ctb\"), person(\"John\", \"Honaker\", role = \"ctb\"), person(\"John\", \"Muschelli\", role = \"ctb\"), person(\"Jonathan\", \"Keane\", role = \"ctb\"), person(\"JJ\", \"Allaire\", role = \"ctb\"), person(\"Johan\", \"Toloe\", role = \"ctb\"), person(\"Jonathan\", \"Sidi\", role = \"ctb\"), person(\"Joseph\", \"Larmarange\", role = \"ctb\"), person(\"Julien\", \"Barnier\", role = \"ctb\"), person(\"Kaiyin\", \"Zhong\", role = \"ctb\"), person(\"Kamil\", \"Slowikowski\", role = \"ctb\"), person(\"Karl\", \"Forner\", role = \"ctb\"), person(c(\"Kevin\", \"K.\"), \"Smith\", role = \"ctb\"), person(\"Kirill\", \"Mueller\", role = \"ctb\"), person(\"Kohske\", \"Takahashi\", role = \"ctb\"), person(\"Lorenz\", \"Walthert\", role = \"ctb\"), person(\"Lucas\", \"Gallindo\", role = \"ctb\"), person(\"Marius\", \"Hofert\", role = \"ctb\"), person(\"Martin\", \"Modrák\", role = \"ctb\"), person(\"Michael\", \"Chirico\", role = \"ctb\"), person(\"Michael\", \"Friendly\", role = \"ctb\"), person(\"Michal\", \"Bojanowski\", role = \"ctb\"), person(\"Michel\", \"Kuhlmann\", role = \"ctb\"), person(\"Miller\", \"Patrick\", role = \"ctb\"), person(\"Nacho\", \"Caballero\", role = \"ctb\"), person(\"Nick\", \"Salkowski\", role = \"ctb\"), person(\"Niels Richard\", \"Hansen\", role = \"ctb\"), person(\"Noam\", \"Ross\", role = \"ctb\"), person(\"Obada\", \"Mahdi\", role = \"ctb\"), person(\"Pavel N.\", \"Krivitsky\", role = \"ctb\", comment=c(ORCID = \"0000-0002-9101-3362\")), person(\"Pedro\", \"Faria\", role = \"ctb\"), person(\"Qiang\", \"Li\", role = \"ctb\"), person(\"Ramnath\", \"Vaidyanathan\", role = \"ctb\"), person(\"Richard\", \"Cotton\", role = \"ctb\"), person(\"Robert\", \"Krzyzanowski\", role = \"ctb\"), person(\"Rodrigo\", \"Copetti\", role = \"ctb\"), person(\"Romain\", \"Francois\", role = \"ctb\"), person(\"Ruaridh\", \"Williamson\", role = \"ctb\"), person(\"Sagiru\", \"Mati\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1413-3974\")), person(\"Scott\", \"Kostyshak\", role = \"ctb\"), person(\"Sebastian\", \"Meyer\", role = \"ctb\"), person(\"Sietse\", \"Brouwer\", role = \"ctb\"), person(c(\"Simon\", \"de\"), \"Bernard\", role = \"ctb\"), person(\"Sylvain\", \"Rousseau\", role = \"ctb\"), person(\"Taiyun\", \"Wei\", role = \"ctb\"), person(\"Thibaut\", \"Assus\", role = \"ctb\"), person(\"Thibaut\", \"Lamadon\", role = \"ctb\"), person(\"Thomas\", \"Leeper\", role = \"ctb\"), person(\"Tim\", \"Mastny\", role = \"ctb\"), person(\"Tom\", \"Torsney-Weir\", role = \"ctb\"), person(\"Trevor\", \"Davis\", role = \"ctb\"), person(\"Viktoras\", \"Veitas\", role = \"ctb\"), person(\"Weicheng\", \"Zhu\", role = \"ctb\"), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Zachary\", \"Foster\", role = \"ctb\"), person(\"Zhian N.\", \"Kamvar\", role = \"ctb\", comment = c(ORCID = \"0000-0003-1458-7108\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a general-purpose tool for dynamic report generation in R using Literate Programming techniques.", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "evaluate (>= 0.15)", + "highr (>= 0.11)", + "methods", + "tools", + "xfun (>= 0.51)", + "yaml (>= 2.1.19)" + ], + "Suggests": [ + "bslib", + "codetools", + "DBI (>= 0.4-1)", + "digest", + "formatR", + "gifski", + "gridSVG", + "htmlwidgets (>= 0.7)", + "jpeg", + "JuliaCall (>= 0.11.1)", + "magick", + "litedown", + "markdown (>= 1.3)", + "png", + "ragg", + "reticulate (>= 1.4)", + "rgl (>= 0.95.1201)", + "rlang", + "rmarkdown", + "sass", + "showtext", + "styler (>= 1.2.0)", + "targets (>= 0.6.0)", + "testit", + "tibble", + "tikzDevice (>= 0.10)", + "tinytex (>= 0.56)", + "webshot", + "rstudioapi", + "svglite" + ], + "License": "GPL", + "URL": "https://yihui.org/knitr/", + "BugReports": "https://github.com/yihui/knitr/issues", + "Encoding": "UTF-8", + "VignetteBuilder": "litedown, knitr", + "SystemRequirements": "Package vignettes based on R Markdown v2 or reStructuredText require Pandoc (http://pandoc.org). The function rst2pdf() requires rst2pdf (https://github.com/rst2pdf/rst2pdf).", + "Collate": "'block.R' 'cache.R' 'citation.R' 'hooks-html.R' 'plot.R' 'utils.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R' 'themes.R' 'header.R' 'hooks-asciidoc.R' 'hooks-chunk.R' 'hooks-extra.R' 'hooks-latex.R' 'hooks-md.R' 'hooks-rst.R' 'hooks-textile.R' 'hooks.R' 'output.R' 'package.R' 'pandoc.R' 'params.R' 'parser.R' 'pattern.R' 'rocco.R' 'spin.R' 'table.R' 'template.R' 'utils-conversion.R' 'utils-rd2html.R' 'utils-string.R' 'utils-sweave.R' 'utils-upload.R' 'utils-vignettes.R' 'zzz.R'", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Abhraneel Sarma [ctb], Adam Vogt [ctb], Alastair Andrew [ctb], Alex Zvoleff [ctb], Amar Al-Zubaidi [ctb], Andre Simon [ctb] (the CSS files under inst/themes/ were derived from the Highlight package http://www.andre-simon.de), Aron Atkins [ctb], Aaron Wolen [ctb], Ashley Manton [ctb], Atsushi Yasumoto [ctb] (), Ben Baumer [ctb], Brian Diggs [ctb], Brian Zhang [ctb], Bulat Yapparov [ctb], Cassio Pereira [ctb], Christophe Dervieux [ctb], David Hall [ctb], David Hugh-Jones [ctb], David Robinson [ctb], Doug Hemken [ctb], Duncan Murdoch [ctb], Elio Campitelli [ctb], Ellis Hughes [ctb], Emily Riederer [ctb], Fabian Hirschmann [ctb], Fitch Simeon [ctb], Forest Fang [ctb], Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty), Garrick Aden-Buie [ctb], Gregoire Detrez [ctb], Hadley Wickham [ctb], Hao Zhu [ctb], Heewon Jeon [ctb], Henrik Bengtsson [ctb], Hiroaki Yutani [ctb], Ian Lyttle [ctb], Hodges Daniel [ctb], Jacob Bien [ctb], Jake Burkhead [ctb], James Manton [ctb], Jared Lander [ctb], Jason Punyon [ctb], Javier Luraschi [ctb], Jeff Arnold [ctb], Jenny Bryan [ctb], Jeremy Ashkenas [ctb, cph] (the CSS file at inst/misc/docco-classic.css), Jeremy Stephens [ctb], Jim Hester [ctb], Joe Cheng [ctb], Johannes Ranke [ctb], John Honaker [ctb], John Muschelli [ctb], Jonathan Keane [ctb], JJ Allaire [ctb], Johan Toloe [ctb], Jonathan Sidi [ctb], Joseph Larmarange [ctb], Julien Barnier [ctb], Kaiyin Zhong [ctb], Kamil Slowikowski [ctb], Karl Forner [ctb], Kevin K. Smith [ctb], Kirill Mueller [ctb], Kohske Takahashi [ctb], Lorenz Walthert [ctb], Lucas Gallindo [ctb], Marius Hofert [ctb], Martin Modrák [ctb], Michael Chirico [ctb], Michael Friendly [ctb], Michal Bojanowski [ctb], Michel Kuhlmann [ctb], Miller Patrick [ctb], Nacho Caballero [ctb], Nick Salkowski [ctb], Niels Richard Hansen [ctb], Noam Ross [ctb], Obada Mahdi [ctb], Pavel N. Krivitsky [ctb] (), Pedro Faria [ctb], Qiang Li [ctb], Ramnath Vaidyanathan [ctb], Richard Cotton [ctb], Robert Krzyzanowski [ctb], Rodrigo Copetti [ctb], Romain Francois [ctb], Ruaridh Williamson [ctb], Sagiru Mati [ctb] (), Scott Kostyshak [ctb], Sebastian Meyer [ctb], Sietse Brouwer [ctb], Simon de Bernard [ctb], Sylvain Rousseau [ctb], Taiyun Wei [ctb], Thibaut Assus [ctb], Thibaut Lamadon [ctb], Thomas Leeper [ctb], Tim Mastny [ctb], Tom Torsney-Weir [ctb], Trevor Davis [ctb], Viktoras Veitas [ctb], Weicheng Zhu [ctb], Wush Wu [ctb], Zachary Foster [ctb], Zhian N. Kamvar [ctb] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "labeling": { + "Package": "labeling", + "Version": "0.4.3", + "Source": "Repository", + "Type": "Package", + "Title": "Axis Labeling", + "Date": "2023-08-29", + "Author": "Justin Talbot,", + "Maintainer": "Nuno Sempere ", + "Description": "Functions which provide a range of axis labeling algorithms.", + "License": "MIT + file LICENSE | Unlimited", + "Collate": "'labeling.R'", + "NeedsCompilation": "no", + "Imports": [ + "stats", + "graphics" + ], + "Repository": "CRAN" + }, + "labelled": { + "Package": "labelled", + "Version": "2.14.0", + "Source": "Repository", + "Type": "Package", + "Title": "Manipulating Labelled Data", + "Maintainer": "Joseph Larmarange ", + "Authors@R": "c( person(\"Joseph\", \"Larmarange\", email = \"joseph@larmarange.net\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0001-7097-700X\")), person(\"Daniel\", \"Ludecke\", role = \"ctb\"), person(\"Hadley\", \"Wickham\", role = \"ctb\"), person(\"Michal\", \"Bojanowski\", role = \"ctb\"), person(\"François\", \"Briatte\", role = \"ctb\") )", + "Description": "Work with labelled data imported from 'SPSS' or 'Stata' with 'haven' or 'foreign'. This package provides useful functions to deal with \"haven_labelled\" and \"haven_labelled_spss\" classes introduced by 'haven' package.", + "License": "GPL (>= 3)", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 3.2)" + ], + "Imports": [ + "haven (>= 2.4.1)", + "cli", + "dplyr (>= 1.1.0)", + "lifecycle", + "rlang (>= 1.1.0)", + "vctrs", + "stringr", + "tidyr", + "tidyselect" + ], + "Suggests": [ + "testthat (>= 3.2.0)", + "knitr", + "rmarkdown", + "questionr", + "snakecase", + "spelling" + ], + "Enhances": [ + "memisc" + ], + "URL": "https://larmarange.github.io/labelled/, https://github.com/larmarange/labelled", + "BugReports": "https://github.com/larmarange/labelled/issues", + "VignetteBuilder": "knitr", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "Language": "en-US", + "Config/testthat/edition": "3", + "Config/Needs/check": "memisc", + "NeedsCompilation": "no", + "Author": "Joseph Larmarange [aut, cre] (), Daniel Ludecke [ctb], Hadley Wickham [ctb], Michal Bojanowski [ctb], François Briatte [ctb]", + "Repository": "CRAN" + }, + "later": { + "Package": "later", + "Version": "1.4.2", + "Source": "Repository", + "Type": "Package", + "Title": "Utilities for Scheduling Functions to Execute Later with Event Loops", + "Authors@R": "c( person(\"Winston\", \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@posit.co\"), person(\"Joe\", \"Cheng\", role = c(\"aut\"), email = \"joe@posit.co\"), person(\"Charlie\", \"Gao\", role = c(\"aut\"), email = \"charlie.gao@shikokuchuo.net\", comment = c(ORCID = \"0000-0002-0750-061X\")), person(family = \"Posit Software, PBC\", role = \"cph\"), person(\"Marcus\", \"Geelnard\", role = c(\"ctb\", \"cph\"), comment = \"TinyCThread library, https://tinycthread.github.io/\"), person(\"Evan\", \"Nemerson\", role = c(\"ctb\", \"cph\"), comment = \"TinyCThread library, https://tinycthread.github.io/\") )", + "Description": "Executes arbitrary R or C functions some time after the current time, after the R execution stack has emptied. The functions are scheduled in an event loop.", + "URL": "https://r-lib.github.io/later/, https://github.com/r-lib/later", + "BugReports": "https://github.com/r-lib/later/issues", + "License": "MIT + file LICENSE", + "Imports": [ + "Rcpp (>= 0.12.9)", + "rlang" + ], + "LinkingTo": [ + "Rcpp" + ], + "RoxygenNote": "7.3.2", + "Suggests": [ + "knitr", + "nanonext", + "R6", + "rmarkdown", + "testthat (>= 2.1.0)" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Winston Chang [aut, cre], Joe Cheng [aut], Charlie Gao [aut] (), Posit Software, PBC [cph], Marcus Geelnard [ctb, cph] (TinyCThread library, https://tinycthread.github.io/), Evan Nemerson [ctb, cph] (TinyCThread library, https://tinycthread.github.io/)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "lattice": { + "Package": "lattice", + "Version": "0.22-7", + "Source": "Repository", + "Date": "2025-03-31", + "Priority": "recommended", + "Title": "Trellis Graphics for R", + "Authors@R": "c(person(\"Deepayan\", \"Sarkar\", role = c(\"aut\", \"cre\"), email = \"deepayan.sarkar@r-project.org\", comment = c(ORCID = \"0000-0003-4107-1553\")), person(\"Felix\", \"Andrews\", role = \"ctb\"), person(\"Kevin\", \"Wright\", role = \"ctb\", comment = \"documentation\"), person(\"Neil\", \"Klepeis\", role = \"ctb\"), person(\"Johan\", \"Larsson\", role = \"ctb\", comment = \"miscellaneous improvements\"), person(\"Zhijian (Jason)\", \"Wen\", role = \"cph\", comment = \"filled contour code\"), person(\"Paul\", \"Murrell\", role = \"ctb\", email = \"paul@stat.auckland.ac.nz\"), person(\"Stefan\", \"Eng\", role = \"ctb\", comment = \"violin plot improvements\"), person(\"Achim\", \"Zeileis\", role = \"ctb\", comment = \"modern colors\"), person(\"Alexandre\", \"Courtiol\", role = \"ctb\", comment = \"generics for larrows, lpolygon, lrect and lsegments\") )", + "Description": "A powerful and elegant high-level data visualization system inspired by Trellis graphics, with an emphasis on multivariate data. Lattice is sufficient for typical graphics needs, and is also flexible enough to handle most nonstandard requirements. See ?Lattice for an introduction.", + "Depends": [ + "R (>= 4.0.0)" + ], + "Suggests": [ + "KernSmooth", + "MASS", + "latticeExtra", + "colorspace" + ], + "Imports": [ + "grid", + "grDevices", + "graphics", + "stats", + "utils" + ], + "Enhances": [ + "chron", + "zoo" + ], + "LazyLoad": "yes", + "LazyData": "yes", + "License": "GPL (>= 2)", + "URL": "https://lattice.r-forge.r-project.org/", + "BugReports": "https://github.com/deepayan/lattice/issues", + "NeedsCompilation": "yes", + "Author": "Deepayan Sarkar [aut, cre] (), Felix Andrews [ctb], Kevin Wright [ctb] (documentation), Neil Klepeis [ctb], Johan Larsson [ctb] (miscellaneous improvements), Zhijian (Jason) Wen [cph] (filled contour code), Paul Murrell [ctb], Stefan Eng [ctb] (violin plot improvements), Achim Zeileis [ctb] (modern colors), Alexandre Courtiol [ctb] (generics for larrows, lpolygon, lrect and lsegments)", + "Maintainer": "Deepayan Sarkar ", + "Repository": "CRAN" + }, + "lazyeval": { + "Package": "lazyeval", + "Version": "0.2.2", + "Source": "Repository", + "Title": "Lazy (Non-Standard) Evaluation", + "Description": "An alternative approach to non-standard evaluation using formulas. Provides a full implementation of LISP style 'quasiquotation', making it easier to generate code with other code.", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", ,\"hadley@rstudio.com\", c(\"aut\", \"cre\")), person(\"RStudio\", role = \"cph\") )", + "License": "GPL-3", + "LazyData": "true", + "Depends": [ + "R (>= 3.1.0)" + ], + "Suggests": [ + "knitr", + "rmarkdown (>= 0.2.65)", + "testthat", + "covr" + ], + "VignetteBuilder": "knitr", + "RoxygenNote": "6.1.1", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre], RStudio [cph]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "lifecycle": { + "Package": "lifecycle", + "Version": "1.0.4", + "Source": "Repository", + "Title": "Manage the Life Cycle of your Package Functions", + "Authors@R": "c( person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Manage the life cycle of your exported functions with shared conventions, documentation badges, and user-friendly deprecation warnings.", + "License": "MIT + file LICENSE", + "URL": "https://lifecycle.r-lib.org/, https://github.com/r-lib/lifecycle", + "BugReports": "https://github.com/r-lib/lifecycle/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "glue", + "rlang (>= 1.1.0)" + ], + "Suggests": [ + "covr", + "crayon", + "knitr", + "lintr", + "rmarkdown", + "testthat (>= 3.0.1)", + "tibble", + "tidyverse", + "tools", + "vctrs", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate, usethis", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "no", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "litedown": { + "Package": "litedown", + "Version": "0.7", + "Source": "Repository", + "Type": "Package", + "Title": "A Lightweight Version of R Markdown", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Tim\", \"Taylor\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8587-7113\")), person() )", + "Description": "Render R Markdown to Markdown (without using 'knitr'), and Markdown to lightweight HTML or 'LaTeX' documents with the 'commonmark' package (instead of 'Pandoc'). Some missing Markdown features in 'commonmark' are also supported, such as raw HTML or 'LaTeX' blocks, 'LaTeX' math, superscripts, subscripts, footnotes, element attributes, and appendices, but not all 'Pandoc' Markdown features are (or will be) supported. With additional JavaScript and CSS, you can also create HTML slides and articles. This package can be viewed as a trimmed-down version of R Markdown and 'knitr'. It does not aim at rich Markdown features or a large variety of output formats (the primary formats are HTML and 'LaTeX'). Book and website projects of multiple input documents are also supported.", + "Depends": [ + "R (>= 3.2.0)" + ], + "Imports": [ + "utils", + "commonmark (>= 1.9.5)", + "xfun (>= 0.52)" + ], + "Suggests": [ + "rbibutils", + "rstudioapi", + "tinytex" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/yihui/litedown", + "BugReports": "https://github.com/yihui/litedown/issues", + "VignetteBuilder": "litedown", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Tim Taylor [ctb] ()", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "lubridate": { + "Package": "lubridate", + "Version": "1.9.4", + "Source": "Repository", + "Type": "Package", + "Title": "Make Dealing with Dates a Little Easier", + "Authors@R": "c( person(\"Vitalie\", \"Spinu\", , \"spinuvit@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Garrett\", \"Grolemund\", role = \"aut\"), person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Davis\", \"Vaughan\", role = \"ctb\"), person(\"Ian\", \"Lyttle\", role = \"ctb\"), person(\"Imanuel\", \"Costigan\", role = \"ctb\"), person(\"Jason\", \"Law\", role = \"ctb\"), person(\"Doug\", \"Mitarotonda\", role = \"ctb\"), person(\"Joseph\", \"Larmarange\", role = \"ctb\"), person(\"Jonathan\", \"Boiser\", role = \"ctb\"), person(\"Chel Hee\", \"Lee\", role = \"ctb\") )", + "Maintainer": "Vitalie Spinu ", + "Description": "Functions to work with date-times and time-spans: fast and user friendly parsing of date-time data, extraction and updating of components of a date-time (years, months, days, hours, minutes, and seconds), algebraic manipulation on date-time and time-span objects. The 'lubridate' package has a consistent and memorable syntax that makes working with dates easy and fun.", + "License": "GPL (>= 2)", + "URL": "https://lubridate.tidyverse.org, https://github.com/tidyverse/lubridate", + "BugReports": "https://github.com/tidyverse/lubridate/issues", + "Depends": [ + "methods", + "R (>= 3.2)" + ], + "Imports": [ + "generics", + "timechange (>= 0.3.0)" + ], + "Suggests": [ + "covr", + "knitr", + "rmarkdown", + "testthat (>= 2.1.0)", + "vctrs (>= 0.6.5)" + ], + "Enhances": [ + "chron", + "data.table", + "timeDate", + "tis", + "zoo" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "SystemRequirements": "C++11, A system with zoneinfo data (e.g. /usr/share/zoneinfo). On Windows the zoneinfo included with R is used.", + "Collate": "'Dates.r' 'POSIXt.r' 'util.r' 'parse.r' 'timespans.r' 'intervals.r' 'difftimes.r' 'durations.r' 'periods.r' 'accessors-date.R' 'accessors-day.r' 'accessors-dst.r' 'accessors-hour.r' 'accessors-minute.r' 'accessors-month.r' 'accessors-quarter.r' 'accessors-second.r' 'accessors-tz.r' 'accessors-week.r' 'accessors-year.r' 'am-pm.r' 'time-zones.r' 'numeric.r' 'coercion.r' 'constants.r' 'cyclic_encoding.r' 'data.r' 'decimal-dates.r' 'deprecated.r' 'format_ISO8601.r' 'guess.r' 'hidden.r' 'instants.r' 'leap-years.r' 'ops-addition.r' 'ops-compare.r' 'ops-division.r' 'ops-integer-division.r' 'ops-m+.r' 'ops-modulo.r' 'ops-multiplication.r' 'ops-subtraction.r' 'package.r' 'pretty.r' 'round.r' 'stamp.r' 'tzdir.R' 'update.r' 'vctrs.R' 'zzz.R'", + "NeedsCompilation": "yes", + "Author": "Vitalie Spinu [aut, cre], Garrett Grolemund [aut], Hadley Wickham [aut], Davis Vaughan [ctb], Ian Lyttle [ctb], Imanuel Costigan [ctb], Jason Law [ctb], Doug Mitarotonda [ctb], Joseph Larmarange [ctb], Jonathan Boiser [ctb], Chel Hee Lee [ctb]", + "Repository": "CRAN" + }, + "magrittr": { + "Package": "magrittr", + "Version": "2.0.3", + "Source": "Repository", + "Type": "Package", + "Title": "A Forward-Pipe Operator for R", + "Authors@R": "c( person(\"Stefan Milton\", \"Bache\", , \"stefan@stefanbache.dk\", role = c(\"aut\", \"cph\"), comment = \"Original author and creator of magrittr\"), person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@rstudio.com\", role = \"cre\"), person(\"RStudio\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides a mechanism for chaining commands with a new forward-pipe operator, %>%. This operator will forward a value, or the result of an expression, into the next function call/expression. There is flexible support for the type of right-hand side expressions. For more information, see package vignette. To quote Rene Magritte, \"Ceci n'est pas un pipe.\"", + "License": "MIT + file LICENSE", + "URL": "https://magrittr.tidyverse.org, https://github.com/tidyverse/magrittr", + "BugReports": "https://github.com/tidyverse/magrittr/issues", + "Depends": [ + "R (>= 3.4.0)" + ], + "Suggests": [ + "covr", + "knitr", + "rlang", + "rmarkdown", + "testthat" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "Yes", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "yes", + "Author": "Stefan Milton Bache [aut, cph] (Original author and creator of magrittr), Hadley Wickham [aut], Lionel Henry [cre], RStudio [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "markdown": { + "Package": "markdown", + "Version": "2.0", + "Source": "Repository", + "Type": "Package", + "Title": "Render Markdown with 'commonmark'", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"JJ\", \"Allaire\", role = \"aut\"), person(\"Jeffrey\", \"Horner\", role = \"aut\"), person(\"Henrik\", \"Bengtsson\", role = \"ctb\"), person(\"Jim\", \"Hester\", role = \"ctb\"), person(\"Yixuan\", \"Qiu\", role = \"ctb\"), person(\"Kohske\", \"Takahashi\", role = \"ctb\"), person(\"Adam\", \"November\", role = \"ctb\"), person(\"Nacho\", \"Caballero\", role = \"ctb\"), person(\"Jeroen\", \"Ooms\", role = \"ctb\"), person(\"Thomas\", \"Leeper\", role = \"ctb\"), person(\"Joe\", \"Cheng\", role = \"ctb\"), person(\"Andrzej\", \"Oles\", role = \"ctb\"), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Render Markdown to full and lightweight HTML/LaTeX documents with the 'commonmark' package. This package has been superseded by 'litedown'.", + "Depends": [ + "R (>= 2.11.1)" + ], + "Imports": [ + "utils", + "xfun", + "litedown (>= 0.6)" + ], + "Suggests": [ + "knitr", + "rmarkdown (>= 2.18)", + "yaml", + "RCurl" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/markdown", + "BugReports": "https://github.com/rstudio/markdown/issues", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre] (), JJ Allaire [aut], Jeffrey Horner [aut], Henrik Bengtsson [ctb], Jim Hester [ctb], Yixuan Qiu [ctb], Kohske Takahashi [ctb], Adam November [ctb], Nacho Caballero [ctb], Jeroen Ooms [ctb], Thomas Leeper [ctb], Joe Cheng [ctb], Andrzej Oles [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "memoise": { + "Package": "memoise", + "Version": "2.0.1", + "Source": "Repository", + "Title": "'Memoisation' of Functions", + "Authors@R": "c(person(given = \"Hadley\", family = \"Wickham\", role = \"aut\", email = \"hadley@rstudio.com\"), person(given = \"Jim\", family = \"Hester\", role = \"aut\"), person(given = \"Winston\", family = \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@rstudio.com\"), person(given = \"Kirill\", family = \"Müller\", role = \"aut\", email = \"krlmlr+r@mailbox.org\"), person(given = \"Daniel\", family = \"Cook\", role = \"aut\", email = \"danielecook@gmail.com\"), person(given = \"Mark\", family = \"Edmondson\", role = \"ctb\", email = \"r@sunholo.com\"))", + "Description": "Cache the results of a function so that when you call it again with the same arguments it returns the previously computed value.", + "License": "MIT + file LICENSE", + "URL": "https://memoise.r-lib.org, https://github.com/r-lib/memoise", + "BugReports": "https://github.com/r-lib/memoise/issues", + "Imports": [ + "rlang (>= 0.4.10)", + "cachem" + ], + "Suggests": [ + "digest", + "aws.s3", + "covr", + "googleAuthR", + "googleCloudStorageR", + "httr", + "testthat" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.1.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Jim Hester [aut], Winston Chang [aut, cre], Kirill Müller [aut], Daniel Cook [aut], Mark Edmondson [ctb]", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "mgcv": { + "Package": "mgcv", + "Version": "1.9-3", + "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) 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)", + "nlme (>= 3.1-64)" + ], + "Imports": [ + "methods", + "stats", + "graphics", + "Matrix", + "splines", + "utils" + ], + "Suggests": [ + "parallel", + "survival", + "MASS" + ], + "LazyLoad": "yes", + "ByteCompile": "yes", + "License": "GPL (>= 2)", + "NeedsCompilation": "yes", + "Author": "Simon Wood [aut, cre]", + "Maintainer": "Simon Wood ", + "Repository": "CRAN" + }, + "mime": { + "Package": "mime", + "Version": "0.13", + "Source": "Repository", + "Type": "Package", + "Title": "Map Filenames to MIME Types", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Jeffrey\", \"Horner\", role = \"ctb\"), person(\"Beilei\", \"Bian\", role = \"ctb\") )", + "Description": "Guesses the MIME type from a filename extension using the data derived from /etc/mime.types in UNIX-type systems.", + "Imports": [ + "tools" + ], + "License": "GPL", + "URL": "https://github.com/yihui/mime", + "BugReports": "https://github.com/yihui/mime/issues", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Yihui Xie [aut, cre] (, https://yihui.org), Jeffrey Horner [ctb], Beilei Bian [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "minty": { + "Package": "minty", + "Version": "0.0.5", + "Source": "Repository", + "Title": "Minimal Type Guesser", + "Authors@R": "c( person(\"Chung-hong\", \"Chan\", role = c(\"aut\", \"cre\"), email = \"chainsawtiney@gmail.com\", comment = c(ORCID = \"0000-0002-6232-7530\")), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = \"author of the ported code from readr\"), person(\"Jim\", \"Hester\", role = \"aut\", comment = \"author of the ported code from readr\"), person(\"Romain\", \"Francois\", role = \"ctb\", comment = \"author of the ported code from readr\"), person(\"Jennifer\", \"Bryan\", , \"jenny@posit.co\", role = c(\"aut\"), comment = \"author of the ported code from readr\"), person(\"Shelby\", \"Bearrows\", role = \"ctb\", comment = \"author of the ported code from readr\"), person(\"Posit Software, PBC\", role = \"cph\", comment = \"copyright holder of readr\"), person(\"David\", \"Olson\", role = \"aut\", comment = \"author of src/tzfile.h\") )", + "Description": "Port the type guesser from 'readr' (so-called 'readr' first edition parsing engine, now superseded by 'vroom').", + "License": "MIT + file LICENSE", + "URL": "https://gesistsa.github.io/minty/, https://github.com/gesistsa/minty", + "BugReports": "https://github.com/gesistsa/minty/issues", + "Depends": [ + "R (>= 3.6)" + ], + "LinkingTo": [ + "cpp11 (>= 0.5.0)", + "tzdb (>= 0.1.1)" + ], + "Config/testthat/edition": "3", + "Config/testthat/parallel": "false", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "Imports": [ + "tzdb" + ], + "Suggests": [ + "knitr", + "stringi", + "testthat", + "withr", + "hms", + "readr" + ], + "Config/Needs/website": "gesistsa/tsatemplate", + "NeedsCompilation": "yes", + "Author": "Chung-hong Chan [aut, cre] (), Hadley Wickham [aut] (author of the ported code from readr), Jim Hester [aut] (author of the ported code from readr), Romain Francois [ctb] (author of the ported code from readr), Jennifer Bryan [aut] (author of the ported code from readr), Shelby Bearrows [ctb] (author of the ported code from readr), Posit Software, PBC [cph] (copyright holder of readr), David Olson [aut] (author of src/tzfile.h)", + "Maintainer": "Chung-hong Chan ", + "Repository": "CRAN" + }, + "nlme": { + "Package": "nlme", + "Version": "3.1-168", + "Source": "Repository", + "Date": "2025-03-31", + "Priority": "recommended", + "Title": "Linear and Nonlinear Mixed Effects Models", + "Authors@R": "c(person(\"José\", \"Pinheiro\", role = \"aut\", comment = \"S version\"), person(\"Douglas\", \"Bates\", role = \"aut\", comment = \"up to 2007\"), person(\"Saikat\", \"DebRoy\", role = \"ctb\", comment = \"up to 2002\"), person(\"Deepayan\", \"Sarkar\", role = \"ctb\", comment = \"up to 2005\"), person(\"EISPACK authors\", role = \"ctb\", comment = \"src/rs.f\"), person(\"Siem\", \"Heisterkamp\", role = \"ctb\", comment = \"Author fixed sigma\"), person(\"Bert\", \"Van Willigen\",role = \"ctb\", comment = \"Programmer fixed sigma\"), person(\"Johannes\", \"Ranke\", role = \"ctb\", comment = \"varConstProp()\"), person(\"R Core Team\", email = \"R-core@R-project.org\", role = c(\"aut\", \"cre\"), comment = c(ROR = \"02zz1nj61\")))", + "Contact": "see 'MailingList'", + "Description": "Fit and compare Gaussian linear and nonlinear mixed-effects models.", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "graphics", + "stats", + "utils", + "lattice" + ], + "Suggests": [ + "MASS", + "SASmixed" + ], + "LazyData": "yes", + "Encoding": "UTF-8", + "License": "GPL (>= 2)", + "BugReports": "https://bugs.r-project.org", + "MailingList": "R-help@r-project.org", + "URL": "https://svn.r-project.org/R-packages/trunk/nlme/", + "NeedsCompilation": "yes", + "Author": "José Pinheiro [aut] (S version), Douglas Bates [aut] (up to 2007), Saikat DebRoy [ctb] (up to 2002), Deepayan Sarkar [ctb] (up to 2005), EISPACK authors [ctb] (src/rs.f), Siem Heisterkamp [ctb] (Author fixed sigma), Bert Van Willigen [ctb] (Programmer fixed sigma), Johannes Ranke [ctb] (varConstProp()), R Core Team [aut, cre] (02zz1nj61)", + "Maintainer": "R Core Team ", + "Repository": "CRAN" + }, + "nnet": { + "Package": "nnet", + "Version": "7.3-20", + "Source": "Repository", + "Priority": "recommended", + "Date": "2025-01-01", + "Depends": [ + "R (>= 3.0.0)", + "stats", + "utils" + ], + "Suggests": [ + "MASS" + ], + "Authors@R": "c(person(\"Brian\", \"Ripley\", role = c(\"aut\", \"cre\", \"cph\"), email = \"Brian.Ripley@R-project.org\"), person(\"William\", \"Venables\", role = \"cph\"))", + "Description": "Software for feed-forward neural networks with a single hidden layer, and for multinomial log-linear models.", + "Title": "Feed-Forward Neural Networks and Multinomial Log-Linear Models", + "ByteCompile": "yes", + "License": "GPL-2 | GPL-3", + "URL": "http://www.stats.ox.ac.uk/pub/MASS4/", + "NeedsCompilation": "yes", + "Author": "Brian Ripley [aut, cre, cph], William Venables [cph]", + "Maintainer": "Brian Ripley ", + "Repository": "CRAN" + }, + "openssl": { + "Package": "openssl", + "Version": "2.3.2", + "Source": "Repository", + "Type": "Package", + "Title": "Toolkit for Encryption, Signatures and Certificates Based on OpenSSL", + "Authors@R": "c(person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Oliver\", \"Keyes\", role = \"ctb\"))", + "Description": "Bindings to OpenSSL libssl and libcrypto, plus custom SSH key parsers. Supports RSA, DSA and EC curves P-256, P-384, P-521, and curve25519. Cryptographic signatures can either be created and verified manually or via x509 certificates. AES can be used in cbc, ctr or gcm mode for symmetric encryption; RSA for asymmetric (public key) encryption or EC for Diffie Hellman. High-level envelope functions combine RSA and AES for encrypting arbitrary sized data. Other utilities include key generators, hash functions (md5, sha1, sha256, etc), base64 encoder, a secure random number generator, and 'bignum' math methods for manually performing crypto calculations on large multibyte integers.", + "License": "MIT + file LICENSE", + "URL": "https://jeroen.r-universe.dev/openssl", + "BugReports": "https://github.com/jeroen/openssl/issues", + "SystemRequirements": "OpenSSL >= 1.0.2", + "VignetteBuilder": "knitr", + "Imports": [ + "askpass" + ], + "Suggests": [ + "curl", + "testthat (>= 2.1.0)", + "digest", + "knitr", + "rmarkdown", + "jsonlite", + "jose", + "sodium" + ], + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), Oliver Keyes [ctb]", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "openxlsx2": { + "Package": "openxlsx2", + "Version": "1.15", + "Source": "Repository", + "Type": "Package", + "Title": "Read, Write and Edit 'xlsx' Files", + "Language": "en-US", + "Authors@R": "c( person(\"Jordan Mark\", \"Barbone\", email = \"jmbarbone@gmail.com\", role = \"aut\", comment = c(ORCID = \"0000-0001-9788-3628\")), person(\"Jan Marvin\", \"Garbuszus\", email = \"jan.garbuszus@ruhr-uni-bochum.de\", role = c(\"aut\", \"cre\")), person(\"Olivier\", \"Roy\", role = \"ctb\"), person(family = \"openxlsx authors\", role = \"cph\", comment = \"openxlsx package\"), person(\"Arseny\", \"Kapoulkine\", role = c(\"ctb\", \"cph\"), comment = \"Author of included pugixml code\") )", + "Description": "Simplifies the creation of 'xlsx' files by providing a high level interface to writing, styling and editing worksheets.", + "License": "MIT + file LICENSE", + "URL": "https://janmarvin.github.io/openxlsx2/, https://github.com/JanMarvin/openxlsx2", + "BugReports": "https://github.com/JanMarvin/openxlsx2/issues", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "R6", + "Rcpp", + "grDevices", + "magrittr", + "stringi", + "utils", + "zip" + ], + "LinkingTo": [ + "Rcpp" + ], + "Suggests": [ + "ggplot2", + "knitr", + "mschart (>= 0.4)", + "rmarkdown", + "rvg", + "testthat (>= 3.0.0)", + "waldo" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "NeedsCompilation": "yes", + "Author": "Jordan Mark Barbone [aut] (), Jan Marvin Garbuszus [aut, cre], Olivier Roy [ctb], openxlsx authors [cph] (openxlsx package), Arseny Kapoulkine [ctb, cph] (Author of included pugixml code)", + "Maintainer": "Jan Marvin Garbuszus ", + "Repository": "CRAN" + }, + "parameters": { + "Package": "parameters", + "Version": "0.24.2", + "Source": "Repository", + "Type": "Package", + "Title": "Processing of Model Parameters", + "Authors@R": "c(person(given = \"Daniel\", family = \"Lüdecke\", role = c(\"aut\", \"cre\"), email = \"d.luedecke@uke.de\", comment = c(ORCID = \"0000-0002-8895-3206\")), person(given = \"Dominique\", family = \"Makowski\", role = \"aut\", email = \"dom.makowski@gmail.com\", comment = c(ORCID = \"0000-0001-5375-9967\")), person(given = \"Mattan S.\", family = \"Ben-Shachar\", role = \"aut\", email = \"matanshm@post.bgu.ac.il\", comment = c(ORCID = \"0000-0002-4287-4801\")), person(given = \"Indrajeet\", family = \"Patil\", role = \"aut\", email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\")), person(given = \"Søren\", family = \"Højsgaard\", role = \"aut\", email = \"sorenh@math.aau.dk\"), person(given = \"Brenton M.\", family = \"Wiernik\", role = \"aut\", email = \"brenton@wiernik.org\", comment = c(ORCID = \"0000-0001-9560-6336\")), person(given = \"Zen J.\", family = \"Lau\", role = \"ctb\", email = \"zenjuen.lau@ntu.edu.sg\"), person(given = \"Vincent\", family = \"Arel-Bundock\", role = \"ctb\", email = \"vincent.arel-bundock@umontreal.ca\", comment = c(ORCID = \"0000-0003-2042-7063\")), person(given = \"Jeffrey\", family = \"Girard\", role = \"ctb\", email = \"me@jmgirard.com\", comment = c(ORCID = \"0000-0002-7359-3746\")), person(given = \"Christina\", family = \"Maimone\", role = \"rev\", email = \"christina.maimone@northwestern.edu\"), person(given = \"Niels\", family = \"Ohlsen\", role = \"rev\"), person(given = \"Douglas Ezra\", family = \"Morrison\", role = \"ctb\", email = \"dmorrison01@ucla.edu\", comment = c(ORCID = \"0000-0002-7195-830X\")), person(given = \"Joseph\", family = \"Luchman\", role = \"ctb\", email = \"jluchman@gmail.com\", comment = c(ORCID = \"0000-0002-8886-9717\")))", + "Maintainer": "Daniel Lüdecke ", + "Description": "Utilities for processing the parameters of various statistical models. Beyond computing p values, CIs, and other indices for a wide variety of models (see list of supported models using the function 'insight::supported_models()'), this package implements features like bootstrapping or simulating of parameters and models, feature reduction (feature extraction and variable selection) as well as functions to describe data and variable characteristics (e.g. skewness, kurtosis, smoothness or distribution).", + "License": "GPL-3", + "URL": "https://easystats.github.io/parameters/", + "BugReports": "https://github.com/easystats/parameters/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "bayestestR (>= 0.15.1)", + "datawizard (>= 1.0.0)", + "insight (>= 1.0.1)", + "graphics", + "methods", + "stats", + "utils" + ], + "Suggests": [ + "AER", + "afex", + "aod", + "BayesFactor (>= 0.9.12-4.7)", + "BayesFM", + "bbmle", + "betareg", + "BH", + "biglm", + "blme", + "boot", + "brglm2", + "brms", + "broom", + "broom.mixed", + "cAIC4", + "car", + "carData", + "cgam", + "ClassDiscovery", + "clubSandwich", + "cluster", + "cobalt", + "coda", + "coxme", + "cplm", + "dbscan", + "did", + "distributional", + "domir (>= 0.2.0)", + "drc", + "DRR", + "effectsize (>= 0.8.6)", + "EGAnet", + "emmeans (>= 1.7.0)", + "epiR", + "estimatr", + "factoextra", + "FactoMineR", + "faraway", + "fastICA", + "fixest", + "fpc", + "gam", + "gamlss", + "gee", + "geepack", + "ggeffects (>= 1.3.2)", + "ggplot2", + "GLMMadaptive", + "glmmTMB (>= 1.1.10)", + "glmtoolbox", + "GPArotation", + "gt", + "haven", + "httr2", + "Hmisc", + "ivreg", + "knitr", + "lavaan", + "lfe", + "lm.beta", + "lme4", + "lmerTest", + "lmtest", + "logistf", + "logitr", + "logspline", + "lqmm", + "M3C", + "marginaleffects (>= 0.25.0)", + "modelbased (>= 0.9.0)", + "MASS", + "Matrix", + "mclogit", + "mclust", + "MCMCglmm", + "mediation", + "merDeriv", + "metaBMA", + "metafor", + "mfx", + "mgcv", + "mice (>= 3.17.0)", + "mmrm", + "multcomp", + "MuMIn", + "NbClust", + "nFactors", + "nestedLogit", + "nlme", + "nnet", + "openxlsx", + "ordinal", + "panelr", + "pbkrtest", + "PCDimension", + "performance (>= 0.12.0)", + "plm", + "PMCMRplus", + "poorman", + "posterior", + "PROreg (>= 1.3.0)", + "pscl", + "psych", + "pvclust", + "quantreg", + "randomForest", + "RcppEigen", + "rmarkdown", + "rms", + "rstan", + "rstanarm", + "sandwich", + "see (>= 0.8.1)", + "serp", + "sparsepca", + "survey", + "survival", + "svylme", + "testthat (>= 3.2.1)", + "tidyselect", + "tinytable (>= 0.1.0)", + "TMB", + "truncreg", + "vdiffr", + "VGAM", + "WeightIt (>= 1.2.0)", + "withr", + "WRS2" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/Needs/website": "easystats/easystatstemplate", + "Config/rcmdcheck/ignore-inconsequential-notes": "true", + "NeedsCompilation": "no", + "Author": "Daniel Lüdecke [aut, cre] (), Dominique Makowski [aut] (), Mattan S. Ben-Shachar [aut] (), Indrajeet Patil [aut] (), Søren Højsgaard [aut], Brenton M. Wiernik [aut] (), Zen J. Lau [ctb], Vincent Arel-Bundock [ctb] (), Jeffrey Girard [ctb] (), Christina Maimone [rev], Niels Ohlsen [rev], Douglas Ezra Morrison [ctb] (), Joseph Luchman [ctb] ()", + "Repository": "CRAN" + }, + "patchwork": { + "Package": "patchwork", + "Version": "1.3.0", + "Source": "Repository", + "Type": "Package", + "Title": "The Composer of Plots", + "Authors@R": "person(given = \"Thomas Lin\", family = \"Pedersen\", role = c(\"cre\", \"aut\"), email = \"thomasp85@gmail.com\", comment = c(ORCID = \"0000-0002-5147-4711\"))", + "Maintainer": "Thomas Lin Pedersen ", + "Description": "The 'ggplot2' package provides a strong API for sequentially building up a plot, but does not concern itself with composition of multiple plots. 'patchwork' is a package that expands the API to allow for arbitrarily complex composition of plots by, among others, providing mathematical operators for combining multiple plots. Other packages that try to address this need (but with a different approach) are 'gridExtra' and 'cowplot'.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Imports": [ + "ggplot2 (>= 3.0.0)", + "gtable", + "grid", + "stats", + "grDevices", + "utils", + "graphics", + "rlang (>= 1.0.0)", + "cli", + "farver" + ], + "RoxygenNote": "7.3.2", + "URL": "https://patchwork.data-imaginist.com, https://github.com/thomasp85/patchwork", + "BugReports": "https://github.com/thomasp85/patchwork/issues", + "Suggests": [ + "knitr", + "rmarkdown", + "gridGraphics", + "gridExtra", + "ragg", + "testthat (>= 2.1.0)", + "vdiffr", + "covr", + "png", + "gt (>= 0.11.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "gifski", + "NeedsCompilation": "no", + "Author": "Thomas Lin Pedersen [cre, aut] ()", + "Repository": "CRAN" + }, + "performance": { + "Package": "performance", + "Version": "0.13.0", + "Source": "Repository", + "Type": "Package", + "Title": "Assessment of Regression Models Performance", + "Authors@R": "c(person(given = \"Daniel\", family = \"Lüdecke\", role = c(\"aut\", \"cre\"), email = \"d.luedecke@uke.de\", comment = c(ORCID = \"0000-0002-8895-3206\")), person(given = \"Dominique\", family = \"Makowski\", role = c(\"aut\", \"ctb\"), email = \"dom.makowski@gmail.com\", comment = c(ORCID = \"0000-0001-5375-9967\")), person(given = \"Mattan S.\", family = \"Ben-Shachar\", role = c(\"aut\", \"ctb\"), email = \"matanshm@post.bgu.ac.il\", comment = c(ORCID = \"0000-0002-4287-4801\")), person(given = \"Indrajeet\", family = \"Patil\", role = c(\"aut\", \"ctb\"), email = \"patilindrajeet.science@gmail.com\", comment = c(ORCID = \"0000-0003-1995-6531\")), person(given = \"Philip\", family = \"Waggoner\", role = c(\"aut\", \"ctb\"), email = \"philip.waggoner@gmail.com\", comment = c(ORCID = \"0000-0002-7825-7573\")), person(given = \"Brenton M.\", family = \"Wiernik\", role = c(\"aut\", \"ctb\"), email = \"brenton@wiernik.org\", comment = c(ORCID = \"0000-0001-9560-6336\")), person(given = \"Rémi\", family = \"Thériault\", role = c(\"aut\", \"ctb\"), email = \"remi.theriault@mail.mcgill.ca\", comment = c(ORCID = \"0000-0003-4315-6788\")), person(given = \"Vincent\", family = \"Arel-Bundock\", email = \"vincent.arel-bundock@umontreal.ca\", role = \"ctb\", comment = c(ORCID = \"0000-0003-2042-7063\")), person(given = \"Martin\", family = \"Jullum\", role = \"rev\"), person(given = \"gjo11\", role = \"rev\"), person(given = \"Etienne\", family = \"Bacher\", , email = \"etienne.bacher@protonmail.com\", role = \"ctb\", comment = c(ORCID = \"0000-0002-9271-5075\")), person(given = \"Joseph\", family = \"Luchman\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8886-9717\")))", + "Maintainer": "Daniel Lüdecke ", + "Description": "Utilities for computing measures to assess model quality, which are not directly provided by R's 'base' or 'stats' packages. These include e.g. measures like r-squared, intraclass correlation coefficient (Nakagawa, Johnson & Schielzeth (2017) ), root mean squared error or functions to check models for overdispersion, singularity or zero-inflation and more. Functions apply to a large variety of regression models, including generalized linear models, mixed effects models and Bayesian models. References: Lüdecke et al. (2021) .", + "License": "GPL-3", + "URL": "https://easystats.github.io/performance/", + "BugReports": "https://github.com/easystats/performance/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "bayestestR (>= 0.15.0)", + "insight (>= 1.0.0)", + "datawizard (>= 0.13.0)", + "stats", + "utils" + ], + "Suggests": [ + "AER", + "afex", + "BayesFactor", + "bayesplot", + "betareg", + "bigutilsr", + "blavaan", + "boot", + "brms", + "car", + "carData", + "CompQuadForm", + "correlation", + "cplm", + "dagitty", + "dbscan", + "DHARMa (>= 0.4.7)", + "estimatr", + "fixest", + "flextable", + "forecast", + "ftExtra", + "gamm4", + "ggdag", + "glmmTMB (>= 1.1.10)", + "graphics", + "Hmisc", + "httr2", + "ICS", + "ICSOutlier", + "ISLR", + "ivreg", + "lavaan", + "lme4", + "lmtest", + "loo", + "MASS", + "Matrix", + "mclogit", + "mclust", + "metadat", + "metafor", + "mgcv", + "mlogit", + "multimode", + "nestedLogit", + "nlme", + "nonnest2", + "ordinal", + "parallel", + "parameters (>= 0.22.0)", + "patchwork", + "pscl", + "psych", + "quantreg", + "qqplotr (>= 0.0.6)", + "randomForest", + "RcppEigen", + "rempsyc", + "rmarkdown", + "rstanarm", + "rstantools", + "sandwich", + "see (>= 0.9.0)", + "survey", + "survival", + "testthat (>= 3.2.1)", + "tweedie", + "VGAM", + "withr (>= 3.0.0)" + ], + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/Needs/website": "rstudio/bslib, r-lib/pkgdown, easystats/easystatstemplate", + "Config/rcmdcheck/ignore-inconsequential-notes": "true", + "NeedsCompilation": "no", + "Author": "Daniel Lüdecke [aut, cre] (), Dominique Makowski [aut, ctb] (), Mattan S. Ben-Shachar [aut, ctb] (), Indrajeet Patil [aut, ctb] (), Philip Waggoner [aut, ctb] (), Brenton M. Wiernik [aut, ctb] (), Rémi Thériault [aut, ctb] (), Vincent Arel-Bundock [ctb] (), Martin Jullum [rev], gjo11 [rev], Etienne Bacher [ctb] (), Joseph Luchman [ctb] ()", + "Repository": "CRAN" + }, + "phosphoricons": { + "Package": "phosphoricons", + "Version": "0.2.1", + "Source": "Repository", + "Title": "'Phosphor' Icons for R", + "Authors@R": "c(person(given = \"Victor\", family = \"Perrier\", role = c(\"aut\", \"cre\", \"cph\"), email = \"victor.perrier@dreamrs.fr\"), person(given = \"Fanny\", family = \"Meyer\", role = \"aut\"), person(given = \"Phosphor Icons\", role = \"cph\", comment = \"Phosphor Icons \"))", + "Description": "Use 'Phosphor' icons in 'shiny' applications or 'rmarkdown' documents. Icons are available in 5 different weights and can be customized by setting color, size, orientation and more.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "htmltools (>= 0.3)" + ], + "Suggests": [ + "covr", + "shiny", + "tinytest" + ], + "URL": "https://dreamrs.github.io/phosphoricons/, https://github.com/dreamRs/phosphoricons", + "BugReports": "https://github.com/dreamRs/phosphoricons/issues", + "NeedsCompilation": "no", + "Author": "Victor Perrier [aut, cre, cph], Fanny Meyer [aut], Phosphor Icons [cph] (Phosphor Icons )", + "Maintainer": "Victor Perrier ", + "Repository": "CRAN" + }, + "pillar": { + "Package": "pillar", + "Version": "1.10.2", + "Source": "Repository", + "Title": "Coloured Formatting for Columns", + "Authors@R": "c(person(given = \"Kirill\", family = \"M\\u00fcller\", role = c(\"aut\", \"cre\"), email = \"kirill@cynkra.com\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(given = \"Hadley\", family = \"Wickham\", role = \"aut\"), person(given = \"RStudio\", role = \"cph\"))", + "Description": "Provides 'pillar' and 'colonnade' generics designed for formatting columns of data using the full range of colours provided by modern terminals.", + "License": "MIT + file LICENSE", + "URL": "https://pillar.r-lib.org/, https://github.com/r-lib/pillar", + "BugReports": "https://github.com/r-lib/pillar/issues", + "Imports": [ + "cli (>= 2.3.0)", + "glue", + "lifecycle", + "rlang (>= 1.0.2)", + "utf8 (>= 1.1.0)", + "utils", + "vctrs (>= 0.5.0)" + ], + "Suggests": [ + "bit64", + "DBI", + "debugme", + "DiagrammeR", + "dplyr", + "formattable", + "ggplot2", + "knitr", + "lubridate", + "nanotime", + "nycflights13", + "palmerpenguins", + "rmarkdown", + "scales", + "stringi", + "survival", + "testthat (>= 3.1.1)", + "tibble", + "units (>= 0.7.2)", + "vdiffr", + "withr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2.9000", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "format_multi_fuzz, format_multi_fuzz_2, format_multi, ctl_colonnade, ctl_colonnade_1, ctl_colonnade_2", + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "true", + "Config/gha/extra-packages": "units=?ignore-before-r=4.3.0", + "Config/Needs/website": "tidyverse/tidytemplate", + "NeedsCompilation": "no", + "Author": "Kirill Müller [aut, cre] (), Hadley Wickham [aut], RStudio [cph]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "pkgconfig": { + "Package": "pkgconfig", + "Version": "2.0.3", + "Source": "Repository", + "Title": "Private Configuration for 'R' Packages", + "Author": "Gábor Csárdi", + "Maintainer": "Gábor Csárdi ", + "Description": "Set configuration options on a per-package basis. Options set by a given package only apply to that package, other packages are unaffected.", + "License": "MIT + file LICENSE", + "LazyData": "true", + "Imports": [ + "utils" + ], + "Suggests": [ + "covr", + "testthat", + "disposables (>= 1.0.3)" + ], + "URL": "https://github.com/r-lib/pkgconfig#readme", + "BugReports": "https://github.com/r-lib/pkgconfig/issues", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "plyr": { + "Package": "plyr", + "Version": "1.8.9", + "Source": "Repository", + "Title": "Tools for Splitting, Applying and Combining Data", + "Authors@R": "person(\"Hadley\", \"Wickham\", , \"hadley@rstudio.com\", role = c(\"aut\", \"cre\"))", + "Description": "A set of tools that solves a common set of problems: you need to break a big problem down into manageable pieces, operate on each piece and then put all the pieces back together. For example, you might want to fit a model to each spatial location or time point in your study, summarise data by panels or collapse high-dimensional arrays to simpler summary statistics. The development of 'plyr' has been generously supported by 'Becton Dickinson'.", + "License": "MIT + file LICENSE", + "URL": "http://had.co.nz/plyr, https://github.com/hadley/plyr", + "BugReports": "https://github.com/hadley/plyr/issues", + "Depends": [ + "R (>= 3.1.0)" + ], + "Imports": [ + "Rcpp (>= 0.11.0)" + ], + "Suggests": [ + "abind", + "covr", + "doParallel", + "foreach", + "iterators", + "itertools", + "tcltk", + "testthat" + ], + "LinkingTo": [ + "Rcpp" + ], + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "polyclip": { + "Package": "polyclip", + "Version": "1.10-7", + "Source": "Repository", + "Date": "2024-07-23", + "Title": "Polygon Clipping", + "Authors@R": "c(person(\"Angus\", \"Johnson\", role = \"aut\", comment=\"C++ original, http://www.angusj.com/delphi/clipper.php\"), person(\"Adrian\", \"Baddeley\", role = c(\"aut\", \"trl\", \"cre\"), email = \"Adrian.Baddeley@curtin.edu.au\"), person(\"Kurt\", \"Hornik\", role = \"ctb\"), person(c(\"Brian\", \"D.\"), \"Ripley\", role = \"ctb\"), person(\"Elliott\", \"Sales de Andrade\", role=\"ctb\"), person(\"Paul\", \"Murrell\", role = \"ctb\"), person(\"Ege\", \"Rubak\", role=\"ctb\"), person(\"Mark\", \"Padgham\", role=\"ctb\"))", + "Maintainer": "Adrian Baddeley ", + "Depends": [ + "R (>= 3.5.0)" + ], + "Description": "R port of Angus Johnson's open source library 'Clipper'. Performs polygon clipping operations (intersection, union, set minus, set difference) for polygonal regions of arbitrary complexity, including holes. Computes offset polygons (spatial buffer zones, morphological dilations, Minkowski dilations) for polygonal regions and polygonal lines. Computes Minkowski Sum of general polygons. There is a function for removing self-intersections from polygon data.", + "License": "BSL", + "URL": "https://www.angusj.com, https://sourceforge.net/projects/polyclipping, https://github.com/baddstats/polyclip", + "BugReports": "https://github.com/baddstats/polyclip/issues", + "ByteCompile": "true", + "Note": "built from Clipper C++ version 6.4.0", + "NeedsCompilation": "yes", + "Author": "Angus Johnson [aut] (C++ original, http://www.angusj.com/delphi/clipper.php), Adrian Baddeley [aut, trl, cre], Kurt Hornik [ctb], Brian D. Ripley [ctb], Elliott Sales de Andrade [ctb], Paul Murrell [ctb], Ege Rubak [ctb], Mark Padgham [ctb]", + "Repository": "CRAN" + }, + "polylabelr": { + "Package": "polylabelr", + "Version": "0.3.0", + "Source": "Repository", + "Title": "Find the Pole of Inaccessibility (Visual Center) of a Polygon", + "Authors@R": "c(person(given = \"Johan\", family = \"Larsson\", role = c(\"aut\", \"cre\"), email = \"johanlarsson@outlook.com\", comment = c(ORCID = \"0000-0002-4029-5945\")), person(given = \"Kent\", family = \"Johnson\", role = \"ctb\", email = \"kent@kentsjohnson.com\"), person(\"Mapbox\", role = \"cph\", comment = \"polylabel, variant, and geometry libraries\"))", + "Description": "A wrapper around the C++ library 'polylabel' from 'Mapbox', providing an efficient routine for finding the approximate pole of inaccessibility of a polygon, which usually serves as an excellent candidate for labeling of a polygon.", + "License": "MIT + file LICENSE", + "Copyright": "see file COPYRIGHTS", + "Encoding": "UTF-8", + "URL": "https://github.com/jolars/polylabelr, https://jolars.github.io/polylabelr/", + "BugReports": "https://github.com/jolars/polylabelr/issues", + "Depends": [ + "R (>= 3.3.0)" + ], + "LinkingTo": [ + "Rcpp" + ], + "Imports": [ + "Rcpp" + ], + "RoxygenNote": "7.3.2", + "Suggests": [ + "covr", + "testthat", + "spelling", + "sf" + ], + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Johan Larsson [aut, cre] (), Kent Johnson [ctb], Mapbox [cph] (polylabel, variant, and geometry libraries)", + "Maintainer": "Johan Larsson ", + "Repository": "CRAN" + }, + "prettyunits": { + "Package": "prettyunits", + "Version": "1.2.0", + "Source": "Repository", + "Title": "Pretty, Human Readable Formatting of Quantities", + "Authors@R": "c( person(\"Gabor\", \"Csardi\", email=\"csardi.gabor@gmail.com\", role=c(\"aut\", \"cre\")), person(\"Bill\", \"Denney\", email=\"wdenney@humanpredictions.com\", role=c(\"ctb\"), comment=c(ORCID=\"0000-0002-5759-428X\")), person(\"Christophe\", \"Regouby\", email=\"christophe.regouby@free.fr\", role=c(\"ctb\")) )", + "Description": "Pretty, human readable formatting of quantities. Time intervals: '1337000' -> '15d 11h 23m 20s'. Vague time intervals: '2674000' -> 'about a month ago'. Bytes: '1337' -> '1.34 kB'. Rounding: '99' with 3 significant digits -> '99.0' p-values: '0.00001' -> '<0.0001'. Colors: '#FF0000' -> 'red'. Quantities: '1239437' -> '1.24 M'.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/prettyunits", + "BugReports": "https://github.com/r-lib/prettyunits/issues", + "Depends": [ + "R(>= 2.10)" + ], + "Suggests": [ + "codetools", + "covr", + "testthat" + ], + "RoxygenNote": "7.2.3", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Gabor Csardi [aut, cre], Bill Denney [ctb] (), Christophe Regouby [ctb]", + "Maintainer": "Gabor Csardi ", + "Repository": "CRAN" + }, + "processx": { + "Package": "processx", + "Version": "3.8.6", + "Source": "Repository", + "Title": "Execute and Control System Processes", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\", \"cph\"), comment = c(ORCID = \"0000-0001-7098-9676\")), person(\"Winston\", \"Chang\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"Ascent Digital Services\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools to run system processes in the background. It can check if a background process is running; wait on a background process to finish; get the exit status of finished processes; kill background processes. It can read the standard output and error of the processes, using non-blocking connections. 'processx' can poll a process for standard output or error, with a timeout. It can also poll several processes at once.", + "License": "MIT + file LICENSE", + "URL": "https://processx.r-lib.org, https://github.com/r-lib/processx", + "BugReports": "https://github.com/r-lib/processx/issues", + "Depends": [ + "R (>= 3.4.0)" + ], + "Imports": [ + "ps (>= 1.2.0)", + "R6", + "utils" + ], + "Suggests": [ + "callr (>= 3.7.3)", + "cli (>= 3.3.0)", + "codetools", + "covr", + "curl", + "debugme", + "parallel", + "rlang (>= 1.0.2)", + "testthat (>= 3.0.0)", + "webfakes", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1.9000", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre, cph] (), Winston Chang [aut], Posit Software, PBC [cph, fnd], Ascent Digital Services [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "progress": { + "Package": "progress", + "Version": "1.2.3", + "Source": "Repository", + "Title": "Terminal Progress Bars", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Rich\", \"FitzJohn\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Configurable Progress bars, they may include percentage, elapsed time, and/or the estimated completion time. They work in terminals, in 'Emacs' 'ESS', 'RStudio', 'Windows' 'Rgui' and the 'macOS' 'R.app'. The package also provides a 'C++' 'API', that works with or without 'Rcpp'.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/progress#readme, http://r-lib.github.io/progress/", + "BugReports": "https://github.com/r-lib/progress/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "crayon", + "hms", + "prettyunits", + "R6" + ], + "Suggests": [ + "Rcpp", + "testthat (>= 3.0.0)", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Gábor Csárdi [aut, cre], Rich FitzJohn [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "promises": { + "Package": "promises", + "Version": "1.3.2", + "Source": "Repository", + "Type": "Package", + "Title": "Abstractions for Promise-Based Asynchronous Programming", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides fundamental abstractions for doing asynchronous programming in R using promises. Asynchronous programming is useful for allowing a single R process to orchestrate multiple tasks in the background while also attending to something else. Semantics are similar to 'JavaScript' promises, but with a syntax that is idiomatic R.", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/promises/, https://github.com/rstudio/promises", + "BugReports": "https://github.com/rstudio/promises/issues", + "Imports": [ + "fastmap (>= 1.1.0)", + "later", + "magrittr (>= 1.5)", + "R6", + "Rcpp", + "rlang", + "stats" + ], + "Suggests": [ + "future (>= 1.21.0)", + "knitr", + "purrr", + "rmarkdown", + "spelling", + "testthat", + "vembedr" + ], + "LinkingTo": [ + "later", + "Rcpp" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "rsconnect", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Joe Cheng ", + "Repository": "CRAN" + }, + "proxy": { + "Package": "proxy", + "Version": "0.4-27", + "Source": "Repository", + "Type": "Package", + "Title": "Distance and Similarity Measures", + "Authors@R": "c(person(given = \"David\", family = \"Meyer\", role = c(\"aut\", \"cre\"), email = \"David.Meyer@R-project.org\"), person(given = \"Christian\", family = \"Buchta\", role = \"aut\"))", + "Description": "Provides an extensible framework for the efficient calculation of auto- and cross-proximities, along with implementations of the most popular ones.", + "Depends": [ + "R (>= 3.4.0)" + ], + "Imports": [ + "stats", + "utils" + ], + "Suggests": [ + "cba" + ], + "Collate": "registry.R database.R dist.R similarities.R dissimilarities.R util.R seal.R", + "License": "GPL-2", + "NeedsCompilation": "yes", + "Author": "David Meyer [aut, cre], Christian Buchta [aut]", + "Maintainer": "David Meyer ", + "Repository": "CRAN" + }, + "ps": { + "Package": "ps", + "Version": "1.9.1", + "Source": "Repository", + "Title": "List, Query, Manipulate System Processes", + "Authors@R": "c( person(\"Jay\", \"Loden\", role = \"aut\"), person(\"Dave\", \"Daeschler\", role = \"aut\"), person(\"Giampaolo\", \"Rodola'\", role = \"aut\"), person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "List, query and manipulate all system processes, on 'Windows', 'Linux' and 'macOS'.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/ps, https://ps.r-lib.org/", + "BugReports": "https://github.com/r-lib/ps/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "utils" + ], + "Suggests": [ + "callr", + "covr", + "curl", + "pillar", + "pingr", + "processx (>= 3.1.0)", + "R6", + "rlang", + "testthat (>= 3.0.0)", + "webfakes", + "withr" + ], + "Biarch": "true", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Jay Loden [aut], Dave Daeschler [aut], Giampaolo Rodola' [aut], Gábor Csárdi [aut, cre], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "purrr": { + "Package": "purrr", + "Version": "1.0.4", + "Source": "Repository", + "Title": "Functional Programming Tools", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "A complete and consistent functional programming toolkit for R.", + "License": "MIT + file LICENSE", + "URL": "https://purrr.tidyverse.org/, https://github.com/tidyverse/purrr", + "BugReports": "https://github.com/tidyverse/purrr/issues", + "Depends": [ + "R (>= 4.0)" + ], + "Imports": [ + "cli (>= 3.6.1)", + "lifecycle (>= 1.0.3)", + "magrittr (>= 1.5.0)", + "rlang (>= 1.1.1)", + "vctrs (>= 0.6.3)" + ], + "Suggests": [ + "covr", + "dplyr (>= 0.7.8)", + "httr", + "knitr", + "lubridate", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble", + "tidyselect" + ], + "LinkingTo": [ + "cli" + ], + "VignetteBuilder": "knitr", + "Biarch": "true", + "Config/build/compilation-database": "true", + "Config/Needs/website": "tidyverse/tidytemplate, tidyr", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "TRUE", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre] (), Lionel Henry [aut], Posit Software, PBC [cph, fnd] (03wc8by49)", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "quarto": { + "Package": "quarto", + "Version": "1.4.4", + "Source": "Repository", + "Title": "R Interface to 'Quarto' Markdown Publishing System", + "Authors@R": "c( person(\"JJ\", \"Allaire\", , \"jj@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-0174-9868\")), person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Convert R Markdown documents and 'Jupyter' notebooks to a variety of output formats using 'Quarto'.", + "License": "GPL (>= 2)", + "URL": "https://github.com/quarto-dev/quarto-r, https://quarto-dev.github.io/quarto-r/", + "BugReports": "https://github.com/quarto-dev/quarto-r/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli", + "jsonlite", + "later", + "processx", + "rlang", + "rmarkdown", + "rstudioapi", + "tools", + "utils", + "yaml" + ], + "Suggests": [ + "curl", + "knitr", + "rsconnect (>= 0.8.26)", + "testthat (>= 3.1.7)", + "withr", + "xfun" + ], + "VignetteBuilder": "quarto", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "Quarto command line tool ().", + "NeedsCompilation": "no", + "Author": "JJ Allaire [aut] (), Christophe Dervieux [cre, aut] (), Posit Software, PBC [cph, fnd]", + "Maintainer": "Christophe Dervieux ", + "Repository": "CRAN" + }, + "rankinPlot": { + "Package": "rankinPlot", + "Version": "1.1.0", + "Source": "Repository", + "Type": "Package", + "Title": "Convenient Plotting for the Modified Rankin Scale and Other Ordinal Outcome Data", + "Authors@R": "person(\"Hannah\",\"Johns\", role=c(\"aut\",\"cre\"),email=\"htjohns@gmail.com\",comment=c(ORCID=\"0000-0003-2135-0504\"))", + "Maintainer": "Hannah Johns ", + "Description": "Provides convenient tools for visualising ordinal outcome data following the \"Grotta Bar\" approach pioneered by The National Institute of Neurological Disorders and Stroke rt-PA Stroke Study Group (1995) .", + "License": "GPL (>= 2.0)", + "Encoding": "UTF-8", + "LazyData": "true", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "ggplot2 (>= 3.3)", + "scales (>= 1.2)" + ], + "RoxygenNote": "7.2.1", + "Suggests": [ + "viridis" + ], + "NeedsCompilation": "no", + "Author": "Hannah Johns [aut, cre] ()", + "Repository": "CRAN" + }, + "rappdirs": { + "Package": "rappdirs", + "Version": "0.3.3", + "Source": "Repository", + "Type": "Package", + "Title": "Application Directories: Determine Where to Save Data, Caches, and Logs", + "Authors@R": "c(person(given = \"Hadley\", family = \"Wickham\", role = c(\"trl\", \"cre\", \"cph\"), email = \"hadley@rstudio.com\"), person(given = \"RStudio\", role = \"cph\"), person(given = \"Sridhar\", family = \"Ratnakumar\", role = \"aut\"), person(given = \"Trent\", family = \"Mick\", role = \"aut\"), person(given = \"ActiveState\", role = \"cph\", comment = \"R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs\"), person(given = \"Eddy\", family = \"Petrisor\", role = \"ctb\"), person(given = \"Trevor\", family = \"Davis\", role = c(\"trl\", \"aut\")), person(given = \"Gabor\", family = \"Csardi\", role = \"ctb\"), person(given = \"Gregory\", family = \"Jefferis\", role = \"ctb\"))", + "Description": "An easy way to determine which directories on the users computer you should use to save data, caches and logs. A port of Python's 'Appdirs' () to R.", + "License": "MIT + file LICENSE", + "URL": "https://rappdirs.r-lib.org, https://github.com/r-lib/rappdirs", + "BugReports": "https://github.com/r-lib/rappdirs/issues", + "Depends": [ + "R (>= 3.2)" + ], + "Suggests": [ + "roxygen2", + "testthat (>= 3.0.0)", + "covr", + "withr" + ], + "Copyright": "Original python appdirs module copyright (c) 2010 ActiveState Software Inc. R port copyright Hadley Wickham, RStudio. See file LICENSE for details.", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [trl, cre, cph], RStudio [cph], Sridhar Ratnakumar [aut], Trent Mick [aut], ActiveState [cph] (R/appdir.r, R/cache.r, R/data.r, R/log.r translated from appdirs), Eddy Petrisor [ctb], Trevor Davis [trl, aut], Gabor Csardi [ctb], Gregory Jefferis [ctb]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "reactR": { + "Package": "reactR", + "Version": "0.6.1", + "Source": "Repository", + "Type": "Package", + "Title": "React Helpers", + "Date": "2024-09-14", + "Authors@R": "c( person( \"Facebook\", \"Inc\" , role = c(\"aut\", \"cph\") , comment = \"React library in lib, https://reactjs.org/; see AUTHORS for full list of contributors\" ), person( \"Michel\",\"Weststrate\", , role = c(\"aut\", \"cph\") , comment = \"mobx library in lib, https://github.com/mobxjs\" ), person( \"Kent\", \"Russell\" , role = c(\"aut\", \"cre\") , comment = \"R interface\" , email = \"kent.russell@timelyportfolio.com\" ), person( \"Alan\", \"Dipert\" , role = c(\"aut\") , comment = \"R interface\" , email = \"alan@rstudio.com\" ), person( \"Greg\", \"Lin\" , role = c(\"aut\") , comment = \"R interface\" , email = \"glin@glin.io\" ) )", + "Maintainer": "Kent Russell ", + "Description": "Make it easy to use 'React' in R with 'htmlwidget' scaffolds, helper dependency functions, an embedded 'Babel' 'transpiler', and examples.", + "URL": "https://github.com/react-R/reactR", + "BugReports": "https://github.com/react-R/reactR/issues", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Imports": [ + "htmltools" + ], + "Suggests": [ + "htmlwidgets (>= 1.5.3)", + "rmarkdown", + "shiny", + "V8", + "knitr", + "usethis", + "jsonlite" + ], + "RoxygenNote": "7.3.2", + "VignetteBuilder": "knitr", + "NeedsCompilation": "no", + "Author": "Facebook Inc [aut, cph] (React library in lib, https://reactjs.org/; see AUTHORS for full list of contributors), Michel Weststrate [aut, cph] (mobx library in lib, https://github.com/mobxjs), Kent Russell [aut, cre] (R interface), Alan Dipert [aut] (R interface), Greg Lin [aut] (R interface)", + "Repository": "CRAN" + }, + "reactable": { + "Package": "reactable", + "Version": "0.4.4", + "Source": "Repository", + "Type": "Package", + "Title": "Interactive Data Tables for R", + "Authors@R": "c( person(\"Greg\", \"Lin\", email = \"glin@glin.io\", role = c(\"aut\", \"cre\")), person(\"Tanner\", \"Linsley\", role = c(\"ctb\", \"cph\"), comment = \"React Table library\"), person(family = \"Emotion team and other contributors\", role = c(\"ctb\", \"cph\"), comment = \"Emotion library\"), person(\"Kent\", \"Russell\", role = c(\"ctb\", \"cph\"), comment = \"reactR package\"), person(\"Ramnath\", \"Vaidyanathan\", role = c(\"ctb\", \"cph\"), comment = \"htmlwidgets package\"), person(\"Joe\", \"Cheng\", role = c(\"ctb\", \"cph\"), comment = \"htmlwidgets package\"), person(\"JJ\", \"Allaire\", role = c(\"ctb\", \"cph\"), comment = \"htmlwidgets package\"), person(\"Yihui\", \"Xie\", role = c(\"ctb\", \"cph\"), comment = \"htmlwidgets package\"), person(\"Kenton\", \"Russell\", role = c(\"ctb\", \"cph\"), comment = \"htmlwidgets package\"), person(family = \"Facebook, Inc. and its affiliates\", role = c(\"ctb\", \"cph\"), comment = \"React library\"), person(family = \"FormatJS\", role = c(\"ctb\", \"cph\"), comment = \"FormatJS libraries\"), person(family = \"Feross Aboukhadijeh, and other contributors\", role = c(\"ctb\", \"cph\"), comment = \"buffer library\"), person(\"Roman\", \"Shtylman\", role = c(\"ctb\", \"cph\"), comment = \"process library\"), person(\"James\", \"Halliday\", role = c(\"ctb\", \"cph\"), comment = \"stream-browserify library\"), person(family = \"Posit Software, PBC\", role = c(\"fnd\", \"cph\")) )", + "Description": "Interactive data tables for R, based on the 'React Table' JavaScript library. Provides an HTML widget that can be used in 'R Markdown' or 'Quarto' documents, 'Shiny' applications, or viewed from an R console.", + "License": "MIT + file LICENSE", + "URL": "https://glin.github.io/reactable/, https://github.com/glin/reactable", + "BugReports": "https://github.com/glin/reactable/issues", + "Depends": [ + "R (>= 3.1)" + ], + "Imports": [ + "digest", + "htmltools (>= 0.5.2)", + "htmlwidgets (>= 1.5.3)", + "jsonlite", + "reactR" + ], + "Suggests": [ + "covr", + "crosstalk", + "dplyr", + "fontawesome", + "knitr", + "leaflet", + "MASS", + "rmarkdown", + "shiny", + "sparkline", + "testthat", + "tippy", + "V8" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.2.1", + "Config/testthat/edition": "3", + "NeedsCompilation": "no", + "Author": "Greg Lin [aut, cre], Tanner Linsley [ctb, cph] (React Table library), Emotion team and other contributors [ctb, cph] (Emotion library), Kent Russell [ctb, cph] (reactR package), Ramnath Vaidyanathan [ctb, cph] (htmlwidgets package), Joe Cheng [ctb, cph] (htmlwidgets package), JJ Allaire [ctb, cph] (htmlwidgets package), Yihui Xie [ctb, cph] (htmlwidgets package), Kenton Russell [ctb, cph] (htmlwidgets package), Facebook, Inc. and its affiliates [ctb, cph] (React library), FormatJS [ctb, cph] (FormatJS libraries), Feross Aboukhadijeh, and other contributors [ctb, cph] (buffer library), Roman Shtylman [ctb, cph] (process library), James Halliday [ctb, cph] (stream-browserify library), Posit Software, PBC [fnd, cph]", + "Maintainer": "Greg Lin ", + "Repository": "CRAN" + }, + "readODS": { + "Package": "readODS", + "Version": "2.3.2", + "Source": "Repository", + "Type": "Package", + "Title": "Read and Write ODS Files", + "Authors@R": "c(person(\"Gerrit-Jan\", \"Schutten\", role = c(\"aut\"), email = \"phonixor@gmail.com\"), person(\"Chung-hong\", \"Chan\", role = c(\"aut\", \"cre\"), email = \"chainsawtiney@gmail.com\", comment = c(ORCID = \"0000-0002-6232-7530\")), person(\"Peter\", \"Brohan\", role = c(\"aut\"), email = \"peter.brohan@gmail.com\"), person(\"Detlef\", \"Steuer\", role = c(\"aut\"), email = \"steuer@hsu-hh.de\", comment = c(ORCID = \"0000-0003-2676-5290\")), person(\"Thomas J.\", \"Leeper\", role = c(\"aut\"), email = \"thosjleeper@gmail.com\", comment = c(ORCID = \"0000-0003-4097-6326\")), person(\"John\", \"Foster\", role = c(\"ctb\"), email = \"john.x.foster@nab.com.au\"), person(\"Sergio\", \"Oller\", role = c(\"ctb\")), person(\"Jim\", \"Hester\", role = c(\"ctb\"), email = \"jim.hester@rstudio.com\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Stephen\", \"Watts\", role = c(\"ctb\")), person(\"Arthur\", \"Katossky\", role = c(\"ctb\")), person(\"Stas\", \"Malavin\", role = c(\"ctb\")), person(\"Duncan\", \"Garmonsway\", role = c(\"ctb\")), person(\"Mehrad\", \"Mahmoudian\", role = c(\"ctb\")), person(\"Matt\", \"Kerlogue\", role = c(\"ctb\")), person(\"Michal\", \"Lauer\", role = c(\"ctb\"), email = \"michal.lauer.25@gmail.com\"), person(\"Till\", \"Straube\", role = c(\"ctb\"), email = \"straube@geo.uni-frankfurt.de\"), person(\"Marcin\", \"Kalicinski\", role = c(\"ctb\", \"cph\"), comment = \"Author of included RapidXML code\"))", + "Description": "Read ODS (OpenDocument Spreadsheet) into R as data frame. Also support writing data frame into ODS file.", + "URL": "https://docs.ropensci.org/readODS/, https://github.com/ropensci/readODS", + "BugReports": "https://github.com/ropensci/readODS/issues", + "Imports": [ + "cellranger", + "minty (>= 0.0.5)", + "stringi", + "tibble", + "vctrs (>= 0.4.2)", + "zip", + "tools" + ], + "LinkingTo": [ + "cpp11 (>= 0.5.0)" + ], + "Suggests": [ + "spelling", + "testthat", + "datasets", + "covr", + "knitr", + "rmarkdown", + "withr", + "readr (>= 1.2.1)" + ], + "License": "GPL-3", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "VignetteBuilder": "knitr", + "Depends": [ + "R (>= 4.0)" + ], + "Language": "en-GB", + "NeedsCompilation": "yes", + "Author": "Gerrit-Jan Schutten [aut], Chung-hong Chan [aut, cre] (), Peter Brohan [aut], Detlef Steuer [aut] (), Thomas J. Leeper [aut] (), John Foster [ctb], Sergio Oller [ctb], Jim Hester [ctb] (), Stephen Watts [ctb], Arthur Katossky [ctb], Stas Malavin [ctb], Duncan Garmonsway [ctb], Mehrad Mahmoudian [ctb], Matt Kerlogue [ctb], Michal Lauer [ctb], Till Straube [ctb], Marcin Kalicinski [ctb, cph] (Author of included RapidXML code)", + "Maintainer": "Chung-hong Chan ", + "Repository": "CRAN" + }, + "readr": { + "Package": "readr", + "Version": "2.1.5", + "Source": "Repository", + "Title": "Read Rectangular Text Data", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Romain\", \"Francois\", role = \"ctb\"), person(\"Jennifer\", \"Bryan\", , \"jenny@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-6983-2759\")), person(\"Shelby\", \"Bearrows\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"https://github.com/mandreyel/\", role = \"cph\", comment = \"mio library\"), person(\"Jukka\", \"Jylänki\", role = c(\"ctb\", \"cph\"), comment = \"grisu3 implementation\"), person(\"Mikkel\", \"Jørgensen\", role = c(\"ctb\", \"cph\"), comment = \"grisu3 implementation\") )", + "Description": "The goal of 'readr' is to provide a fast and friendly way to read rectangular data (like 'csv', 'tsv', and 'fwf'). It is designed to flexibly parse many types of data found in the wild, while still cleanly failing when data unexpectedly changes.", + "License": "MIT + file LICENSE", + "URL": "https://readr.tidyverse.org, https://github.com/tidyverse/readr", + "BugReports": "https://github.com/tidyverse/readr/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli (>= 3.2.0)", + "clipr", + "crayon", + "hms (>= 0.4.1)", + "lifecycle (>= 0.2.0)", + "methods", + "R6", + "rlang", + "tibble", + "utils", + "vroom (>= 1.6.0)" + ], + "Suggests": [ + "covr", + "curl", + "datasets", + "knitr", + "rmarkdown", + "spelling", + "stringi", + "testthat (>= 3.2.0)", + "tzdb (>= 0.1.1)", + "waldo", + "withr", + "xml2" + ], + "LinkingTo": [ + "cpp11", + "tzdb (>= 0.1.1)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "false", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut], Jim Hester [aut], Romain Francois [ctb], Jennifer Bryan [aut, cre] (), Shelby Bearrows [ctb], Posit Software, PBC [cph, fnd], https://github.com/mandreyel/ [cph] (mio library), Jukka Jylänki [ctb, cph] (grisu3 implementation), Mikkel Jørgensen [ctb, cph] (grisu3 implementation)", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN" + }, + "readxl": { + "Package": "readxl", + "Version": "1.4.5", + "Source": "Repository", + "Title": "Read Excel Files", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Jennifer\", \"Bryan\", , \"jenny@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-6983-2759\")), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\"), comment = \"Copyright holder of all R code and all C/C++ code without explicit copyright attribution\"), person(\"Marcin\", \"Kalicinski\", role = c(\"ctb\", \"cph\"), comment = \"Author of included RapidXML code\"), person(\"Komarov Valery\", role = c(\"ctb\", \"cph\"), comment = \"Author of included libxls code\"), person(\"Christophe Leitienne\", role = c(\"ctb\", \"cph\"), comment = \"Author of included libxls code\"), person(\"Bob Colbert\", role = c(\"ctb\", \"cph\"), comment = \"Author of included libxls code\"), person(\"David Hoerl\", role = c(\"ctb\", \"cph\"), comment = \"Author of included libxls code\"), person(\"Evan Miller\", role = c(\"ctb\", \"cph\"), comment = \"Author of included libxls code\") )", + "Description": "Import excel files into R. Supports '.xls' via the embedded 'libxls' C library and '.xlsx' via the embedded 'RapidXML' C++ library . Works on Windows, Mac and Linux without external dependencies.", + "License": "MIT + file LICENSE", + "URL": "https://readxl.tidyverse.org, https://github.com/tidyverse/readxl", + "BugReports": "https://github.com/tidyverse/readxl/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cellranger", + "tibble (>= 2.0.1)", + "utils" + ], + "Suggests": [ + "covr", + "knitr", + "rmarkdown", + "testthat (>= 3.1.6)", + "withr" + ], + "LinkingTo": [ + "cpp11 (>= 0.4.0)", + "progress" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate, tidyverse", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "Note": "libxls v1.6.3 c199d13", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut] (), Jennifer Bryan [aut, cre] (), Posit, PBC [cph, fnd] (Copyright holder of all R code and all C/C++ code without explicit copyright attribution), Marcin Kalicinski [ctb, cph] (Author of included RapidXML code), Komarov Valery [ctb, cph] (Author of included libxls code), Christophe Leitienne [ctb, cph] (Author of included libxls code), Bob Colbert [ctb, cph] (Author of included libxls code), David Hoerl [ctb, cph] (Author of included libxls code), Evan Miller [ctb, cph] (Author of included libxls code)", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN" + }, + "rematch": { + "Package": "rematch", + "Version": "2.0.0", + "Source": "Repository", + "Title": "Match Regular Expressions with a Nicer 'API'", + "Author": "Gabor Csardi", + "Maintainer": "Gabor Csardi ", + "Description": "A small wrapper on 'regexpr' to extract the matches and captured groups from the match of a regular expression to a character vector.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/gaborcsardi/rematch", + "BugReports": "https://github.com/gaborcsardi/rematch/issues", + "RoxygenNote": "5.0.1.9000", + "Suggests": [ + "covr", + "testthat" + ], + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Repository": "CRAN" + }, + "remotes": { + "Package": "remotes", + "Version": "2.5.0", + "Source": "Repository", + "Title": "R Package Installation from Remote Repositories, Including 'GitHub'", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Winston\", \"Chang\", role = \"aut\"), person(\"Martin\", \"Morgan\", role = \"aut\"), person(\"Dan\", \"Tenenbaum\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"Ascent Digital Services\", role = \"cph\") )", + "Description": "Download and install R packages stored in 'GitHub', 'GitLab', 'Bitbucket', 'Bioconductor', or plain 'subversion' or 'git' repositories. This package provides the 'install_*' functions in 'devtools'. Indeed most of the code was copied over from 'devtools'.", + "License": "MIT + file LICENSE", + "URL": "https://remotes.r-lib.org, https://github.com/r-lib/remotes#readme", + "BugReports": "https://github.com/r-lib/remotes/issues", + "Depends": [ + "R (>= 3.0.0)" + ], + "Imports": [ + "methods", + "stats", + "tools", + "utils" + ], + "Suggests": [ + "brew", + "callr", + "codetools", + "covr", + "curl", + "git2r (>= 0.23.0)", + "knitr", + "mockery", + "pingr", + "pkgbuild (>= 1.0.1)", + "rmarkdown", + "rprojroot", + "testthat (>= 3.0.0)", + "webfakes", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "Subversion for install_svn, git for install_git", + "NeedsCompilation": "no", + "Author": "Gábor Csárdi [aut, cre], Jim Hester [aut], Hadley Wickham [aut], Winston Chang [aut], Martin Morgan [aut], Dan Tenenbaum [aut], Posit Software, PBC [cph, fnd], Ascent Digital Services [cph]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + }, + "rempsyc": { + "Package": "rempsyc", + "Version": "0.1.9", + "Source": "Repository", + "Title": "Convenience Functions for Psychology", + "Date": "2025-02-01", + "Authors@R": "person(\"Rémi\", \"Thériault\", , \"remi.theriault@mail.mcgill.ca\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-4315-6788\"))", + "Description": "Make your workflow faster and easier. Easily customizable plots (via 'ggplot2'), nice APA tables (following the style of the *American Psychological Association*) exportable to Word (via 'flextable'), easily run statistical tests or check assumptions, and automatize various other tasks.", + "License": "GPL (>= 3)", + "URL": "https://rempsyc.remi-theriault.com", + "BugReports": "https://github.com/rempsyc/rempsyc/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "rlang", + "dplyr (>= 1.1.0)" + ], + "Suggests": [ + "flextable (>= 0.9.1)", + "ggplot2 (>= 3.4.0)", + "effectsize (>= 0.8.5)", + "performance (>= 0.10.0)", + "insight (>= 0.18.4)", + "correlation", + "datawizard (>= 0.5.0)", + "report (>= 0.5.1)", + "modelbased", + "see", + "lmtest", + "ggrepel", + "boot", + "bootES", + "ggsignif", + "qqplotr (>= 0.0.6)", + "broom", + "emmeans", + "ggpubr", + "interactions", + "openxlsx2 (>= 0.8)", + "patchwork", + "psych", + "VennDiagram", + "Rmisc", + "methods", + "tidyr", + "testthat (>= 3.0.0)", + "knitr", + "markdown", + "rmarkdown" + ], + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Rémi Thériault [aut, cre] ()", + "Maintainer": "Rémi Thériault ", + "Repository": "CRAN" + }, + "reshape2": { + "Package": "reshape2", + "Version": "1.4.4", + "Source": "Repository", + "Title": "Flexibly Reshape Data: A Reboot of the Reshape Package", + "Author": "Hadley Wickham ", + "Maintainer": "Hadley Wickham ", + "Description": "Flexibly restructure and aggregate data using just two functions: melt and 'dcast' (or 'acast').", + "License": "MIT + file LICENSE", + "URL": "https://github.com/hadley/reshape", + "BugReports": "https://github.com/hadley/reshape/issues", + "Depends": [ + "R (>= 3.1)" + ], + "Imports": [ + "plyr (>= 1.8.1)", + "Rcpp", + "stringr" + ], + "Suggests": [ + "covr", + "lattice", + "testthat (>= 0.8.0)" + ], + "LinkingTo": [ + "Rcpp" + ], + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.1.0", + "NeedsCompilation": "yes", + "Repository": "CRAN" + }, + "rio": { + "Package": "rio", + "Version": "1.2.3", + "Source": "Repository", + "Type": "Package", + "Title": "A Swiss-Army Knife for Data I/O", + "Authors@R": "c(person(\"Jason\", \"Becker\", role = \"aut\", email = \"jason@jbecker.co\"), person(\"Chung-hong\", \"Chan\", role = c(\"aut\", \"cre\"), email = \"chainsawtiney@gmail.com\", comment = c(ORCID = \"0000-0002-6232-7530\")), person(\"David\", \"Schoch\", email = \"david@schochastics.net\", role = c(\"aut\"), comment = c(ORCID = \"0000-0003-2952-4812\")), person(\"Geoffrey CH\", \"Chan\", role = \"ctb\", email = \"gefchchan@gmail.com\"), person(\"Thomas J.\", \"Leeper\", role = \"aut\", email = \"thosjleeper@gmail.com\", comment = c(ORCID = \"0000-0003-4097-6326\")), person(\"Christopher\", \"Gandrud\", role = \"ctb\"), person(\"Andrew\", \"MacDonald\", role = \"ctb\"), person(\"Ista\", \"Zahn\", role = \"ctb\"), person(\"Stanislaus\", \"Stadlmann\", role = \"ctb\"), person(\"Ruaridh\", \"Williamson\", role = \"ctb\", email = \"ruaridh.williamson@gmail.com\"), person(\"Patrick\", \"Kennedy\", role = \"ctb\"), person(\"Ryan\", \"Price\", email = \"ryapric@gmail.com\", role = \"ctb\"), person(\"Trevor L\", \"Davis\", email = \"trevor.l.davis@gmail.com\", role = \"ctb\"), person(\"Nathan\", \"Day\", email = \"nathancday@gmail.com\", role = \"ctb\"), person(\"Bill\", \"Denney\", email=\"wdenney@humanpredictions.com\", role=\"ctb\", comment=c(ORCID=\"0000-0002-5759-428X\")), person(\"Alex\", \"Bokov\", email = \"alex.bokov@gmail.com\", role = \"ctb\", comment=c(ORCID=\"0000-0002-0511-9815\")), person(\"Hugo\", \"Gruson\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4094-1476\")) )", + "Description": "Streamlined data import and export by making assumptions that the user is probably willing to make: 'import()' and 'export()' determine the data format from the file extension, reasonable defaults are used for data import and export, web-based import is natively supported (including from SSL/HTTPS), compressed files can be read directly, and fast import packages are used where appropriate. An additional convenience function, 'convert()', provides a simple method for converting between file types.", + "URL": "https://gesistsa.github.io/rio/, https://github.com/gesistsa/rio", + "BugReports": "https://github.com/gesistsa/rio/issues", + "Depends": [ + "R (>= 4.0)" + ], + "Imports": [ + "tools", + "stats", + "utils", + "foreign", + "haven (>= 1.1.2)", + "curl (>= 0.6)", + "data.table (>= 1.11.2)", + "readxl (>= 0.1.1)", + "tibble", + "writexl", + "lifecycle", + "R.utils", + "readr" + ], + "Suggests": [ + "datasets", + "bit64", + "testthat", + "knitr", + "magrittr", + "clipr", + "fst", + "hexView", + "jsonlite", + "pzfx", + "readODS (>= 2.1.0)", + "rmarkdown", + "rmatio", + "xml2 (>= 1.2.0)", + "yaml", + "qs", + "arrow (>= 0.17.0)", + "stringi", + "withr", + "nanoparquet" + ], + "License": "GPL-2", + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.1", + "Config/Needs/website": "gesistsa/tsatemplate", + "NeedsCompilation": "no", + "Author": "Jason Becker [aut], Chung-hong Chan [aut, cre] (), David Schoch [aut] (), Geoffrey CH Chan [ctb], Thomas J. Leeper [aut] (), Christopher Gandrud [ctb], Andrew MacDonald [ctb], Ista Zahn [ctb], Stanislaus Stadlmann [ctb], Ruaridh Williamson [ctb], Patrick Kennedy [ctb], Ryan Price [ctb], Trevor L Davis [ctb], Nathan Day [ctb], Bill Denney [ctb] (), Alex Bokov [ctb] (), Hugo Gruson [ctb] ()", + "Maintainer": "Chung-hong Chan ", + "Repository": "CRAN" + }, + "rlang": { + "Package": "rlang", + "Version": "1.1.6", + "Source": "Repository", + "Title": "Functions for Base Types and Core R and 'Tidyverse' Features", + "Description": "A toolbox for working with base types, core R features like the condition system, and core 'Tidyverse' features like tidy evaluation.", + "Authors@R": "c( person(\"Lionel\", \"Henry\", ,\"lionel@posit.co\", c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", ,\"hadley@posit.co\", \"aut\"), person(given = \"mikefc\", email = \"mikefc@coolbutuseless.com\", role = \"cph\", comment = \"Hash implementation based on Mike's xxhashlite\"), person(given = \"Yann\", family = \"Collet\", role = \"cph\", comment = \"Author of the embedded xxHash library\"), person(given = \"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "License": "MIT + file LICENSE", + "ByteCompile": "true", + "Biarch": "true", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "utils" + ], + "Suggests": [ + "cli (>= 3.1.0)", + "covr", + "crayon", + "desc", + "fs", + "glue", + "knitr", + "magrittr", + "methods", + "pillar", + "pkgload", + "rmarkdown", + "stats", + "testthat (>= 3.2.0)", + "tibble", + "usethis", + "vctrs (>= 0.2.3)", + "withr" + ], + "Enhances": [ + "winch" + ], + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "URL": "https://rlang.r-lib.org, https://github.com/r-lib/rlang", + "BugReports": "https://github.com/r-lib/rlang/issues", + "Config/build/compilation-database": "true", + "Config/testthat/edition": "3", + "Config/Needs/website": "dplyr, tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut], mikefc [cph] (Hash implementation based on Mike's xxhashlite), Yann Collet [cph] (Author of the embedded xxHash library), Posit, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "rmarkdown": { + "Package": "rmarkdown", + "Version": "2.29", + "Source": "Repository", + "Type": "Package", + "Title": "Dynamic Documents for R", + "Authors@R": "c( person(\"JJ\", \"Allaire\", , \"jj@posit.co\", role = \"aut\"), person(\"Yihui\", \"Xie\", , \"xie@yihui.name\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-0645-5666\")), person(\"Christophe\", \"Dervieux\", , \"cderv@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Jonathan\", \"McPherson\", , \"jonathan@posit.co\", role = \"aut\"), person(\"Javier\", \"Luraschi\", role = \"aut\"), person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"aut\"), person(\"Aron\", \"Atkins\", , \"aron@posit.co\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Joe\", \"Cheng\", , \"joe@posit.co\", role = \"aut\"), person(\"Winston\", \"Chang\", , \"winston@posit.co\", role = \"aut\"), person(\"Richard\", \"Iannone\", , \"rich@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Andrew\", \"Dunning\", role = \"ctb\", comment = c(ORCID = \"0000-0003-0464-5036\")), person(\"Atsushi\", \"Yasumoto\", role = c(\"ctb\", \"cph\"), comment = c(ORCID = \"0000-0002-8335-495X\", cph = \"Number sections Lua filter\")), person(\"Barret\", \"Schloerke\", role = \"ctb\"), person(\"Carson\", \"Sievert\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Devon\", \"Ryan\", , \"dpryan79@gmail.com\", role = \"ctb\", comment = c(ORCID = \"0000-0002-8549-0971\")), person(\"Frederik\", \"Aust\", , \"frederik.aust@uni-koeln.de\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4900-788X\")), person(\"Jeff\", \"Allen\", , \"jeff@posit.co\", role = \"ctb\"), person(\"JooYoung\", \"Seo\", role = \"ctb\", comment = c(ORCID = \"0000-0002-4064-6012\")), person(\"Malcolm\", \"Barrett\", role = \"ctb\"), person(\"Rob\", \"Hyndman\", , \"Rob.Hyndman@monash.edu\", role = \"ctb\"), person(\"Romain\", \"Lesur\", role = \"ctb\"), person(\"Roy\", \"Storey\", role = \"ctb\"), person(\"Ruben\", \"Arslan\", , \"ruben.arslan@uni-goettingen.de\", role = \"ctb\"), person(\"Sergio\", \"Oller\", role = \"ctb\"), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(, \"jQuery UI contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery UI library; authors listed in inst/rmd/h/jqueryui/AUTHORS.txt\"), person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"), person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(, \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Alexander\", \"Farkas\", role = c(\"ctb\", \"cph\"), comment = \"html5shiv library\"), person(\"Scott\", \"Jehl\", role = c(\"ctb\", \"cph\"), comment = \"Respond.js library\"), person(\"Ivan\", \"Sagalaev\", role = c(\"ctb\", \"cph\"), comment = \"highlight.js library\"), person(\"Greg\", \"Franko\", role = c(\"ctb\", \"cph\"), comment = \"tocify library\"), person(\"John\", \"MacFarlane\", role = c(\"ctb\", \"cph\"), comment = \"Pandoc templates\"), person(, \"Google, Inc.\", role = c(\"ctb\", \"cph\"), comment = \"ioslides library\"), person(\"Dave\", \"Raggett\", role = \"ctb\", comment = \"slidy library\"), person(, \"W3C\", role = \"cph\", comment = \"slidy library\"), person(\"Dave\", \"Gandy\", role = c(\"ctb\", \"cph\"), comment = \"Font-Awesome\"), person(\"Ben\", \"Sperry\", role = \"ctb\", comment = \"Ionicons\"), person(, \"Drifty\", role = \"cph\", comment = \"Ionicons\"), person(\"Aidan\", \"Lister\", role = c(\"ctb\", \"cph\"), comment = \"jQuery StickyTabs\"), person(\"Benct Philip\", \"Jonsson\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\"), person(\"Albert\", \"Krewinkel\", role = c(\"ctb\", \"cph\"), comment = \"pagebreak Lua filter\") )", + "Description": "Convert R Markdown documents into a variety of formats.", + "License": "GPL-3", + "URL": "https://github.com/rstudio/rmarkdown, https://pkgs.rstudio.com/rmarkdown/", + "BugReports": "https://github.com/rstudio/rmarkdown/issues", + "Depends": [ + "R (>= 3.0)" + ], + "Imports": [ + "bslib (>= 0.2.5.1)", + "evaluate (>= 0.13)", + "fontawesome (>= 0.5.0)", + "htmltools (>= 0.5.1)", + "jquerylib", + "jsonlite", + "knitr (>= 1.43)", + "methods", + "tinytex (>= 0.31)", + "tools", + "utils", + "xfun (>= 0.36)", + "yaml (>= 2.1.19)" + ], + "Suggests": [ + "digest", + "dygraphs", + "fs", + "rsconnect", + "downlit (>= 0.4.0)", + "katex (>= 1.4.0)", + "sass (>= 0.4.0)", + "shiny (>= 1.6.0)", + "testthat (>= 3.0.3)", + "tibble", + "vctrs", + "cleanrmd", + "withr (>= 2.4.2)", + "xml2" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "rstudio/quillt, pkgdown", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "pandoc (>= 1.14) - http://pandoc.org", + "NeedsCompilation": "no", + "Author": "JJ Allaire [aut], Yihui Xie [aut, cre] (), Christophe Dervieux [aut] (), Jonathan McPherson [aut], Javier Luraschi [aut], Kevin Ushey [aut], Aron Atkins [aut], Hadley Wickham [aut], Joe Cheng [aut], Winston Chang [aut], Richard Iannone [aut] (), Andrew Dunning [ctb] (), Atsushi Yasumoto [ctb, cph] (, Number sections Lua filter), Barret Schloerke [ctb], Carson Sievert [ctb] (), Devon Ryan [ctb] (), Frederik Aust [ctb] (), Jeff Allen [ctb], JooYoung Seo [ctb] (), Malcolm Barrett [ctb], Rob Hyndman [ctb], Romain Lesur [ctb], Roy Storey [ctb], Ruben Arslan [ctb], Sergio Oller [ctb], Posit Software, PBC [cph, fnd], jQuery UI contributors [ctb, cph] (jQuery UI library; authors listed in inst/rmd/h/jqueryui/AUTHORS.txt), Mark Otto [ctb] (Bootstrap library), Jacob Thornton [ctb] (Bootstrap library), Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Alexander Farkas [ctb, cph] (html5shiv library), Scott Jehl [ctb, cph] (Respond.js library), Ivan Sagalaev [ctb, cph] (highlight.js library), Greg Franko [ctb, cph] (tocify library), John MacFarlane [ctb, cph] (Pandoc templates), Google, Inc. [ctb, cph] (ioslides library), Dave Raggett [ctb] (slidy library), W3C [cph] (slidy library), Dave Gandy [ctb, cph] (Font-Awesome), Ben Sperry [ctb] (Ionicons), Drifty [cph] (Ionicons), Aidan Lister [ctb, cph] (jQuery StickyTabs), Benct Philip Jonsson [ctb, cph] (pagebreak Lua filter), Albert Krewinkel [ctb, cph] (pagebreak Lua filter)", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "rpart": { + "Package": "rpart", + "Version": "4.1.24", + "Source": "Repository", + "Priority": "recommended", + "Date": "2025-01-06", + "Authors@R": "c(person(\"Terry\", \"Therneau\", role = \"aut\", email = \"therneau@mayo.edu\"), person(\"Beth\", \"Atkinson\", role = c(\"aut\", \"cre\"), email = \"atkinson@mayo.edu\"), person(\"Brian\", \"Ripley\", role = \"trl\", email = \"ripley@stats.ox.ac.uk\", comment = \"producer of the initial R port, maintainer 1999-2017\"))", + "Description": "Recursive partitioning for classification, regression and survival trees. An implementation of most of the functionality of the 1984 book by Breiman, Friedman, Olshen and Stone.", + "Title": "Recursive Partitioning and Regression Trees", + "Depends": [ + "R (>= 2.15.0)", + "graphics", + "stats", + "grDevices" + ], + "Suggests": [ + "survival" + ], + "License": "GPL-2 | GPL-3", + "LazyData": "yes", + "ByteCompile": "yes", + "NeedsCompilation": "yes", + "Author": "Terry Therneau [aut], Beth Atkinson [aut, cre], Brian Ripley [trl] (producer of the initial R port, maintainer 1999-2017)", + "Maintainer": "Beth Atkinson ", + "Repository": "CRAN", + "URL": "https://github.com/bethatkinson/rpart, https://cran.r-project.org/package=rpart", + "BugReports": "https://github.com/bethatkinson/rpart/issues" + }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.0.4", + "Source": "Repository", + "Title": "Finding Files in Project Subdirectories", + "Authors@R": "person(given = \"Kirill\", family = \"M\\u00fcller\", role = c(\"aut\", \"cre\"), email = \"kirill@cynkra.com\", comment = c(ORCID = \"0000-0002-1416-3412\"))", + "Description": "Robust, reliable and flexible paths to files below a project root. The 'root' of a project is defined as a directory that matches a certain criterion, e.g., it contains a certain regular file.", + "License": "MIT + file LICENSE", + "URL": "https://rprojroot.r-lib.org/, https://github.com/r-lib/rprojroot", + "BugReports": "https://github.com/r-lib/rprojroot/issues", + "Depends": [ + "R (>= 3.0.0)" + ], + "Suggests": [ + "covr", + "knitr", + "lifecycle", + "mockr", + "rlang", + "rmarkdown", + "testthat (>= 3.0.0)", + "withr" + ], + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Kirill Müller [aut, cre] ()", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "rstudioapi": { + "Package": "rstudioapi", + "Version": "0.17.1", + "Source": "Repository", + "Title": "Safely Access the RStudio API", + "Description": "Access the RStudio API (if available) and provide informative error messages when it's not.", + "Authors@R": "c( person(\"Kevin\", \"Ushey\", role = c(\"aut\", \"cre\"), email = \"kevin@rstudio.com\"), person(\"JJ\", \"Allaire\", role = c(\"aut\"), email = \"jj@posit.co\"), person(\"Hadley\", \"Wickham\", role = c(\"aut\"), email = \"hadley@posit.co\"), person(\"Gary\", \"Ritchie\", role = c(\"aut\"), email = \"gary@posit.co\"), person(family = \"RStudio\", role = \"cph\") )", + "Maintainer": "Kevin Ushey ", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/rstudioapi/, https://github.com/rstudio/rstudioapi", + "BugReports": "https://github.com/rstudio/rstudioapi/issues", + "RoxygenNote": "7.3.2", + "Suggests": [ + "testthat", + "knitr", + "rmarkdown", + "clipr", + "covr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Kevin Ushey [aut, cre], JJ Allaire [aut], Hadley Wickham [aut], Gary Ritchie [aut], RStudio [cph]", + "Repository": "CRAN" + }, + "sass": { + "Package": "sass", + "Version": "0.4.10", + "Source": "Repository", + "Type": "Package", + "Title": "Syntactically Awesome Style Sheets ('Sass')", + "Description": "An 'SCSS' compiler, powered by the 'LibSass' library. With this, R developers can use variables, inheritance, and functions to generate dynamic style sheets. The package uses the 'Sass CSS' extension language, which is stable, powerful, and CSS compatible.", + "Authors@R": "c( person(\"Joe\", \"Cheng\", , \"joe@rstudio.com\", \"aut\"), person(\"Timothy\", \"Mastny\", , \"tim.mastny@gmail.com\", \"aut\"), person(\"Richard\", \"Iannone\", , \"rich@rstudio.com\", \"aut\", comment = c(ORCID = \"0000-0003-3925-190X\")), person(\"Barret\", \"Schloerke\", , \"barret@rstudio.com\", \"aut\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Carson\", \"Sievert\", , \"carson@rstudio.com\", c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Christophe\", \"Dervieux\", , \"cderv@rstudio.com\", c(\"ctb\"), comment = c(ORCID = \"0000-0003-4474-2498\")), person(family = \"RStudio\", role = c(\"cph\", \"fnd\")), person(family = \"Sass Open Source Foundation\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Greter\", \"Marcel\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Mifsud\", \"Michael\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Hampton\", \"Catlin\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Natalie\", \"Weizenbaum\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Chris\", \"Eppstein\", role = c(\"ctb\", \"cph\"), comment = \"LibSass library\"), person(\"Adams\", \"Joseph\", role = c(\"ctb\", \"cph\"), comment = \"json.cpp\"), person(\"Trifunovic\", \"Nemanja\", role = c(\"ctb\", \"cph\"), comment = \"utf8.h\") )", + "License": "MIT + file LICENSE", + "URL": "https://rstudio.github.io/sass/, https://github.com/rstudio/sass", + "BugReports": "https://github.com/rstudio/sass/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "GNU make", + "Imports": [ + "fs (>= 1.2.4)", + "rlang (>= 0.4.10)", + "htmltools (>= 0.5.1)", + "R6", + "rappdirs" + ], + "Suggests": [ + "testthat", + "knitr", + "rmarkdown", + "withr", + "shiny", + "curl" + ], + "VignetteBuilder": "knitr", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Joe Cheng [aut], Timothy Mastny [aut], Richard Iannone [aut] (), Barret Schloerke [aut] (), Carson Sievert [aut, cre] (), Christophe Dervieux [ctb] (), RStudio [cph, fnd], Sass Open Source Foundation [ctb, cph] (LibSass library), Greter Marcel [ctb, cph] (LibSass library), Mifsud Michael [ctb, cph] (LibSass library), Hampton Catlin [ctb, cph] (LibSass library), Natalie Weizenbaum [ctb, cph] (LibSass library), Chris Eppstein [ctb, cph] (LibSass library), Adams Joseph [ctb, cph] (json.cpp), Trifunovic Nemanja [ctb, cph] (utf8.h)", + "Maintainer": "Carson Sievert ", + "Repository": "CRAN" + }, + "scales": { + "Package": "scales", + "Version": "1.4.0", + "Source": "Repository", + "Title": "Scale Functions for Visualization", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"cre\", \"aut\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Dana\", \"Seidel\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\"), comment = c(ROR = \"03wc8by49\")) )", + "Description": "Graphical scales map data to aesthetics, and provide methods for automatically determining breaks and labels for axes and legends.", + "License": "MIT + file LICENSE", + "URL": "https://scales.r-lib.org, https://github.com/r-lib/scales", + "BugReports": "https://github.com/r-lib/scales/issues", + "Depends": [ + "R (>= 4.1)" + ], + "Imports": [ + "cli", + "farver (>= 2.0.3)", + "glue", + "labeling", + "lifecycle", + "R6", + "RColorBrewer", + "rlang (>= 1.1.0)", + "viridisLite" + ], + "Suggests": [ + "bit64", + "covr", + "dichromat", + "ggplot2", + "hms (>= 0.5.0)", + "stringi", + "testthat (>= 3.0.0)" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/usethis/last-upkeep": "2025-04-23", + "Encoding": "UTF-8", + "LazyLoad": "yes", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut], Thomas Lin Pedersen [cre, aut] (), Dana Seidel [aut], Posit Software, PBC [cph, fnd] (03wc8by49)", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "shiny": { + "Package": "shiny", + "Version": "1.10.0", + "Source": "Repository", + "Type": "Package", + "Title": "Web Application Framework for R", + "Authors@R": "c( person(\"Winston\", \"Chang\", role = c(\"aut\", \"cre\"), email = \"winston@posit.co\", comment = c(ORCID = \"0000-0002-1576-2126\")), person(\"Joe\", \"Cheng\", role = \"aut\", email = \"joe@posit.co\"), person(\"JJ\", \"Allaire\", role = \"aut\", email = \"jj@posit.co\"), person(\"Carson\", \"Sievert\", role = \"aut\", email = \"carson@posit.co\", comment = c(ORCID = \"0000-0002-4958-2844\")), person(\"Barret\", \"Schloerke\", role = \"aut\", email = \"barret@posit.co\", comment = c(ORCID = \"0000-0001-9986-114X\")), person(\"Yihui\", \"Xie\", role = \"aut\", email = \"yihui@posit.co\"), person(\"Jeff\", \"Allen\", role = \"aut\"), person(\"Jonathan\", \"McPherson\", role = \"aut\", email = \"jonathan@posit.co\"), person(\"Alan\", \"Dipert\", role = \"aut\"), person(\"Barbara\", \"Borges\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(family = \"jQuery Foundation\", role = \"cph\", comment = \"jQuery library and jQuery UI library\"), person(family = \"jQuery contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt\"), person(family = \"jQuery UI contributors\", role = c(\"ctb\", \"cph\"), comment = \"jQuery UI library; authors listed in inst/www/shared/jqueryui/AUTHORS.txt\"), person(\"Mark\", \"Otto\", role = \"ctb\", comment = \"Bootstrap library\"), person(\"Jacob\", \"Thornton\", role = \"ctb\", comment = \"Bootstrap library\"), person(family = \"Bootstrap contributors\", role = \"ctb\", comment = \"Bootstrap library\"), person(family = \"Twitter, Inc\", role = \"cph\", comment = \"Bootstrap library\"), person(\"Prem Nawaz\", \"Khan\", role = \"ctb\", comment = \"Bootstrap accessibility plugin\"), person(\"Victor\", \"Tsaran\", role = \"ctb\", comment = \"Bootstrap accessibility plugin\"), person(\"Dennis\", \"Lembree\", role = \"ctb\", comment = \"Bootstrap accessibility plugin\"), person(\"Srinivasu\", \"Chakravarthula\", role = \"ctb\", comment = \"Bootstrap accessibility plugin\"), person(\"Cathy\", \"O'Connor\", role = \"ctb\", comment = \"Bootstrap accessibility plugin\"), person(family = \"PayPal, Inc\", role = \"cph\", comment = \"Bootstrap accessibility plugin\"), person(\"Stefan\", \"Petre\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap-datepicker library\"), person(\"Andrew\", \"Rowls\", role = c(\"ctb\", \"cph\"), comment = \"Bootstrap-datepicker library\"), person(\"Brian\", \"Reavis\", role = c(\"ctb\", \"cph\"), comment = \"selectize.js library\"), person(\"Salmen\", \"Bejaoui\", role = c(\"ctb\", \"cph\"), comment = \"selectize-plugin-a11y library\"), person(\"Denis\", \"Ineshin\", role = c(\"ctb\", \"cph\"), comment = \"ion.rangeSlider library\"), person(\"Sami\", \"Samhuri\", role = c(\"ctb\", \"cph\"), comment = \"Javascript strftime library\"), person(family = \"SpryMedia Limited\", role = c(\"ctb\", \"cph\"), comment = \"DataTables library\"), person(\"John\", \"Fraser\", role = c(\"ctb\", \"cph\"), comment = \"showdown.js library\"), person(\"John\", \"Gruber\", role = c(\"ctb\", \"cph\"), comment = \"showdown.js library\"), person(\"Ivan\", \"Sagalaev\", role = c(\"ctb\", \"cph\"), comment = \"highlight.js library\"), person(family = \"R Core Team\", role = c(\"ctb\", \"cph\"), comment = \"tar implementation from R\") )", + "Description": "Makes it incredibly easy to build interactive web applications with R. Automatic \"reactive\" binding between inputs and outputs and extensive prebuilt widgets make it possible to build beautiful, responsive, and powerful applications with minimal effort.", + "License": "GPL-3 | file LICENSE", + "Depends": [ + "R (>= 3.0.2)", + "methods" + ], + "Imports": [ + "utils", + "grDevices", + "httpuv (>= 1.5.2)", + "mime (>= 0.3)", + "jsonlite (>= 0.9.16)", + "xtable", + "fontawesome (>= 0.4.0)", + "htmltools (>= 0.5.4)", + "R6 (>= 2.0)", + "sourcetools", + "later (>= 1.0.0)", + "promises (>= 1.3.2)", + "tools", + "crayon", + "rlang (>= 0.4.10)", + "fastmap (>= 1.1.1)", + "withr", + "commonmark (>= 1.7)", + "glue (>= 1.3.2)", + "bslib (>= 0.6.0)", + "cachem (>= 1.1.0)", + "lifecycle (>= 0.2.0)" + ], + "Suggests": [ + "coro (>= 1.1.0)", + "datasets", + "DT", + "Cairo (>= 1.5-5)", + "testthat (>= 3.0.0)", + "knitr (>= 1.6)", + "markdown", + "rmarkdown", + "ggplot2", + "reactlog (>= 1.0.0)", + "magrittr", + "yaml", + "future", + "dygraphs", + "ragg", + "showtext", + "sass" + ], + "URL": "https://shiny.posit.co/, https://github.com/rstudio/shiny", + "BugReports": "https://github.com/rstudio/shiny/issues", + "Collate": "'globals.R' 'app-state.R' 'app_template.R' 'bind-cache.R' 'bind-event.R' 'bookmark-state-local.R' 'bookmark-state.R' 'bootstrap-deprecated.R' 'bootstrap-layout.R' 'conditions.R' 'map.R' 'utils.R' 'bootstrap.R' 'busy-indicators-spinners.R' 'busy-indicators.R' 'cache-utils.R' 'deprecated.R' 'devmode.R' 'diagnose.R' 'extended-task.R' 'fileupload.R' 'graph.R' 'reactives.R' 'reactive-domains.R' 'history.R' 'hooks.R' 'html-deps.R' 'image-interact-opts.R' 'image-interact.R' 'imageutils.R' 'input-action.R' 'input-checkbox.R' 'input-checkboxgroup.R' 'input-date.R' 'input-daterange.R' 'input-file.R' 'input-numeric.R' 'input-password.R' 'input-radiobuttons.R' 'input-select.R' 'input-slider.R' 'input-submit.R' 'input-text.R' 'input-textarea.R' 'input-utils.R' 'insert-tab.R' 'insert-ui.R' 'jqueryui.R' 'knitr.R' 'middleware-shiny.R' 'middleware.R' 'timer.R' 'shiny.R' 'mock-session.R' 'modal.R' 'modules.R' 'notifications.R' 'priorityqueue.R' 'progress.R' 'react.R' 'reexports.R' 'render-cached-plot.R' 'render-plot.R' 'render-table.R' 'run-url.R' 'runapp.R' 'serializers.R' 'server-input-handlers.R' 'server-resource-paths.R' 'server.R' 'shiny-options.R' 'shiny-package.R' 'shinyapp.R' 'shinyui.R' 'shinywrappers.R' 'showcase.R' 'snapshot.R' 'staticimports.R' 'tar.R' 'test-export.R' 'test-server.R' 'test.R' 'update-input.R' 'utils-lang.R' 'version_bs_date_picker.R' 'version_ion_range_slider.R' 'version_jquery.R' 'version_jqueryui.R' 'version_selectize.R' 'version_strftime.R' 'viewer.R'", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "RdMacros": "lifecycle", + "Config/testthat/edition": "3", + "Config/Needs/check": "shinytest2", + "NeedsCompilation": "no", + "Author": "Winston Chang [aut, cre] (), Joe Cheng [aut], JJ Allaire [aut], Carson Sievert [aut] (), Barret Schloerke [aut] (), Yihui Xie [aut], Jeff Allen [aut], Jonathan McPherson [aut], Alan Dipert [aut], Barbara Borges [aut], Posit Software, PBC [cph, fnd], jQuery Foundation [cph] (jQuery library and jQuery UI library), jQuery contributors [ctb, cph] (jQuery library; authors listed in inst/www/shared/jquery-AUTHORS.txt), jQuery UI contributors [ctb, cph] (jQuery UI library; authors listed in inst/www/shared/jqueryui/AUTHORS.txt), Mark Otto [ctb] (Bootstrap library), Jacob Thornton [ctb] (Bootstrap library), Bootstrap contributors [ctb] (Bootstrap library), Twitter, Inc [cph] (Bootstrap library), Prem Nawaz Khan [ctb] (Bootstrap accessibility plugin), Victor Tsaran [ctb] (Bootstrap accessibility plugin), Dennis Lembree [ctb] (Bootstrap accessibility plugin), Srinivasu Chakravarthula [ctb] (Bootstrap accessibility plugin), Cathy O'Connor [ctb] (Bootstrap accessibility plugin), PayPal, Inc [cph] (Bootstrap accessibility plugin), Stefan Petre [ctb, cph] (Bootstrap-datepicker library), Andrew Rowls [ctb, cph] (Bootstrap-datepicker library), Brian Reavis [ctb, cph] (selectize.js library), Salmen Bejaoui [ctb, cph] (selectize-plugin-a11y library), Denis Ineshin [ctb, cph] (ion.rangeSlider library), Sami Samhuri [ctb, cph] (Javascript strftime library), SpryMedia Limited [ctb, cph] (DataTables library), John Fraser [ctb, cph] (showdown.js library), John Gruber [ctb, cph] (showdown.js library), Ivan Sagalaev [ctb, cph] (highlight.js library), R Core Team [ctb, cph] (tar implementation from R)", + "Maintainer": "Winston Chang ", + "Repository": "CRAN" + }, + "shinyTime": { + "Package": "shinyTime", + "Version": "1.0.3", + "Source": "Repository", + "Type": "Package", + "Title": "A Time Input Widget for Shiny", + "Authors@R": "person(\"Gerhard\", \"Burger\", email = \"burger.ga@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0003-1062-5576\"))", + "Description": "Provides a time input widget for Shiny. This widget allows intuitive time input in the '[hh]:[mm]:[ss]' or '[hh]:[mm]' (24H) format by using a separate numeric input for each time component. The interface with R uses date-time objects. See the project page for more information and examples.", + "License": "GPL-3 | file LICENSE", + "Imports": [ + "htmltools", + "shiny" + ], + "URL": "https://burgerga.github.io/shinyTime/, https://github.com/burgerga/shinyTime", + "BugReports": "https://github.com/burgerga/shinyTime/issues", + "RoxygenNote": "7.2.1", + "Encoding": "UTF-8", + "Language": "en-US", + "Suggests": [ + "testthat (>= 2.1.0)", + "spelling", + "hms" + ], + "NeedsCompilation": "no", + "Author": "Gerhard Burger [aut, cre] ()", + "Maintainer": "Gerhard Burger ", + "Repository": "CRAN" + }, + "shinyWidgets": { + "Package": "shinyWidgets", + "Version": "0.9.0", + "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\") )", + "Description": "Collection of custom input controls and user interface components for 'Shiny' applications. Give your applications a unique and colorful style !", + "URL": "https://github.com/dreamRs/shinyWidgets, https://dreamrs.github.io/shinyWidgets/", + "BugReports": "https://github.com/dreamRs/shinyWidgets/issues", + "License": "GPL-3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.2", + "Depends": [ + "R (>= 3.1.0)" + ], + "Imports": [ + "bslib", + "sass", + "shiny (>= 1.6.0)", + "htmltools (>= 0.5.1)", + "jsonlite", + "grDevices", + "rlang" + ], + "Suggests": [ + "testthat", + "covr", + "ggplot2", + "DT", + "scales", + "shinydashboard", + "shinydashboardPlus" + ], + "NeedsCompilation": "no", + "Author": "Victor Perrier [aut, cre, cph], Fanny Meyer [aut], David Granjon [aut], Ian Fellows [ctb] (Methods for mutating vertical tabs & updateMultiInput), Wil Davis [ctb] (numericRangeInput function), Spencer Matthews [ctb] (autoNumeric methods), JavaScript and CSS libraries authors [ctb, cph] (All authors are listed in LICENSE.md)", + "Maintainer": "Victor Perrier ", + "Repository": "CRAN" + }, + "shinybusy": { + "Package": "shinybusy", + "Version": "0.3.3", + "Source": "Repository", + "Title": "Busy Indicators and Notifications for 'Shiny' Applications", + "Authors@R": "c(person(\"Fanny\", \"Meyer\", role = \"aut\"), person(\"Victor\", \"Perrier\", email = \"victor.perrier@dreamrs.fr\", role = c(\"aut\", \"cre\")), person(\"Silex Technologies\", comment = \"https://www.silex-ip.com\", role = \"fnd\"))", + "Description": "Add indicators (spinner, progress bar, gif) in your 'shiny' applications to show the user that the server is busy. And other tools to let your users know something is happening (send notifications, reports, ...).", + "License": "GPL-3", + "Encoding": "UTF-8", + "Imports": [ + "htmltools", + "shiny", + "jsonlite", + "htmlwidgets" + ], + "RoxygenNote": "7.3.1", + "URL": "https://github.com/dreamRs/shinybusy, https://dreamrs.github.io/shinybusy/", + "BugReports": "https://github.com/dreamRs/shinybusy/issues", + "Suggests": [ + "testthat", + "covr", + "knitr", + "rmarkdown" + ], + "VignetteBuilder": "knitr", + "NeedsCompilation": "no", + "Author": "Fanny Meyer [aut], Victor Perrier [aut, cre], Silex Technologies [fnd] (https://www.silex-ip.com)", + "Maintainer": "Victor Perrier ", + "Repository": "CRAN" + }, + "shinyjs": { + "Package": "shinyjs", + "Version": "2.1.0", + "Source": "Repository", + "Title": "Easily Improve the User Experience of Your Shiny Apps in Seconds", + "Authors@R": "person(\"Dean\", \"Attali\", email = \"daattali@gmail.com\", role = c(\"aut\", \"cre\"), comment= c(ORCID=\"0000-0002-5645-3493\"))", + "Description": "Perform common useful JavaScript operations in Shiny apps that will greatly improve your apps without having to know any JavaScript. Examples include: hiding an element, disabling an input, resetting an input back to its original value, delaying code execution by a few seconds, and many more useful functions for both the end user and the developer. 'shinyjs' can also be used to easily call your own custom JavaScript functions from R.", + "URL": "https://deanattali.com/shinyjs/", + "BugReports": "https://github.com/daattali/shinyjs/issues", + "Depends": [ + "R (>= 3.1.0)" + ], + "Imports": [ + "digest (>= 0.6.8)", + "jsonlite", + "shiny (>= 1.0.0)" + ], + "Suggests": [ + "htmltools (>= 0.2.9)", + "knitr (>= 1.7)", + "rmarkdown", + "shinyAce", + "shinydisconnect", + "testthat (>= 0.9.1)" + ], + "License": "MIT + file LICENSE", + "VignetteBuilder": "knitr", + "RoxygenNote": "7.1.1", + "Encoding": "UTF-8", + "NeedsCompilation": "no", + "Author": "Dean Attali [aut, cre] ()", + "Maintainer": "Dean Attali ", + "Repository": "CRAN" + }, + "sodium": { + "Package": "sodium", + "Version": "1.4.0", + "Source": "Repository", + "Type": "Package", + "Title": "A Modern and Easy-to-Use Crypto Library", + "Authors@R": "person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\"))", + "Description": "Bindings to 'libsodium' : a modern, easy-to-use software library for encryption, decryption, signatures, password hashing and more. Sodium uses curve25519, a state-of-the-art Diffie-Hellman function by Daniel Bernstein, which has become very popular after it was discovered that the NSA had backdoored Dual EC DRBG.", + "License": "MIT + file LICENSE", + "URL": "https://docs.ropensci.org/sodium/ https://github.com/r-lib/sodium", + "BugReports": "https://github.com/r-lib/sodium/issues", + "SystemRequirements": "libsodium (>= 1.0.3)", + "VignetteBuilder": "knitr", + "Suggests": [ + "knitr", + "rmarkdown" + ], + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] ()", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "sourcetools": { + "Package": "sourcetools", + "Version": "0.1.7-1", + "Source": "Repository", + "Type": "Package", + "Title": "Tools for Reading, Tokenizing and Parsing R Code", + "Author": "Kevin Ushey", + "Maintainer": "Kevin Ushey ", + "Description": "Tools for the reading and tokenization of R code. The 'sourcetools' package provides both an R and C++ interface for the tokenization of R code, and helpers for interacting with the tokenized representation of R code.", + "License": "MIT + file LICENSE", + "Depends": [ + "R (>= 3.0.2)" + ], + "Suggests": [ + "testthat" + ], + "RoxygenNote": "5.0.1", + "BugReports": "https://github.com/kevinushey/sourcetools/issues", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Repository": "CRAN" + }, + "stringi": { + "Package": "stringi", + "Version": "1.8.7", + "Source": "Repository", + "Date": "2025-03-27", + "Title": "Fast and Portable Character String Processing Facilities", + "Description": "A collection of character string/text/natural language processing tools for pattern searching (e.g., with 'Java'-like regular expressions or the 'Unicode' collation algorithm), random string generation, case mapping, string transliteration, concatenation, sorting, padding, wrapping, Unicode normalisation, date-time formatting and parsing, and many more. They are fast, consistent, convenient, and - thanks to 'ICU' (International Components for Unicode) - portable across all locales and platforms. Documentation about 'stringi' is provided via its website at and the paper by Gagolewski (2022, ).", + "URL": "https://stringi.gagolewski.com/, https://github.com/gagolews/stringi, https://icu.unicode.org/", + "BugReports": "https://github.com/gagolews/stringi/issues", + "SystemRequirements": "ICU4C (>= 61, optional)", + "Type": "Package", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "tools", + "utils", + "stats" + ], + "Biarch": "TRUE", + "License": "file LICENSE", + "Authors@R": "c(person(given = \"Marek\", family = \"Gagolewski\", role = c(\"aut\", \"cre\", \"cph\"), email = \"marek@gagolewski.com\", comment = c(ORCID = \"0000-0003-0637-6028\")), person(given = \"Bartek\", family = \"Tartanus\", role = \"ctb\"), person(\"Unicode, Inc. and others\", role=\"ctb\", comment = \"ICU4C source code, Unicode Character Database\") )", + "RoxygenNote": "7.3.2", + "Encoding": "UTF-8", + "NeedsCompilation": "yes", + "Author": "Marek Gagolewski [aut, cre, cph] (), Bartek Tartanus [ctb], Unicode, Inc. and others [ctb] (ICU4C source code, Unicode Character Database)", + "Maintainer": "Marek Gagolewski ", + "License_is_FOSS": "yes", + "Repository": "CRAN" + }, + "stringr": { + "Package": "stringr", + "Version": "1.5.1", + "Source": "Repository", + "Title": "Simple, Consistent Wrappers for Common String Operations", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\", \"cph\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A consistent, simple and easy to use set of wrappers around the fantastic 'stringi' package. All function and argument names (and positions) are consistent, all functions deal with \"NA\"'s and zero length vectors in the same way, and the output from one function is easy to feed into the input of another.", + "License": "MIT + file LICENSE", + "URL": "https://stringr.tidyverse.org, https://github.com/tidyverse/stringr", + "BugReports": "https://github.com/tidyverse/stringr/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli", + "glue (>= 1.6.1)", + "lifecycle (>= 1.0.3)", + "magrittr", + "rlang (>= 1.0.0)", + "stringi (>= 1.5.3)", + "vctrs (>= 0.4.0)" + ], + "Suggests": [ + "covr", + "dplyr", + "gt", + "htmltools", + "htmlwidgets", + "knitr", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Hadley Wickham [aut, cre, cph], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "sys": { + "Package": "sys", + "Version": "3.4.3", + "Source": "Repository", + "Type": "Package", + "Title": "Powerful and Reliable Tools for Running System Commands in R", + "Authors@R": "c(person(\"Jeroen\", \"Ooms\", role = c(\"aut\", \"cre\"), email = \"jeroenooms@gmail.com\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = \"ctb\"))", + "Description": "Drop-in replacements for the base system2() function with fine control and consistent behavior across platforms. Supports clean interruption, timeout, background tasks, and streaming STDIN / STDOUT / STDERR over binary or text connections. Arguments on Windows automatically get encoded and quoted to work on different locales.", + "License": "MIT + file LICENSE", + "URL": "https://jeroen.r-universe.dev/sys", + "BugReports": "https://github.com/jeroen/sys/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.1.1", + "Suggests": [ + "unix (>= 1.4)", + "spelling", + "testthat" + ], + "Language": "en-US", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), Gábor Csárdi [ctb]", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "systemfonts": { + "Package": "systemfonts", + "Version": "1.2.2", + "Source": "Repository", + "Type": "Package", + "Title": "System Native Font Finding", + "Authors@R": "c( person(\"Thomas Lin\", \"Pedersen\", , \"thomas.pedersen@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-5147-4711\")), person(\"Jeroen\", \"Ooms\", , \"jeroen@berkeley.edu\", role = \"aut\", comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"Devon\", \"Govett\", role = \"aut\", comment = \"Author of font-manager\"), person(\"Posit, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides system native access to the font catalogue. As font handling varies between systems it is difficult to correctly locate installed fonts across different operating systems. The 'systemfonts' package provides bindings to the native libraries on Windows, macOS and Linux for finding font files that can then be used further by e.g. graphic devices. The main use is intended to be from compiled code but 'systemfonts' also provides access from R.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/systemfonts, https://systemfonts.r-lib.org", + "BugReports": "https://github.com/r-lib/systemfonts/issues", + "Depends": [ + "R (>= 3.2.0)" + ], + "Suggests": [ + "covr", + "farver", + "graphics", + "knitr", + "rmarkdown", + "testthat (>= 2.1.0)" + ], + "LinkingTo": [ + "cpp11 (>= 0.2.1)" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "SystemRequirements": "fontconfig, freetype2", + "Config/Needs/website": "tidyverse/tidytemplate", + "Imports": [ + "grid", + "jsonlite", + "lifecycle", + "tools", + "utils" + ], + "Config/build/compilation-database": "true", + "NeedsCompilation": "yes", + "Author": "Thomas Lin Pedersen [aut, cre] (), Jeroen Ooms [aut] (), Devon Govett [aut] (Author of font-manager), Posit, PBC [cph, fnd]", + "Maintainer": "Thomas Lin Pedersen ", + "Repository": "CRAN" + }, + "tibble": { + "Package": "tibble", + "Version": "3.2.1", + "Source": "Repository", + "Title": "Simple Data Frames", + "Authors@R": "c(person(given = \"Kirill\", family = \"M\\u00fcller\", role = c(\"aut\", \"cre\"), email = \"kirill@cynkra.com\", comment = c(ORCID = \"0000-0002-1416-3412\")), person(given = \"Hadley\", family = \"Wickham\", role = \"aut\", email = \"hadley@rstudio.com\"), person(given = \"Romain\", family = \"Francois\", role = \"ctb\", email = \"romain@r-enthusiasts.com\"), person(given = \"Jennifer\", family = \"Bryan\", role = \"ctb\", email = \"jenny@rstudio.com\"), person(given = \"RStudio\", role = c(\"cph\", \"fnd\")))", + "Description": "Provides a 'tbl_df' class (the 'tibble') with stricter checking and better formatting than the traditional data frame.", + "License": "MIT + file LICENSE", + "URL": "https://tibble.tidyverse.org/, https://github.com/tidyverse/tibble", + "BugReports": "https://github.com/tidyverse/tibble/issues", + "Depends": [ + "R (>= 3.4.0)" + ], + "Imports": [ + "fansi (>= 0.4.0)", + "lifecycle (>= 1.0.0)", + "magrittr", + "methods", + "pillar (>= 1.8.1)", + "pkgconfig", + "rlang (>= 1.0.2)", + "utils", + "vctrs (>= 0.4.2)" + ], + "Suggests": [ + "bench", + "bit64", + "blob", + "brio", + "callr", + "cli", + "covr", + "crayon (>= 1.3.4)", + "DiagrammeR", + "dplyr", + "evaluate", + "formattable", + "ggplot2", + "here", + "hms", + "htmltools", + "knitr", + "lubridate", + "mockr", + "nycflights13", + "pkgbuild", + "pkgload", + "purrr", + "rmarkdown", + "stringi", + "testthat (>= 3.0.2)", + "tidyr", + "withr" + ], + "VignetteBuilder": "knitr", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "true", + "Config/testthat/start-first": "vignette-formats, as_tibble, add, invariants", + "Config/autostyle/scope": "line_breaks", + "Config/autostyle/strict": "true", + "Config/autostyle/rmd": "false", + "Config/Needs/website": "tidyverse/tidytemplate", + "NeedsCompilation": "yes", + "Author": "Kirill Müller [aut, cre] (), Hadley Wickham [aut], Romain Francois [ctb], Jennifer Bryan [ctb], RStudio [cph, fnd]", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "tidyr": { + "Package": "tidyr", + "Version": "1.3.1", + "Source": "Repository", + "Title": "Tidy Messy Data", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = c(\"aut\", \"cre\")), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = \"aut\"), person(\"Maximilian\", \"Girlich\", role = \"aut\"), person(\"Kevin\", \"Ushey\", , \"kevin@posit.co\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Tools to help to create tidy data, where each column is a variable, each row is an observation, and each cell contains a single value. 'tidyr' contains tools for changing the shape (pivoting) and hierarchy (nesting and 'unnesting') of a dataset, turning deeply nested lists into rectangular data frames ('rectangling'), and extracting values out of string columns. It also includes tools for working with missing values (both implicit and explicit).", + "License": "MIT + file LICENSE", + "URL": "https://tidyr.tidyverse.org, https://github.com/tidyverse/tidyr", + "BugReports": "https://github.com/tidyverse/tidyr/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "cli (>= 3.4.1)", + "dplyr (>= 1.0.10)", + "glue", + "lifecycle (>= 1.0.3)", + "magrittr", + "purrr (>= 1.0.1)", + "rlang (>= 1.1.1)", + "stringr (>= 1.5.0)", + "tibble (>= 2.1.1)", + "tidyselect (>= 1.2.0)", + "utils", + "vctrs (>= 0.5.2)" + ], + "Suggests": [ + "covr", + "data.table", + "knitr", + "readr", + "repurrrsive (>= 1.1.0)", + "rmarkdown", + "testthat (>= 3.0.0)" + ], + "LinkingTo": [ + "cpp11 (>= 0.4.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "LazyData": "true", + "RoxygenNote": "7.3.0", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut, cre], Davis Vaughan [aut], Maximilian Girlich [aut], Kevin Ushey [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Hadley Wickham ", + "Repository": "CRAN" + }, + "tidyselect": { + "Package": "tidyselect", + "Version": "1.2.1", + "Source": "Repository", + "Title": "Select from a Set of Strings", + "Authors@R": "c( person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = c(\"aut\", \"cre\")), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A backend for the selecting functions of the 'tidyverse'. It makes it easy to implement select-like functions in your own packages in a way that is consistent with other 'tidyverse' interfaces for selection.", + "License": "MIT + file LICENSE", + "URL": "https://tidyselect.r-lib.org, https://github.com/r-lib/tidyselect", + "BugReports": "https://github.com/r-lib/tidyselect/issues", + "Depends": [ + "R (>= 3.4)" + ], + "Imports": [ + "cli (>= 3.3.0)", + "glue (>= 1.3.0)", + "lifecycle (>= 1.0.3)", + "rlang (>= 1.0.4)", + "vctrs (>= 0.5.2)", + "withr" + ], + "Suggests": [ + "covr", + "crayon", + "dplyr", + "knitr", + "magrittr", + "rmarkdown", + "stringr", + "testthat (>= 3.1.1)", + "tibble (>= 2.1.3)" + ], + "VignetteBuilder": "knitr", + "ByteCompile": "true", + "Config/testthat/edition": "3", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.0.9000", + "NeedsCompilation": "yes", + "Author": "Lionel Henry [aut, cre], Hadley Wickham [aut], Posit Software, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "timechange": { + "Package": "timechange", + "Version": "0.3.0", + "Source": "Repository", + "Title": "Efficient Manipulation of Date-Times", + "Authors@R": "c(person(\"Vitalie\", \"Spinu\", email = \"spinuvit@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Google Inc.\", role = c(\"ctb\", \"cph\")))", + "Description": "Efficient routines for manipulation of date-time objects while accounting for time-zones and daylight saving times. The package includes utilities for updating of date-time components (year, month, day etc.), modification of time-zones, rounding of date-times, period addition and subtraction etc. Parts of the 'CCTZ' source code, released under the Apache 2.0 License, are included in this package. See for more details.", + "Depends": [ + "R (>= 3.3)" + ], + "License": "GPL (>= 3)", + "Encoding": "UTF-8", + "LinkingTo": [ + "cpp11 (>= 0.2.7)" + ], + "Suggests": [ + "testthat (>= 0.7.1.99)", + "knitr" + ], + "SystemRequirements": "A system with zoneinfo data (e.g. /usr/share/zoneinfo) as well as a recent-enough C++11 compiler (such as g++-4.8 or later). On Windows the zoneinfo included with R is used.", + "BugReports": "https://github.com/vspinu/timechange/issues", + "URL": "https://github.com/vspinu/timechange/", + "RoxygenNote": "7.2.1", + "NeedsCompilation": "yes", + "Author": "Vitalie Spinu [aut, cre], Google Inc. [ctb, cph]", + "Maintainer": "Vitalie Spinu ", + "Repository": "CRAN" + }, + "tinytex": { + "Package": "tinytex", + "Version": "0.57", + "Source": "Repository", + "Type": "Package", + "Title": "Helper Functions to Install and Maintain TeX Live, and Compile LaTeX Documents", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\")), person(given = \"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"Christophe\", \"Dervieux\", role = \"ctb\", comment = c(ORCID = \"0000-0003-4474-2498\")), person(\"Devon\", \"Ryan\", role = \"ctb\", email = \"dpryan79@gmail.com\", comment = c(ORCID = \"0000-0002-8549-0971\")), person(\"Ethan\", \"Heinzen\", role = \"ctb\"), person(\"Fernando\", \"Cagua\", role = \"ctb\"), person() )", + "Description": "Helper functions to install and maintain the 'LaTeX' distribution named 'TinyTeX' (), a lightweight, cross-platform, portable, and easy-to-maintain version of 'TeX Live'. This package also contains helper functions to compile 'LaTeX' documents, and install missing 'LaTeX' packages automatically.", + "Imports": [ + "xfun (>= 0.48)" + ], + "Suggests": [ + "testit", + "rstudioapi" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/rstudio/tinytex", + "BugReports": "https://github.com/rstudio/tinytex/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "no", + "Author": "Yihui Xie [aut, cre, cph] (), Posit Software, PBC [cph, fnd], Christophe Dervieux [ctb] (), Devon Ryan [ctb] (), Ethan Heinzen [ctb], Fernando Cagua [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "toastui": { + "Package": "toastui", + "Version": "0.4.0", + "Source": "Repository", + "Title": "Interactive Tables, Calendars and Charts for the Web", + "Authors@R": "c( person(\"Victor\", \"Perrier\", email = \"victor.perrier@dreamrs.fr\", role = c(\"aut\", \"cre\", \"cph\")), person(\"Fanny\", \"Meyer\", role = \"aut\"), person(\"NHN FE Development Lab\", role = \"cph\", comment = \"tui-grid, tui-calendar, tui-chart libraries\"))", + "Description": "Create interactive tables, calendars, charts and markdown WYSIWYG editor with 'TOAST UI' libraries to integrate in 'shiny' applications or 'rmarkdown' 'HTML' documents.", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "LazyData": "true", + "Depends": [ + "R (>= 2.10)" + ], + "Imports": [ + "utils", + "htmlwidgets", + "htmltools", + "magrittr", + "phosphoricons", + "rlang", + "shiny (>= 1.1.0)", + "shinyWidgets" + ], + "Suggests": [ + "apexcharter", + "bslib", + "knitr", + "rmarkdown", + "scales", + "tinytest" + ], + "VignetteBuilder": "knitr", + "RoxygenNote": "7.3.2", + "URL": "https://dreamrs.github.io/toastui/", + "BugReports": "https://github.com/dreamRs/toastui/issues", + "NeedsCompilation": "no", + "Author": "Victor Perrier [aut, cre, cph], Fanny Meyer [aut], NHN FE Development Lab [cph] (tui-grid, tui-calendar, tui-chart libraries)", + "Maintainer": "Victor Perrier ", + "Repository": "CRAN" + }, + "tweenr": { + "Package": "tweenr", + "Version": "2.0.3", + "Source": "Repository", + "Type": "Package", + "Title": "Interpolate Data for Smooth Animations", + "Authors@R": "c(person(given = \"Thomas Lin\", family = \"Pedersen\", role = c(\"aut\", \"cre\"), email = \"thomasp85@gmail.com\", comment = c(ORCID = \"0000-0002-5147-4711\")))", + "Maintainer": "Thomas Lin Pedersen ", + "Description": "In order to create smooth animation between states of data, tweening is necessary. This package provides a range of functions for creating tweened data that can be used as basis for animation. Furthermore it adds a number of vectorized interpolaters for common R data types such as numeric, date and colour.", + "URL": "https://github.com/thomasp85/tweenr", + "BugReports": "https://github.com/thomasp85/tweenr/issues", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 3.2.0)" + ], + "Imports": [ + "farver", + "magrittr", + "rlang", + "vctrs" + ], + "LinkingTo": [ + "cpp11 (>= 0.4.2)" + ], + "RoxygenNote": "7.2.3", + "Suggests": [ + "testthat", + "covr" + ], + "NeedsCompilation": "yes", + "Author": "Thomas Lin Pedersen [aut, cre] ()", + "Repository": "CRAN" + }, + "tzdb": { + "Package": "tzdb", + "Version": "0.5.0", + "Source": "Repository", + "Title": "Time Zone Database Information", + "Authors@R": "c( person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = c(\"aut\", \"cre\")), person(\"Howard\", \"Hinnant\", role = \"cph\", comment = \"Author of the included date library\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Provides an up-to-date copy of the Internet Assigned Numbers Authority (IANA) Time Zone Database. It is updated periodically to reflect changes made by political bodies to time zone boundaries, UTC offsets, and daylight saving time rules. Additionally, this package provides a C++ interface for working with the 'date' library. 'date' provides comprehensive support for working with dates and date-times, which this package exposes to make it easier for other R packages to utilize. Headers are provided for calendar specific calculations, along with a limited interface for time zone manipulations.", + "License": "MIT + file LICENSE", + "URL": "https://tzdb.r-lib.org, https://github.com/r-lib/tzdb", + "BugReports": "https://github.com/r-lib/tzdb/issues", + "Depends": [ + "R (>= 4.0.0)" + ], + "Suggests": [ + "covr", + "testthat (>= 3.0.0)" + ], + "LinkingTo": [ + "cpp11 (>= 0.5.2)" + ], + "Biarch": "yes", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "NeedsCompilation": "yes", + "Author": "Davis Vaughan [aut, cre], Howard Hinnant [cph] (Author of the included date library), Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN" + }, + "utf8": { + "Package": "utf8", + "Version": "1.2.4", + "Source": "Repository", + "Title": "Unicode Text Processing", + "Authors@R": "c(person(given = c(\"Patrick\", \"O.\"), family = \"Perry\", role = c(\"aut\", \"cph\")), person(given = \"Kirill\", family = \"M\\u00fcller\", role = \"cre\", email = \"kirill@cynkra.com\"), person(given = \"Unicode, Inc.\", role = c(\"cph\", \"dtc\"), comment = \"Unicode Character Database\"))", + "Description": "Process and print 'UTF-8' encoded international text (Unicode). Input, validate, normalize, encode, format, and display.", + "License": "Apache License (== 2.0) | file LICENSE", + "URL": "https://ptrckprry.com/r-utf8/, https://github.com/patperry/r-utf8", + "BugReports": "https://github.com/patperry/r-utf8/issues", + "Depends": [ + "R (>= 2.10)" + ], + "Suggests": [ + "cli", + "covr", + "knitr", + "rlang", + "rmarkdown", + "testthat (>= 3.0.0)", + "withr" + ], + "VignetteBuilder": "knitr, rmarkdown", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Patrick O. Perry [aut, cph], Kirill Müller [cre], Unicode, Inc. [cph, dtc] (Unicode Character Database)", + "Maintainer": "Kirill Müller ", + "Repository": "CRAN" + }, + "vctrs": { + "Package": "vctrs", + "Version": "0.6.5", + "Source": "Repository", + "Title": "Vector Helpers", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = \"aut\"), person(\"Davis\", \"Vaughan\", , \"davis@posit.co\", role = c(\"aut\", \"cre\")), person(\"data.table team\", role = \"cph\", comment = \"Radix sort based on data.table's forder() and their contribution to R's order()\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Defines new notions of prototype and size that are used to provide tools for consistent and well-founded type-coercion and size-recycling, and are in turn connected to ideas of type- and size-stability useful for analysing function interfaces.", + "License": "MIT + file LICENSE", + "URL": "https://vctrs.r-lib.org/, https://github.com/r-lib/vctrs", + "BugReports": "https://github.com/r-lib/vctrs/issues", + "Depends": [ + "R (>= 3.5.0)" + ], + "Imports": [ + "cli (>= 3.4.0)", + "glue", + "lifecycle (>= 1.0.3)", + "rlang (>= 1.1.0)" + ], + "Suggests": [ + "bit64", + "covr", + "crayon", + "dplyr (>= 0.8.5)", + "generics", + "knitr", + "pillar (>= 1.4.4)", + "pkgdown (>= 2.0.1)", + "rmarkdown", + "testthat (>= 3.0.0)", + "tibble (>= 3.1.3)", + "waldo (>= 0.2.0)", + "withr", + "xml2", + "zeallot" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "Language": "en-GB", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut], Lionel Henry [aut], Davis Vaughan [aut, cre], data.table team [cph] (Radix sort based on data.table's forder() and their contribution to R's order()), Posit Software, PBC [cph, fnd]", + "Maintainer": "Davis Vaughan ", + "Repository": "CRAN" + }, + "viridis": { + "Package": "viridis", + "Version": "0.6.5", + "Source": "Repository", + "Type": "Package", + "Title": "Colorblind-Friendly Color Maps for R", + "Date": "2024-01-28", + "Authors@R": "c( person(\"Simon\", \"Garnier\", email = \"garnier@njit.edu\", role = c(\"aut\", \"cre\")), person(\"Noam\", \"Ross\", email = \"noam.ross@gmail.com\", role = c(\"ctb\", \"cph\")), person(\"Bob\", \"Rudis\", email = \"bob@rud.is\", role = c(\"ctb\", \"cph\")), person(\"Marco\", \"Sciaini\", email = \"sciaini.marco@gmail.com\", role = c(\"ctb\", \"cph\")), person(\"Antônio Pedro\", \"Camargo\", role = c(\"ctb\", \"cph\")), person(\"Cédric\", \"Scherer\", email = \"scherer@izw-berlin.de\", role = c(\"ctb\", \"cph\")) )", + "Maintainer": "Simon Garnier ", + "Description": "Color maps designed to improve graph readability for readers with common forms of color blindness and/or color vision deficiency. The color maps are also perceptually-uniform, both in regular form and also when converted to black-and-white for printing. This package also contains 'ggplot2' bindings for discrete and continuous color and fill scales. A lean version of the package called 'viridisLite' that does not include the 'ggplot2' bindings can be found at .", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 2.10)", + "viridisLite (>= 0.4.0)" + ], + "Imports": [ + "ggplot2 (>= 1.0.1)", + "gridExtra" + ], + "Suggests": [ + "hexbin (>= 1.27.0)", + "scales", + "MASS", + "knitr", + "dichromat", + "colorspace", + "httr", + "mapproj", + "vdiffr", + "svglite (>= 1.2.0)", + "testthat", + "covr", + "rmarkdown", + "maps", + "terra" + ], + "LazyData": "true", + "VignetteBuilder": "knitr", + "URL": "https://sjmgarnier.github.io/viridis/, https://github.com/sjmgarnier/viridis/", + "BugReports": "https://github.com/sjmgarnier/viridis/issues", + "RoxygenNote": "7.3.1", + "NeedsCompilation": "no", + "Author": "Simon Garnier [aut, cre], Noam Ross [ctb, cph], Bob Rudis [ctb, cph], Marco Sciaini [ctb, cph], Antônio Pedro Camargo [ctb, cph], Cédric Scherer [ctb, cph]", + "Repository": "CRAN" + }, + "viridisLite": { + "Package": "viridisLite", + "Version": "0.4.2", + "Source": "Repository", + "Type": "Package", + "Title": "Colorblind-Friendly Color Maps (Lite Version)", + "Date": "2023-05-02", + "Authors@R": "c( person(\"Simon\", \"Garnier\", email = \"garnier@njit.edu\", role = c(\"aut\", \"cre\")), person(\"Noam\", \"Ross\", email = \"noam.ross@gmail.com\", role = c(\"ctb\", \"cph\")), person(\"Bob\", \"Rudis\", email = \"bob@rud.is\", role = c(\"ctb\", \"cph\")), person(\"Marco\", \"Sciaini\", email = \"sciaini.marco@gmail.com\", role = c(\"ctb\", \"cph\")), person(\"Antônio Pedro\", \"Camargo\", role = c(\"ctb\", \"cph\")), person(\"Cédric\", \"Scherer\", email = \"scherer@izw-berlin.de\", role = c(\"ctb\", \"cph\")) )", + "Maintainer": "Simon Garnier ", + "Description": "Color maps designed to improve graph readability for readers with common forms of color blindness and/or color vision deficiency. The color maps are also perceptually-uniform, both in regular form and also when converted to black-and-white for printing. This is the 'lite' version of the 'viridis' package that also contains 'ggplot2' bindings for discrete and continuous color and fill scales and can be found at .", + "License": "MIT + file LICENSE", + "Encoding": "UTF-8", + "Depends": [ + "R (>= 2.10)" + ], + "Suggests": [ + "hexbin (>= 1.27.0)", + "ggplot2 (>= 1.0.1)", + "testthat", + "covr" + ], + "URL": "https://sjmgarnier.github.io/viridisLite/, https://github.com/sjmgarnier/viridisLite/", + "BugReports": "https://github.com/sjmgarnier/viridisLite/issues/", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "no", + "Author": "Simon Garnier [aut, cre], Noam Ross [ctb, cph], Bob Rudis [ctb, cph], Marco Sciaini [ctb, cph], Antônio Pedro Camargo [ctb, cph], Cédric Scherer [ctb, cph]", + "Repository": "CRAN" + }, + "vroom": { + "Package": "vroom", + "Version": "1.6.5", + "Source": "Repository", + "Title": "Read and Write Rectangular Text Data Quickly", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\", comment = c(ORCID = \"0000-0002-2739-7082\")), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\", comment = c(ORCID = \"0000-0003-4757-117X\")), person(\"Jennifer\", \"Bryan\", , \"jenny@posit.co\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-6983-2759\")), person(\"Shelby\", \"Bearrows\", role = \"ctb\"), person(\"https://github.com/mandreyel/\", role = \"cph\", comment = \"mio library\"), person(\"Jukka\", \"Jylänki\", role = \"cph\", comment = \"grisu3 implementation\"), person(\"Mikkel\", \"Jørgensen\", role = \"cph\", comment = \"grisu3 implementation\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "The goal of 'vroom' is to read and write data (like 'csv', 'tsv' and 'fwf') quickly. When reading it uses a quick initial indexing step, then reads the values lazily , so only the data you actually use needs to be read. The writer formats the data in parallel and writes to disk asynchronously from formatting.", + "License": "MIT + file LICENSE", + "URL": "https://vroom.r-lib.org, https://github.com/tidyverse/vroom", + "BugReports": "https://github.com/tidyverse/vroom/issues", + "Depends": [ + "R (>= 3.6)" + ], + "Imports": [ + "bit64", + "cli (>= 3.2.0)", + "crayon", + "glue", + "hms", + "lifecycle (>= 1.0.3)", + "methods", + "rlang (>= 0.4.2)", + "stats", + "tibble (>= 2.0.0)", + "tidyselect", + "tzdb (>= 0.1.1)", + "vctrs (>= 0.2.0)", + "withr" + ], + "Suggests": [ + "archive", + "bench (>= 1.1.0)", + "covr", + "curl", + "dplyr", + "forcats", + "fs", + "ggplot2", + "knitr", + "patchwork", + "prettyunits", + "purrr", + "rmarkdown", + "rstudioapi", + "scales", + "spelling", + "testthat (>= 2.1.0)", + "tidyr", + "utils", + "waldo", + "xml2" + ], + "LinkingTo": [ + "cpp11 (>= 0.2.0)", + "progress (>= 1.2.1)", + "tzdb (>= 0.1.1)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "nycflights13, tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Config/testthat/parallel": "false", + "Copyright": "file COPYRIGHTS", + "Encoding": "UTF-8", + "Language": "en-US", + "RoxygenNote": "7.2.3.9000", + "NeedsCompilation": "yes", + "Author": "Jim Hester [aut] (), Hadley Wickham [aut] (), Jennifer Bryan [aut, cre] (), Shelby Bearrows [ctb], https://github.com/mandreyel/ [cph] (mio library), Jukka Jylänki [cph] (grisu3 implementation), Mikkel Jørgensen [cph] (grisu3 implementation), Posit Software, PBC [cph, fnd]", + "Maintainer": "Jennifer Bryan ", + "Repository": "CRAN" + }, + "withr": { + "Package": "withr", + "Version": "3.0.2", + "Source": "Repository", + "Title": "Run Code 'With' Temporarily Modified Global State", + "Authors@R": "c( person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Lionel\", \"Henry\", , \"lionel@posit.co\", role = c(\"aut\", \"cre\")), person(\"Kirill\", \"Müller\", , \"krlmlr+r@mailbox.org\", role = \"aut\"), person(\"Kevin\", \"Ushey\", , \"kevinushey@gmail.com\", role = \"aut\"), person(\"Hadley\", \"Wickham\", , \"hadley@posit.co\", role = \"aut\"), person(\"Winston\", \"Chang\", role = \"aut\"), person(\"Jennifer\", \"Bryan\", role = \"ctb\"), person(\"Richard\", \"Cotton\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "A set of functions to run code 'with' safely and temporarily modified global state. Many of these functions were originally a part of the 'devtools' package, this provides a simple package with limited dependencies to provide access to these functions.", + "License": "MIT + file LICENSE", + "URL": "https://withr.r-lib.org, https://github.com/r-lib/withr#readme", + "BugReports": "https://github.com/r-lib/withr/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "graphics", + "grDevices" + ], + "Suggests": [ + "callr", + "DBI", + "knitr", + "methods", + "rlang", + "rmarkdown (>= 2.12)", + "RSQLite", + "testthat (>= 3.0.0)" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "Collate": "'aaa.R' 'collate.R' 'connection.R' 'db.R' 'defer-exit.R' 'standalone-defer.R' 'defer.R' 'devices.R' 'local_.R' 'with_.R' 'dir.R' 'env.R' 'file.R' 'language.R' 'libpaths.R' 'locale.R' 'makevars.R' 'namespace.R' 'options.R' 'par.R' 'path.R' 'rng.R' 'seed.R' 'wrap.R' 'sink.R' 'tempfile.R' 'timezone.R' 'torture.R' 'utils.R' 'with.R'", + "NeedsCompilation": "no", + "Author": "Jim Hester [aut], Lionel Henry [aut, cre], Kirill Müller [aut], Kevin Ushey [aut], Hadley Wickham [aut], Winston Chang [aut], Jennifer Bryan [ctb], Richard Cotton [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Lionel Henry ", + "Repository": "CRAN" + }, + "writexl": { + "Package": "writexl", + "Version": "1.5.4", + "Source": "Repository", + "Type": "Package", + "Title": "Export Data Frames to Excel 'xlsx' Format", + "Authors@R": "c( person(\"Jeroen\", \"Ooms\", ,\"jeroenooms@gmail.com\", role = c(\"aut\", \"cre\"), comment = c(ORCID = \"0000-0002-4035-0289\")), person(\"John McNamara\", role = \"cph\", comment = \"Author of libxlsxwriter (see AUTHORS and COPYRIGHT files for details)\"))", + "Description": "Zero-dependency data frame to xlsx exporter based on 'libxlsxwriter' . Fast and no Java or Excel required.", + "License": "BSD_2_clause + file LICENSE", + "Encoding": "UTF-8", + "URL": "https://ropensci.r-universe.dev/writexl https://docs.ropensci.org/writexl/", + "BugReports": "https://github.com/ropensci/writexl/issues", + "RoxygenNote": "7.0.2", + "Suggests": [ + "spelling", + "readxl", + "nycflights13", + "testthat", + "bit64" + ], + "Language": "en-US", + "SystemRequirements": "zlib", + "NeedsCompilation": "yes", + "Author": "Jeroen Ooms [aut, cre] (), John McNamara [cph] (Author of libxlsxwriter (see AUTHORS and COPYRIGHT files for details))", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "xfun": { + "Package": "xfun", + "Version": "0.52", + "Source": "Repository", + "Type": "Package", + "Title": "Supporting Functions for Packages Maintained by 'Yihui Xie'", + "Authors@R": "c( person(\"Yihui\", \"Xie\", role = c(\"aut\", \"cre\", \"cph\"), email = \"xie@yihui.name\", comment = c(ORCID = \"0000-0003-0645-5666\", URL = \"https://yihui.org\")), person(\"Wush\", \"Wu\", role = \"ctb\"), person(\"Daijiang\", \"Li\", role = \"ctb\"), person(\"Xianying\", \"Tan\", role = \"ctb\"), person(\"Salim\", \"Brüggemann\", role = \"ctb\", email = \"salim-b@pm.me\", comment = c(ORCID = \"0000-0002-5329-5987\")), person(\"Christophe\", \"Dervieux\", role = \"ctb\"), person() )", + "Description": "Miscellaneous functions commonly used in other packages maintained by 'Yihui Xie'.", + "Depends": [ + "R (>= 3.2.0)" + ], + "Imports": [ + "grDevices", + "stats", + "tools" + ], + "Suggests": [ + "testit", + "parallel", + "codetools", + "methods", + "rstudioapi", + "tinytex (>= 0.30)", + "mime", + "litedown (>= 0.4)", + "commonmark", + "knitr (>= 1.50)", + "remotes", + "pak", + "curl", + "xml2", + "jsonlite", + "magick", + "yaml", + "qs" + ], + "License": "MIT + file LICENSE", + "URL": "https://github.com/yihui/xfun", + "BugReports": "https://github.com/yihui/xfun/issues", + "Encoding": "UTF-8", + "RoxygenNote": "7.3.2", + "VignetteBuilder": "litedown", + "NeedsCompilation": "yes", + "Author": "Yihui Xie [aut, cre, cph] (, https://yihui.org), Wush Wu [ctb], Daijiang Li [ctb], Xianying Tan [ctb], Salim Brüggemann [ctb] (), Christophe Dervieux [ctb]", + "Maintainer": "Yihui Xie ", + "Repository": "CRAN" + }, + "xml2": { + "Package": "xml2", + "Version": "1.3.8", + "Source": "Repository", + "Title": "Parse XML", + "Authors@R": "c( person(\"Hadley\", \"Wickham\", role = \"aut\"), person(\"Jim\", \"Hester\", role = \"aut\"), person(\"Jeroen\", \"Ooms\", email = \"jeroenooms@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")), person(\"R Foundation\", role = \"ctb\", comment = \"Copy of R-project homepage cached as example\") )", + "Description": "Bindings to 'libxml2' for working with XML data using a simple, consistent interface based on 'XPath' expressions. Also supports XML schema validation; for 'XSLT' transformations see the 'xslt' package.", + "License": "MIT + file LICENSE", + "URL": "https://xml2.r-lib.org, https://r-lib.r-universe.dev/xml2", + "BugReports": "https://github.com/r-lib/xml2/issues", + "Depends": [ + "R (>= 3.6.0)" + ], + "Imports": [ + "cli", + "methods", + "rlang (>= 1.1.0)" + ], + "Suggests": [ + "covr", + "curl", + "httr", + "knitr", + "magrittr", + "mockery", + "rmarkdown", + "testthat (>= 3.2.0)", + "xslt" + ], + "VignetteBuilder": "knitr", + "Config/Needs/website": "tidyverse/tidytemplate", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "SystemRequirements": "libxml2: libxml2-dev (deb), libxml2-devel (rpm)", + "Collate": "'S4.R' 'as_list.R' 'xml_parse.R' 'as_xml_document.R' 'classes.R' 'format.R' 'import-standalone-obj-type.R' 'import-standalone-purrr.R' 'import-standalone-types-check.R' 'init.R' 'nodeset_apply.R' 'paths.R' 'utils.R' 'xml2-package.R' 'xml_attr.R' 'xml_children.R' 'xml_document.R' 'xml_find.R' 'xml_missing.R' 'xml_modify.R' 'xml_name.R' 'xml_namespaces.R' 'xml_node.R' 'xml_nodeset.R' 'xml_path.R' 'xml_schema.R' 'xml_serialize.R' 'xml_structure.R' 'xml_text.R' 'xml_type.R' 'xml_url.R' 'xml_write.R' 'zzz.R'", + "Config/testthat/edition": "3", + "NeedsCompilation": "yes", + "Author": "Hadley Wickham [aut], Jim Hester [aut], Jeroen Ooms [aut, cre], Posit Software, PBC [cph, fnd], R Foundation [ctb] (Copy of R-project homepage cached as example)", + "Maintainer": "Jeroen Ooms ", + "Repository": "CRAN" + }, + "xtable": { + "Package": "xtable", + "Version": "1.8-4", + "Source": "Repository", + "Date": "2019-04-08", + "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 ", + "Imports": [ + "stats", + "utils" + ], + "Suggests": [ + "knitr", + "plm", + "zoo", + "survival" + ], + "VignetteBuilder": "knitr", + "Description": "Coerce data to LaTeX and HTML tables.", + "URL": "http://xtable.r-forge.r-project.org/", + "Depends": [ + "R (>= 2.10.0)" + ], + "License": "GPL (>= 2)", + "Repository": "CRAN", + "NeedsCompilation": "no", + "Author": "David B. Dahl [aut], David Scott [aut, cre], Charles Roosen [aut], Arni Magnusson [aut], Jonathan Swinton [aut], Ajay Shah [ctb], Arne Henningsen [ctb], Benno Puetz [ctb], Bernhard Pfaff [ctb], Claudio Agostinelli [ctb], Claudius Loehnert [ctb], David Mitchell [ctb], David Whiting [ctb], Fernando da Rosa [ctb], Guido Gay [ctb], Guido Schulz [ctb], Ian Fellows [ctb], Jeff Laake [ctb], John Walker [ctb], Jun Yan [ctb], Liviu Andronic [ctb], Markus Loecher [ctb], Martin Gubri [ctb], Matthieu Stigler [ctb], Robert Castelo [ctb], Seth Falcon [ctb], Stefan Edwards [ctb], Sven Garbade [ctb], Uwe Ligges [ctb]" + }, + "yaml": { + "Package": "yaml", + "Version": "2.3.10", + "Source": "Repository", + "Type": "Package", + "Title": "Methods to Convert R Data to YAML and Back", + "Date": "2024-07-22", + "Suggests": [ + "RUnit" + ], + "Author": "Shawn P Garbett [aut], Jeremy Stephens [aut, cre], Kirill Simonov [aut], Yihui Xie [ctb], Zhuoer Dong [ctb], Hadley Wickham [ctb], Jeffrey Horner [ctb], reikoch [ctb], Will Beasley [ctb], Brendan O'Connor [ctb], Gregory R. Warnes [ctb], Michael Quinn [ctb], Zhian N. Kamvar [ctb], Charlie Gao [ctb]", + "Maintainer": "Shawn Garbett ", + "License": "BSD_3_clause + file LICENSE", + "Description": "Implements the 'libyaml' 'YAML' 1.1 parser and emitter () for R.", + "URL": "https://github.com/vubiostat/r-yaml/", + "BugReports": "https://github.com/vubiostat/r-yaml/issues", + "NeedsCompilation": "yes", + "Repository": "CRAN" + }, + "zip": { + "Package": "zip", + "Version": "2.3.2", + "Source": "Repository", + "Title": "Cross-Platform 'zip' Compression", + "Authors@R": "c( person(\"Gábor\", \"Csárdi\", , \"csardi.gabor@gmail.com\", role = c(\"aut\", \"cre\")), person(\"Kuba\", \"Podgórski\", role = \"ctb\"), person(\"Rich\", \"Geldreich\", role = \"ctb\"), person(\"Posit Software, PBC\", role = c(\"cph\", \"fnd\")) )", + "Description": "Cross-Platform 'zip' Compression Library. A replacement for the 'zip' function, that does not require any additional external tools on any platform.", + "License": "MIT + file LICENSE", + "URL": "https://github.com/r-lib/zip, https://r-lib.github.io/zip/", + "BugReports": "https://github.com/r-lib/zip/issues", + "Suggests": [ + "covr", + "pillar", + "processx", + "R6", + "testthat", + "withr" + ], + "Config/Needs/website": "tidyverse/tidytemplate", + "Config/testthat/edition": "3", + "Encoding": "UTF-8", + "RoxygenNote": "7.2.3", + "NeedsCompilation": "yes", + "Author": "Gábor Csárdi [aut, cre], Kuba Podgórski [ctb], Rich Geldreich [ctb], Posit Software, PBC [cph, fnd]", + "Maintainer": "Gábor Csárdi ", + "Repository": "CRAN" + } + } +}

Xo_5RAZsWO2kqGtA^ktnf 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 z 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