From 9dd14c23ce2dedc292a35b8023d22bebbff46ad2 Mon Sep 17 00:00:00 2001 From: Dan Gerlanc Date: Sun, 10 Nov 2024 12:36:16 -0500 Subject: [PATCH] Fix incorrect calculation of Pearson's r Previously, bootES calculated Pearson's r incorrectly if the `contrasts` argument to `bootES` was not lexicographically sorted. The error arose from a bug in the reordering of the `lambdas` at line 39 in `pearsonsr.R`. --- R/pearsonsr.R | 4 ++-- tests/testthat/test_calcPearsonsR.R | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/R/pearsonsr.R b/R/pearsonsr.R index a19236d..f1705a6 100644 --- a/R/pearsonsr.R +++ b/R/pearsonsr.R @@ -18,7 +18,7 @@ calcPearsonsR <- function(vals, freq, grps, lambdas) { ## This function is meant to be passed as the 'statistic' argument ## to the 'boot' function. 'freq' should be a frequency vector of ## the type returned by 'boot' - + ## Get the integer indices of the different groups. grp.idx = split(seq_along(vals), grps, drop=TRUE) grp.nms = names(grp.idx) @@ -36,7 +36,7 @@ calcPearsonsR <- function(vals, freq, grps, lambdas) { } ## Put means and lambdas in the same order - lambdas = lambdas[match(names(lambdas), grp.nms)] + lambdas = lambdas[grp.nms] C = sum(lambdas * means) # contrast sumWts = sum(lambdas^2 / ns) # sum of the weights SSw = sum(ss) diff --git a/tests/testthat/test_calcPearsonsR.R b/tests/testthat/test_calcPearsonsR.R index 2a4e52e..351c4fa 100644 --- a/tests/testthat/test_calcPearsonsR.R +++ b/tests/testthat/test_calcPearsonsR.R @@ -24,3 +24,25 @@ test_that("calcPearsonsR produces known result", { r.res = bootES:::calcPearsonsR(threeGpsVec, freq=rep(1, length(threeGpsVec)), grps=grpLabels3, lambdas=lambdas3) expect_equal(truth, r.res, tolerance=1e-4) }) + +test_that("produces same result with non-lexicographic contrast sorting", { + dat = data.frame(cond=rep(c("A", "B", "C"), each=10), score=1:30) + + truth = 0.926 + res_1 = bootES( + dat, data.col="score", group.col="cond", contrast=c(A=-1, B=0.5, C=0.5), + effect.type="r")$t0 + expect_equal(truth, res_1, tolerance=1e-3) + + + res_2 = bootES( + dat, data.col="score", group.col="cond", contrast=c(B=0.5, C=0.5, A=-1), + effect.type="r")$t0 + expect_equal(truth, res_2, tolerance=1e-3) + + + res_3 = bootES( + dat, data.col="score", group.col="cond", contrast=c(C=0.5, A=-1, B=0.5), + effect.type="r")$t0 + expect_equal(truth, res_3, tolerance=1e-3) +})