diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index b32be55..02789c9 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -1,29 +1,77 @@ -# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples -# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +# .github/workflows/R-CMD-check.yaml +# Based on r-lib/actions examples; trimmed + one extra job to build the manual. + on: push: - branches: [main, master] + branches: [master] pull_request: - branches: [main, master] + branches: [master] name: R-CMD-check jobs: R-CMD-check: - runs-on: ubuntu-latest + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.os }} (${{ matrix.config.r }}) + strategy: + fail-fast: false + matrix: + config: + - { os: macos-latest, r: "release" } + - { os: windows-latest, r: "release" } + - { os: ubuntu-latest, r: "devel", http-user-agent: "release" } + - { os: ubuntu-latest, r: "release" } + - { os: ubuntu-latest, r: "oldrel-1" } env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} R_KEEP_PKG_SOURCE: yes steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 - uses: r-lib/actions/setup-r@v2 with: + r-version: ${{ matrix.config.r }} + http-user-agent: ${{ matrix.config.http-user-agent }} use-public-rspm: true - uses: r-lib/actions/setup-r-dependencies@v2 with: + needs: check extra-packages: any::rcmdcheck + + - uses: r-lib/actions/check-r-package@v2 + with: + error-on: '"warning"' + upload-snapshots: true + + # 2) Linux "full docs" check (build vignettes + PDF manual) + R-CMD-check-docs: + runs-on: ubuntu-latest + needs: R-CMD-check + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes + steps: + - uses: actions/checkout@v4 + + - uses: r-lib/actions/setup-pandoc@v2 + - uses: r-lib/actions/setup-r@v2 + with: + r-version: "release" + use-public-rspm: true + + - uses: r-lib/actions/setup-tinytex@v2 + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: needs: check + extra-packages: any::rcmdcheck - uses: r-lib/actions/check-r-package@v2 + with: + args: 'c("--as-cran")' + build_args: 'c("--compact-vignettes=gs+qpdf")' + error-on: '"warning"' + upload-snapshots: true diff --git a/DESCRIPTION b/DESCRIPTION index ae9835a..17419fb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: corx Type: Package Title: Create and Format Correlation Matrices -Version: 1.0.7.2 -Date: 2023-06-15 +Version: 1.0.7.3 +Date: 2025-11-03 Authors@R: person(given = "James", family = "Conigrave", @@ -21,13 +21,15 @@ Imports: glue, clipr, tidyselect, + rlang, moments, ggpubr, ggplot2, stats, methods, - ppcor -RoxygenNote: 7.2.3 + ppcor, + labelled +RoxygenNote: 7.3.3 Suggests: covr, papaja, diff --git a/NEWS.md b/NEWS.md index 4774398..0aae9c9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,13 +1,21 @@ +# corx 1.0.7.3 + +- Corx now can identify haven labelled variables as numeric + +# corx 1.0.7.2 + +- Fixed issue with incorrect class declaration + # corx 1.0.7.1 -* Fixed issue where misspelling columns did not result in error -* Removed leading zeros for p-values in to_table -* P-values are now rounded consistently to three decimal places +- Fixed issue where misspelling columns did not result in error +- Removed leading zeros for p-values in to_table +- P-values are now rounded consistently to three decimal places # corx 1.0.7.0 -* Removed magrittr pipe operator -* Added corx method for papaja::apa_table -* Now use cor.test for non-partial correlations -* Added ability to adjust p-values using stats::p.adjust -* Added new function "to_table" which provides additional options for corx tabulation (i.e., inclusion of p-values) +- Removed magrittr pipe operator +- Added corx method for papaja::apa_table +- Now use cor.test for non-partial correlations +- Added ability to adjust p-values using stats::p.adjust +- Added new function "to_table" which provides additional options for corx tabulation (i.e., inclusion of p-values) diff --git a/R/cormat_list.R b/R/cormat_list.R index a0d77eb..1f3554f 100644 --- a/R/cormat_list.R +++ b/R/cormat_list.R @@ -6,7 +6,14 @@ #' @param method string, passed to cor.test #' @param p_adjust string, passed to p.adjust -cormat_list <- function(data, x, y, z, method, p_adjust) { +cormat_list <- function( + data, + x, + y, + z, + method, + p_adjust +) { cors <- list() cormat <- matrix(nrow = length(x), ncol = length(y)) @@ -31,7 +38,6 @@ cormat_list <- function(data, x, y, z, method, p_adjust) { cors$r[r, c] <- cor_ob$r cors$n[r, c] <- cor_ob$n cors$p[r, c] <- cor_ob$p - } } @@ -40,7 +46,6 @@ cormat_list <- function(data, x, y, z, method, p_adjust) { } cors - } flex_cor <- function(x, y, z = NULL, method, data) { @@ -70,13 +75,16 @@ flex_cor <- function(x, y, z = NULL, method, data) { method = method ) - list(r = cor_ob.partial$estimate, - n = cor_ob.partial$n, - p = cor_ob.partial$p.value) - } else{ - list(r = 1, - n = nrow(partial_data), - p = 1) + list( + r = cor_ob.partial$estimate, + n = cor_ob.partial$n, + p = cor_ob.partial$p.value + ) + } else { + list( + r = 1, + n = nrow(partial_data), + p = 1 + ) } - } diff --git a/R/corx.R b/R/corx.R index 25ecd2d..a2e5c00 100644 --- a/R/corx.R +++ b/R/corx.R @@ -7,7 +7,7 @@ #' @param y a vector of colnames. If not supplied, y is set to x. #' @param z a vector of variable names. Control variables to be used in partial correlations - defaults to NULL #' @param method character. One of "pearson", "spearman", or "kendall" -#' @param round numeric. Number of digits in printing +#' @param round numeric. How many digits should correlation coefficients be rounded to in printing? #' @param stars a numeric vector. This argument defines cut-offs for p-value stars. #' @param p_adjust character. What adjustment for multiple tests should be used? One of "none" (default), "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", or "fdr" #' @param remove_lead logical. if TRUE (the default), leading zeros are removed in summaries @@ -55,72 +55,97 @@ #' @export corx <- - function(data, - x = NULL, - y = NULL, - z = NULL, - method = c("pearson", "spearman", "kendall"), - stars = c(0.05,0.01,0.001), - p_adjust = c("none", "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", "fdr"), - round = 2, - remove_lead = TRUE, - triangle = NULL, - caption = NULL, - note = NULL, - describe = FALSE, - grey_nonsig = TRUE, - call_only = FALSE) { - - + function( + data, + x = NULL, + y = NULL, + z = NULL, + method = c("pearson", "spearman", "kendall"), + stars = c(0.05, 0.01, 0.001), + p_adjust = c( + "none", + "holm", + "hochberg", + "hommel", + "bonferroni", + "BH", + "BY", + "fdr" + ), + round = 2, + remove_lead = TRUE, + triangle = NULL, + caption = NULL, + note = NULL, + describe = FALSE, + grey_nonsig = TRUE, + call_only = FALSE + ) { call <- match.call() env <- environment() parent_env <- sys.frame(sys.parent()) - if(call_only) return(list(call = call, env = env, parent_env = parent_env)) + if (call_only) { + return(list(call = call, env = env, parent_env = parent_env)) + } - if(nrow(data) < 3){ + if (nrow(data) < 3) { stop("Can't calculate p-values with fewer than four rows of data.") } - if(methods::is(data, "matrix")) data <- data.frame(data, check.names = FALSE) + if (methods::is(data, "matrix")) { + data <- data.frame(data, check.names = FALSE) + } - x <- tidyselect::vars_select(colnames(data), {{x}}, .strict = TRUE) - y <- tidyselect::vars_select(colnames(data), {{y}}, .strict = TRUE) - z <- tidyselect::vars_select(colnames(data), {{z}}, .strict = TRUE) + x <- eval_select_names(colnames(data), {{ x }}, strict = TRUE) + y <- eval_select_names(colnames(data), {{ y }}, strict = TRUE) + z <- eval_select_names(colnames(data), {{ z }}, strict = TRUE) # allow rename within select data <- rename_if_needed(data, x) data <- rename_if_needed(data, y) data <- rename_if_needed(data, z) - if(length(x) > 0) x <- names(x) - if(length(y) > 0) y <- names(y) - if(length(z) > 0) z <- names(z) + if (length(x) > 0) { + x <- names(x) + } + if (length(y) > 0) { + y <- names(y) + } + if (length(z) > 0) { + z <- names(z) + } - if(length(x) == 0){ + if (length(x) == 0) { x <- names(data) } - if(length(y) == 0){ + if (length(y) == 0) { y <- x } - if(length(z) == 0){ + if (length(z) == 0) { z <- NULL } - if(length(z) > 0){ # remove partialled out variable from x and y + if (length(z) > 0) { + # remove partialled out variable from x and y x <- x[!x %in% z] y <- y[!y %in% z] } - if(length(x) == 0 | length(y) == 0) stop("Can't partial out the entirety of x or y") + if (length(x) == 0 | length(y) == 0) { + stop("Can't partial out the entirety of x or y") + } # check classes are appropriate - check_classes(data[,unique(c(x,y,z))], c("numeric","integer"), "All classes must be numeric.") - + check_classes( + data[, unique(c(x, y, z))], + c("numeric", "integer"), + "All classes must be numeric." + ) - method <- method[1] # take the first method in case more than one supplied + method <- method[1] # take the first method in case more than one supplied p_adjust <- p_adjust[1] cors <- cormat_list( @@ -132,48 +157,81 @@ corx <- p_adjust = p_adjust ) - pres_matrix <- apa_matrix(cors$r, #get apa matrix - cors$p, - stars, - round, - remove_lead, - triangle) + pres_matrix <- apa_matrix( + r_matrix = cors$r, #get apa matrix + p_matrix = cors$p, + stars = stars, + round = round, + remove_lead = remove_lead, + triangle = triangle + ) # describe function ---------------------------------------------------- # allow shortcuts - all_desc <- list(mean = function(x) mean(x, na.rm=T), - sd = function(x) stats::sd(x, na.rm=T), - var = function(x) stats::var(x, na.rm = T), - median = function(x) stats::median(x, na.rm = T), - iqr = function(x) stats::IQR(x, na.rm = T), - skewness = function(x) moments::skewness(x, na.rm = T), - kurtosis = function(x) moments::kurtosis(x, na.rm =T), - n = function(x) digits(length(stats::na.omit(x)),0) + all_desc <- list( + mean = function(x) mean(x, na.rm = T), + sd = function(x) stats::sd(x, na.rm = T), + var = function(x) stats::var(x, na.rm = T), + median = function(x) stats::median(x, na.rm = T), + iqr = function(x) stats::IQR(x, na.rm = T), + skewness = function(x) moments::skewness(x, na.rm = T), + kurtosis = function(x) moments::kurtosis(x, na.rm = T), + n = function(x) digits(length(stats::na.omit(x)), 0) ) - tryCatch({ # allow lists to be sent to tidyselect - describe_name <- tidyselect::vars_select(names(all_desc), {{describe}}, .strict = F) - }, error = function(e) assign("describe_name", c(), envir = env)) # assign empty vec if error + describe_name <- character() + describe_expr <- call$describe + run_select <- !is.null(describe_expr) && + !identical(describe_expr, quote(T)) && + !identical(describe_expr, quote(TRUE)) && + !identical(describe_expr, quote(F)) && + !identical(describe_expr, quote(FALSE)) + + if (run_select) { + describe_name <- + tryCatch( + { + # allow lists to be sent to tidyselect + eval_select_names( + names(all_desc), + {{ describe }}, + strict = FALSE + ) + }, + error = function(e) character() + ) + } - if(length(describe_name) > 0){ # if vars were found + if (length(describe_name) > 0) { + # if vars were found - if(length(describe_name) != (length(call$describe) -1)){ # check if all vars were found - describe_name <- tidyselect::vars_select(names(all_desc), {{describe}}, .strict = T) + if (length(describe_name) != (length(call$describe) - 1)) { + # check if all vars were found + describe_name <- eval_select_names( + names(all_desc), + {{ describe }}, + strict = TRUE + ) } describe <- all_desc[describe_name] # set describe to all_desc names(describe) <- names(describe_name) # rename as needed } - if (!identical(describe, F)) { # if describe is selected - if (identical(describe, T)) { # if it is equal to true - describe = list( # define default describe functions - "M" = function(x) - mean(x, na.rm = TRUE), - "SD" = function(x) + if (!identical(describe, F)) { + # if describe is selected + if (identical(describe, T)) { + # if it is equal to true + describe = list( + # define default describe functions + "M" = function(x) { + mean(x, na.rm = TRUE) + }, + "SD" = function(x) { stats::sd(x, na.rm = TRUE) + } ) } @@ -183,9 +241,10 @@ corx <- orig_names <- colnames(pres_matrix) pres_matrix <- data.frame(pres_matrix) - for (i in seq_along(describe)) { # then apply describe function to data - safe_round <- function(x, round){ - if(methods::is(x, "numeric")){ + for (i in seq_along(describe)) { + # then apply describe function to data + safe_round <- function(x, round) { + if (methods::is(x, "numeric")) { return(digits(x, round)) } x @@ -201,21 +260,20 @@ corx <- colnames(pres_matrix)[seq_along(orig_names)] <- orig_names } - if(!is.null(triangle)){ # if triangle change names ------- + if (!is.null(triangle)) { + # if triangle change names ------- nums <- seq_along(rownames(pres_matrix)) - rownames(pres_matrix) <- paste0(nums,". ", rownames(pres_matrix)) + rownames(pres_matrix) <- paste0(nums, ". ", rownames(pres_matrix)) colnames(pres_matrix)[1:length(nums)] <- nums - pres_matrix <- pres_matrix[,-length(nums)] + pres_matrix <- pres_matrix[, -length(nums)] } # add in note -------------------------------------------- - if(is.null(note)){ - - note <- lapply(seq_along(stars), function(s){ - - temp_stars <- paste(rep("*",s), collapse = "") + if (is.null(note)) { + note <- lapply(seq_along(stars), function(s) { + temp_stars <- paste(rep("*", s), collapse = "") paste0(temp_stars, " p < ", stars[s]) }) @@ -248,15 +306,14 @@ corx <- #' @param y colnames #' @param z partial variable vector -partial_n_matrix <- function(data, x, y, z){ - +partial_n_matrix <- function(data, x, y, z) { mx <- matrix(nrow = length(x), ncol = length(y)) rownames(mx) <- x colnames(mx) <- y - for(row in rownames(mx)){ - for(col in colnames(mx)){ - mx[row,col] <- sum(stats::complete.cases(data[,c(row, col, z)])) + for (row in rownames(mx)) { + for (col in colnames(mx)) { + mx[row, col] <- sum(stats::complete.cases(data[, c(row, col, z)])) } } @@ -273,16 +330,24 @@ partial_n_matrix <- function(data, x, y, z){ #' @param remove_lead a logical. Should leading zeros be removed? #' @param triangle can select lower upper or NULL -apa_matrix <- function(r_matrix, - p_matrix, - stars, - round, - remove_lead, - triangle) { +apa_matrix <- function( + r_matrix, + p_matrix, + stars, + round, + remove_lead, + triangle +) { f_matrix <- r_matrix - f_matrix[] <- digits(f_matrix , round) + f_matrix[] <- digits(f_matrix, round) + row_names <- matrix(rownames(r_matrix), nrow(r_matrix), ncol = ncol(r_matrix)) - col_names <- matrix(colnames(r_matrix), nrow = nrow(r_matrix), ncol = ncol(r_matrix), byrow = T) + col_names <- matrix( + colnames(r_matrix), + nrow = nrow(r_matrix), + ncol = ncol(r_matrix), + byrow = T + ) f_matrix[row_names == col_names] <- " - " @@ -304,9 +369,10 @@ apa_matrix <- function(r_matrix, f_matrix[] <- paste0(f_matrix, s_matrix) - if (remove_lead) + if (remove_lead) { f_matrix[] <- - gsub("0\\.", ".", f_matrix) #remove leading zeros if requested + gsub("0\\.", ".", f_matrix) + } #remove leading zeros if requested return(f_matrix) } @@ -316,8 +382,7 @@ apa_matrix <- function(r_matrix, #' @param x object #' @param ... extra arguments #' @export -print.corx <- function(x,...){ - +print.corx <- function(x, ...) { apa <- x$apa text <- utils::capture.output(print(apa, quote = F, right = T)) @@ -327,42 +392,45 @@ print.corx <- function(x,...){ grey <- attr(x, "grey_nonsig") star_call <- attr(x, "stars") - if(length(star_call) > 0 & grey & identical(attr(x, "describe"), F)){# make nonsig grey + if (length(star_call) > 0 & grey & identical(attr(x, "describe"), F)) { + # make nonsig grey - if(attr(x, "round") != 0 ){ # if no decimal places change regex + if (attr(x, "round") != 0) { + # if no decimal places change regex patt <- "(-)?[0-9]?\\.[0-9]{1,}(?![\\*0-9])" # possible negative, then a possible 0-9 character, then a decimal - }else{ # then more 0-9 characters (at least one), but not followed by any number of stars! + } else { + # then more 0-9 characters (at least one), but not followed by any number of stars! patt <- "-?[0-1](?![\\*\\.0-9]{1,})" # different pattern for round = 0 (even though no one will ever use that setting) } - gr <- gregexpr(patt,text, perl = T) # get match locations - mat <- regmatches(text,gr) - regmatches(text,gr) <- lapply(mat, function(x) crayon::silver(x)) # replace with silver text + gr <- gregexpr(patt, text, perl = T) # get match locations + mat <- regmatches(text, gr) + regmatches(text, gr) <- lapply(mat, function(x) crayon::silver(x)) # replace with silver text } text <- gsub("\\bNA\\b", crayon::red("NA"), text) # make NAs red - text <- gsub("\\*", crayon::yellow("*"),text) # make stars yelloe - text <- gsub("\\ - ", crayon::silver(" - "),text) # make dashes silver + text <- gsub("\\*", crayon::yellow("*"), text) # make stars yellow + text <- gsub("\\ - ", crayon::silver(" - "), text) # make dashes silver text <- text[-1] # remove header - bar <- paste(rep(crayon::silver("-"), width),collapse = "") # create a bar same length as table - temp_note <- paste("Note.",x$note) # get note ready - - - - final_text <- paste(c( - crayon::blue(utils::capture.output(x$call)), # call - "", # then an empty line - x$caption, # table caption - bar, # a bar - header, # a header - bar, # a bar - text, # table contents - bar, # final bar - temp_note, # the note - "" - ), - collapse = "\n") # all separated with line breaks + bar <- paste(rep(crayon::silver("-"), width), collapse = "") # create a bar same length as table + temp_note <- paste("Note.", x$note) # get note ready + + final_text <- paste( + c( + crayon::blue(utils::capture.output(x$call)), # call + "", # then an empty line + x$caption, # table caption + bar, # a bar + header, # a header + bar, # a bar + text, # table contents + bar, # final bar + temp_note, # the note + "" + ), + collapse = "\n" + ) # all separated with line breaks cat(final_text) } @@ -378,7 +446,11 @@ coef.corx <- function(object, ...) object$r # coef returns r matrix digits <- function(x, n = 2) { x <- round(x, n) x[] <- sapply(x, function(i) { - ifelse(!is.na(i), trimws(format(round(as.numeric(as.character(i)), n), nsmall = n)),NA) + ifelse( + !is.na(i), + trimws(format(round(as.numeric(as.character(i)), n), nsmall = n)), + NA + ) }) x } @@ -388,28 +460,36 @@ digits <- function(x, n = 2) { #' @param ... other arguments to ggcorrplot::ggcorrplot #' @export -plot.corx <- function(x, ...){ +plot.corx <- function(x, ...) { call <- match.call() elip <- list(...) tri <- x$call$triangle - if(is.null(tri)) tri <- "full" - if(!is.null(call$type)) tri <- call$type + if (is.null(tri)) { + tri <- "full" + } + if (!is.null(call$type)) { + tri <- call$type + } caption <- x$call$caption - if(is.null(caption)) caption <- "" - if(!is.null(call$title)) caption <- call$title + if (is.null(caption)) { + caption <- "" + } + if (!is.null(call$title)) { + caption <- call$title + } elip[['title']] <- caption # elip is designed - elip[['type']] <- tri # To be a call - elip[['corr']] <- x$r # I'm setting arguments which will be used in do.call - elip[['p.mat']] <- x$p # We include the p.matrix for signifance rules in ggcorrplot + elip[['type']] <- tri # To be a call + elip[['corr']] <- x$r # I'm setting arguments which will be used in do.call + elip[['p.mat']] <- x$p # We include the p.matrix for signifance rules in ggcorrplot do.call(ggcorrplot::ggcorrplot, elip) } #' @export -summary.corx <- function(object,... , digits, quantile.type){ +summary.corx <- function(object, ..., digits, quantile.type) { name_mat <- colnames(object$apa) obj <- data.frame(object$apa) names(obj) <- name_mat @@ -417,7 +497,7 @@ summary.corx <- function(object,... , digits, quantile.type){ } #' @export -as.data.frame.corx <- function(x,...){ +as.data.frame.corx <- function(x, ...) { name_mat <- colnames(x$apa) obj <- data.frame(x$apa) names(obj) <- name_mat @@ -433,22 +513,36 @@ as.data.frame.corx <- function(x,...){ #' @param stop should the variable stop, or create a warning? check_classes <- function(data, ok_classes, stop_message, stop = TRUE) { + v_is <- function(x, classes) { + x <- labelled::remove_labels(x) + any(sapply(classes, function(y) { + methods::is(x, y) + })) + } + classes <- lapply(data, class) - class_ok <- sapply(classes, function(x) any(ok_classes %in% x)) + + class_ok <- sapply(data, function(x) v_is(x, ok_classes)) bad_cols <- names(data)[!class_ok] bad_index <- which(names(data) %in% bad_cols) - bad_classes <- lapply(classes[!class_ok], function(x) paste(abbreviate(x,3), collapse = ",")) - script <- paste(glue::glue("[{bad_index}] '{bad_cols}' <{bad_classes}>"), collapse = ", ") + bad_classes <- sapply(classes[!class_ok], function(x) { + paste(abbreviate(x, 3), collapse = ",") + }) + script <- paste( + glue::glue("[{bad_index}] '{bad_cols}' <{bad_classes}>"), + collapse = ", " + ) if (!all(class_ok)) { - if(stop){ - stop(stop_message," ", script, ".", call. = F) - }else{ - warning(stop_message," ", script, ".", call. = F) + if (stop) { + stop(stop_message, " ", script, ".", call. = F) + } else { + warning(stop_message, " ", script, ".", call. = F) } } } + #' star_matrix #' #' Replaces p-values with stars @@ -457,15 +551,17 @@ check_classes <- function(data, ok_classes, stop_message, stop = TRUE) { star_matrix <- function(m, stars) { get_stars <- function(p, stars) { - if (is.na(p)) + if (is.na(p)) { p <- 1 + } n_stars <- sum(p < stars) paste(rep("*", n_stars), collapse = "") } s_matrix <- m - s_matrix[] <- sapply(m, function(p) - get_stars(p, stars = stars)) + s_matrix[] <- sapply(m, function(p) { + get_stars(p, stars = stars) + }) s_matrix } @@ -475,13 +571,15 @@ star_matrix <- function(m, stars) { #' @param data data object #' @param x a character vector. If named, columns will be renamed - rename_if_needed <- function(data, x) { - rename_vars <- x[names(x) != x] - for (i in seq_along(rename_vars)) { - if (names(x)[i] != x[i]) { - colnames(data)[colnames(data) == x[i]] <- names(rename_vars[rename_vars == x[i]]) - } - } - - data +rename_if_needed <- function(data, x) { + rename_vars <- x[names(x) != x] + for (i in seq_along(rename_vars)) { + if (names(x)[i] != x[i]) { + colnames(data)[colnames(data) == x[i]] <- names(rename_vars[ + rename_vars == x[i] + ]) } + } + + data +} diff --git a/R/utils.R b/R/utils.R new file mode 100644 index 0000000..e2b69bd --- /dev/null +++ b/R/utils.R @@ -0,0 +1,32 @@ +# replacement for tidyselect::vars_select +eval_select_names <- function( + vars, + expr, + strict = TRUE, + allow_predicates = TRUE +) { + quo <- rlang::enquo(expr) + + if (rlang::quo_is_null(quo)) { + return(character()) + } + + data_mask <- stats::setNames(seq_along(vars), vars) + + eval_call <- function() { + tidyselect::eval_select( + quo, + data = data_mask, + strict = strict, + allow_predicates = allow_predicates + ) + } + + locations <- if (allow_predicates) { + eval_call() + } else { + suppressWarnings(eval_call()) + } + + stats::setNames(vars[locations], names(locations)) +} diff --git a/man/corx.Rd b/man/corx.Rd index 91d1090..1e54429 100644 --- a/man/corx.Rd +++ b/man/corx.Rd @@ -37,7 +37,7 @@ corx( \item{p_adjust}{character. What adjustment for multiple tests should be used? One of "none" (default), "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", or "fdr"} -\item{round}{numeric. Number of digits in printing} +\item{round}{numeric. How many digits should correlation coefficients be rounded to in printing?} \item{remove_lead}{logical. if TRUE (the default), leading zeros are removed in summaries} diff --git a/tests/testthat/test_describe.R b/tests/testthat/test_describe.R new file mode 100644 index 0000000..0b27dc0 --- /dev/null +++ b/tests/testthat/test_describe.R @@ -0,0 +1,29 @@ +test_that("describe name vector works", { + cx <- corx::corx(mtcars, describe = c(iqr, median)) + res <- all(c("iqr", "median") %in% colnames(cx$apa)) + testthat::expect_true(res) +}) + +test_that("describe name vector with rename works", { + cx <- corx::corx(mtcars, describe = c("TEST" = iqr, "MEDIAN" = median)) + res <- all( + c("TEST", "MEDIAN") %in% colnames(cx$apa) + ) + testthat::expect_true(res) +}) + +test_that("describe bool works", { + cx <- corx::corx(mtcars, describe = TRUE) + res <- all( + c("M", "SD") %in% colnames(cx$apa) + ) + testthat::expect_true(res) +}) + +test_that("describe quote works", { + cx <- corx::corx(mtcars, describe = c("TEST" = "iqr", "sd")) + res <- all( + c("TEST", "sd") %in% colnames(cx$apa) + ) + testthat::expect_true(res) +}) diff --git a/tests/testthat/test_value_labels.R b/tests/testthat/test_value_labels.R new file mode 100644 index 0000000..57c35cc --- /dev/null +++ b/tests/testthat/test_value_labels.R @@ -0,0 +1,10 @@ +testthat::test_that("value_labels works correctly", { + iris_new <- iris |> + labelled::set_value_labels( + Sepal.Length = c(mediumlength = 5.1, lowerlength = 4.6) + ) + testthat::expect_no_error( + iris_new[, 1:4] |> + corx() + ) +})