This page shows functions to extract data from Frost using the R language.
#########################################################################################################################
# Get hourly data from Frost. This function gets hourly data from a given period. Gaps in the time series are set to NA
##########################################################################################################################
GetHourly <- function(from_date, to_date, stnr, Welements, TimeRes, client_id) {
url <- paste("https://", client_id, "@frost.met.no/observations/v0.jsonld?",
"sources=", paste(stnr,collapse=",") ,
"&referencetime=", from_date, "/", to_date,
"&elements=", paste(Welements,collapse=","),
"&timeresolutions=", paste(TimeRes),
sep = "", collapse= "")
# Henter ut data via API
xs <- scan(url, what="")
a <- grep("referenceTime", xs, fixed=TRUE)
b <- grep("sourceId", xs, fixed=TRUE)
d <- grep(Welements, xs, fixed=TRUE)
# Fjerner førte element i vektor dersom den viser til en streng som er forskjellig fra parameternavn
if (xs[d[1]] != Welements) {d <- d[2:length(d)]}
# Stasjonsnummer
Serie <- as.character(xs[b+2])
# Fjern komma bak verdi og gjør om til numerisk
Param <- as.character(xs[d+4])
Param <- substring(Param,1,nchar(Param)-1)
Param <- as.numeric(Param)
# Tidspunkter fra Frost i tekstformat
datetime <- strptime(x = as.character(xs[a+2]), format = "%Y-%m-%dT%H:%M:%S")
datetimeCh <- substring(datetime,1,13)
# Alle dagene i perioden, må fjerne siste dag ettersom til dato er kl 00
DayPeriod <- seq(as.Date(from_date), as.Date(to_date), by = "day")
DayPeriod <- DayPeriod[-length(DayPeriod)]
DayPeriod <- as.character(DayPeriod)
# Lager vektor med alle timer i tidsrom
HoursPeriod <- c(1:(24*length(DayPeriod)))
i <- 0
for (dag in 1 : length(DayPeriod)) {
DenneDag <- as.character(DayPeriod[dag])
for (time in 0 : 23) {
i <- i+1
if (time < 10) {DenneTime <- paste("0",time, sep="")} else {DenneTime <- as.character(time)}
HoursPeriod[i] <- paste(DenneDag, DenneTime, sep=" ")
}
}
StID = substring(Serie, 0, (nchar(Serie) - 2))
# Denne legger inn manglende timer i en tidsserie.
# Sjekker først time separat før man løper gjennom resten
if (datetimeCh[1] != HoursPeriod[1]) {
datetimeCh <- append(HoursPeriod[1], datetimeCh)
Param <- append(NA, Param)
Serie <- append(Serie[1], Serie)
}
for (time in 1:length(HoursPeriod)){
if (datetimeCh[time] != HoursPeriod[time]) {
# Legg til et element i OBS data
datetimeCh <- append(datetimeCh, HoursPeriod[time], after=(time-1))
Param <- append(Param, NA, after=(time-1))
Serie <- append(Serie, Serie[1], after=(time-1))
}
}
# Time series is stored in a frame and returned
stTable <- data.frame(datetimeCh, Serie, Param, pri = substring(Serie, nchar(Serie), nchar(Serie)), stringsAsFactors=FALSE)
names(stTable) <- c("Time", "Source", "Value", "Pri")
return(stTable)
} # End of fucntion GetHourly
############################################################################################################################
############################################################################################################################
# Get daily data from Frost
# This function gets hourly data from a given period. Gaps in the time series are set to Na.
#############################################################################################################################
GetDaily <- function(from_date, to_date, stnr, Welements, client_id) {
url <- paste("https://", client_id, "@frost.met.no/observations/v0.jsonld?",
"sources=", paste(stnr,collapse=",") ,
"&referencetime=", from_date, "/", to_date,
"&elements=", paste(Welements,collapse=","),
sep = "", collapse= "")
# Henter ut data via API
xs <- scan(url, what="")
a <- grep("referenceTime", xs, fixed=TRUE)
b <- grep("sourceId", xs, fixed=TRUE)
d <- grep(Welements, xs, fixed=TRUE) # Funker hit
# Stasjonsnummer
Serie <- as.character(xs[b+2])
# Fjern komma bak verdi og gjør om til numerisk
Param <- as.character(xs[d+4])
Param <- substring(Param,1,nchar(Param)-1)
Param <- as.numeric(Param)
# Tidspunkter fra Frost i tekstformat
datetime <- strptime(x = as.character(xs[a+2]), format = "%Y-%m-%dT%H:%M:%S")
datetimeCh <- substring(datetime,1,11)
# Alle dagene i perioden, må fjerne siste dag ettersom til dato er kl 00
DayPeriod <- seq(as.Date(from_date), as.Date(to_date), by = "day")
DayPeriod <- DayPeriod[-length(DayPeriod)]
DayPeriod <- as.character(DayPeriod)
StID = substring(Serie, 0, (nchar(Serie) - 2))
# Denne legger inn manglende dager i en tidsserie.
# Første dag må sjekkes separat, deretter løper man gjennom hele perioden.
if (!is.na(datetimeCh[1])) {
if (datetimeCh[1] != DayPeriod[1]) {
datetimeCh <- append(DayPeriod[1], datetimeCh)
Param <- append(NA, Param)
Serie <- append(Serie[1], Serie)
}
}
for (dag in 1:length(DayPeriod)){
if (!is.na(datetimeCh[dag])) {
if (datetimeCh[dag] != DayPeriod[dag]) {
# Legg til et element i OBS data
datetimeCh <- append(datetimeCh, DayPeriod[dag], after=(dag-1))
Param <- append(Param, NA, after=(dag-1))
Serie <- append(Serie, Serie[1], after=(dag-1))
}
}
}
stTable <- data.frame(datetimeCh, Serie, Param, pri = substring(Serie, nchar(Serie), nchar(Serie)), stringsAsFactors=FALSE)
names(stTable) <- c("Time", "Source", "Value", "Pri")
return(stTable)
} # End of function GetDaily
######################################################################################
# Get hourly data between two given dates from Frost
# Data are retruned in a data frame, and missing values are set to NA
# Only one element and one station a time.
# If perdiod os longer than one year, period is split
# Function GetHourly is called
######################################################################################
GetHourlyDataFrost <- function(start_date, stop_date, stnr, Welements, TimeRes, client_id) {
StartAar <- as.numeric(substring(start_date,1,4))
EndAar <- as.numeric(substring(stop_date,1,4))
if (StartAar == EndAar) { # Less than a year, no loop required
stTable <- GetHourly(start_date, stop_date, stnr, Welements, TimeRes, client_id)
return(stTable) }
else {
# Henter data for maks et år av gangen og legger inn i dataframe
for (yy in StartAar:(EndAar-1)) {
if (yy == StartAar) {from_date <- start_date} else {from_date <- sprintf("%d-01-01T00:00", yy) }
if (yy == (EndAar-1)) {to_date <- stop_date} else {to_date <- sprintf("%d-01-01T00:00", yy+1) }
if (yy == StartAar) {
stTable <- GetHourly(from_date, to_date, stnr, Welements, TimeRes, client_id)
} else {
TempTable <- GetHourly(from_date, to_date, stnr, Welements, TimeRes, client_id)
stTable <- rbind(stTable, TempTable)
}
}
}
return(stTable)
} # Funksjonen slutter
################################################################################################################
######################################################################################
# Get dailydata between two given dates from Frost
# Data are retruned in a data frame, and missing values are set to NA
# Only one element and one station a time.
# If perdiod os longer than one year, period is split
# Function GetDaily is called
######################################################################################
GetDailyDataFrost <- function(start_date, stop_date, stnr, Welements, client_id) {
StartAar <- as.numeric(substring(start_date,1,4))
EndAar <- as.numeric(substring(stop_date,1,4))
if (StartAar == EndAar) { # Less than a year, no loop required
stTable <- GetDaily(start_date, stop_date, stnr, Welements, client_id)
return(stTable) }
else {
# Henter data for maks et år av gangen og legger inn i dataframe
for (yy in StartAar:(EndAar-1)) {
if (yy == StartAar) {from_date <- start_date} else {from_date <- sprintf("%d-01-01T00:00", yy) } # Hva med from to_date
if (yy == (EndAar-1)) {to_date <- stop_date} else {to_date <- sprintf("%d-01-01T00:00", yy+1) }
if (yy == StartAar) {
stTable <- GetDaily(from_date, to_date, stnr, Welements, client_id)
} else {
TempTable <- GetDaily(from_date, to_date, stnr, Welements, client_id)
stTable <- rbind(stTable, TempTable)
}
}
}
return(stTable)
} # Funksjonen slutter
####
Side note: ESD is an R-package for climate and weather analysis developed at MET Norway. Try it out!