The aim of this assignment is to examine monthly mean sea level records from tide gauges around Ireland and use these records to calculate trends in sea level around Ireland.
To begin, libraries must be loaded and the working directory set.
library(maps)
library(lubridate)
## Warning: package 'lubridate' was built under R version 3.5.3
##
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
##
## date
library(leaflet)
library(dygraphs)
library(tmap)
## Warning: package 'tmap' was built under R version 3.5.3
library(tmaptools)
## Warning: package 'tmaptools' was built under R version 3.5.3
library(sp)
library(markdown)
library(tidyr)
library(plyr)
##
## Attaching package: 'plyr'
## The following object is masked from 'package:lubridate':
##
## here
## The following object is masked from 'package:maps':
##
## ozone
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:plyr':
##
## arrange, count, desc, failwith, id, mutate, rename, summarise,
## summarize
## The following objects are masked from 'package:lubridate':
##
## intersect, setdiff, union
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(data.table)
## Warning: package 'data.table' was built under R version 3.5.3
##
## Attaching package: 'data.table'
## The following objects are masked from 'package:dplyr':
##
## between, first, last
## The following objects are masked from 'package:lubridate':
##
## hour, isoweek, mday, minute, month, quarter, second, wday,
## week, yday, year
setwd("F:\\MSc\\GY667 Ocean\\Assignment 1")
Initially, the monthly mean sea level data for the 13 National Tide Gauge Network records were loaded into R and examined.
arklow <- read.csv(file.path(getwd(),"arklow_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
arklow <- arklow[c("month","year","h","time")]
ballycotton <- read.csv(file.path(getwd(),"ballycotton_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
ballycotton <- ballycotton[c("month","year","h","time")]
ballyglass <- read.csv(file.path(getwd(),"ballyglass_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
ballyglass <- ballyglass[c("month","year","h","time")]
castletownbere <- read.csv(file.path(getwd(),"castletownbere_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
castletownbere <- castletownbere[c("month","year","h","time")]
dublin <- read.csv(file.path(getwd(),"dublin_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
dublin <- dublin[c("month","year","h","time")]
dunmore <- read.csv(file.path(getwd(),"dunmore_east_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
dunmore <- dunmore[c("month","year","h","time")]
fenit <- read.csv(file.path(getwd(),"fenit_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
fenit <- fenit[c("month","year","h","time")]
galway <- read.csv(file.path(getwd(),"galway_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
galway <- galway[c("month","year","h","time")]
howth <- read.csv(file.path(getwd(),"howth_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
howth <- howth[c("month","year","sl","time")]
names(howth) <- c("month","year","h","time")
malin <- read.csv(file.path(getwd(),"malin_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
malin <- malin[c("month","year","h","time")]
port_oriel <- read.csv(file.path(getwd(),"port_oriel_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
port_oriel <- port_oriel[c("month","year","h","time")]
ringaskiddy <- read.csv(file.path(getwd(),"ringaskiddy_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
ringaskiddy <- ringaskiddy[c("month","year","h","time")]
rossaveel <- read.csv(file.path(getwd(),"rossaveel_monthly.csv"),fill=TRUE,header=TRUE,sep=",")
rossaveel <- rossaveel[c("month","year","h","time")]
The NTGN has four columns: month, year, mean sea level (h), and time. The time columns in these dataframes must be converted from a factor class to a date class. The as.POSIXlt() function has been used here. The Ballyglass record is missing time data. However, as it includes month and year data, the as.POSIXlt() has used these to calculate each individual date.
arklow$time <- as.POSIXlt(sprintf("%s/%s/15", arklow$year, arklow$month),tz="UTC")
ballycotton$time <- as.POSIXlt(sprintf("%s/%s/15", ballycotton$year, ballycotton$month),tz="UTC")
ballyglass$time <- as.POSIXlt(sprintf("%s/%s/15", ballyglass$year, ballyglass$month),tz="UTC")
castletownbere$time <- as.POSIXlt(sprintf("%s/%s/15", castletownbere$year, castletownbere$month),tz="UTC")
dublin$time <- as.POSIXlt(sprintf("%s/%s/15", dublin$year, dublin$month),tz="UTC")
dunmore$time <- as.POSIXlt(sprintf("%s/%s/15", dunmore$year, dunmore$month),tz="UTC")
fenit$time <- as.POSIXlt(sprintf("%s/%s/15", fenit$year, fenit$month),tz="UTC")
galway$time <- as.POSIXlt(sprintf("%s/%s/15", galway$year, galway$month),tz="UTC")
howth$time <- as.POSIXlt(sprintf("%s/%s/15", howth$year, howth$month),tz="UTC")
malin$time <- as.POSIXlt(sprintf("%s/%s/15", malin$year, malin$month),tz="UTC")
port_oriel$time <- as.POSIXlt(sprintf("%s/%s/15", port_oriel$year, port_oriel$month),tz="UTC")
ringaskiddy$time <- as.POSIXlt(sprintf("%s/%s/15", ringaskiddy$year, ringaskiddy$month),tz="UTC")
rossaveel$time <- as.POSIXlt(sprintf("%s/%s/15", rossaveel$year, rossaveel$month),tz="UTC")
The mean sea level in the NTGN records is given in metres (m). In order to ensure consistency with the PSMSL records, these records were converted to millimetres (mm).
arklow$h <- arklow$h*1000
ballycotton$h <- ballycotton$h*1000
ballyglass$h <- ballyglass$h*1000
castletownbere$h <- castletownbere$h*1000
dublin$h <- dublin$h*1000
dunmore$h <- dunmore$h*1000
fenit$h <- fenit$h*1000
galway$h <- galway$h*1000
howth$h <- howth$h*1000
malin$h <- malin$h*1000
port_oriel$h <- port_oriel$h*1000
ringaskiddy$h <- ringaskiddy$h*1000
rossaveel$h <- rossaveel$h*1000
Finally, the NTGN records used do not contain location data. Longitude and latitude were found at https://erddap.marine.ie/erddap/tabledap/IrishNationalTideGaugeNetwork and assigned to each station.
arklow.lat <- 52.792046
arklow.lon <- -6.145231
ballycotton.lat <- 51.8278
ballycotton.lon <- -8.0007
ballyglass.lat <- 54.2536
ballyglass.lon <- -9.8928
castletownbere.lat <- 51.6496
castletownbere.lon <- -9.9034
dublin.lat <- 53.3457
dublin.lon <- -6.2217
dunmore.lat <- 52.14767
dunmore.lon <- -6.99188
fenit.lat <- 52.270702
fenit.lon <- -9.8635645
galway.lat <- 53.269
galway.lon <- -9.048
howth.lat <- 53.3915
howth.lon <- -6.0683
malin.lat <- 55.3717
malin.lon <- -7.3344
port_oriel.lat <- 53.798042
port_oriel.lon <- -6.221441
ringaskiddy.lat <- 51.83496
ringaskiddy.lon <- -8.305566
rossaveel.lat <- 53.266926
rossaveel.lon <- -9.562056
The PSMSL mean sea level records forwere downloaded from www.psmsl.org. This data has four columns: decimal year, mean sea level, number of missing days, and flag. The missing values were recoded as NA. The time column containing the decimal year was converted from a numeric to date class using as.POSIXlt() and was separated into month and year which were added to new columns.
The NTGN and PSMSL mean sea level records are measured against different datum. All NTGN are referenced against mean sea level at Malin Head. The PSMSL records are offset by approximately 7m when compared to OD Malin. Hence, this offset was subtracted from the mean sea level of each PSMSL record to ensure the records are consistent.
The longitude and latitude of each station was then assigned.
bangor <- read.csv(file.path(getwd(),"Bangor.rlrdata.csv"),fill=TRUE,header=FALSE,sep=",")
bangor <- cbind(bangor, NA, NA)
names(bangor) <- c("time","h","missing","flag", "month","year")
bangor$h[bangor$h==-99999] <- NA
bangor$time <- date_decimal(bangor$time, tz = "UTC")
bangor.time <- as.POSIXlt(bangor$time,format="%Y-%m-%d %H:%M:%S",tz='UTC')
bangor <- data.frame("time"=bangor.time,
"year"=bangor.time$year+1900,
"month"=bangor.time$mon+1,
"day"=bangor.time$mday,
"h"=bangor$h,
"flag"=bangor$flag)
bangor$time <- as.POSIXlt(sprintf("%s/%s/15", bangor$year, bangor$month),tz="UTC")
bangor$h <- bangor$h-6962 # to maintain consistency with OD Malin
bangor <- bangor[ ,c(3, 2, 5, 1)]
bangor.lat <- 54.66475
bangor.lon <- -5.669472
belfast <- read.csv(file.path(getwd(),"Belfast.rlrdata.csv"),fill=TRUE,header=FALSE,sep=",")
belfast <- cbind(belfast, NA, NA)
names(belfast) <- c("time","h","missing","flag", "month","year")
belfast$h[belfast$h==-99999] <- NA
belfast$time <- date_decimal(belfast$time, tz = "UTC")
belfast.time <- as.POSIXlt(belfast$time,format="%Y-%m-%d %H:%M:%S",tz='UTC')
belfast <- data.frame("time"=belfast.time,
"year"=belfast.time$year+1900,
"month"=belfast.time$mon+1,
"day"=belfast.time$mday,
"h"=belfast$h,
"flag"=belfast$flag)
belfast$time <- as.POSIXlt(sprintf("%s/%s/15", belfast$year, belfast$month),tz="UTC")
belfast$h <- belfast$h-6954
belfast <- belfast[ ,c(3, 2, 5, 1)]
belfast.lat <- 54.6
belfast.lon <- -5.916667
dublin_psmsl <- read.csv(file.path(getwd(),"Dublin.rlrdata.csv"),fill=TRUE,header=FALSE,sep=",")
dublin_psmsl <- cbind(dublin_psmsl, NA, NA)
names(dublin_psmsl) <- c("time","h","missing","flag", "month","year")
dublin_psmsl$h[dublin_psmsl$h==-99999] <- NA
dublin_psmsl$time <- date_decimal(dublin_psmsl$time, tz = "UTC")
dublin_psmsl.time <- as.POSIXlt(dublin_psmsl$time,format="%Y-%m-%d %H:%M:%S",tz='UTC')
dublin_psmsl <- data.frame("time"=dublin_psmsl.time,
"year"=dublin_psmsl.time$year+1900,
"month"=dublin_psmsl.time$mon+1,
"day"=dublin_psmsl.time$mday,
"h"=dublin_psmsl$h,
"flag"=dublin_psmsl$flag)
dublin_psmsl$time <- as.POSIXlt(sprintf("%s/%s/15", dublin_psmsl$year, dublin_psmsl$month),tz="UTC")
dublin_psmsl$h <- dublin_psmsl$h-7007
dublin_psmsl <- dublin_psmsl[ ,c(3, 2, 5, 1)]
malin_psmsl <- read.csv(file.path(getwd(),"MalinHead.rlrdata.csv"),fill=TRUE,header=FALSE,sep=",")
malin_psmsl <- cbind(malin_psmsl, NA, NA)
names(malin_psmsl) <- c("time","h","missing","flag", "month","year")
malin_psmsl$h[malin_psmsl$h==-99999] <- NA
malin_psmsl$time <- date_decimal(malin_psmsl$time, tz = "UTC")
malin_psmsl.time <- as.POSIXlt(malin_psmsl$time,format="%Y-%m-%d %H:%M:%S",tz='UTC')
malin_psmsl <- data.frame("time"=malin_psmsl.time,
"year"=malin_psmsl.time$year+1900,
"month"=malin_psmsl.time$mon+1,
"day"=malin_psmsl.time$mday,
"h"=malin_psmsl$h,
"flag"=malin_psmsl$flag)
malin_psmsl$time <- as.POSIXlt(sprintf("%s/%s/15", malin_psmsl$year, malin_psmsl$month),tz="UTC")
malin_psmsl$h <- malin_psmsl$h-7037
malin_psmsl <- malin_psmsl[ ,c(3, 2, 5, 1)]
portrush <- read.csv(file.path(getwd(),"Portrush.rlrdata.csv"),fill=TRUE,header=FALSE,sep=",")
portrush <- cbind(portrush, NA, NA)
names(portrush) <- c("time","h","missing","flag", "month","year")
portrush$h[portrush$h==-99999] <- NA
portrush$time <- date_decimal(portrush$time, tz = "UTC")
portrush.time <- as.POSIXlt(portrush$time,format="%Y-%m-%d %H:%M:%S",tz='UTC')
portrush <- data.frame("time"=portrush.time,
"year"=portrush.time$year+1900,
"month"=portrush.time$mon+1,
"day"=portrush.time$mday,
"h"=portrush$h,
"flag"=portrush$flag)
portrush$time <- as.POSIXlt(sprintf("%s/%s/15", portrush$year, portrush$month),tz="UTC")
portrush$h <- portrush$h-7027
portrush <- portrush[ ,c(3, 2, 5, 1)]
portrush.lat <- 55.206778
portrush.lon <- -6.656833
The map() function was used to plot the location of both the PSMSL and NTGN tide gauges based on their respective longitude and latitude.
map("world",c("ireland","uk"),fill=FALSE,xlim=c(-12,-4),ylim=c(51,56))
map.axes(cex.axis=1)
title(main="Location of Tide Gauges",xlab="Longitude",ylab="Latitude")
points(arklow.lon,arklow.lat,pch=21,col="gray",bg="red",cex=1.1)
text(arklow.lon+0.3,arklow.lat,"1",col="black")
points(ballycotton.lon,ballycotton.lat,pch=21,col="gray",bg="red",cex=1.1)
text(ballycotton.lon+0.1,ballycotton.lat-0.2,"2",col="black")
points(ballyglass.lon,ballyglass.lat,pch=21,col="gray",bg="red",cex=1.1)
text(ballyglass.lon,ballyglass.lat+0.2,"3",col="black")
points(bangor.lon,bangor.lat,pch=21,col="gray",bg="red",cex=1.1)
text(bangor.lon+0.25,bangor.lat+0.1,"4",col="black")
points(belfast.lon,belfast.lat,pch=21,col="gray",bg="red",cex=1.1)
text(belfast.lon-0.25,belfast.lat,"5",col="black")
points(castletownbere.lon,castletownbere.lat,pch=21,col="gray",bg="red",cex=1.1)
text(castletownbere.lon-0.1,castletownbere.lat-0.22,"6",col="black")
points(dublin.lon,dublin.lat,pch=21,col="gray",bg="red",cex=1.1)
text(dublin.lon-0.22,dublin.lat,"7",col="black")
points(dunmore.lon,dunmore.lat,pch=21,col="gray",bg="red",cex=1.1)
text(dunmore.lon+0.1,dunmore.lat-0.2,"8",col="black")
points(fenit.lon,fenit.lat,pch=21,col="gray",bg="red",cex=1.1)
text(fenit.lon-0.2,fenit.lat+0.18,"9",col="black")
points(galway.lon,galway.lat,pch=21,col="gray",bg="red",cex=1.1)
text(galway.lon+0.1,galway.lat+0.22,"10",col="black")
points(howth.lon,howth.lat,pch=21,col="gray",bg="red",cex=1.1)
text(howth.lon+0.28,howth.lat,"11",col="black")
points(malin.lon,malin.lat,pch=21,col="gray",bg="red",cex=1.1)
text(malin.lon,malin.lat+0.22,"12",col="black")
points(port_oriel.lon,port_oriel.lat,pch=21,col="gray",bg="red",cex=1.1)
text(port_oriel.lon+0.28,port_oriel.lat,"13",col="black")
points(portrush.lon,portrush.lat,pch=21,col="gray",bg="red",cex=1.1)
text(portrush.lon,portrush.lat+0.2,"14",col="black")
points(ringaskiddy.lon,ringaskiddy.lat,pch=21,col="gray",bg="red",cex=1.1)
text(ringaskiddy.lon-0.1,ringaskiddy.lat+0.21,"15",col="black")
points(rossaveel.lon,rossaveel.lat,pch=21,col="gray",bg="red",cex=1.1)
text(rossaveel.lon-0.2,rossaveel.lat-0.18,"16",col="black")
legend("topright",
legend = c("1: Arklow", "2: Ballycotton", "3: Ballyglass", "4: Bangor (PSMSL)",
"5: Belfast (PSMSL)", "6: Castletownbere", "7: Dublin (NTGN & PSMSL)",
"8: Dunmore","9: Fenit", "10: Galway", "11: Howth",
"12: Malin Head (NTGN & PSMSL)","13: Port Oriel", "14: Portrush (PSMSL)",
"15: Ringaskiddy", "16: Rossaveel"),bty="n", cex=0.7,inset=c(-0.60,0),xpd=TRUE)
Figure 1: Map of tide gauge locations for PSMSL and NTGN
A time series plot for all stations was then plotted to compare the length of the records.
plot(dublin_psmsl$time,dublin_psmsl$h,col='coral2',
main = 'Monthly Tide Gauge Data',ylim=c(-4500,4000),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(belfast$time,belfast$h+500,col='chartreuse4')
lines(malin_psmsl$time,malin_psmsl$h+1000,col='cadetblue3')
lines(bangor$time,bangor$h+1500,col='burlywood3')
lines(portrush$time,portrush$h+2000,col='lightcoral')
lines(arklow$time, arklow$h+2500,col='blue4')
lines(ballycotton$time, ballycotton$h+3000, col='black')
lines(ballyglass$time, ballyglass$h-500, col='aquamarine3')
lines(castletownbere$time, castletownbere$h-1000,col='deeppink2')
lines(dublin$time, dublin$h-1500,col='darkseagreen3')
lines(dunmore$time, dunmore$h-2000,col='darksalmon')
lines(fenit$time, fenit$h-2500,col='darkgoldenrod2')
lines(galway$time, galway$h-3000,col='cyan')
lines(howth$time, howth$h+3500,col='cornflowerblue')
lines(malin$time, malin$h+4000,col='firebrick1')
lines(port_oriel$time, port_oriel$h-3500,col='dodgerblue2')
lines(ringaskiddy$time, ringaskiddy$h-4000,col='lightpink1')
lines(rossaveel$time, rossaveel$h-4500,col='yellow2')
legend("bottomleft",
legend=c("Dublin PSMSL","Belfast","Malin Head PSMSL","Bangor","Portrush","Arklow",
"Ballycotton","Ballyglass","Castletownbere","Dublin NTGN","Dunmore East","Fenit",
"Galway","Howth","Malin Head NTGN","Port Oriel","Ringaskiddy","Rossaveel"),
col=c("coral2","chartreuse4","cadetblue3","burlywood3","lightcoral","blue4","black",
"aquamarine3","deeppink2","darkseagreen3","darksalmon","darkgoldenrod2",
"cyan","cornflowerblue","firebrick1","dodgerblue2","lightpink1",
"yellow2"),lty=1,lwd=2,bty="n",cex=0.4)
Figure 2: Time series plot of NTGN and PSMSL records
The PSMSL records are considerably longer than the NTGN records however, the NTGN records contain more recent data than the PSMSL records (see also Figures 3 and 4).
Plotting the NTGN records only.
plot(arklow$time,arklow$h,col='coral2',
main = 'Monthly NTGN Tide Gauge Data',ylim=c(-3000,3000),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(ringaskiddy$time, ringaskiddy$h+900,col='lightpink1')
lines(rossaveel$time, rossaveel$h+800,col='cornflowerblue')
lines(howth$time, howth$h+1500,col='yellow2')
lines(port_oriel$time, port_oriel$h+2000,col='dodgerblue2')
lines(malin$time, malin$h+2500,col='firebrick1')
lines(ballycotton$time, ballycotton$h+3000, col='black')
lines(ballyglass$time, ballyglass$h-700, col='aquamarine3')
lines(castletownbere$time, castletownbere$h-900,col='deeppink2')
lines(dublin$time, dublin$h-1500,col='darkseagreen3')
lines(dunmore$time, dunmore$h-1800,col='darksalmon')
lines(fenit$time, fenit$h-2500,col='darkgoldenrod2')
lines(galway$time, galway$h-3000,col='cyan')
legend("topleft",
legend=c("Arklow","Ballycotton","Ballyglass","Castletownbere","Dublin NTGN","Dunmore East","Fenit",
"Galway","Howth","Malin Head NTGN","Port Oriel","Ringaskiddy","Rossaveel"),
col=c("coral2","black","aquamarine3","deeppink2","darkseagreen3","darksalmon","darkgoldenrod2",
"cyan","yellow2","firebrick1","dodgerblue2","lightpink1",
"cornflowerblue"),lty=1,lwd=2,bty="n",cex=0.5)
Figure 3: Time series plot of NTGN records
Plotting PSMSL records only.
plot(dublin_psmsl$time,dublin_psmsl$h,col='coral2',
main = 'Monthly PSMSL Tide Gauge Data',ylim=c(-4500,300),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(belfast$time, belfast$h-1000,col='lightpink1')
lines(malin_psmsl$time, malin_psmsl$h-2000,col='yellow2')
lines(bangor$time, bangor$h-3000,col='cornflowerblue')
lines(portrush$time, portrush$h-4000,col='darkseagreen3')
legend("bottomleft",
legend=c("Dublin PSMSL","Belfast","Malin Head PSMSL","Bangor","Portrush"),
col=c("coral2","lightpink1","yellow2","cornflowerblue","darkseagreen3"),
lty=1,lwd=2,bty="n",cex=0.6)
Figure 4: Time series of PSMSL records
In order to ensure there is one row for each month of the records, a data frame (full_dates) of every month from the start to the end of each record was created and merged with the original record, allowing for the inclusion of missing values (all.x=TRUE).
bangor$time <- as.Date(bangor$time, format = "%Y-%m-%d")
full_dates <- seq(min(bangor$time), max(bangor$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
bangor <- merge(full_dates, bangor, by = "time",
all.x = TRUE)
belfast$time <- as.Date(belfast$time, format = "%Y-%m-%d")
full_dates <- seq(min(belfast$time), max(belfast$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
belfast <- merge(full_dates, belfast, by = "time",
all.x = TRUE)
dublin_psmsl$time <- as.Date(dublin_psmsl$time, format = "%Y-%m-%d")
full_dates <- seq(min(dublin_psmsl$time), max(dublin_psmsl$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
dublin_psmsl <- merge(full_dates, dublin_psmsl, by = "time",
all.x = TRUE)
malin_psmsl$time <- as.Date(malin_psmsl$time, format = "%Y-%m-%d")
full_dates <- seq(min(malin_psmsl$time), max(malin_psmsl$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
malin_psmsl <- merge(full_dates, malin_psmsl, by = "time",
all.x = TRUE)
portrush$time <- as.Date(portrush$time, format = "%Y-%m-%d")
full_dates <- seq(min(portrush$time), max(portrush$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
portrush <- merge(full_dates, portrush, by = "time",
all.x = TRUE)
arklow$time <- as.Date(arklow$time, format = "%Y-%m-%d")
full_dates <- seq(min(arklow$time), max(arklow$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
arklow <- merge(full_dates, arklow, by = "time",
all.x = TRUE)
ballycotton$time <- as.Date(ballycotton$time, format = "%Y-%m-%d")
full_dates <- seq(min(ballycotton$time), max(ballycotton$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
ballycotton <- merge(full_dates, ballycotton, by = "time",
all.x = TRUE)
ballyglass$time <- as.Date(ballyglass$time, format = "%Y-%m-%d")
full_dates <- seq(min(ballyglass$time), max(ballyglass$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
ballyglass <- merge(full_dates, ballyglass, by = "time",
all.x = TRUE)
castletownbere$time <- as.Date(castletownbere$time, format = "%d/%m/%Y")
full_dates <- seq(min(castletownbere$time), max(castletownbere$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
castletownbere <- merge(full_dates, castletownbere, by = "time",
all.x = TRUE)
dublin$time <- as.Date(dublin$time, format = "%Y-%m-%d")
full_dates <- seq(min(dublin$time), max(dublin$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
dublin <- merge(full_dates, dublin, by = "time",
all.x = TRUE)
dunmore$time <- as.Date(dunmore$time, format = "%d/%m/%Y")
full_dates <- seq(min(dunmore$time), max(dunmore$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
dunmore <- merge(full_dates, dunmore, by = "time",
all.x = TRUE)
fenit$time <- as.Date(fenit$time, format = "%Y-%m-%d")
full_dates <- seq(min(fenit$time), max(fenit$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
fenit <- merge(full_dates, fenit, by = "time",
all.x = TRUE)
galway$time <- as.Date(galway$time, format = "%d/%m/%Y")
full_dates <- seq(min(galway$time), max(galway$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
galway <- merge(full_dates, galway, by = "time",
all.x = TRUE)
howth$time <- as.Date(howth$time, format = "%Y-%m-%d")
full_dates <- seq(min(howth$time), max(howth$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
howth <- merge(full_dates, howth, by = "time",
all.x = TRUE)
malin$time <- as.Date(malin$time, format = "%d/%m/%Y")
full_dates <- seq(min(malin$time), max(malin$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
malin <- merge(full_dates, malin, by = "time",
all.x = TRUE)
port_oriel$time <- as.Date(port_oriel$time, format = "%d/%m/%Y")
full_dates <- seq(min(port_oriel$time), max(port_oriel$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
port_oriel <- merge(full_dates, port_oriel, by = "time",
all.x = TRUE)
ringaskiddy$time <- as.Date(ringaskiddy$time, format = "%Y-%m-%d")
full_dates <- seq(min(ringaskiddy$time), max(ringaskiddy$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
ringaskiddy <- merge(full_dates, ringaskiddy, by = "time",
all.x = TRUE)
rossaveel$time <- as.Date(rossaveel$time, format = "%d/%m/%Y")
full_dates <- seq(min(rossaveel$time), max(rossaveel$time),
by = "1 month")
full_dates <- data.frame(time = full_dates)
rossaveel <- merge(full_dates, rossaveel, by = "time",
all.x = TRUE)
There are two tide gauges that have both NTGN and PSMSL records: Dublin and Malin Head. Both records for these locations were merged to compile a continuous record of mean monthly sea level.
The PSMSL and NTGN records for Dublin overlap from 4/2007 to 12/2009 (see Figure 5). As the sea levels recorded in the NTGN and PSMSL are originally in different units and measured against different datum, an arbitrary offset may be expected despite allowing for these differences.
Yet, Figure 5 shows that the sea level trends in the records agree for the period of overlap. This is also evident in the scatterplot in Figure 6. The correlation between the two records for this period is 0.99; a very strong positive relationship.
plot(dublin$time[1:33],dublin$h[1:33],col='green3',
main = 'Dublin Monthly Tide Gauge Data',ylim=c(-200,350),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(dublin_psmsl$time[832:864], dublin_psmsl$h[832:864],col='blue')
legend("topleft",
legend=c("NTGN","PSMSL"),
col=c("green3","blue"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 5: Overlap of Dublin PSMSL and NTGN records
cor(dublin_psmsl$h[832:864],dublin$h[1:33],use="complete") # 0.991705
## [1] 0.991705
plot(dublin$h[1:33],dublin_psmsl$h[832:864],main= "Dublin: NTGN vs. PSMSL",
xlab="NTGN sea level (mm)", ylab="PSMSL sea level (mm)")
abline(lm(dublin_psmsl$h[832:864]~dublin$h[1:33]),col="red",lwd=2)
Figure 6: Scatterplot of Dublin NTGN and PSMSL sea level
The relationship between the records can be used to adjust one record to correspond with the other and form a continuous record of sea level from 1938 to 2019 rather than two separate records.
Linear regression may be used to further explore the relationship between the records.
lm(dublin_psmsl$h[832:864]~dublin$h[1:33]) # Intercept: 168.3338 x: 0.9713
##
## Call:
## lm(formula = dublin_psmsl$h[832:864] ~ dublin$h[1:33])
##
## Coefficients:
## (Intercept) dublin$h[1:33]
## 168.3338 0.9713
The linear model output reveals the adjustment that must be made to the NTGN in order for it to agree with the PSMSL record. By adding the intercept to the NTGN record and multiplying the result by the regression coefficient, the NTGN record is transformed to correspond with the PSMSL record while maintaining the trends from the original data (see Figure 7).
plot(dublin$time[1:33],(dublin$h[1:33]+168.3338)*0.9713,col='green3',
main = 'Dublin Monthly Tide Gauge Data',ylim=c(-50,350),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(dublin_psmsl$time[832:864], dublin_psmsl$h[832:864],col='blue')
legend("topleft",
legend=c("NTGN adjusted","PSMSL"),
col=c("green3","blue"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 7: Dublin PSMSL and adjusted NTGN sea level
Using this relationship, the NTGN record can be adjusted and combined with the entirety of the PSMSL record to create a longer Dublin sea level record (see Figures 8 and 9). The adjusted record provides a good indication of the trends in mean monthly sea level in Dublin.
dublin_adjusted <- dublin
dublin_adjusted$h <- (dublin$h+168.3338)*0.9713
dublinN_year <- aggregate(h~year,dublin_adjusted,mean)
dublinP_year <- aggregate(h~year,dublin_psmsl,mean)
plot(dublinP_year$year,dublinP_year$h,col='red',
main = 'Continuous Dublin time series',ylim=c(-180,300),xlim=c(1938,2020),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(dublinN_year$year[4:13], dublinN_year$h[4:13],col='green3')
legend("topleft",
legend=c("PSMSL","Adjusted NTGN"),
col=c("red","green3"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 8: Continuous Dublin sea level record showing two components
dublin <- rbind(dublin_psmsl,dublin_adjusted[34:143,], make.row.names=FALSE)
plot(dublin$time,dublin$h,col="blue",
main = "Continuous Dublin time series",ylim=c(-400,400),xlab="Years",ylab="Sea Level (mm)", type="l")
Figure 9: Continuous Dublin sea level record
The merging of the Malin Head records poses a greater challenge than merging the Dublin records as there is no overlap betweem the two Malin records with the PSMSL running 1958-2002 and the NTGN 2008-2019. Hence, the direct relationship between the two cannot be explored using linear regression as was done for the Dublin record. However, there is an overlap between both Malin records and the nearby Portrush record (see Figure 1). Hence, the relationship between these can be examined and the Portrush record may be transformed to correspond to the Malin records and fill the gap in the Malin record from 2002-2008.
The Portrush and Malin PSMSL records overlap 1995-2002 whereas the Portrush record overlaps with the Malin NTGN record 2008-2017.
Figure 10 shows the similarity in the trends of the Malin PSMSL and Portrush records.
plot(malin_psmsl$time[450:533],malin_psmsl$h[450:533],col='green4',
main = 'Malin Head PSMSL vs. Portrush 1995-2002',ylim=c(-300,500),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(portrush$time[1:84], portrush$h[1:84],col='blue')
legend("topleft",
legend=c("Malin PSMSL","Portrush"),
col=c("green4","blue"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 10: Malin Head PSMSL and Portrush overlap
There is a clear relationship between the two records, also evident in the scatter plot in Figure 11. There is a correlation of 0.56 between the records; a moderate positive relationship.
cor(portrush$h[1:84],malin_psmsl$h[450:533],use="complete") # 0.5583724
## [1] 0.5583724
plot(malin_psmsl$h[450:533],portrush$h[1:84],main= "Malin PSMSL vs. Portrush", xlab="Malin sea level (mm)", ylab="Portrush sea level (mm)")
abline(lm(malin_psmsl$h[450:533]~portrush$h[1:84]),col="red",lwd=2)
Figure 11: Scatterplot of Malin PSMSL and Portrush sea level
As was done with the Dublin records, linear regression can be used to examine the relationship between Portrush and Malin PSMSL in order to transform the Portrush record and use the adjusted data to link the two Malin records.
lm(malin_psmsl$h[450:533]~portrush$h[1:84]) # intercept: 2.5433 x: 0.6657
##
## Call:
## lm(formula = malin_psmsl$h[450:533] ~ portrush$h[1:84])
##
## Coefficients:
## (Intercept) portrush$h[1:84]
## 2.5433 0.6657
This linear model output can be used to transform the Portrush data and link it to the Malin PSMSL record. As can be seen in Figure 12, the adjusted Portrush record now agrees well with the Malin PSMSL record.
plot(malin_psmsl$time[450:533],malin_psmsl$h[450:533],col='green4',
main = 'Monthly Tide Gauge Data',ylim=c(-300,500),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(portrush$time[1:84], (portrush$h[1:84]+2.5433)*0.6657,col='blue')
legend("topleft",
legend=c("Malin PSMSL","Portrush"),
col=c("green4","blue"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 12: Malin PSMSL vs. adjusted Portrush sea level
The same process was carried out to relate the Portrush record to the Malin NTGN record. Figure 13 shows there is a similarity in the trends of the records despite the offset between the two. The correlation between Portrush and Malin NTGN is seen in the scatterplot in Figure 14. The correlation of 0.92 denotes a strong positive relationship between the records.
plot(malin$time[1:108],malin$h[1:108],col='orange',
main = 'Malin NTGN vs. Portrush',ylim=c(-300,500),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(portrush$time[162:269], portrush$h[162:269],col='blue')
legend("topleft",
legend=c("Malin","Portrush"),
col=c("orange","blue"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 13: Malin NTGN and Portrush overlap
cor(portrush$h[162:269],malin$h[1:108],use="complete") ## 0.9202005
## [1] 0.9202005
plot(malin$h[1:108],portrush$h[162:269],main= "Malin vs. Portrush", xlab="Malin sea level (mm)", ylab="Portrush sea level (mm)")
abline(lm(malin$h[1:108]~portrush$h[162:269]),col="red",lwd=2)
Figure 14: Scatterplot of Malin NTGN and Portrush
Again, linear regression can be used to adjust the Portrush record and link the Malin records. Figure 15 shows the adjusted Portrush record compared to the Malin NTGN record.
lm(malin$h[1:108]~portrush$h[162:269]) # intercept: -4.8484 x: 0.9453
##
## Call:
## lm(formula = malin$h[1:108] ~ portrush$h[162:269])
##
## Coefficients:
## (Intercept) portrush$h[162:269]
## -4.8484 0.9453
plot(malin$time[1:108],malin$h[1:108],col='orange',
main = 'Malin NTGN vs. Adjusted Portrush',ylim=c(-300,500),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(portrush$time[162:269], (portrush$h[162:269]-4.8484)*0.9453,col='blue')
legend("topleft",
legend=c("Malin","Portrush"),
col=c("orange","blue"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 15: Malin NTGN vs. adjusted Portrush sea level
The Portrush record can thus be adjusted in two ways to agree with the Malin records. Figure 16 shows the comparison of both methods of adjusting the Portrush record. The adjustments are similar but there are some differences in the magnitudes of the sea level data.
plot(portrush$time,(portrush$h+2.5433)*0.6657,main="Portrush adjusted for PSMSL vs NTGN",
xlab="Years",ylab="Sea Level (mm)",col="blue",type="l")
lines(portrush$time, (portrush$h-4.8484)*0.9453,col="red")
legend("topleft",
legend=c("PSMSL Adjustment","NTGN Adjustment"),
col=c("blue","red"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 16: PSMSL adjusted vs. NTGN adjusted Portrush
In order to compile a record that will best link the Malin PSMSL and NTGN records, the Portrush record can be adjusted for both the PSMSL and NTGN data. These datasets can then be merged and their mean can be found.
portrush_PSML <- portrush
portrush_PSML$h <- (portrush_PSML$h+2.5433)*0.6657
portrush_NTGN <- portrush
portrush_NTGN$h <- (portrush_NTGN$h-4.8484)*0.9453
portrush_adj <- merge(portrush_PSML,portrush_NTGN,by="time", all.x=TRUE)
portrush_adj <- portrush_adj[,c(1,2,3,4,7)]
colnames(portrush_adj) <- c("time","month","year","PSMSL","NTGN")
P_adjMean <- rowMeans(portrush_adj[,4:5],na.rm=TRUE)
portrush_adj <- cbind(portrush_adj,NA)
colnames(portrush_adj) <- c("time","month","year","PSMSL","NTGN","mean")
portrush_adj$mean <- P_adjMean
portrush_adj <- portrush_adj[,c(1:3,6)]
Using the adjusted Portrush data from 2002 to 2008, a virtual station for Malin for that period can be derived. This virtual station can be used to fill the gap between the Malin PSMSL and NTGN records.
virtual_malin <- portrush_adj
colnames(virtual_malin) <- c("time","month","year","h")
plot(malin_psmsl$time[450:533],malin_psmsl$h[450:533],col='red',
main = 'Monthly Tide Gauge Data',ylim=c(-300,500),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(virtual_malin$time[1:84], virtual_malin$h[1:84],col='green3')
legend("topleft",
legend=c("Malin PSMSL","Virtual Malin"),
col=c("red","green3"),lty=1,lwd=1,bty="n",cex=0.9)
plot(malin$time[1:108],malin$h[1:108],col='red',
main = 'Monthly Tide Gauge Data',ylim=c(-300,500),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(virtual_malin$time[162:269], virtual_malin$h[162:269],col='green3')
legend("topleft",
legend=c("Malin NTGN","Virtual Malin"),
col=c("red","green3"),lty=1,lwd=1,bty="n",cex=0.9)
Figures 17 & 18: Virtual Malin record vs. PSMSL (top) and NTGN (bottom) record
As there is no direct observations of sea level at Malin Head for 7/2002-11/2008, this period in the virtual record derived from Portrush may be subsetted and merged with the two direct records to create a continuous record of mean monthly sea level at Malin Head (Figures 19 and 20).
malinN_month <- aggregate(h~year,malin,mean)
malinP_month <- aggregate(h~year,malin_psmsl,mean)
malinV_month <- aggregate(h~year,virtual_malin,mean)
plot(malinP_month$year,malinP_month$h,col='red',
main = 'Continuous Malin time series',ylim=c(-100,120),xlim=c(1958,2020),xlab = 'Years',ylab = 'Sea Level (mm)',type = 'l')
lines(malinV_month$year[7:13], malinV_month$h[7:13],col='green3')
lines(malinN_month$year, malinN_month$h,col='blue')
legend("topleft",
legend=c("Malin Head PSMSL","Portrush Adjusted", "Malin Head NTGN"),
col=c("red","green3","blue"),lty=1,lwd=1,bty="n",cex=0.9)
Figure 19: Continuous Malin Head sea level record showing three components
malin <- rbind(malin_psmsl,virtual_malin[85:161,],malin, make.row.names=FALSE)
plot(malin$time,malin$h,col="blue",
main = "Continuous Malin time series",ylim=c(-400,400),xlab="Years",ylab="Sea Level (mm)", type="l")
Figure 20: Continuous Malin Head sea level record
Linear regression can be used to calculate the trends in the sea level records. By examining the relationship between the sea level and time using a linear model, the annual change in sea level can be derived from the regression coefficient of the model.
The records were aggregated by year before examining trends. Aggregating the records by year to find the annual averages removes the affect of seasonality and tidal cycles. In order to avoid skewing the averages, the stations were aggregated not from the beginning to the end of their record but from the first full year to the last full year of data.
# Arklow
ark.year <- aggregate (h~year,arklow[5:184,],mean)
ark.year <- cbind(ark.year, NA)
colnames(ark.year) <- c("year", "h", "time")
ark.year$time <- as.POSIXlt(sprintf("%s/7/1", ark.year$year),tz="UTC")
plot(ark.year$year, ark.year$h, type="l",
main="Arklow average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(ark.year$h~ark.year$year), col="red")
ark_lm <- lm(h~year, ark.year)
ark_lm
##
## Call:
## lm(formula = h ~ year, data = ark.year)
##
## Coefficients:
## (Intercept) year
## -3897.728 1.906
ark_slope <- 1.906
# Ballycotton
ballyc.year <- aggregate (h~year,ballycotton[3:98,],mean)
ballyc.year <- cbind(ballyc.year, NA)
colnames(ballyc.year) <- c("year", "h", "time")
ballyc.year$time <- as.POSIXlt(sprintf("%s/7/1", ballyc.year$year),tz="UTC")
plot(ballyc.year$year, ballyc.year$h, type="l",
main="Ballycotton average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(ballyc.year$h~ballyc.year$year), col="red")
ballyc_lm <- lm(h~year, ballyc.year)
ballyc_lm
##
## Call:
## lm(formula = h ~ year, data = ballyc.year)
##
## Coefficients:
## (Intercept) year
## -5330.803 2.565
ballyc_slope <- 2.565
# Ballyglass
ballyg.year <- aggregate (h~year,ballyglass[10:129,],mean)
ballyg.year <- cbind(ballyg.year, NA)
colnames(ballyg.year) <- c("year", "h", "time")
ballyg.year$time <- as.POSIXlt(sprintf("%s/7/1", ballyg.year$year),tz="UTC")
plot(ballyg.year$year, ballyg.year$h, type="l",
main="Ballyglass average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(ballyg.year$h~ballyg.year$year), col="red")
ballyg_lm <- lm(h~year, ballyg.year)
ballyg_lm
##
## Call:
## lm(formula = h ~ year, data = ballyg.year)
##
## Coefficients:
## (Intercept) year
## -7111.782 3.571
ballyg_slope <- 3.571
# Bangor
bang.year <- aggregate (h~year,bangor[3:254,],mean)
bang.year <- cbind(bang.year, NA)
colnames(bang.year) <- c("year", "h", "time")
bang.year$time <- as.POSIXlt(sprintf("%s/7/1", bang.year$year),tz="UTC")
plot(bang.year$year, bang.year$h, type="l",
main="Bangor average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(h~year,bang.year), col="red")
bang_lm <- lm(h~year, bang.year)
bang_lm
##
## Call:
## lm(formula = h ~ year, data = bang.year)
##
## Coefficients:
## (Intercept) year
## -9920.299 4.935
bang_slope <- 4.935
# Belfast
belf.year <- aggregate (h~year,belfast[1:264,],mean)
belf.year <- cbind(belf.year, NA)
colnames(belf.year) <- c("year", "h", "time")
belf.year$time <- as.POSIXlt(sprintf("%s/7/1", belf.year$year),tz="UTC")
plot(belf.year$year, belf.year$h, type="l",
main="Belfast average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(h~year,belf.year), col="red")
belf_lm <- lm(h~year, belf.year)
belf_lm
##
## Call:
## lm(formula = h ~ year, data = belf.year)
##
## Coefficients:
## (Intercept) year
## 1718.5277 -0.8535
belf_slope <- -0.8535
# Castletownbere
castlet.year <- aggregate (h~year,castletownbere[1:132,],mean)
castlet.year <- cbind(castlet.year, NA)
colnames(castlet.year) <- c("year", "h", "time")
castlet.year$time <- as.POSIXlt(sprintf("%s/7/1", castlet.year$year),tz="UTC")
plot(castlet.year$year, castlet.year$h, type="l",
main="Castletownbere average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(castlet.year$h~castlet.year$year), col="red")
castlet_lm <- lm(h~year, castlet.year)
castlet_lm
##
## Call:
## lm(formula = h ~ year, data = castlet.year)
##
## Coefficients:
## (Intercept) year
## -18998.284 9.353
castlet_slope <- 9.353
# Dublin
dub.year <- aggregate(h~year,dublin[1:972,],mean)
dub.year <- cbind(dub.year, NA)
colnames(dub.year) <- c("year", "h", "time")
dub.year$time <- as.POSIXlt(sprintf("%s/7/1", dub.year$year),tz="UTC")
plot(dub.year$year, dub.year$h, type="l",
main="Dublin average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(h~year,dub.year), col="red")
dub_lm <- lm(h~year, dub.year)
dub_lm
##
## Call:
## lm(formula = h ~ year, data = dub.year)
##
## Coefficients:
## (Intercept) year
## -5136.10 2.59
dub_slope <- 2.59
# Dunmore East
dun.year <- aggregate (h~year,dunmore[9:80,],mean)
dun.year <- cbind(dun.year, NA)
colnames(dun.year) <- c("year", "h", "time")
dun.year$time <- as.POSIXlt(sprintf("%s/7/1", dun.year$year),tz="UTC")
plot(dun.year$year, dun.year$h, type="l",
main="Dunmore East average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(dun.year$h~dun.year$year), col="red")
dunmore_lm <- lm(h~year, dun.year)
dunmore_lm
##
## Call:
## lm(formula = h ~ year, data = dun.year)
##
## Coefficients:
## (Intercept) year
## -37854.21 18.69
dunmore_slope <- 18.69
# Fenit
fen.year <- aggregate (h~year,fenit[6:77,],mean)
fen.year <- cbind(fen.year, NA)
colnames(fen.year) <- c("year", "h", "time")
fen.year$time <- as.POSIXlt(sprintf("%s/7/1", fen.year$year),tz="UTC")
plot(fen.year$year, fen.year$h, type="l",
main="Fenit average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(fen.year$h~fen.year$year), col="red")
fenit_lm <- lm(h~year, fen.year)
fenit_lm
##
## Call:
## lm(formula = h ~ year, data = fen.year)
##
## Coefficients:
## (Intercept) year
## 22342.83 -11.07
fenit_slope <- -11.07
# Galway
gal.year <- aggregate (h~year,galway[10:141,],mean)
gal.year <- cbind(gal.year, NA)
colnames(gal.year) <- c("year", "h", "time")
gal.year$time <- as.POSIXlt(sprintf("%s/7/1", gal.year$year),tz="UTC")
plot(gal.year$year, gal.year$h, type="l",
main="Galway average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(gal.year$h~gal.year$year), col="red")
galw_lm <- lm(h~year, gal.year)
galw_lm
##
## Call:
## lm(formula = h ~ year, data = gal.year)
##
## Coefficients:
## (Intercept) year
## -6776.686 3.392
galw_slope <- 3.392
# Howth
how.year <- aggregate (h~year,howth[3:146,],mean)
how.year <- cbind(how.year, NA)
colnames(how.year) <- c("year", "h", "time")
how.year$time <- as.POSIXlt(sprintf("%s/7/1", how.year$year),tz="UTC")
plot(how.year$year, how.year$h, type="l",
main="Howth average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(how.year$h~how.year$year), col="red")
howth_lm <- lm(h~year, how.year)
howth_lm
##
## Call:
## lm(formula = h ~ year, data = how.year)
##
## Coefficients:
## (Intercept) year
## -5688.646 2.804
howth_slope <- 2.804
# Malin
mal.year <- aggregate(h~year,malin[12:731,],mean)
mal.year <- cbind(mal.year, NA)
colnames(mal.year) <- c("year", "h", "time")
mal.year$time <- as.POSIXlt(sprintf("%s/7/1", mal.year$year),tz="UTC")
plot(mal.year$year, mal.year$h, type="l",
main="Malin Head average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(h~year,mal.year), col="red")
malin_lm <- lm(h~year, mal.year)
malin_lm
##
## Call:
## lm(formula = h ~ year, data = mal.year)
##
## Coefficients:
## (Intercept) year
## 2297.446 -1.137
malin_slope <- -1.139
# Port Oriel
PO.year <- aggregate (h~year,port_oriel[9:140,],mean)
PO.year <- cbind(PO.year, NA)
colnames(PO.year) <- c("year", "h", "time")
PO.year$time <- as.POSIXlt(sprintf("%s/7/1", PO.year$year),tz="UTC")
plot(PO.year$year, PO.year$h, type="l",
main="Port Oriel average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(PO.year$h~PO.year$year), col="red")
portor_lm <- lm(h~year, PO.year)
portor_lm
##
## Call:
## lm(formula = h ~ year, data = PO.year)
##
## Coefficients:
## (Intercept) year
## 7119.891 -3.556
portor_slope <- -3.556
# Portrush
portru.year <- aggregate (h~year,portrush[7:258,],mean)
portru.year <- cbind(portru.year, NA)
colnames(portru.year) <- c("year", "h", "time")
portru.year$time <- as.POSIXlt(sprintf("%s/7/1", portru.year$year),tz="UTC")
plot(portru.year$year, portru.year$h, type="l",
main="Portrush average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(portru.year$h~portru.year$year), col="red")
portru_lm <- lm(h~year, portru.year)
portru_lm
##
## Call:
## lm(formula = h ~ year, data = portru.year)
##
## Coefficients:
## (Intercept) year
## -2399.080 1.205
portru_slope <- 1.205
# Ringaskiddy
ring.year <- aggregate (h~year,ringaskiddy[1:84,],mean)
ring.year <- cbind(ring.year, NA)
colnames(ring.year) <- c("year", "h", "time")
ring.year$time <- as.POSIXlt(sprintf("%s/7/1", ring.year$year),tz="UTC")
plot(ring.year$year, ring.year$h, type="l",
main="Ringaskiddy average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(ring.year$h~ring.year$year), col="red")
ring_lm <- lm(h~year, ring.year)
ring_lm
##
## Call:
## lm(formula = h ~ year, data = ring.year)
##
## Coefficients:
## (Intercept) year
## -9176.565 4.367
ring_slope <- 4.367
# Rossaveel
ross.year <- aggregate (h~year,rossaveel[4:99,],mean)
ross.year <- cbind(ross.year, NA)
colnames(ross.year) <- c("year", "h", "time")
ross.year$time <- as.POSIXlt(sprintf("%s/7/1", ross.year$year),tz="UTC")
plot(ross.year$year, ross.year$h, type="l",
main="Rossaveel average annual sea level",ylab="Sea level (mm)",xlab="Year")
abline(lm(ross.year$h~ross.year$year), col="red")
ross_lm <- lm(h~year, ross.year)
ross_lm
##
## Call:
## lm(formula = h ~ year, data = ross.year)
##
## Coefficients:
## (Intercept) year
## 2348.113 -1.063
ross_slope <- -1.063
The sea level records used in this exercise are all of different lengths and hence the trends are indicative of trends across different time periods. Records such as the continuous Dublin and Malin records, which run 1938-2018 and 1959-2018, are long samples of sea level and thus the affect of the annual variation in sea level is lessened. Hence, these records provide a good indication of sea level changes at their respective locations. However, other records run for far shorter periods, such as Dunmore and Fenit which both run 2013-2018. These records are not long enough to provide as accurate an indication of sea level changes as the longer records.
The sea level trends can be mapped using the tmap package. In order to do this, a shapefile must be constucted that contains information on the trends and station locations that can be mapped over a basemap. To do this, the rates of change derived from the linear models can be compiled into a data frame, as can the longitude, latitude, and name of each station. The absolute value of the trends have been added to a column in the data frame (“sizes”) so that the magnitude of the trend can be reflected in the size of the symbol on the map. This data frame can then be converted to a shapefile. This is done by converting the longitude and latitude to coordinates and then to a CRS object with the datum WGS84, thus creating a spatial points dataframe. This can then be converted to a shapefile (.shp) using spTransform() and raster::shapefile(). The tmap package can then be used to create an interactive map of these trends (Figure 21).
trends <- c(ark_slope,ballyc_slope,ballyg_slope,bang_slope,belf_slope,castlet_slope,dub_slope,dunmore_slope,
fenit_slope,galw_slope,howth_slope,malin_slope,portor_slope,portru_slope,ring_slope,ross_slope)
long <- c(arklow.lon,ballycotton.lon,ballyglass.lon,bangor.lon,belfast.lon,castletownbere.lon,dublin.lon,
dunmore.lon,fenit.lon,galway.lon,howth.lon,malin.lon,port_oriel.lon,portrush.lon,ringaskiddy.lon,
rossaveel.lon)
lat <- c(arklow.lat,ballycotton.lat,ballyglass.lat,bangor.lat,belfast.lat,castletownbere.lat,dublin.lat,
dunmore.lat,fenit.lat,galway.lat,howth.lat,malin.lat,port_oriel.lat,portrush.lat,ringaskiddy.lat,
rossaveel.lat)
location <- c("Arklow", "Ballycotton", "Ballyglass", "Bangor", "Belfast", "Castletownbere", "Dublin", "Dunmore East",
"Fenit", "Galway", "Howth", "Malin Head", "Port Oriel", "Portrush", "Ringaskiddy",
"Rossaveel")
sizes <- abs(trends)
trend_data <- data.frame(location,long,lat,trends,sizes)
colnames(trend_data) <- c("location","long", "lat", "trends (mm/yr)","sizes")
## To make a shapefile
WGScoor <- trend_data
coordinates(WGScoor) = ~long+lat
proj4string(WGScoor) <- CRS("+proj=longlat +datum=WGS84")
LLcoor <- spTransform(WGScoor,CRS("+proj=longlat"))
raster::shapefile(LLcoor, "MyShapefile.shp", overwrite=TRUE)
## Warning in rgdal::writeOGR(x, filename, layer, driver = "ESRI Shapefile", :
## Field names abbreviated for ESRI Shapefile driver
class(LLcoor)
## [1] "SpatialPointsDataFrame"
## attr(,"package")
## [1] "sp"
# map
tm_basemap("Esri.WorldGrayCanvas") +
tm_shape(LLcoor) +
tm_symbols(size = "sizes", size.max=1, col = "trends (mm/yr)", shape= 21, palette = "-RdBu") +
tmap_mode("view")
## tmap mode set to interactive viewing
## Variable "trends (mm/yr)" contains positive and negative values, so midpoint is set to 0. Set midpoint = NA to show the full spectrum of the color palette.
## Note that 15 values of the variable "sizes" (the highest being 18.69) are larger than size.max, which is currently set to 1. It is recommended to set size.max to at least 18.69. Another option is to set size.lim = c(0, 1), which truncates the size of the 15 larger symbols. Use the scale argument to increase the size of all symbols.
## Warning: package 'sf' was built under R version 3.5.3
## Linking to GEOS 3.6.1, GDAL 2.2.3, PROJ 4.9.3
## Legend for symbol sizes not available in view mode.
Figure 21: Map of Irish sea level trends
Most stations in Figure 21 exhibit an increasing trend in sea level during their record. The largest rates of rising sea level are in the south while the decreasing trends are concentrated in the north of the country. This may be due to post glacial rebound in this part of the country (Dangendorf et al., 2017; Hay et al., 2015). However, Fenit in the south east exhibits the largest falling sea level trends which seems anomalous. This is likely due to a large negative outlier recorded at Fenit in June 2018 which may have skewed the calculation of trends.
There are issues when relating the records to each other. As previously explained, the PSMSL and NTGN data is measured in different units and against different datum.There are issues of accuracy when comparing records that are inhomogeneous as they may not reflect true sea level.
Furthermore, the records are of different lengths. There are no NTGN records available before 2003 and only Dublin and Malin Head extend from the mid 1900s to 2018. The linear regression method used to merge the Dublin and Malin Head could also be used to relate the trends in the shorter records the the longer Dublin and Malin Head records and compile a longer dataset of trends for these shorter records. However, in this exercise, only the direct observations were used to give an indication of Irish mean sea level trends.
The “fingerprints” discussed by Dangendorf et al. (2017) and Hay et al. (2015) are evident in the falling sea level apparent in the north and north west of the country (see Figure 21). This may be attributed to glacial isostatic adjustment as the land in the north of the country rebounds following the end of the last glacial period. Yet, there is also evidence in this exercise of falling sea levels in the south and south east e.g. at Fenit (see Figure 21). However, this could be due to the shorter length of the records for these locations; the trend apparent in the last five years may not be representative of the overall trend at the location since the mid-1900s.
The approach used by Jevrejeva et al. (2008) has been used as a starting point for compiling an Irish mean sea level curve. This approach involves merging the sea level data from two stations closest to a point in order to create a virtual record of sea level at that point. This method is repeated until one overall mean record is left (Jevrejeva et al., 2014). This was used in this exercise by first merging and finding the mean of the Malin Head and Portrush records. The resulting record was then merged with Belfast and the mean found. This was repeated for each station moving in a clockwise direction around the island until one record of average annual sea level was remained. Jevrejeva et al. (2008) used weighted averages to calculate a more accurate overall record of sea level. However, simple averaging has been used in this exercise.
# Malin & Portrush
AOKE <- merge(mal.year,portru.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Belfast
AOKE <- merge(AOKE,belf.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Bangor
AOKE <- merge(AOKE,bang.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Port Oriel
AOKE <- merge(AOKE,PO.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Howth
AOKE <- merge(AOKE,how.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Dublin
AOKE <- merge(AOKE,dub.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Arklow
AOKE <- merge(AOKE,ark.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Dunmore East
AOKE <- merge(AOKE,dun.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Ballycotton
AOKE <- merge(AOKE,ballyc.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Ringaskiddy
AOKE <- merge(AOKE,ring.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Castletown
AOKE <- merge(AOKE,castlet.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Fenit
AOKE <- merge(AOKE,fen.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Galway
AOKE <- merge(AOKE,gal.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Rossaveel
AOKE <- merge(AOKE,ross.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5,4)]
# Add Ballyglass
AOKE <- merge(AOKE,ballyg.year,by="year",all=TRUE)
AOKE <- AOKE[,c(1,2,4,3)]
colnames(AOKE) <- c("year","x_h","y_h","time")
AOKE_mean <- rowMeans(AOKE[,2:3],na.rm=TRUE)
AOKE <- cbind(AOKE,NA)
colnames(AOKE) <- c("year","x_h","y_h","time","mean")
AOKE$mean <- AOKE_mean
AOKE <- AOKE[,c(1,5)]
The resulting all-Ireland mean sea level curve is plotted in Figure 22.
lm(AOKE$mean~AOKE$year) # Intercept: -2372.680 x: 1.194 mm/yr
##
## Call:
## lm(formula = AOKE$mean ~ AOKE$year)
##
## Coefficients:
## (Intercept) AOKE$year
## -2372.680 1.194
# Plot a curve
plot(AOKE$year, AOKE$mean, type="l", col="blue",
main="Irish Mean Sea Level",ylab="Mean Sea level (mm)",xlab="Year")
abline(lm(AOKE$mean~AOKE$year),col="red")
Figure 22: Irish mean sea level curve
Evident in the curve in Figure 22 is an overall rising trend in Irish mean sea level. Using linear regression, the rate of rise has been found to be 1.194 mm/yr based on this curve. This is similar to estimates of 1.9 ± 0.4 mm/year of global sea level rise since 1961 (Church and White, 2011).
Due to the differing lengths of the records used in this exercise, and the inconsistency in the gathering of data, the curve here may not indicate the exact magnitude of sea level change. Furthermore, the records have not been adjusted to account for glacial isostatic adjustment and hence may include land level change signals alongside signals of sea level change (Dangendorf et al. 2017; Hay et al. 2015) However, it acts as an indicator of the trends in Irish mean sea level and showcases evidence of rising sea levels in Ireland.
Bibliography
Church, J.A. and White, N.J., 2011. Sea-level rise from the late 19th to the early 21st century. Surveys in geophysics, 32(4-5), pp.585-602.
Dangendorf, S., Marcos, M., Wöppelmann, G., Conrad, C. P., Frederikse, T., & Riva, R. (2017). Reassessment of 20th century global mean sea level rise. Proceedings of the National Academy of Sciences, 201616007.
Hay, C. C., Morrow, E., Kopp, R. E., & Mitrovica, J. X. (2015). Probabilistic reanalysis of twentieth-century sea-level rise. Nature, 517(7535), 481.
Jevrejeva, S., Moore, J. C., Grinsted, A., & Woodworth, P. L. (2008). Recent global sea level acceleration started over 200 years ago?. Geophysical Research Letters, 35(8).
Jevrejeva, S., Moore, J.C., Grinsted, A., Matthews, A.P. and Spada, G., 2014. Trends and acceleration in global and regional sea levels since 1807. Global and Planetary Change, 113, pp.11-22.