#' 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 <- tempfile(fileext = ".rds") readr::write_rds(data, file = temp) ## 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 = 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 <- openxlsx2::read_xlsx(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 #' 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 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() default_parsing <- function(data) { name_labels <- lapply(data,\(.x) REDCapCAST::get_attr(.x,attr = "label")) out <- data |> REDCapCAST::parse_data() |> REDCapCAST::as_factor() |> REDCapCAST::numchar2fct() purrr::map2(out,name_labels,\(.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 NA labels #' #' @param data data #' #' @returns data.frame #' @export #' #' @examples #' ds <- mtcars |> lapply(\(.x) REDCapCAST::set_attr(.x,label=NA,attr = "label")) #' ds |> remove_na_attr() |> str() remove_na_attr <- function(data,attr="label"){ out <- data |> lapply(\(.x){ ls <- REDCapCAST::get_attr(data = .x,attr = attr) if (is.na(ls) | ls == ""){ attr(x = .x, which = attr) <- NULL } .x }) dplyr::bind_cols(out) }