Skip to content

Commit bdb0108

Browse files
committed
update
1 parent 5e73572 commit bdb0108

File tree

9 files changed

+238
-7
lines changed

9 files changed

+238
-7
lines changed

DESCRIPTION

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
Package: delayedflow
2-
Title: What the Package Does (One Line, Title Case)
3-
Version: 0.0.0.9000
2+
Title: Delayed flow separation to estimate multiple delayed streamflow contributions.
3+
Version: 0.1
44
Authors@R:
5-
person(given = "First",
6-
family = "Last",
5+
person(given = "Michael",
6+
family = "Stoelzle",
77
role = c("aut", "cre"),
8-
email = "first.last@example.com",
9-
comment = c(ORCID = "YOUR-ORCID-ID"))
10-
Description: What the package does (one paragraph).
8+
email = "michael.stoelzle@hydro.uni-freiburg.de",
9+
comment = c(ORCID = "0000-0003-0021-4351"))
10+
Description: Delayed flow separation (DFS) is an extentions of baseflow separation where
11+
hydrographs are separated in quick- and baseflow. DFS deconvolute the hydrograph
12+
into multiple delayed streamflow contributions.
1113
License: `use_mit_license()`, `use_gpl3_license()` or friends to
1214
pick a license
1315
Encoding: UTF-8

NAMESPACE

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# Generated by roxygen2: do not edit by hand
22

3+
export(find_bp)
4+
export(mae)
5+
export(rmse)

R/find_bps.R

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
#' Find breakpoints in DFI curve
2+
#'
3+
#' @param dfi numeric, DFI values between 1 and 0
4+
#' @param n_bp numeric, number of breakpoints
5+
#' @param min_gp_gap numeric, smallest interval between two breakpoints
6+
#' @param filter_min numeric, filter_max+1 is minimum potential breakpoint estimate
7+
#' @param filter_max numeric, filter_max-1 is maximum potential breakpoint estimate
8+
#' @param dfi_check logical, if TRUE DFI values are converted to be continuously descreasing with cummin()
9+
#' @param print logical, if TRUE calculation of breakpoints are printed
10+
#' @param plotting logical, if TRUE the DFI curve and piecewise linear segments are plotted
11+
#'
12+
#' @return Returns a list.
13+
#' \item{breakpoints}{estimates for the n breakpoints with names "bp_x"}
14+
#' \item{bias}{value of the objective function OF = 1/2 RMSE + 1/2 MAE"}
15+
#' \item{rel_contr}{Relative streamflow contributions between \code{filter_min}, the breakpoints and \code{filter_max}}
16+
17+
#'
18+
#' @export
19+
#' @examples
20+
#' # use dfi_example as an DFI vector with 121 values
21+
#' find_bp(dfi_example, n_bp = 2, filter_max = 90, dfi_check = FALSE)
22+
find_bp <- function(dfi,
23+
n_bp = 3,
24+
min_gp_gap = 5,
25+
filter_min = 0,
26+
filter_max = 120,
27+
dfi_check = TRUE,
28+
print = FALSE,
29+
plotting = FALSE) {
30+
31+
len <- length(dfi)
32+
33+
if(any(is.na(dfi))) {
34+
stop("DFI vector has NA values.")
35+
}
36+
if(len <= filter_max) {
37+
stop("DFI vector is too short or reduce filter_max, i.e. length(dfi) > filter_max")
38+
}
39+
if(filter_max < filter_min + 5){
40+
stop("Adjust \"filter_min\" or \"filter_max\"!" )
41+
}
42+
if(min_gp_gap <= 2) {
43+
stop("\"min_gap\" is too small, should be 3 or larger.")
44+
}
45+
if(!n_bp %in% 1:3) {
46+
stop("Number of breakpoints must be 1,2 or 3")
47+
}
48+
if(dfi_check) {
49+
dfi <- cummin(dfi)
50+
}
51+
52+
# breakpoint grid
53+
len <- length(dfi)
54+
pot_bp <- (filter_min+1):(filter_max-1)
55+
bp_grid <- expand.grid(rep(list(pot_bp),n_bp))
56+
names(bp_grid) <- paste0("bp_",1:n_bp)
57+
58+
# create breakpoint combinations
59+
if (n_bp == 1) bp_grid <- as.matrix(pot_bp)
60+
61+
if (n_bp == 2) {
62+
bp_grid <- subset(bp_grid, (bp_1 < bp_2 & bp_1 + min_gp_gap <= bp_2))
63+
bp_grid <- as.matrix(bp_grid, rownames.force = FALSE)
64+
}
65+
if (n_bp == 3) {
66+
bp_grid <- subset(bp_grid, (bp_1 < bp_2 &
67+
bp_1 + min_gp_gap <= bp_2 &
68+
bp_2 < bp_3 &
69+
bp_2 + min_gp_gap <= bp_3 ))
70+
bp_grid <- as.matrix(bp_grid, rownames.force = FALSE)
71+
}
72+
73+
# fit breakpoint model
74+
dummy <- 999
75+
best_bps <- NULL
76+
cat("Calculating breakpoints . . . \n")
77+
for (i in 1:nrow(bp_grid)) {
78+
79+
bps <- bp_grid[i,]
80+
fit <- approx(x = c(0,bps,len-1), dfi[c(1,bps+1,len)], xout = 0:(len-1))$y
81+
OF <- rmse(fit,dfi) * 0.50 + mae(fit, dfi) * 0.50
82+
if(OF < dummy){
83+
if(print) cat(i,bps,OF,"\n")
84+
dummy <- OF
85+
best_fit <- fit
86+
result <- list(breakpoints = bps, bias = dummy )
87+
}
88+
89+
if(i %in% floor(nrow(bp_grid) * 1:10/10)) cat(paste0(round(i/nrow(bp_grid)*100,0)),"% ")
90+
91+
}
92+
cat("\nBreakpoints ready . . . \n\n\n")
93+
94+
result$rel_contr <- -diff(c(dfi[c(1, result$breakpoints+1)], 0))
95+
96+
if (plotting){
97+
plot(0:120, dfi,
98+
type = "l",
99+
col = "blue",
100+
ylim = c(0,1),
101+
ylab = "DFI",
102+
xlab = "Filter width N")
103+
points(0:120, best_fit, type = "l", col = "red")
104+
abline(v=result$breakpoints)
105+
}
106+
107+
108+
return(result)
109+
}

R/mae.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#' Mean Absolute Error
2+
#'
3+
#' @param sim numeric, simulated values
4+
#' @param obs numeric, observed values
5+
#'
6+
#' @return Mean absolute error between sim and obs.
7+
#' @export
8+
#'
9+
#' @examples
10+
#' mae(c(1:3), (2:4))
11+
mae = function(sim, obs){
12+
mean(abs(sim - obs))
13+
}

R/rmse.R

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#' Root Mean Square Error
2+
#'
3+
#' @param sim numeric with simulated values
4+
#' @param obs numeric with observed values
5+
#'
6+
#' @return Root mean square error (rmse) between sim and obs.
7+
#' @export
8+
#'
9+
#' @examples
10+
#' rmse(c(1:3), c(1, 3, 5))
11+
rmse = function(sim, obs){
12+
sqrt(mean((sim - obs)^2))
13+
}

data/dfi_example.RData

488 Bytes
Binary file not shown.

man/find_bp.Rd

Lines changed: 47 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/mae.Rd

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/rmse.Rd

Lines changed: 22 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)