SYNOP is a standardized format for reporting weather observations usually every hour. This vignette demonstrates how to work with SYNOP FM-12 meteorological messages using the climate package.
The package provides two complementary functions for handling SYNOP data:
synop_parser() — parse raw SYNOP
message strings into structured datameteo_ogimet(source = "synop") —
download raw SYNOP messages from Ogimet web service and decode them
automaticallysynop_parser() Function
The synop_parser() function decodes raw SYNOP messages
into either a tidy data frame or a nested list structure.
SYNOP messages should be provided as text vector of any length, e.g:
# Parse multiple messages
messages = c(
"AAXX 01004 88889 12782 61506 10094 20047 30111 40197 53007 60001 81541",
"AAXX 01006 12330 32782 61506 10094 20047 30111 40197 53007 60001 81541"
)
# Multiple messages as a data frame
df_multiple = synop_parser(messages, as_data_frame = TRUE)
df_multiple$source = NULL # remove raw message from output
# Display the results in a table
kable(t(df_multiple), caption = "Examplary results of parsing multiple SYNOP message into data frame")| station_type | AAXX | AAXX |
| station_id | 88889 | 12330 |
| region | III | VI |
| obs_day | 1 | 1 |
| obs_hour | 0 | 0 |
| wind_unit | KT | KT |
| wind_estimated | FALSE | FALSE |
| visibility | 40000 | 40000 |
| cloud_cover | 6 | 6 |
| wind_direction | 150 | 150 |
| wind_speed | 6 | 6 |
| air_temperature | 9.4 | 9.4 |
| dewpoint_temperature | 4.7 | 4.7 |
| station_pressure | 1011.1 | 1011.1 |
| sea_level_pressure | 1019.7 | 1019.7 |
| pressure_tendency | 3 | 3 |
| pressure_change | 0.7 | 0.7 |
| precipitation_amount | 0 | NA |
| precipitation_time | 12 | NA |
| cloud_base_min | 1500 | 1500 |
| cloud_base_max | 2000 | 2000 |
| low_cloud_type | 5 | 5 |
| middle_cloud_type | 4 | 4 |
| high_cloud_type | 1 | 1 |
| low_cloud_amount | 1 | 1 |
| maximum_temperature | NA | NA |
| minimum_temperature | NA | NA |
| gust | NA | NA |
| cloudiness_height | NA | NA |
| sunshine_duration | NA | NA |
| snow_depth | NA | NA |
| snow_depth_state | NA | NA |
When as_data_frame = TRUE, the returned data frame
includes the following columns:
Identification and metadata: -
station_type — station classification code -
station_id — WMO station identifier - region —
geographic region code - obs_day — observation day of month
- obs_hour — observation hour (UTC)
Wind: - wind_unit — either “m/s” or
“knots” - wind_estimated — whether wind is estimated -
wind_direction — direction in degrees (0–360°) -
wind_speed — speed in the reported unit
Temperature and moisture: -
air_temperature — air temperature (°C) -
dewpoint_temperature — dew point (°C)
Pressure: - station_pressure —
station-level pressure (hPa) - sea_level_pressure —
sea-level pressure (hPa) - pressure_tendency — pressure
change indicator - pressure_change — 3-hour pressure change
(hPa)
Clouds: - cloud_cover — total cloud
cover (oktas, 0–8) - low_cloud_type — type of low clouds
(Sc, St, Cu, Cb) - middle_cloud_type — type of middle
clouds (Ac, As, Ns) - high_cloud_type — type of high clouds
(Ci, Cc, Cs) - low_cloud_amount — cover of low clouds
(oktas) - visibility — horizontal visibility (m) -
cloud_base_min, cloud_base_max — cloud base
height range (m)
Precipitation and other: -
precipitation_amount — total precipitation (mm) -
precipitation_time — precipitation period (hours) -
maximum_temperature — daily maximum (°C, from Section 3) -
minimum_temperature — daily minimum (°C, from Section 3) -
gust — highest wind gust (in the message’s wind unit) -
sunshine_duration — daily sunshine duration (hours) -
snow_depth — total snow depth (cm) -
snow_depth_state — descriptive snow/ground state
For more granular access most of decoded field, use the default list output:
# Single message as a nested list
synop_code = messages[1]
decoded = synop_parser(synop_code)
str(decoded)## List of 18
## $ station_type :List of 1
## ..$ value: chr "AAXX"
## $ obs_time :List of 2
## ..$ day :List of 1
## .. ..$ value: int 1
## ..$ hour:List of 1
## .. ..$ value: int 0
## $ wind_indicator :List of 3
## ..$ value : int 4
## ..$ unit : chr "KT"
## ..$ estimated: logi FALSE
## $ station_id :List of 1
## ..$ value: chr "88889"
## $ region :List of 1
## ..$ value: chr "III"
## $ precipitation_indicator:List of 3
## ..$ value : int 1
## ..$ in_group_1: logi TRUE
## ..$ in_group_3: logi FALSE
## $ weather_indicator :List of 2
## ..$ value : int 2
## ..$ automatic: logi FALSE
## $ lowest_cloud_base :List of 6
## ..$ min : num 1500
## ..$ max : num 2000
## ..$ quantifier: NULL
## ..$ _table : chr "1600"
## ..$ _code : int 7
## ..$ unit : chr "m"
## $ visibility :List of 6
## ..$ value : num 40000
## ..$ quantifier: NULL
## ..$ use90 : logi FALSE
## ..$ _table : chr "4377"
## ..$ _code : int 82
## ..$ unit : chr "m"
## $ cloud_cover :List of 5
## ..$ value : int 6
## ..$ obscured: logi FALSE
## ..$ unit : chr "okta"
## ..$ _table : chr "2700"
## ..$ _code : int 6
## $ surface_wind :List of 2
## ..$ direction:List of 6
## .. ..$ value : num 150
## .. ..$ varAllUnknown: logi FALSE
## .. ..$ calm : logi FALSE
## .. ..$ _table : chr "0877"
## .. ..$ _code : int 15
## .. ..$ unit : chr "deg"
## ..$ speed :List of 2
## .. ..$ value: int 6
## .. ..$ unit : chr "KT"
## $ air_temperature :List of 2
## ..$ value: num 9.4
## ..$ unit : chr "Celsius"
## $ dewpoint_temperature :List of 2
## ..$ value: num 4.7
## ..$ unit : chr "Celsius"
## $ station_pressure :List of 2
## ..$ value: num 1011
## ..$ unit : chr "hPa"
## $ sea_level_pressure :List of 2
## ..$ value: num 1020
## ..$ unit : chr "hPa"
## $ pressure_tendency :List of 2
## ..$ tendency:List of 1
## .. ..$ value: int 3
## ..$ change :List of 2
## .. ..$ value: num 0.7
## .. ..$ unit : chr "hPa"
## $ precipitation_s1 :List of 2
## ..$ amount :List of 6
## .. ..$ value : int 0
## .. ..$ quantifier: NULL
## .. ..$ trace : logi FALSE
## .. ..$ _table : chr "3590"
## .. ..$ _code : int 0
## .. ..$ unit : chr "mm"
## ..$ time_before_obs:List of 4
## .. ..$ value : num 12
## .. ..$ unit : chr "h"
## .. ..$ _table: chr "4019"
## .. ..$ _code : int 1
## $ cloud_types :List of 4
## ..$ low_cloud_type :List of 1
## .. ..$ value: int 5
## ..$ middle_cloud_type:List of 1
## .. ..$ value: int 4
## ..$ high_cloud_type :List of 1
## .. ..$ value: int 1
## ..$ low_cloud_amount :List of 5
## .. ..$ value : int 1
## .. ..$ obscured: logi FALSE
## .. ..$ unit : chr "okta"
## .. ..$ _table : chr "2700"
## .. ..$ _code : int 1
To parse multiple messages and keep each as a separate list element:
# Returns a list of two decoded messages
decoded_list = synop_parser(messages, simplify = FALSE)
# Access the first message
decoded_list[[1]]Some SYNOP groups (e.g., precipitation indicators) are
country-specific. Pass the country parameter to adjust
decoding:
# Parse with Russia-specific precipitation decoding
decoded_ru = synop_parser(synop_code, country = "RU", as_data_frame = TRUE)
# Compare with default
decoded_default = synop_parser(synop_code, as_data_frame = TRUE)meteo_ogimet() Function — SYNOP Backend
The meteo_ogimet() function (with
source = "synop") downloads SYNOP messages from Ogimet and automatically decodes them
using parser().
Fetch SYNOP data from OGIMET service for one or more WMO station IDs:
# can be used with multiple stations:
two_stations = meteo_ogimet(
source = "synop",
station = c(12330, 12375),
date = c("2024-01-01", "2024-01-10")
)## station: 12330
## http://www.ogimet.com/cgi-bin/getsynop?block=12330&begin=202401010000&end=202401102359
## Downloaded 240 SYNOP messages for: 12330
## station: 12375
## http://www.ogimet.com/cgi-bin/getsynop?block=12375&begin=202401010000&end=202401102359
## Downloaded 240 SYNOP messages for: 12375
| date | station | t2m | dpt2m | rel_hum | tmax | tmin | wd | ws | gust | press | slp | press_tend | precip | Nt | Nh | N_base | insol | visibility | snow |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2024-01-01 00:00:00 | 12330 | 3.1 | 2.2 | 93.8 | NA | NA | 160 | 1 | NA | 995.6 | 1006.6 | -0.2 | 0 | 8 | 7 | 1000 | NA | 1200 | NA |
| 2024-01-01 01:00:00 | 12330 | 2.7 | 1.8 | 93.8 | NA | NA | 200 | 1 | NA | 995.7 | 1006.7 | -0.2 | NA | 8 | 4 | 1500 | NA | 1000 | NA |
| 2024-01-01 02:00:00 | 12330 | 2.5 | 1.8 | 95.1 | NA | NA | 230 | 2 | NA | 995.6 | 1006.6 | -0.3 | NA | 8 | NA | NA | NA | 4000 | NA |
| 2024-01-01 03:00:00 | 12330 | 3.2 | 2.2 | 93.2 | NA | NA | 220 | 3 | NA | 995.5 | 1006.5 | -0.1 | NA | 8 | 3 | 1000 | NA | 7000 | NA |
| 2024-01-01 04:00:00 | 12330 | 3.3 | 2.1 | 91.8 | NA | NA | 220 | 2 | NA | 995.3 | 1006.3 | -0.4 | NA | 8 | 3 | 1000 | NA | 9000 | NA |
| 2024-01-01 05:00:00 | 12330 | 3.4 | 2.4 | 93.2 | NA | NA | 200 | 2 | NA | 995.0 | 1006.0 | -0.6 | NA | 8 | NA | NA | NA | 9000 | NA |
Fetch SYNOP data for all Ogimet stations in a country for a given time range:
# All Polish stations for a single day
poland = meteo_ogimet(
source = "synop",
country_name = "Poland",
date = c("2024-01-15", "2024-01-15")
)## Downloading country: Poland
## http://www.ogimet.com/cgi-bin/getsynop?begin=202401150000&end=202401152359&state=Poland
## Could not retrieve data for: Poland
## No SYNOP data returned for: Poland
head(poland)## NULL
By default, meteo_ogimet() returns a simplified data
frame with the most commonly used variables. To get all decoded SYNOP
fields, use simplified = FALSE:
# Full synop_parser output
full = meteo_ogimet(
source = "synop",
station = 12330,
date = c("2024-01-01", "2024-01-05"),
simplified = FALSE
)## station: 12330
## http://www.ogimet.com/cgi-bin/getsynop?block=12330&begin=202401010000&end=202401052359
## Could not retrieve data for: 12330
## No SYNOP data returned for: 12330
head(full)## NULL
To obtain both the simplified and full data frames in one call, use
return_list = TRUE:
result = meteo_ogimet(
source = "synop",
station = 12330,
date = c("2024-01-01", "2024-01-05"),
return_list = TRUE
)
# Compact 20-column view
names(result$data)
# Full 30+ column parser output
names(result$full)NA.meteo_ogimet(source = "html")