Nothing
# File KGElf.R
# Part of the hydroGOF R package, https://github.com/hzambran/hydroGOF ;
# https://cran.r-project.org/package=hydroGOF
# http://www.rforge.net/hydroGOF/
# Copyright 2017-2024 Mauricio Zambrano-Bigiarini
# Distributed under GPL 2 or later
################################################################################
# 'KGElf': Kling-Gupta Efficiency with focus on low flows #
################################################################################
# Author : Mauricio Zambrano-Bigiarini #
################################################################################
# Started: 2017 #
# Updates: 07-Jul-2022 ; 11-Jul-2022 ;12-Jul-2022 #
# Updates: 15-Jan-2023 ; 16-Jan-2023 #
# 08-May-2024 #
################################################################################
# The optimal value of KGElf is 1
# Ref1:
# Garcia, F., Folton, N. and Oudin, L. (2017).
# Which objective function to calibrate rainfall-runoff models for low-flow index simulations?.
# Hydrological sciences journal, 62(7), pp.1149-1166. doi:10.1080/02626667.2017.1308511
# Ref2:
# Pushpalatha, R., Perrin, C., Le Moine, N. and Andreassian, V. (2012).
# A review of efficiency criteria suitable for evaluating low-flow simulations.
# Journal of Hydrology, 420, pp.171-182. doi: 10.1016/j.jhydrol.2011.11.055
KGElf <- function(sim, obs, ...) UseMethod("KGElf")
# epsilon: By default it is set at one hundredth of the mean flow. See Pushpalatha et al. (2012)
KGElf.default <- function(sim, obs, s=c(1,1,1), na.rm=TRUE,
method=c("2009", "2012", "2021"),
epsilon.type=c("Pushpalatha2012", "otherFactor", "otherValue", "none"),
epsilon.value=NA, ...) {
# Checking 'method' and 'epsilon''
method <- match.arg(method)
epsilon.type <- match.arg(epsilon.type)
# 1) KGE(Q): KGE (2009 or 2012)
kge <- KGE(sim=sim, obs=obs, s=s, na.rm=na.rm, method=method, out.type="single")
# 2) KGE(1/Q): KGE based on Garcia et al. (2017), with epsilon based on Pushpalatha et al. (2012)
new <- preproc(sim=sim, obs=obs, fun=function(x) 1/x,
epsilon.type=epsilon.type, epsilon.value=epsilon.value)
sim.lf <- new[["sim"]]
obs.lf <- new[["obs"]]
kge.lf <- KGE(sim=sim.lf, obs=obs.lf, s=s, na.rm=na.rm, method=method, out.type="single")
# 3) [KGE(Q) + KGE(1/Q)] / 2 : comprehensive goodness-of-fit value
out <- (kge + kge.lf) / 2
return(out)
} # 'KGElf.default' END
################################################################################
# Author : Mauricio Zambrano-Bigiarini #
################################################################################
# Started: 12-Jul-2022 #
# Updates: 15-Jan-2023 ; 16-Jan-2023 #
# 08-May-2024 #
################################################################################
KGElf.matrix <- function(sim, obs, s=c(1,1,1), na.rm=TRUE,
method=c("2009", "2012", "2021"),
epsilon.type=c("Pushpalatha2012", "otherFactor", "otherValue", "none"),
epsilon.value=NA, ...) {
# Checking that 'sim' and 'obs' have the same dimensions
if ( all.equal(dim(sim), dim(obs)) != TRUE )
stop( paste("Invalid argument: dim(sim) != dim(obs) ( [",
paste(dim(sim), collapse=" "), "] != [",
paste(dim(obs), collapse=" "), "] )", sep="") )
# If the user provided a value for 's'
if (!all.equal(s, c(1,1,1)) ) {
if ( length(s) != 3 ) stop("Invalid argument: lenght(s) must be equal to 3 !")
if ( sum(s) != 1 ) stop("Invalid argument: sum(s) must be equal to 1.0 !")
} # IF end
method <- match.arg(method)
epsilon.type <- match.arg(epsilon.type)
ifelse(method=="2012", vr.stg <- "Gamma", vr.stg <- "Alpha")
KGElf <- rep(NA, ncol(obs))
elements <- matrix(NA, nrow=3, ncol=ncol(obs))
rownames(elements) <- c("r", "Beta", vr.stg)
colnames(elements) <- colnames(obs)
out <- sapply(1:ncol(obs), function(i,x,y) {
KGElf[i] <- KGElf.default( x[,i], y[,i], s=s, na.rm=na.rm,
method=method,
epsilon.type=epsilon.type,
epsilon.value=epsilon.value, ... )
}, x=sim, y=obs )
names(out) <- colnames(obs)
return(out)
} # 'KGElf.matrix' end
################################################################################
# Author : Mauricio Zambrano-Bigiarini #
################################################################################
# Started: 12-Jul-2022 #
# Updates: 15-Jan-2023 ; 16-Jan-2023 #
# 08-May-2024 #
################################################################################
KGElf.data.frame <- function(sim, obs, s=c(1,1,1), na.rm=TRUE,
method=c("2009", "2012", "2021"),
epsilon.type=c("Pushpalatha2012", "otherFactor", "otherValue", "none"),
epsilon.value=NA, ...) {
sim <- as.matrix(sim)
obs <- as.matrix(obs)
method <- match.arg(method)
epsilon.type <- match.arg(epsilon.type)
KGElf.matrix(sim, obs, s=s, na.rm=na.rm, method=method,
epsilon.type=epsilon.type, epsilon.value=epsilon.value, ...)
} # 'KGElf.data.frame' end
################################################################################
# Author : Mauricio Zambrano-Bigiarini #
################################################################################
# Started: 12-Jul-2022 #
# Updates: 15-Jan-2023 ; 16-Jan-2023 #
# 08-May-2024 #
################################################################################
KGElf.zoo <- function(sim, obs, s=c(1,1,1), na.rm=TRUE,
method=c("2009", "2012", "2021"),
epsilon.type=c("Pushpalatha2012", "otherFactor", "otherValue", "none"),
epsilon.value=NA, ...) {
sim <- zoo::coredata(sim)
if (is.zoo(obs)) obs <- zoo::coredata(obs)
if (is.matrix(sim) | is.data.frame(sim)) {
KGElf.matrix(sim, obs, s=s, na.rm=na.rm, method=method,
epsilon.type=epsilon.type, epsilon.value=epsilon.value, ...)
} else NextMethod(sim, obs, s=s, na.rm=na.rm, method=method,
epsilon.type=epsilon.type, epsilon.value=epsilon.value, ...)
} # 'KGElf.zoo' end
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.