From c3e85d46f41c2a1b6625916fe9d2deb00b677361 Mon Sep 17 00:00:00 2001 From: Ravi Selker Date: Wed, 10 Jun 2026 17:15:08 +0200 Subject: [PATCH] Fix correlation crash on NA p-values Constant or degenerate inputs make cor.test return an NA p-value, which broke the significance-flag comparisons and aborted the whole table. Skip flagging when the p-value is missing. --- R/corrmatrix.b.R | 6 +++--- R/corrpart.b.R | 12 ++++++++---- tests/testthat/testcorrmatrix.R | 29 +++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/R/corrmatrix.b.R b/R/corrmatrix.b.R index 964c2cd3..6363a1b4 100644 --- a/R/corrmatrix.b.R +++ b/R/corrmatrix.b.R @@ -159,7 +159,7 @@ corrMatrixClass <- R6::R6Class( matrix$addFootnote(rowNo=i, paste0(colVarName, '[r]'), .('Pearson correlation cannot be calculated for non-numeric values')) if (flag) { - if ( ! self$options$pearson || mtord) + if ( ! self$options$pearson || mtord || is.na(result$rp)) {} # do nothing else if (result$rp < .001) matrix$addSymbol(rowNo=i, paste0(colVarName, '[r]'), '***') @@ -168,7 +168,7 @@ corrMatrixClass <- R6::R6Class( else if (result$rp < .05) matrix$addSymbol(rowNo=i, paste0(colVarName, '[r]'), '*') - if ( ! self$options$spearman) + if ( ! self$options$spearman || is.na(result$rhop)) {} # do nothing else if (result$rhop < .001) matrix$addSymbol(rowNo=i, paste0(colVarName, '[rho]'), '***') @@ -177,7 +177,7 @@ corrMatrixClass <- R6::R6Class( else if (result$rhop < .05) matrix$addSymbol(rowNo=i, paste0(colVarName, '[rho]'), '*') - if ( ! self$options$kendall) + if ( ! self$options$kendall || is.na(result$taup)) {} # do nothing else if (result$taup < .001) matrix$addSymbol(rowNo=i, paste0(colVarName, '[tau]'), '***') diff --git a/R/corrpart.b.R b/R/corrpart.b.R index 889e6e37..d2cd2ffb 100644 --- a/R/corrpart.b.R +++ b/R/corrpart.b.R @@ -192,22 +192,26 @@ corrPartClass <- R6::R6Class( matrix$setRow(rowNo=i, values) if (flag) { - if (result$rp < .001) + if (is.na(result$rp)) + {} # do nothing + else if (result$rp < .001) matrix$addSymbol(rowNo=i, paste0(colVarName, '[r]'), '***') else if (result$rp < .01) matrix$addSymbol(rowNo=i, paste0(colVarName, '[r]'), '**') else if (result$rp < .05) matrix$addSymbol(rowNo=i, paste0(colVarName, '[r]'), '*') - if (result$rhop < .001) + if (is.na(result$rhop)) + {} # do nothing + else if (result$rhop < .001) matrix$addSymbol(rowNo=i, paste0(colVarName, '[rho]'), '***') else if (result$rhop < .01) matrix$addSymbol(rowNo=i, paste0(colVarName, '[rho]'), '**') else if (result$rhop < .05) matrix$addSymbol(rowNo=i, paste0(colVarName, '[rho]'), '*') - if ( ! self$options$kendall) - {} # do nothing + if ( ! self$options$kendall || is.na(result$taup)) + {} # do nothing else if (result$taup < .001) matrix$addSymbol(rowNo=i, paste0(colVarName, '[tau]'), '***') else if (result$taup < .01) diff --git a/tests/testthat/testcorrmatrix.R b/tests/testthat/testcorrmatrix.R index dc09462d..69067c8d 100644 --- a/tests/testthat/testcorrmatrix.R +++ b/tests/testthat/testcorrmatrix.R @@ -123,3 +123,32 @@ testthat::test_that('All options in the corrMatrix work (sunny)', { testthat::expect_equal(13, as.numeric(corTable$getCell(rowKey="var 3", "var 1[n]")$value)) testthat::expect_equal(11, as.numeric(corTable$getCell(rowKey="var 3", "var 2[n]")$value)) }) + +testthat::test_that('corrMatrix does not error on NaN p-values with flagging enabled', { + # GIVEN a variable paired with a constant column (zero variance), which + # makes cor.test return an NA p-value + df <- data.frame( + `var 1` = c(8, 51, 2, 74, 1, 91, 5, 25, 1, 59, 5, 32, 7), + `constant` = rep(3, 13), + check.names = FALSE + ) + + # WHEN we run a correlation with significance flagging enabled + # THEN the analysis should not error (the flag logic used to do + # `if (p < .001)` on NA and crash with "missing value where TRUE/FALSE needed") + testthat::expect_error( + r <- jmv::corrMatrix( + data = df, + vars = c("var 1", "constant"), + pearson = TRUE, + spearman = TRUE, + kendall = TRUE, + flag = TRUE + ), + regexp = NA + ) + + # AND the degenerate correlation should be reported as a missing value + corTable <- r$matrix + testthat::expect_true(is.na(as.numeric(corTable$getCell(rowKey="constant", "var 1[rho]")$value))) +})