Calculating Agrometeorological Variables for Crops

Quick Start

You can install the development version of cropgrowdays from GitLab with:

## if you don't have 'remotes' installed, automatically install it
if (!require("remotes")) {
  install.packages("remotes", repos = "http://cran.rstudio.com/")
  library("remotes")
}
install_gitlab("petebaker/cropgrowdays", build_vignettes = TRUE)

Overview

The cropgrowdays package provides functions to calculate agrometeorological quantities of interest for modelling crop data. Currently, functions are provided for calculating growing degree days, stress days, cumulative and daily means of weather data. Australian meteorological data can be obtained from Queensland Government’s Department of Environment and Science (DES) website. In addition, functions are provided to convert days of the year to dates, and vice-versa.

We recommend using the cropgrowdays package in conjunction with the tidyverse and lubridate packages.

suppressMessages(library(tidyverse))
suppressMessages(library(lubridate))
library(cropgrowdays)

Note that if you are not familiar with these packages then, in order to see which functions are provided and which functions conflict with other packages, initially it may best not to suppress messages using suppressMessages.

Obtaining Australian meteorological data

The boonah dataset was obtained from the Queensland Government DES longpaddock website https://www.longpaddock.qld.gov.au using the get_silodata function. Please see getting-weather-data vignette for details.

The data obtained is

## weather data object
print(boonah, n=5)
#: # A tibble: 517 x 10
#:    year   day  radn  maxt  mint  rain  evap    vp   code date_met  
#:   <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <int> <date>    
#: 1  2019     1  26.2  33.9  16.3     0   7.8  20.6 222222 2019-01-01
#: 2  2019     2  28.2  33.4  17.6     0   7.7  19.8 222222 2019-01-02
#: 3  2019     3  20.5  32.8  16.7     0   6.8  21.9 222222 2019-01-03
#: 4  2019     4  23    32.5  21       2   7.7  22   222222 2019-01-04
#: 5  2019     5  27    33.6  16.8     0   6    21.8 222222 2019-01-05
#: # … with 512 more rows

Agrometeorological calculations

The crop dataset consists of dates for a hypothetical crop data set which would also usually contain agronomic traits of interest such as yield, dry matter yield and so on. Each row of data contains sowing, flowering and harvest dates for a typical field or farm in Queensland, Australia.

## crop data object
print(crop, n=5)
#: # A tibble: 10 x 3
#:   sowing_date flower_date harvest_date
#:   <date>      <date>      <date>      
#: 1 2019-08-25  2019-10-14  2019-11-03  
#: 2 2019-09-20  2019-11-09  2019-11-29  
#: 3 2019-12-18  2020-02-06  2020-02-26  
#: 4 2020-01-15  2020-03-06  2020-03-26  
#: 5 2020-02-15  2020-04-06  2020-04-26  
#: # … with 5 more rows

Example R syntax is provided for calculating daily mean radiation, total rainfall, growing degree dates and the number of stress days between two dates. Alternatively, a number of days before or after a certain date may be specified.

Growing Degree Days

The growing_degree_days function calculates the sum of degree days for each day \(i = 1 \ldots n\). The growing degree days \(GDD\) summed over \(n\) days are

\[GDD = \sum_i^n (Tmax_{i} + Tmin_{i}) / 2 - T_{base}\]

during specified dates for a tibble/data frame of daily weather data. For each day \(i\), the maximum temperature is \(Tmax_{i}\) and minimum is \(Tmin_{i}\). Note that the maximum temperature \(Tmax\) is capped at maxt_cap degrees when calculating average temperature. The defaults are \(T_{base} = 5^{\circ}C\) and \(Tmax\) is capped at \(Tmax_{cap} = 30^{\circ}C\). (See McMaster and Wilhelm (1997) or https://farmwest.com/climate/calculator-information/gdd/ (Anon 2021))

The gdd functions in the pollen package (Nowosad 2019) and in agroclim (Serrano-Notivoli 2020) also calculate growing degree days. While these functions do not allow for a fixed number of days, and in the case of agroclim::gdd assume a more limited growing season since the function appears to be tailored to grapes, further variations on the formula above as outlined in Baskerville and Emin (1969) are available.

To calculate the growing degree days at Boonah between flowering and harvest use:

## Growing Degree Days between two dates
crop$flower_date[4]     # flowering date for 4th field or farm in 'crop'
#: [1] "2020-03-06"
crop$harvest_date[4]    # harvest date for 4th field or farm in 'crop'
#: [1] "2020-03-26"
growing_degree_days(boonah, startdate = crop$flower_date[4],
                         enddate = crop$harvest_date[4]) #, monitor = TRUE)
#: [1] 359.05

Stress days

stress_days_over calculates the number of days when the maximum temperature exceeded a base line stress_temp during specified dates for a tibble/data frame of daily weather data. The default stress_temp is set at \(30^{\circ}C\).

To calculate the number of stress days at Boonah between flowering and harvest, use:

## Stress days  between two dates
stress_days_over(boonah, startdate = crop$flower_date[4],
                 enddate = crop$harvest_date[4]) # , monitor = TRUE)
#: [1] 4

Cumulative calculations

cumulative calculates the sum total of daily values between two dates from a tibble/data frame of daily weather data. Typically this is used for solar radiation or rainfall.

To calculate the total rainfall at Boonah between flowering and harvest, use:

## cumulative rainfall between two dates (flowering and harvest)
cumulative(boonah, var = rain, startdate = crop$flower_date[4],
           enddate = crop$harvest_date[4])
#: [1] 22.8

Daily means

daily_mean calculates the daily average of a variable between two dates from a tibble/data frame of daily weather data. Typically this would be for temperature, rainfall or solar radiation.

To calculate daily mean radiation in the 3 day period from day of flowering onwards (which also includes day of flowering), use:

## daily mean radiation for the three days ending on crop$flower_date[4]
crop$flower_date[4] # a particular flowering date
#: [1] "2020-03-06"
daily_mean(boonah, enddate = crop$flower_date[4], ndays = 3,
           monitor = TRUE)
#: # A tibble: 3 x 2
#:   date_met    radn
#:   <date>     <dbl>
#: 1 2020-03-04  10.7
#: 2 2020-03-05  11.8
#: 3 2020-03-06  11
#: [1] 11.16667

Extracting weather data from a tibble or dataframe

To extract column(s) from a tibble/data frame of daily weather data between two specified dates we use weather_extract. Either specify the start and end dates or specify one of these dates and also the number of days after or before, respectively.

## Extract rainfall data using the %>% pipe operator
boonah %>%
  weather_extract(rain, date = date_met, startdate = ymd("2019-08-16"),
                  enddate = ymd("2019-08-21"))
#: # A tibble: 6 x 2
#:   date_met    rain
#:   <date>     <dbl>
#: 1 2019-08-16     0
#: 2 2019-08-17     0
#: 3 2019-08-18     0
#: 4 2019-08-19     0
#: 5 2019-08-20     0
#: 6 2019-08-21     0

Adding agrometeorological variables to dataframes

We can add columns using weather calculations to the crop tibble using the tidyverse functions map_dbl if for one varying date and map_dbl2 for varying start and end dates. For more than two varying parameters we can use pmap. These functions are from the purrr library.

To add growing degree days 7 days post sowing and the number of stress days above \(30^\circ C\) from flowering to harvest we employ:

## Growing degree and stress days
crop2 <- crop %>%
  mutate(gddays_post_sow_7d =
           map_dbl(sowing_date, function(x)
             growing_degree_days(boonah, startdate = x, ndays = 7)),
         stressdays_flower_harvest =
           map2_dbl(flower_date, harvest_date, function(x, y)
             stress_days_over(boonah, startdate = x, enddate = y)))
print(crop2, n=5)
#: # A tibble: 10 x 5
#:   sowing_date flower_date harvest_date gddays_post_sow_7d stressdays_flower_har…
#:   <date>      <date>      <date>                    <dbl>                  <dbl>
#: 1 2019-08-25  2019-10-14  2019-11-03                 76.4                     10
#: 2 2019-09-20  2019-11-09  2019-11-29                104.                      20
#: 3 2019-12-18  2020-02-06  2020-02-26                132.                      11
#: 4 2020-01-15  2020-03-06  2020-03-26                142.                       4
#: 5 2020-02-15  2020-04-06  2020-04-26                145.                       5
#: # … with 5 more rows

Similarly, to add total rainfall for the 7 days post sowing and the mean daily radiation from flowering to harvest we use:

## Totals and daily means
crop3 <- crop %>%
  mutate(totalrain_post_sow_7d =
           map_dbl(sowing_date, function(x)
             cumulative(boonah, var = rain, startdate = x, ndays = 7)),
         meanrad_flower_harvest =
           map2_dbl(flower_date, harvest_date, function(x, y)
             daily_mean(boonah, var = radn, startdate = x, enddate = y)))
print(crop3, n=5)
#: # A tibble: 10 x 5
#:   sowing_date flower_date harvest_date totalrain_post_sow_… meanrad_flower_harv…
#:   <date>      <date>      <date>                      <dbl>                <dbl>
#: 1 2019-08-25  2019-10-14  2019-11-03                   10.5                 22.9
#: 2 2019-09-20  2019-11-09  2019-11-29                    0                   25.5
#: 3 2019-12-18  2020-02-06  2020-02-26                    0                   16.5
#: 4 2020-01-15  2020-03-06  2020-03-26                   88.4                 15.5
#: 5 2020-02-15  2020-04-06  2020-04-26                   20.7                 16.6
#: # … with 5 more rows

Day of year calculations

When modelling crops, agronomists typically specify dates as the day of year. Several functions are available for day of year calculations and converting these back to dates. In R, dates, times and timezone data are easily manipulated using the lubridate package.

The day_of_year function is used to convert a date to the day of year, which could be based on the calendar year starting on 1 January, the Australian financial year starting on 1 June or an arbitrary starting date.

##  Day of Calendar Year
day_of_year(ymd(c("2020-12-31", "2020-06-01", "2020-01-01")))
#: [1] 366 153   1
day_of_year(ymd(c("2020-12-31", "2020-06-01", "2020-01-01")), return_year = TRUE)
#:   day year
#: 1 366 2020
#: 2 153 2020
#: 3   1 2020

## Day of Financial Year
day_of_year(ymd(c("2020-12-31", "2020-06-01", "2020-01-01")), type = "financial")
#: [1] 214   1 215
day_of_year(ymd(c("2020-12-31", "2020-06-01", "2020-01-01")), type = "fin",
            return_year = TRUE)
#:   day  fin_year
#: 1 214 2020/2021
#: 2   1 2020/2021
#: 3 215 2019/2020

To convert a day of year to a date, use date_from_day_year noting that while the calendar year is the default, we can specify the Australian financial year or an arbitrary starting date.

## Convert day of year to a date
date_from_day_year(21,2021)
#: [1] "2021-01-21"
date_from_day_year(21,2021, type = "fina")
#: [1] "2021-06-21"

Finally, while we can use day_of_year to obtain the day of the current year, if a crop is planted near the end of the year then we way wish to know the day of harvest which will fall in the next year. day_of_harvest provides the day of year in the year of sowing which can be used to calculate other quantities like day of flowering etc. Thus, quantities like the number of days between harvest and sowing are easily calculated taking into account that the crop may grow past the end of the year. Alternatively, these quantities are also easily computed directly on the dates by using the lubridate package. For instance the convenience function cropgrowdays::number_of_days is essentially a call to as.numeric(finish_date - start_date).

## Day of harvest using the first day of the year of sowing as the base day
day_of_year(ymd("2021-01-05"))
#: [1] 5
day_of_harvest(x = ymd("2021-01-05"), sowing = ymd("2020-12-20"))  # > 366
#: [1] 371

References

Baskerville, G. L., and P. Emin. 1969. “Rapid Estimation of Heat Accumulation from Maximum and Minimum Temperatures.” Ecology 50 (3): 514–17. https://doi.org/10.2307/1933912.

McMaster, Gregory S, and W W Wilhelm. 1997. “Growing Degree-Days: One Equation, Two Interpretations.” Agricultural and Forest Meteorology 87 (4): 291–300. https://doi.org/10.1016/S0168-1923(97)00027-0.

Nowosad, Jakub. 2019. Pollen: Analysis of Aerobiological Data. https://CRAN.R-project.org/package=pollen.

Serrano-Notivoli, Roberto. 2020. Agroclim: Climatic Indices for Agriculture. https://CRAN.R-project.org/package=agroclim.