Freeze-thaw cycle trends for Waterville, ME (USA)

Author

Manuel Gimond

The inspiration for this brief analysis is to validate an observation made in central Maine (USA) whereby occurrences of freeze-thaw events seem to have increased over the past several decades. Freeze-thaw events have an impact on road infrastructures by increasing the likelihood of frost heaving. It also impacts maple syrup producers who time their tapping season based on freeze-thaw events.

Dataset

Code
library(dplyr)
library(tidyr)
library(lubridate)
library(ggplot2)

# A few variables
nn <- 4 # Number of continuous hours
na_hours <- 96

# Load the data
dat <- readRDS("met1991_2023.Rds")

# Identify continuous hourly gaps
dates.all <- seq(min(dat$Date_EST), max(dat$Date_EST), by = "1 hour")
dat_complete <- dat %>% 
  select(Date_EST, Temp) %>% 
  complete(Date_EST = dates.all,
           fill = list(Temp = NA)) %>% 
  mutate(year = year(Date_EST), 
         month = month(Date_EST, label = TRUE),
         day = day(Date_EST),
         hour = hour(Date_EST)) 

# Identify all months with at least 4 days worth of missing values
months_na <- dat_complete %>% 
  group_by(year, month) %>% 
  summarise(missing = sum(is.na(Temp))) %>% 
  filter(missing > na_hours)

# Count the number of times temperatures have flipped
# (4 continuous hours below freezing followed by 4 continuous
# hours above freezing, etc ...)
dat_flip <- dat_complete %>% 
  mutate(bin = ifelse(Temp >= 32, 1, 0)) %>% 
  group_by(year , month ) %>% 
  reframe(rl = list(rle(bin)),
            bin = rl[[1]]$values,
            cnt = rl[[1]]$lengths) %>% 
  ungroup() %>% 
  select(-rl) %>% 
  mutate(cnt_lag = lag(cnt),
         bin_lag = lag(bin),
         flip = case_when(cnt >= nn & cnt_lag >= nn & bin != bin_lag ~ TRUE,
                          TRUE ~ FALSE)) %>% 
  group_by(year, month) %>% 
  summarize(flip= sum(flip)) %>% 
  filter(flip !=0)

# Remove all months with at least na_hours worth of missing values
dat_flip_no_na <- dat_flip %>% 
  anti_join(months_na, by=c("year","month"))

The meteorological data are recorded at the Robert LaFleur airport in Waterville, Maine (USA). Its WGS84 coordinate location is 44.5332°N and 69.6755°W. The data have been tabulated in a separate repo. For this analysis, a freeze-thaw event is defined as one where a temperature above or below 32°F for a continuous period of at least 4 hours is followed by a period of 4 or more hours where the temperature swings to the other side of the 32°F freezing threshold.

The freeze-thaw counts are aggregated by month and year. If any one month has more than 96 hours worth of missing temperature values, that month is flagged and removed from all subsequent analyses.

Results

Heat map of freeze-thaw frequencies

The following figure generates a heat map of freeze-thaw counts by month and year. The light grey boxes show month/years for which more than 96 hours worth of data were missing for that month.

Code
ggplot() + 
  geom_tile(data = months_na, aes(x=month,y=year, fill = "Count"), 
            fill = "grey", alpha=0.3) +
  geom_tile(data = dat_flip_no_na, aes(x=month, y = year, fill = flip)) +
  scale_fill_binned(low = "yellow", high = "red", name = "count",
                    breaks =  as.numeric(quantile(dat_flip_no_na$flip, probs = 1:10/10))) +
  theme_minimal() +
  ggtitle("Freeze-thaw cycle count") +
  theme(plot.title = element_text(color = "grey40"))