Skip to content
Open
29 changes: 11 additions & 18 deletions modules/benchmark/R/metric_R2.R
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
##' @name metric_R2
##' @title Coefficient of Determination (R2)
##' @title Squared Pearson Correlation (R²)
Comment thread
ayushman1210 marked this conversation as resolved.
Outdated
##' @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}
##'
##' @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)

} # metric_R2
PEcAn.logger::logger.info("Metric: Squared Pearson Correlation (R²)")
Comment thread
ayushman1210 marked this conversation as resolved.
Outdated
stats::cor(metric_dat$model, metric_dat$obvs, use = "pairwise.complete.obs")^2
} # metric_R2
Comment thread
ayushman1210 marked this conversation as resolved.
Outdated
17 changes: 15 additions & 2 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_)
})
Comment thread
ayushman1210 marked this conversation as resolved.
Outdated
Loading