-
Notifications
You must be signed in to change notification settings - Fork 320
Take over PR #3888: Add unit tests for benchmarking metrics and document metric_R2 #4041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 19 commits
2559a3a
08e9e7b
ce4d354
a2df664
2bc3d33
8e61801
122831f
4b9a3e3
3b719d3
0c9cbee
905477b
6ed1570
f14de15
21eed46
c13715c
ba1a489
7c86a1d
b50a74d
c57e496
92deb97
93a48a0
ec844e3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| 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 | ||
| ##' 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 | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| 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_) | ||
| }) |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Uh oh!
There was an error while loading. Please reload this page.