diff --git a/R/download_climate_data.R b/R/download_climate_data.R index 04c7e63..cc9cdf6 100644 --- a/R/download_climate_data.R +++ b/R/download_climate_data.R @@ -1,6 +1,6 @@ -#' Download and Save Climate Data for Multiple Countries (Parquet Format) +#' Download and Save Climate Data for Multiple Countries (Parquet Format, Single Model) #' -#' This function downloads daily climate data for a list of specified countries, saving the data as Parquet files. The data includes both historical and future climate variables at grid points within each country. +#' This function downloads daily climate data for a list of specified countries, saving the data as Parquet files. The data includes both historical and future climate variables at grid points within each country for a specified climate model. #' #' @param PATHS A list containing paths where raw and processed data are stored. #' PATHS is typically the output of the `get_paths()` function and should include: @@ -13,12 +13,22 @@ #' @param n_points An integer specifying the number of grid points to generate within each country for which climate data will be downloaded. #' @param date_start A character string representing the start date for the climate data (in "YYYY-MM-DD" format). #' @param date_stop A character string representing the end date for the climate data (in "YYYY-MM-DD" format). +#' @param climate_model A single character string representing the climate model to use. Available models include: +#' \itemize{ +#' \item \strong{CMCC_CM2_VHR4} +#' \item \strong{FGOALS_f3_H} +#' \item \strong{HiRAM_SIT_HR} +#' \item \strong{MRI_AGCM3_2_S} +#' \item \strong{EC_Earth3P_HR} +#' \item \strong{MPI_ESM1_2_XR} +#' \item \strong{NICAM16_8S} +#' } #' #' @return The function does not return a value. It downloads the climate data for each country and saves the results as Parquet files in the specified directory. #' -#' @details This function uses country shapefiles to generate a grid of points within each country, at which climate data is downloaded. The function retrieves climate data for the specified date range (`date_start` to `date_stop`). The data is saved for each country in a Parquet file named `climate_data___.parquet`. +#' @details This function uses country shapefiles to generate a grid of points within each country, at which climate data is downloaded. The function retrieves climate data for the specified date range (`date_start` to `date_stop`) and the specified climate model. The data is saved for each country in a Parquet file named `climate_data_{climate_model}_{date_start}_{date_stop}_{ISO3}.parquet`. #' -#' The climate data variables include temperature, wind speed, cloud cover, precipitation, and more. The function retrieves data from multiple climate models, including MRI and EC Earth models. +#' The climate data variables include temperature, wind speed, cloud cover, precipitation, and more. The function retrieves data from a single climate model. #' #' @importFrom dplyr select mutate #' @importFrom lubridate year month week yday @@ -36,16 +46,30 @@ #' # API key for climate data API #' api_key <- "your-api-key-here" #' -#' # Download climate data and save it for the specified countries -#' download_climate_data(PATHS, iso_codes, api_key, n_points = 5, -#' date_start = "1970-01-01", date_stop = "2030-12-31") +#' # Download climate data for a specified model and save it for the specified countries +#' download_climate_data(PATHS, iso_codes, n_points = 5, +#' date_start = "1970-01-01", date_stop = "2030-12-31", +#' climate_model = "MRI_AGCM3_2_S", api_key) #'} #' #' @export -download_climate_data <- function(PATHS, iso_codes, api_key, n_points, date_start, date_stop) { - if (!dir.exists(PATHS$DATA_CLIMATE)) dir.create(PATHS$DATA_CLIMATE, recursive = TRUE) +download_climate_data <- function(PATHS, + iso_codes, + n_points, + date_start, + date_stop, + climate_model, + api_key) { + + if (length(climate_model) > 1) stop("One climate model at a time") + + # Ensure output directory exists, if not, create it + if (!dir.exists(PATHS$DATA_CLIMATE)) { + dir.create(PATHS$DATA_CLIMATE, recursive = TRUE) + } + # List of climate variables for both historical and future data climate_variables_historical_and_future <- c( "temperature_2m_mean", "temperature_2m_max", "temperature_2m_min", "wind_speed_10m_mean", "wind_speed_10m_max", "cloud_cover_mean", @@ -60,7 +84,7 @@ download_climate_data <- function(PATHS, iso_codes, api_key, n_points, date_star # Loop through each ISO3 country code for (country_iso_code in iso_codes) { - message(glue::glue("Downloading daily climate data for {country_iso_code} at {n_points} points")) + message(glue::glue("Downloading daily climate data for {country_iso_code} using {climate_model} at {n_points} points")) # Convert ISO3 code to country name and read country shapefile country_name <- MOSAIC::convert_iso_to_country(country_iso_code) @@ -70,14 +94,16 @@ download_climate_data <- function(PATHS, iso_codes, api_key, n_points, date_star grid_points <- MOSAIC::generate_country_grid_n(country_shp, n_points = n_points) coords <- sf::st_coordinates(grid_points) coords <- as.data.frame(coords) + rm(grid_points) + rm(country_shp) # Download climate data for the generated grid points climate_data <- MOSAIC::get_climate_future(lat = coords$Y, lon = coords$X, - start_date = date_start, - end_date = date_stop, + date_start = date_start, + date_stop = date_stop, climate_variables = climate_variables_historical_and_future, - climate_models = c("MRI_AGCM3_2_S", "EC_Earth3P_HR"), + climate_model = climate_model, api_key = api_key) # Add additional metadata columns @@ -91,10 +117,10 @@ download_climate_data <- function(PATHS, iso_codes, api_key, n_points, date_star climate_data ) - # Save climate data as Parquet + # Save climate data as Parquet, including the climate model in the file name arrow::write_parquet(climate_data, - sink = file.path(PATHS$DATA_CLIMATE, paste0("climate_data_", date_start, "_", date_stop, "_", country_iso_code, ".parquet"))) + sink = file.path(PATHS$DATA_CLIMATE, paste0("climate_data_", climate_model, "_", date_start, "_", date_stop, "_", country_iso_code, ".parquet"))) } - message(glue::glue("Climate data saved for all countries here: {PATHS$DATA_CLIMATE}")) + message(glue::glue("Climate data saved for all countries using {climate_model} here: {PATHS$DATA_CLIMATE}")) } diff --git a/R/get_climate_future.R b/R/get_climate_future.R index 0b674e5..c151b79 100644 --- a/R/get_climate_future.R +++ b/R/get_climate_future.R @@ -1,11 +1,11 @@ -#' Download Future Climate Data for Multiple Locations +#' Download Future Climate Data for Multiple Locations (One Model at a Time) #' -#' This function retrieves daily future climate data for multiple specified locations and climate variables over a specified date range using specified climate models. +#' This function retrieves daily future climate data for multiple specified locations and climate variables over a specified date range using a specified climate model. #' #' @param lat A numeric vector representing the latitudes of the locations. #' @param lon A numeric vector representing the longitudes of the locations. -#' @param start_date A character string representing the start date for the data in "YYYY-MM-DD" format. -#' @param end_date A character string representing the end date for the data in "YYYY-MM-DD" format. +#' @param date_start A character string representing the start date for the data in "YYYY-MM-DD" format. +#' @param date_stop A character string representing the end date for the data in "YYYY-MM-DD" format. #' @param climate_variables A character vector of climate variables to retrieve. Valid options include: #' \itemize{ #' \item \strong{temperature_2m_mean}: Mean 2m air temperature. @@ -28,7 +28,7 @@ #' \item \strong{soil_moisture_0_to_10cm_mean}: Mean soil moisture (0-10 cm depth). #' \item \strong{et0_fao_evapotranspiration_sum}: Sum of evapotranspiration (FAO standard). #' } -#' @param climate_models A character vector of climate models to use. Available models include: +#' @param climate_model A single character string representing the climate model to use. Available models include: #' \itemize{ #' \item \strong{CMCC_CM2_VHR4} #' \item \strong{FGOALS_f3_H} @@ -51,7 +51,7 @@ #' } #' #' @details -#' The function retrieves daily future climate data for multiple specified locations using the Open-Meteo Climate API. It downloads the specified climate variables for each latitude and longitude provided, using the selected climate models. The data is retrieved for the date range specified by \code{start_date} and \code{end_date}. A progress bar is displayed to indicate the download progress. +#' The function retrieves daily future climate data for multiple specified locations using the Open-Meteo Climate API. It downloads the specified climate variables for each latitude and longitude provided, using a single climate model. The data is retrieved for the date range specified by \code{date_start} and \code{date_stop}. A progress bar is displayed to indicate the download progress. #' #' @examples #' \dontrun{ @@ -59,25 +59,34 @@ #' lat <- c(40.7128, 34.0522) #' lon <- c(-74.0060, -118.2437) #' -#' # Define the climate variables and models +#' # Define the climate variables and model #' climate_vars <- c("temperature_2m_mean", "precipitation_sum") -#' climate_models <- c("MRI_AGCM3_2_S", "EC_Earth3P_HR") +#' climate_model <- "MRI_AGCM3_2_S" #' #' # Set the date range and API key -#' start_date <- "2023-01-01" -#' end_date <- "2030-12-31" +#' date_start <- "2023-01-01" +#' date_stop <- "2030-12-31" #' api_key <- "your_api_key_here" #' #' # Download the climate data -#' climate_data <- get_climate_future(lat, lon, start_date, end_date, -#' climate_vars, climate_models, api_key) +#' climate_data <- get_climate_future(lat, lon, date_start, date_stop, +#' climate_vars, climate_model, api_key) #' #' # Display the climate data #' head(climate_data) #' } #' #' @export -get_climate_future <- function(lat, lon, start_date, end_date, climate_variables, climate_models, api_key = NULL) { + +get_climate_future <- function(lat, + lon, + date_start, + date_stop, + climate_variables, + climate_model, + api_key = NULL) { + + if (length(climate_model) > 1) stop("One climate model at a time") available_climate_variables <- c( "temperature_2m_mean", "temperature_2m_max", "temperature_2m_min", @@ -100,11 +109,10 @@ get_climate_future <- function(lat, lon, start_date, end_date, climate_variables "NICAM16_8S" ) - if (!all(climate_models %in% available_models)) { - stop(paste("Error: Some of the provided models are not available. Please choose from:", paste(available_models, collapse = ", "))) + if (!(climate_model %in% available_models)) { + stop(paste("Error: The provided climate model is not available. Please choose from:", paste(available_models, collapse = ", "))) } - models_param <- paste(climate_models, collapse = ",") variables_param <- paste(climate_variables, collapse = ",") results_list <- list() @@ -117,9 +125,9 @@ get_climate_future <- function(lat, lon, start_date, end_date, climate_variables "https://customer-climate-api.open-meteo.com/v1/climate?", "latitude=", lat[i], "&longitude=", lon[i], - "&start_date=", start_date, - "&end_date=", end_date, - "&models=", models_param, + "&date_start=", date_start, + "&date_stop=", date_stop, + "&models=", climate_model, "&daily=", variables_param, "&apikey=", api_key ) @@ -130,27 +138,20 @@ get_climate_future <- function(lat, lon, start_date, end_date, climate_variables data <- jsonlite::fromJSON(httr::content(response, "text", encoding = "UTF-8")) dates <- data$daily$time + if (is.character(dates)) dates <- as.Date(substr(dates, 1, 10)) # trim hours if present - if (is.character(dates)) { - dates <- as.Date(substr(dates, 1, 10)) - } - - for (model in climate_models) { + for (variable in climate_variables) { - for (variable in climate_variables) { + if (!is.null(data$daily[[variable]])) { - variable_name <- paste0(variable, "_", model) + results_list[[paste0(i, "_", variable)]] <- + data.frame(date = dates, + latitude = lat[i], + longitude = lon[i], + climate_model = climate_model, + variable_name = variable, + value = data$daily[[variable]]) - if (!is.null(data$daily[[variable_name]])) { - results_list[[paste0(i, "_", model, "_", variable)]] <- data.frame( - date = dates, - latitude = lat[i], - longitude = lon[i], - climate_model = model, - variable_name = variable, - value = data$daily[[variable_name]] - ) - } } } diff --git a/R/get_elevation.R b/R/get_elevation.R index 4f39b58..3b44ada 100644 --- a/R/get_elevation.R +++ b/R/get_elevation.R @@ -35,27 +35,25 @@ get_elevation <- function(PATHS, n_points, api_key = NULL) { requireNamespace('utils') # Load the list of ISO3 country codes for the MOSAIC model - iso_codes <- MOSAIC::iso_codes_mosaic + iso_codes <- MOSAIC::iso_codes_africa # Ensure the elevation directory exists if (!dir.exists(PATHS$DATA_ELEVATION)) dir.create(PATHS$DATA_ELEVATION, recursive = TRUE) results_list <- list() - # Initialize a progress bar pb <- utils::txtProgressBar(min = 0, max = length(iso_codes), style = 3) - # Loop through each country's ISO3 code in iso_codes_mosaic - for (idx in seq_along(iso_codes)) { + for (i in seq_along(iso_codes)) { - iso_code <- iso_codes[idx] + country_results_list <- list() # Construct the path to the shapefile for each country - shapefile_path <- file.path(PATHS$DATA_SHAPEFILES, paste0(iso_code, "_ADM0.shp")) + shapefile_path <- file.path(PATHS$DATA_SHAPEFILES, paste0(iso_codes[i], "_ADM0.shp")) # Check if the shapefile exists if (!file.exists(shapefile_path)) { - message(paste("Shapefile for", iso_code, "not found. Skipping.")) + message(paste("Shapefile for", iso_codes[i], "not found. Skipping.")) next } @@ -63,15 +61,16 @@ get_elevation <- function(PATHS, n_points, api_key = NULL) { country_shapefile <- sf::st_read(shapefile_path, quiet = TRUE) # Generate n_points random points within the country's shapefile boundary - random_points <- sf::st_sample(country_shapefile, size = n_points, type = "random") - coords <- sf::st_coordinates(random_points) + pts <- MOSAIC::generate_country_grid_n(country_shapefile, n_points) + coords <- sf::st_coordinates(pts) + rm(pts) + rm(country_shapefile) - # Loop through each generated point to get elevation - for (i in seq_len(nrow(coords))) { - lat <- coords[i, "Y"] - lon <- coords[i, "X"] + for (j in 1:nrow(coords)) { + + lat <- coords[j, "Y"] + lon <- coords[j, "X"] - # Construct the API request URL for each location url <- paste0( "https://customer-api.open-meteo.com/v1/elevation?", "latitude=", lat, @@ -79,46 +78,33 @@ get_elevation <- function(PATHS, n_points, api_key = NULL) { "&apikey=", api_key ) - # Create a temporary file to save the data temp_file <- tempfile(fileext = ".json") - - # Download the file using download.file with mode = "wb" utils::download.file(url, temp_file, mode = "wb", quiet = TRUE) - - # Load the downloaded JSON file into a data frame data <- jsonlite::fromJSON(temp_file) - # Append the result for this location to the results list - results_list[[length(results_list) + 1]] <- data.frame( - country = iso_code, - latitude = lat, - longitude = lon, - elevation = data$elevation - ) + country_df <- data.frame(country = iso_codes[i], + latitude = lat, + longitude = lon, + elevation = data$elevation) + + country_results_list <- c(country_results_list, list(country_df)) + } - # Update progress bar - utils::setTxtProgressBar(pb, idx) + result_country <- do.call(rbind, country_results_list) + result_country <- aggregate(elevation ~ country, data = result_country, FUN = median, na.rm = TRUE) + results_list <- c(results_list, list(result_country)) + + utils::setTxtProgressBar(pb, i) + } - # Close the progress bar close(pb) - # Combine all results into a single data frame out <- do.call(rbind, results_list) - # Calculate the median elevation for each country - median_elevations <- aggregate(elevation ~ country, data = out, FUN = median, na.rm = TRUE) - - # Define the file path to save the elevation data file_path <- file.path(PATHS$DATA_ELEVATION, "median_elevation_data.csv") - - # Save the data to a CSV file utils::write.csv(out, file = file_path, row.names = FALSE) - message(paste("Elevation data saved to:", file_path)) - # Return the median elevations as a data frame - return(median_elevations) - } diff --git a/man/download_climate_data.Rd b/man/download_climate_data.Rd index 29b7f74..8175a2e 100644 --- a/man/download_climate_data.Rd +++ b/man/download_climate_data.Rd @@ -2,15 +2,16 @@ % Please edit documentation in R/download_climate_data.R \name{download_climate_data} \alias{download_climate_data} -\title{Download and Save Climate Data for Multiple Countries (Parquet Format)} +\title{Download and Save Climate Data for Multiple Countries (Parquet Format, Single Model)} \usage{ download_climate_data( PATHS, iso_codes, - api_key, n_points, date_start, - date_stop + date_stop, + climate_model, + api_key ) } \arguments{ @@ -23,24 +24,35 @@ PATHS is typically the output of the \code{get_paths()} function and should incl \item{iso_codes}{A character vector of ISO3 country codes for which climate data should be downloaded.} -\item{api_key}{A character string representing the API key required to access the climate data API.} - \item{n_points}{An integer specifying the number of grid points to generate within each country for which climate data will be downloaded.} \item{date_start}{A character string representing the start date for the climate data (in "YYYY-MM-DD" format).} \item{date_stop}{A character string representing the end date for the climate data (in "YYYY-MM-DD" format).} + +\item{climate_model}{A single character string representing the climate model to use. Available models include: +\itemize{ +\item \strong{CMCC_CM2_VHR4} +\item \strong{FGOALS_f3_H} +\item \strong{HiRAM_SIT_HR} +\item \strong{MRI_AGCM3_2_S} +\item \strong{EC_Earth3P_HR} +\item \strong{MPI_ESM1_2_XR} +\item \strong{NICAM16_8S} +}} + +\item{api_key}{A character string representing the API key required to access the climate data API.} } \value{ The function does not return a value. It downloads the climate data for each country and saves the results as Parquet files in the specified directory. } \description{ -This function downloads daily climate data for a list of specified countries, saving the data as Parquet files. The data includes both historical and future climate variables at grid points within each country. +This function downloads daily climate data for a list of specified countries, saving the data as Parquet files. The data includes both historical and future climate variables at grid points within each country for a specified climate model. } \details{ -This function uses country shapefiles to generate a grid of points within each country, at which climate data is downloaded. The function retrieves climate data for the specified date range (\code{date_start} to \code{date_stop}). The data is saved for each country in a Parquet file named \verb{climate_data___.parquet}. +This function uses country shapefiles to generate a grid of points within each country, at which climate data is downloaded. The function retrieves climate data for the specified date range (\code{date_start} to \code{date_stop}) and the specified climate model. The data is saved for each country in a Parquet file named \verb{climate_data_\{climate_model\}_\{date_start\}_\{date_stop\}_\{ISO3\}.parquet}. -The climate data variables include temperature, wind speed, cloud cover, precipitation, and more. The function retrieves data from multiple climate models, including MRI and EC Earth models. +The climate data variables include temperature, wind speed, cloud cover, precipitation, and more. The function retrieves data from a single climate model. } \examples{ \dontrun{ @@ -53,9 +65,10 @@ iso_codes <- c("ZAF", "KEN", "NGA") # API key for climate data API api_key <- "your-api-key-here" -# Download climate data and save it for the specified countries -download_climate_data(PATHS, iso_codes, api_key, n_points = 5, - date_start = "1970-01-01", date_stop = "2030-12-31") +# Download climate data for a specified model and save it for the specified countries +download_climate_data(PATHS, iso_codes, n_points = 5, + date_start = "1970-01-01", date_stop = "2030-12-31", + climate_model = "MRI_AGCM3_2_S", api_key) } } diff --git a/man/get_climate_future.Rd b/man/get_climate_future.Rd index 26e6d7f..4b90c8b 100644 --- a/man/get_climate_future.Rd +++ b/man/get_climate_future.Rd @@ -2,15 +2,15 @@ % Please edit documentation in R/get_climate_future.R \name{get_climate_future} \alias{get_climate_future} -\title{Download Future Climate Data for Multiple Locations} +\title{Download Future Climate Data for Multiple Locations (One Model at a Time)} \usage{ get_climate_future( lat, lon, - start_date, - end_date, + date_start, + date_stop, climate_variables, - climate_models, + climate_model, api_key = NULL ) } @@ -19,9 +19,9 @@ get_climate_future( \item{lon}{A numeric vector representing the longitudes of the locations.} -\item{start_date}{A character string representing the start date for the data in "YYYY-MM-DD" format.} +\item{date_start}{A character string representing the start date for the data in "YYYY-MM-DD" format.} -\item{end_date}{A character string representing the end date for the data in "YYYY-MM-DD" format.} +\item{date_stop}{A character string representing the end date for the data in "YYYY-MM-DD" format.} \item{climate_variables}{A character vector of climate variables to retrieve. Valid options include: \itemize{ @@ -46,7 +46,7 @@ get_climate_future( \item \strong{et0_fao_evapotranspiration_sum}: Sum of evapotranspiration (FAO standard). }} -\item{climate_models}{A character vector of climate models to use. Available models include: +\item{climate_model}{A single character string representing the climate model to use. Available models include: \itemize{ \item \strong{CMCC_CM2_VHR4} \item \strong{FGOALS_f3_H} @@ -71,10 +71,10 @@ A data frame with columns: } } \description{ -This function retrieves daily future climate data for multiple specified locations and climate variables over a specified date range using specified climate models. +This function retrieves daily future climate data for multiple specified locations and climate variables over a specified date range using a specified climate model. } \details{ -The function retrieves daily future climate data for multiple specified locations using the Open-Meteo Climate API. It downloads the specified climate variables for each latitude and longitude provided, using the selected climate models. The data is retrieved for the date range specified by \code{start_date} and \code{end_date}. A progress bar is displayed to indicate the download progress. +The function retrieves daily future climate data for multiple specified locations using the Open-Meteo Climate API. It downloads the specified climate variables for each latitude and longitude provided, using a single climate model. The data is retrieved for the date range specified by \code{date_start} and \code{date_stop}. A progress bar is displayed to indicate the download progress. } \examples{ \dontrun{ @@ -82,18 +82,18 @@ The function retrieves daily future climate data for multiple specified location lat <- c(40.7128, 34.0522) lon <- c(-74.0060, -118.2437) -# Define the climate variables and models +# Define the climate variables and model climate_vars <- c("temperature_2m_mean", "precipitation_sum") -climate_models <- c("MRI_AGCM3_2_S", "EC_Earth3P_HR") +climate_model <- "MRI_AGCM3_2_S" # Set the date range and API key -start_date <- "2023-01-01" -end_date <- "2030-12-31" +date_start <- "2023-01-01" +date_stop <- "2030-12-31" api_key <- "your_api_key_here" # Download the climate data -climate_data <- get_climate_future(lat, lon, start_date, end_date, - climate_vars, climate_models, api_key) +climate_data <- get_climate_future(lat, lon, date_start, date_stop, + climate_vars, climate_model, api_key) # Display the climate data head(climate_data)