v01-Get Started

library(RADIS)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

Introduction

This vignette presents an example of how RADIS can be used.

Inputs

Mandatory inputs for the package are:

  • an sf object representing the study area.
  • the year of interest, to retrieve crop data.
  • the column name in the sf object that contains the unique identifier for spatial features.
  • the period of interest, to retrieve weather data.

Study area

The study area used for demonstration and testing is provided as a shapefile (test.shp) included in the package’s extdata directory. It is loaded as an sf object and serves as the spatial reference for extracting soil and climate data.

study_area_sf <- sf::read_sf(
  system.file("extdata/study_area/test.shp", package = "RADIS")
)
plot(study_area_sf)

Retrieve rpg data

The figure below show 2020 RPG data extracted for each polygon in the study area. This information is used to get crop types, plot areas, etc.

rpg <- get_rpg_data(sf = study_area_sf, year = 2020, id = "id")
## Spherical geometry (s2) switched off
plot(rpg[, "code_cultu"])

Retrieve soil depth

The table below shows the soil depth values extracted for each spatial unit in the study area. These values are used as a basis for estimating available water capacity and simulating water balance.

soil_depth <- get_soil_depth(sf = study_area_sf) %>%
  relocate(id)
## No API token provided.
knitr::kable(soil_depth, format = "pipe")
id AREA PERIMETER PROF_ PROF_ID PR_CL soil_depth_max soil_depth_min soil_depth area_m2 mask_row mask_area geometry
1 3655030000 886775 1224 1223 30 0.3 0 0.3 3655033450 1 6178.549 POLYGON ((770388.6 6283478,…
2 3655030000 886775 1224 1223 30 0.3 0 0.3 3655033450 2 7012.793 POLYGON ((770278.9 6283453,…

Retrieve Soil Available Water Capacity (AWC)

From BDGSF

AWC values from the BDGSF database are extracted for each polygon in the study area. This information is used to characterize the soil available water capacity according to the national typology.

soil_awc_bdgsf <- get_soil_awc(sf = study_area_sf, source = "BDGSF") %>%
  relocate(id)
## No API token provided.
knitr::kable(soil_awc_bdgsf, format = "pipe")
id AREA PERIMETER RESERVE_ RESERVE_ID CLASSE soil_awc_max soil_awc_min soil_awc area_m2 mask_row mask_area geometry
1 3868230000 924525 1439 1438 1 50 0 50 3868225193 1 6178.549 POLYGON ((770388.6 6283478,…
2 3868230000 924525 1439 1438 1 50 0 50 3868225193 2 7012.793 POLYGON ((770278.9 6283453,…

From Info&Sols

To use the Info&Sols database, you need to:

  • Create an account in https://entrepot.recherche.data.gouv.fr.
  • Get an API token from this website (click on your name in the upper right corner and go to API Token).
  • Set an environment variable named API_TOKEN_DATAVERSE or pass you API token directly as the key argument in the get_soil_awc function.

RADIS can retrieve soil AWC :

  • With coarse elements:

AWC estimates from the Info&Sols database, including the effect of coarse elements, provide a more realistic value of available water capacity, especially in stony soils.

soil_awc_infosols_with_coarse <- get_soil_awc(
  sf = study_area_sf, source = "Info&Sols", key = ""
)
knitr::kable(soil_awc_infosols_with_coarse, format = "pipe")
awc_mm_000_200 awc_mm_000_200_sd id mask_row mask_area geometry
83.30530 30.92851 1 1 6178.549 POLYGON ((770388.6 6283478,…
91.86892 35.14992 2 2 7012.793 POLYGON ((770278.9 6283453,…
  • Without coarse elements

AWC values extracted without accounting for coarse elements represent a theoretical maximum, useful for comparing the impact of coarse fragments on water retention.

soil_awc_infosols_without_coarse <- get_soil_awc(
  sf = study_area_sf, source = "Info&Sols", with_coarse_elements = FALSE
)
knitr::kable(soil_awc_infosols_without_coarse, format = "pipe")
awc_mm_000_005 awc_mm_005_015 awc_mm_015_030 awc_mm_030_060 awc_mm_060_100 awc_mm_100_200 id mask_row mask_area geometry
4.578966 8.876132 14.22550 26.63194 33.66027 84.70542 1 1 6178.549 POLYGON ((770388.6 6283478,…
4.601285 8.878830 14.14045 26.75712 34.63015 82.65664 2 2 7012.793 POLYGON ((770278.9 6283453,…

Retrieve Soil Texture

The get_soil_texture() function extracts soil texture information for each spatial unit in the study area. This function supports multiple data sources (e.g., Info&Sols, HWSD, SoilGrids) and allows you to specify the overlay mode for aggregating values. The resulting data includes proportions of sand, silt, and clay, which are essential for characterizing soil physical properties.

From Info&Sols

# Raw format
soil_texture_infosols <- get_soil_texture(
  study_area_sf,
  source = "infosols",
  overlay_mode = "aggregate"
)
knitr::kable(soil_texture_infosols, format = "pipe")
argile.0_5 sable.0_5 limon.0_5 argile.5_15 sable.5_15 limon.5_15 argile.15_30 sable.15_30 limon.15_30 argile.30_60 sable.30_60 limon.30_60 argile.60_100 sable.60_100 limon.60_100 argile.100_200 sable.100_200 limon.100_200 id mask_row mask_area geometry
23.25474 36.73828 40.00697 27.58718 38.33991 34.07292 22.28895 37.66135 40.04969 27.06374 33.20574 39.73052 26.53395 26.98165 46.48440 37.37249 12.47378 50.15373 1 1 6178.549 POLYGON ((770388.6 6283478,…
22.97455 37.24767 39.77778 26.95737 38.67827 34.36436 21.97088 37.64478 40.38434 26.58099 33.68973 39.72928 25.96348 25.91760 48.11892 38.51726 11.83172 49.65101 2 2 7012.793 POLYGON ((770278.9 6283453,…

From HWSD

# Raw format
soil_texture_hwsd <- get_soil_texture(
  study_area_sf,
  source = "hwsd",
  overlay_mode = "aggregate"
)
knitr::kable(soil_texture_hwsd, format = "pipe")
SAND_D1 SAND_D2 SAND_D3 SAND_D4 SAND_D5 SAND_D6 SAND_D7 SILT_D1 SILT_D2 SILT_D3 SILT_D4 SILT_D5 SILT_D6 SILT_D7 CLAY_D1 CLAY_D2 CLAY_D3 CLAY_D4 CLAY_D5 CLAY_D6 CLAY_D7 id mask_row mask_area geometry
31 29 28 29 29 26 29 40 40 41 42 42 43 40 29 31 31 29 29 31 31 1 1 6178.549 POLYGON ((770388.6 6283478,…
31 29 28 29 29 26 29 40 40 41 42 42 43 40 29 31 31 29 29 31 31 2 2 7012.793 POLYGON ((770278.9 6283453,…

SoilGrids

# Raw format
soil_texture_soilgrids <- get_soil_texture(
  study_area_sf,
  source = "soilgrids",
  overlay_mode = "aggregate"
)
knitr::kable(soil_texture_soilgrids, format = "pipe")
sand_0-5cm_mean silt_0-5cm_mean clay_0-5cm_mean sand_5-15cm_mean silt_5-15cm_mean clay_5-15cm_mean sand_15-30cm_mean silt_15-30cm_mean clay_15-30cm_mean sand_30-60cm_mean silt_30-60cm_mean clay_30-60cm_mean sand_60-100cm_mean silt_60-100cm_mean clay_60-100cm_mean sand_100-200cm_mean silt_100-200cm_mean clay_100-200cm_mean id mask_row mask_area geometry
18.40246 23.80822 16.55173 18.17699 24.56995 15.97584 17.50380 22.80869 18.44992 15.84965 22.34541 20.50808 15.77965 22.87616 20.07696 16.60264 21.56242 20.56772 1 1 6178.549 POLYGON ((770388.6 6283478,…
15.38661 19.80250 13.87969 15.20751 20.50634 13.33898 14.56756 19.00281 15.49844 13.17811 18.74157 17.11718 13.17811 19.10091 16.77381 13.83290 18.08678 17.13316 2 2 7012.793 POLYGON ((770278.9 6283453,…

This is a comparison of soil texture results obtained from different data sources (Info&Sols, HWSD, SoilGrids). This helps to highlight differences in estimates and potential implications for downstream analyses.

  • Info&Sols: National French database, high spatial resolution, based on field observations and expert knowledge.
  • HWSD: Global database, moderate resolution, harmonized from multiple sources.
  • SoilGrids: Global database, high spatial resolution, based on machine learning predictions.

Comparing these sources allows to assess the variability and reliability of soil texture data for their specific study area.

# reshape InfoSols
tb_infosols <- tibble::tibble(
  depth = c("0_5", "5_15", "15_30", "30_60", "60_100", "100_200"),
  top   = c(0, 5, 15, 30, 60, 100),
  bot   = c(5, 15, 30, 60, 100, 200)
)
df_infosols <- soil_texture_infosols %>%
  tidyr::pivot_longer(
    matches("^(argile|sable|limon)\\.\\d+_\\d+$"),
    names_to  = c("texture", "depth"),
    names_sep = "\\.",
    values_to = "pc"
  ) %>%
  dplyr::mutate(texture = dplyr::recode(
    texture,
    argile = "Clay",
    limon = "Silt",
    sable = "Sand"
  )) %>%
  dplyr::left_join(tb_infosols, by = "depth") %>%
  dplyr::mutate(source = "InfoSols")

# reshape HWSD
tb_hwsd <- tibble::tibble(
  d   = paste0("D", 1:7),
  top = c(0, 20, 40, 60, 80, 100, 150),
  bot = c(20, 40, 60, 80, 100, 150, 200)
)
df_hwsd <- soil_texture_hwsd %>%
  tidyr::pivot_longer(
    matches("^(SAND|SILT|CLAY)_D\\d+$"),
    names_to      = c("texture", "d"),
    names_pattern = "^(.*)_(D\\d+)$",
    values_to     = "pc"
  ) %>%
  dplyr::mutate(texture = dplyr::recode(
    texture,
    CLAY = "Clay",
    SILT = "Silt",
    SAND = "Sand"
  )) %>%
  dplyr::left_join(tb_hwsd, by = "d") %>%
  dplyr::mutate(source = "HWSD")

# reshape SoilGrids
tb_soilgrids <- tibble::tibble(
  depth = c("0-5cm", "5-15cm", "15-30cm", "30-60cm", "60-100cm", "100-200cm"),
  top   = c(0, 5, 15, 30, 60, 100),
  bot   = c(5, 15, 30, 60, 100, 200)
)
df_soilgrids <- soil_texture_soilgrids %>%
  tidyr::pivot_longer(
    matches("^(sand|silt|clay)_\\d+-\\d+cm_mean$"),
    names_to      = c("texture", "depth"),
    names_pattern = "^(sand|silt|clay)_(\\d+-\\d+cm)_mean$",
    values_to     = "pc"
  ) %>%
  dplyr::mutate(texture = dplyr::recode(
    toupper(texture),
    CLAY = "Clay",
    SILT = "Silt",
    SAND = "Sand"
  )) %>%
  dplyr::left_join(tb_soilgrids, by = "depth") %>%
  dplyr::mutate(source = "SoilGrids")


# combine + prep
df <- dplyr::bind_rows(df_infosols, df_hwsd, df_soilgrids) %>%
  dplyr::filter(!is.na(pc), !is.na(top), !is.na(bot)) %>%
  dplyr::group_by(source, texture, top, bot) %>%
  dplyr::summarise(pc = mean(pc, na.rm = TRUE), .groups = "drop") %>%
  dplyr::mutate(
    y_mid  = (top + bot) / 2,
    source = factor(source, c("InfoSols", "HWSD", "SoilGrids")),
    x_num  = as.numeric(source)
  )

# plot
ggplot2::ggplot(df, ggplot2::aes(x = source)) +
  ggplot2::geom_rect(
    ggplot2::aes(
      xmin = x_num - 0.35, xmax = x_num + 0.35,
      ymin = top, ymax = bot, fill = pc
    ),
    color = "grey30", linewidth = 0.2
  ) +
  ggplot2::geom_text(
    ggplot2::aes(y = y_mid, label = paste0(round(pc, 1), "%")),
    color = "black", size = 3
  ) +
  ggplot2::facet_wrap(~texture, nrow = 1) +
  ggplot2::scale_y_reverse(
    name = "Depth (cm)",
    limits = c(max(df$bot), 0),
    expand = c(0, 0)
  ) +
  ggplot2::scale_x_discrete(name = "Source") +
  ggplot2::scale_fill_gradient(
    low = "#deebf7",
    high = "#3182bd",
    name = "Percentage"
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    panel.grid.major.x = ggplot2::element_blank(),
    panel.grid.minor = ggplot2::element_blank(),
    strip.text = ggplot2::element_text(face = "bold")
  )

Extracted Data Vizualisation

merged <- Reduce(
  f = function(b, lyr) {
    attrs <- sf::st_set_geometry(lyr, NULL)
    left_join(b, attrs, by = "id")
  },
  x = list(
    soil_depth,
    soil_awc_bdgsf,
    soil_awc_infosols_with_coarse,
    soil_awc_infosols_without_coarse,
    soil_texture_infosols
  ),
  init = study_area_sf
)

view_data_map(
  sf = merged,
  cols_to_show = c(
    "AREA.x", "soil_depth", "argile.0_5", "limon.0_5", "sable.0_5",
    "awc_mm_015_030", "awc_mm_030_060", "awc_mm_060_100"
  ),
  rpg_sf = rpg,
  basemaps = "OpenStreetMap"
)