Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2559a3a
Add unit tests for benchmarking metrics and document metric_R2 fallback
tanmaydimriGSOC Mar 19, 2026
08e9e7b
Update metric_R2.Rd to match roxygen documentation
tanmaydimriGSOC Mar 31, 2026
ce4d354
fix: address review comments on metric_R2 and test logic
ayushman1210 Jun 30, 2026
a2df664
Merge branch 'develop' into pr_3888
ayushman1210 Jun 30, 2026
2bc3d33
Merge branch 'develop' into pr_3888
ayushman1210 Jul 3, 2026
8e61801
Merge branch 'develop' into pr_3888
dlebauer Jul 13, 2026
122831f
Update modules/benchmark/R/metric_R2.R
ayushman1210 Jul 14, 2026
4b9a3e3
Update modules/benchmark/R/metric_R2.R
ayushman1210 Jul 14, 2026
3b719d3
updated the pr as per the akash suggestion
ayushman1210 Jul 14, 2026
0c9cbee
Merge branch 'develop' into pr_3888
ayushman1210 Jul 20, 2026
905477b
regenrated the docs by running devtools::document()
ayushman1210 Jul 24, 2026
6ed1570
Merge branch 'develop' into pr_3888
ayushman1210 Jul 24, 2026
f14de15
style: regenerate package documentation
ayushman1210 Jul 24, 2026
21eed46
Merge branch 'develop' into pr_3888
dlebauer Jul 30, 2026
c13715c
Merge branch 'develop' into pr_3888
ayushman1210 Aug 4, 2026
ba1a489
Merge branch 'develop' into pr_3888
ayushman1210 Aug 7, 2026
7c86a1d
Merge branch 'develop' into pr_3888
dlebauer Aug 14, 2026
b50a74d
Merge branch 'develop' into pr_3888
ayushman1210 Aug 15, 2026
c57e496
Merge branch 'develop' into pr_3888
dlebauer Aug 18, 2026
92deb97
Revert changes in models/basgra/man, models/sipnet/man, and modules/rtm
ayushman1210 Aug 18, 2026
93a48a0
Revert changes in modules/benchmark/man
ayushman1210 Aug 18, 2026
ec844e3
regenerate metric_R2 man page to match source
divine7022 Aug 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 13 additions & 16 deletions modules/benchmark/R/metric_R2.R
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
##' @name metric_R2
##' @title Coefficient of Determination (R2)
##' @title Squared Pearson Correlation (R2)
##' @export
##' @param metric_dat dataframe
##' @param metric_dat dataframe with columns \code{model} and \code{obvs}
##' @param ... ignored
##'
##' @details
Comment thread
ayushman1210 marked this conversation as resolved.
##' Computes R-squared using the correlation-based formula:
##' \eqn{R^2 = \left(\frac{\sum(obs - \bar{obs})(mod - \bar{mod})}
##' {\sqrt{\sum(obs - \bar{obs})^2} \cdot \sqrt{\sum(mod - \bar{mod})^2}}\right)^2}
##'
##' Note: Because this is a correlation-based R2, it is invariant to bias and slope.
##' A model that is perfectly correlated but biased (e.g., model = obs + 100) will still
##' score 1. This is distinct from variance explained or Nash-Sutcliffe Efficiency (NSE).
##'
##' @author Betsy Cowdery

metric_R2 <- function(metric_dat, ...) {
PEcAn.logger::logger.info("Metric: Coefficient of Determination (R2)")
numer <- sum((metric_dat$obvs - mean(metric_dat$obvs)) * (metric_dat$model - mean(metric_dat$model)))
denom <- sqrt(sum((metric_dat$obvs - mean(metric_dat$obvs)) ^ 2)) * sqrt(sum((metric_dat$model - mean(metric_dat$model)) ^ 2))

out <- (numer / denom) ^ 2

if(is.na(out)){
fit <- stats::lm(metric_dat$model ~ metric_dat$obvs)
out <- summary(fit)$r.squared
}

return(out)

PEcAn.logger::logger.info("Metric: Squared Pearson Correlation (R2)")
stats::cor(metric_dat$model, metric_dat$obvs, use = "pairwise.complete.obs")^2
} # metric_R2
15 changes: 12 additions & 3 deletions modules/benchmark/man/metric_R2.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 43 additions & 0 deletions modules/benchmark/tests/testthat/test-metrics.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
test_that("metric_RMSE returns 0 for perfect predictions", {
dat <- data.frame(model = c(1, 2, 3), obvs = c(1, 2, 3))
expect_equal(metric_RMSE(dat), 0)
})

test_that("metric_RMSE handles NA values", {
dat <- data.frame(model = c(1, NA, 3), obvs = c(1, 2, 3))
expect_equal(metric_RMSE(dat), 0)
})

test_that("metric_RMSE returns numeric", {
dat <- data.frame(model = c(2, 4), obvs = c(1, 3))
expect_equal(metric_RMSE(dat), 1)
})

test_that("metric_MAE returns 0 for perfect predictions", {
dat <- data.frame(model = c(1, 2, 3), obvs = c(1, 2, 3))
expect_equal(metric_MAE(dat), 0)
})

test_that("metric_MAE returns correct value", {
dat <- data.frame(model = c(3, 3), obvs = c(1, 1))
expect_equal(metric_MAE(dat), 2)
})

test_that("metric_cor returns 1 for perfect linear relationship", {
dat <- data.frame(model = c(1, 2, 3), obvs = c(1, 2, 3))
expect_equal(metric_cor(dat), 1)
})

test_that("metric_R2 returns 1 for perfect predictions", {
dat <- data.frame(model = c(1, 2, 3), obvs = c(1, 2, 3))
expect_equal(metric_R2(dat), 1)
})

test_that("metric_R2 returns NA for constant model output", {
dat <- data.frame(model = c(2, 2, 2), obvs = c(1, 2, 3))
expect_warning(
result <- metric_R2(dat),
"the standard deviation is zero"
)
expect_equal(result, NA_real_)
})
Loading