In this blog post, I will go over a very helpful hydrologic package in R that can make your hydro-life much easier. The package is called HydroGOF, and it can be used to make different types of plots, including mean monthly, annual, and seasonal plots for streamflow, rainfall, temperature, and other environmental variables. You can also use HydroGOF to compare your simulated flow to observed flow and calculate various performance metrics such as Nash-Sutcliffe efficiency. Indeed, the *GOF* part of HydroGOF stands for “goodness of fit.” More information about HydroGOF and its applications for hydrologists can be found here. Also, you can find a more comprehensive list of hydrologic R packages from this water programming blog post.

### 1- **Library and Data Preparation**

HydroGOF accepts R data frames and R zoo objects. If you are not familiar with R’s zoo objects, you can find more information at here. In this tutorial, I use HydroGOF’s test case streamflow data, which are in zoo format. Here is how you can install and load zoo and HydroGOF.

```
install.packages("zoo")
library(zoo)
install.packages("hydroGOF ")
library(hydroGOF)
```

After you load the package, you need to activate your streamflow data. This is how you do so.

```
# Activate HydroGOF's streamflow data
data(EgaEnEstellaQts)
```

Now, let’s take a look at the first few lines of our streamflow data.

```
head(EgaEnEstellaQts)
```

Note that the first column is date and that the second column is streamflow data; the unit is m3/sec. Also, keep in mind that you can use zoo to manipulate the temporal regime of your data. For example, you can convert your daily data to monthly or annual.

### 2- **Streamflow Plots**

Now, let’s use HydroGOF to visualize our observed streamflow data. You can use the following commands to generate some nice figures that will help you explore the overall regime of the streamflow data.

```
obs<-EgaEnEstellaQts
hydroplot(x = obs,var.type = "FLOW", var.unit = "m3/s", ptype = "ts+boxplot", FUN=mean)
# Note that "hydroplot" command is very flexible and there are many
# options that users can add or remove
```

### 3- **Generate Simulated Dataset**

For this tutorial, I have written the following function, which uses observed streamflow to generate a very simple estimation of daily streamflow. Basically, the function takes the observed data and calculates daily average flow for each day of the year. Then, the function repeats the one-year data as many times as you need, which for our case, is ten times to match the observed flow.

```
simple_predictor<-function(obs){
# This function generates a very simple prediction of streamflow
# based on observed streamflow inputs
DOY<-data.frame(matrix(ncol =1, nrow = length(EgaEnEstellaQts)))
for (i_day in 1:length(EgaEnEstellaQts)){
DOY[i_day,]=as.numeric(strftime(index(EgaEnEstellaQts[i_day]), format = "%j"))
}
# Create a 365 day timeseries of average daily streamflow.
m_inflow_obs<-as.numeric(aggregate(obs[,1], by=list(DOY[,1]), mean))
simplest_predictor<-data.frame(matrix(ncol=3, nrow =length(obs )))
names(simplest_predictor)<-c("Date", "Observed", "Predicted")
simplest_predictor[,1]=index(obs)
simplest_predictor[,2]=coredata(obs)
for (i_d in 1:length(obs)){
# Iterates average daily flow for entire simulation period
simplest_predictor[i_d,3]=m_inflow_obs[DOY[i_d,1]]
}
# Convert to zoo format
dt_z<-read.zoo(simplest_predictor, format="%Y-%m-%d")
return(dt_z)
}
```

After loading the function, you can use the following to create your combined observed and simulated data frame.

```
# Here we just call the function
obs_sim<-simple_predictor(obs)
```

### 4- **Hydrologic Error Metrics Using HydroGOF**

There are twenty error metrics in HydroGOF—for example, mean error (ME), mean absolute error (MAE), root mean square error (RMSE), normalized root mean square error (NRMSE), percent bias (PBIAS), ratio of standard deviations (Rsd), and Nash-Sutcliffe efficiency (NSE). You can find more information about them here. You can use the following commands to calculate specific error metrics.

```
# Nash-Sutcliffe Efficiency
NSE(sim=obs_sim$Predicted, obs=obs_sim$Observed)
# Root Mean Squared Error
rmse(sim=obs_sim$Predicted, obs=obs_sim$Observed)
# Mean Error
me(sim=obs_sim$Predicted, obs=obs_sim$Observed)
```

You can also use this cool command to see all of the available error metrics in HydroGOF.

```
gof(sim=obs_sim$Predicted, obs=obs_sim$Observed)
```

### 5- **Visualizing Observed and Simulated Streamflow**

Here is the most interesting part: you can plot observed and simulated on the same graph and add all error metrics to the plot.

```
ggof(sim=obs_sim$Predicted, obs=obs_sim$Observed, ftype="dm", gofs = c("NSE", "rNSE", "ME", "MSE", "d", "RMSE", "PBIAS"), FUN=mean)
# You should explore different options that you can add to this figure.
# For example you can choose which error metrics you want to display, etc
```