Annex II: R scripts for extra functions
Script to estimate Organic Carbon Stock
# Estimate Organic Carbon Stock (ocs) ===========================
# SOC must be in g/kg (% * 10)
# BLD in kg/m3
# CRF in percentage
<- read_csv("02-Outputs/spline_soil_profile.csv")
d # 0 - 30 cm
<- d$soc_0_30*10
ORCDRC <- 30
HSIZE <- d$bd_0_30*1000
BLD <- d$crf_0_30
CRFVOL
<- ORCDRC/1000 * HSIZE/100 * BLD * (100 - CRFVOL)/100
OCSKG_0_30
# Convert Organic Carbon Stock from kg/m3 to t/ha
$ocs_0_30 <- OCSKG_0_30*10 d
Script to mosaic tiles from covariates downloaded from GEE
library(terra)
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
setwd("..")
# read the tiles
<- list.files(path = "01-Data/covs/", pattern = ".tif$",
f full.names = TRUE)
# put the tiles in a list
<- list()
r_l for (i in seq_along(f)){
<- rast(f[i])
r_l[i]
}# Convert the list in a spatial raster collection
<- sprc(r_l)
r # Mosaic the tiles
<- mosaic(r)
covs # Rename the layers in case the names were lost
<- rast(f[1])
x names(covs) <- names(x)
Script for large countries that cannot mosaic covariates downloaded from GEE
Part I:
## 1.1 - Load covariates files(list of GEE tiles of covariates)--
<- list.files("01-Data/covs", ".tif$", full.names = TRUE)
f <- rast(f[1])
covs <- names(covs)
ncovs
# 1.2 - Load the soil data (Script 2) ---------------------------
<- read_csv("02-Outputs/harmonized_AFACI_soil_data.csv")
dat <- dat
X # Convert soil data into a spatial object
#(check https://epsg.io/6204)
<- vect(dat, geom=c("x", "y"), crs = crs(covs))
dat
## 1.3 - Extract values from covariates to the soil points ------
$ID <- 1:nrow(X)
X
for (i in seq_along(f)) {
<- rast(f[i])
covs <- terra::extract(x = covs, y = dat, xy=FALSE, ID=TRUE)
pv <- pv$ID[complete.cases(pv)]
ids if (i==1) {
<- left_join(X,pv, by = "ID")
X else {
} if (length(ids)>0) {
<- which(names(X)=="ID")
ID.idx <- ncol(X)
X.ncol :X.ncol] <-
X[,ID.idxmap2_df(X[,ID.idx:X.ncol], pv, ~ coalesce(.x, .y))
}
}print(i)
}
summary(X)
%>%
X::st_as_sf(coords = c("x", "y"), crs = 4326) %>%
sf# convert to spatial object
::mapview(zcol = "dtm_twi_500m", cex = 3, lwd = 0.1)
mapview
write_csv(X, "02-Outputs/regression_matrix.csv")
Part II:
## Load covariates ----------------------------------------------
::terraOptions(memfrac = 0.9)
terra<- list()
covs <- list.files("01-Data/covs", ".tif$", full.names = TRUE)
f for (i in seq_along(f)) {
<- rast(f[i])
covs[[i]]
}<- names(covs[[i]])
ncovs
## 5.2 - Predict soil attributes per tiles ----------------------
# country borders
<- vect(shp)
v
for (i in seq_along(target_properties)) {
<- target_properties[i])
(soilatt #load model
<-
model_rn read_rds(
paste0("02-Outputs/models/ranger_model_",soilatt,".rds"))
for (j in seq_along(covs)) {
gc()
# select covariates with the tile j
<- covs[[j]][[1]]
r # Split GEE tiles into 4 smaller tiles
<- rast(nrows = 4, ncols = 1, extent = ext(r), crs = crs(r))
t <- makeTiles(r, t,overwrite=TRUE, filename=
tile "02-Outputs/tiles/tiles.tif")
for (n in seq_along(tile)) {
<- rast(tile[n])
t <- crop(covs[[j]], t)
covst
# create a function to extract the predited
# values from ranger::predict.ranger()
<- \(...) { predict(...)$predictions |> t() }
pfun
# predict conditional standard deviation
::interpolate(covst,
terramodel = model_rn$finalModel,
fun=pfun,
na.rm=TRUE,
type = "quantiles",
what=sd,
filename =
paste0("02-Outputs/tiles/soilatt_tiles/sd_",
"_tile_", j,"_",n, ".tif"),
soilatt,overwrite = TRUE, gdal=c("COMPRESS=DEFLATE"))
gc()
# predict conditional mean
::interpolate(covst,
terramodel = model_rn$finalModel,
fun=pfun,
na.rm=TRUE,
type = "quantiles",
what=mean,
filename = paste0("02-Outputs/tiles/soilatt_tiles/mean_",
"_tile_", j,"_",n, ".tif"),
soilatt,overwrite = TRUE, gdal=c("COMPRESS=DEFLATE"))
gc()
print(paste("tile", j,"_", n, "of", length(covs)))
}
}## 5.3 - Merge tiles both prediction and st -------------------
<- list.files(path = "02-Outputs/tiles/soilatt_tiles/",
f_mean pattern = paste0("mean_", soilatt),
full.names = TRUE)
<- list.files(path = "02-Outputs/tiles/soilatt_tiles/",
f_sd pattern = paste0("sd_", soilatt),
full.names = TRUE)
<- list()
r_mean_l <- list()
r_sd_l
for (g in 1:length(f_mean)){
<- rast(f_mean[g])
r <-r
r_mean_l[[g]] rm(r)
}
for (g in 1:length(f_sd)){
<- rast(f_sd[g])
r <-r
r_sd_l[[g]] rm(r)
}<-sprc(r_mean_l)
r_mean <-sprc(r_sd_l)
r_sd
<- mosaic(r_mean)
pred_mean <- mosaic(r_sd)
pred_sd
# Crop and mask the maps for each country
for (h in seq_along(cty)) {
%>%
pred_mean crop(v[v$ISO3CD==cty[h]]) %>%
mask(v[v$ISO3CD==cty[h]]) %>%
writeRaster(paste0("02-Outputs/maps/",
cty[h],"/",
cty[h],"_mean_",
soilatt,".tif"),
gdal=c("COMPRESS=DEFLATE"))
%>%
pred_sd crop(v[v$ISO3CD==cty[h]]) %>%
mask(v[v$ISO3CD==cty[h]]) %>%
writeRaster(paste0("02-Outputs/maps/",
cty[h],"/",
cty[h],"_sd_",
soilatt,".tif"),
gdal=c("COMPRESS=DEFLATE"))
print(cty[h])
}rm(pred_sd)
rm(pred_mean)
unlink(f_mean)
unlink(f_sd)
gc()
}