briskaR
This vignette explains how to use the briskaR
package.
The R package briskaR
offers a generic framework for the simulation of spatially-explicit exposure-hazard model for ecotoxicological studies.
The modeling framework has four main components:
A simulation run is divided in 7 steps:
data("sfMaize65")
# PLOT ------------------------------------------------------------------------
ggplot() + theme_minimal() +
scale_fill_manual(values = c("grey", "orange"),
name = "Maize") +
geom_sf(data = sfMaize65,
aes(fill = as.factor(maize)))
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
# Random 20% are GM field
$maize_GM <- sfMaize65$maize * rbinom(n = nrow(sfMaize65), size = 1 , prob = 0.2) sfMaize65
# filter table to have only GM fields
sfMaize65[sfMaize65$maize_GM == 1,] sfMaize65_GM <-
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## PLOT ------------------------------------------------------------------------
ggplot() + theme_minimal() +
plt_GM <- scale_fill_manual(values = c("grey", "red"),
name = "GM maize") +
geom_sf(data = sfMaize65,
aes(fill = as.factor(maize_GM)))
+
plt_GM geom_sf_text(data = sfMaize65_GM,
aes(label = label))
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
Before proceding the dispersal, we can add a buffer around the landscape. A good approach would be to define sources and receptors at this step in order to embedded all area within the square frame. The eposure is going to be computed over this square frame.
st_squared_geometry(list(sfMaize65), buffer = 200) squareFrame_sfMaize65 <-
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
# PLOT ------------------------------------------------------------------------
+
plt_GM geom_sf(data = squareFrame_sfMaize65, fill = NA)
## old-style crs object detected; please recreate object with a recent sf::st_crs()
## old-style crs object detected; please recreate object with a recent sf::st_crs()
brk_dispersal(sfMaize65_GM,
stack_dispersal <-size_raster = 2^8,
kernel = "geometric",
kernel.options = list("a" = -2.63),
squared_frame = squareFrame_sfMaize65)
## Starting dispersal computing...
## Raster size : 2.56e+02
## Step 1/2: Rasterize... done
## Step 2/2: Compute field... 1... 2... 3... 4... 5... 6... 7... 8... 9... 10... 11... 12... 13... 14... 15... 16... 17... 18... 19... 20... 21... 22... 23... 24... 25... 26... 27... 28... 29... 30... 31... 32... 33... 34... 35... 36... 37... 38... 39... 40... done
# PLOT ------------------------------------------------------------------------
::plot(stack_dispersal[[1:6]]) raster
Emission, Exposure, and then individuals developement, migration and so need a time line. This is done using the function brk_timeline
as follow:
brk_timeline(sf = sfMaize65_GM,
sfMaize65_GM_Pollen <-key = "timeline",
from = as.Date("01-07-2018", format = "%d-%m-%y"),
to = as.Date("01-09-2018", format = "%d-%m-%y"),
by = "days")
# Profile of emission:
data("maize.proportion_pollen")
::plot(maize.proportion_pollen, type= "l") graphics
function(time){
funTimePollen <- runif(1, 7, 11)
density = rgamma(1, shape = 1.6, scale = 1 / (2 * 10 ^ -7))
pollen = length(time)
nbr_days = sample(1:(nbr_days - length(maize.proportion_pollen)), 1)
deb = (deb + length(maize.proportion_pollen) - 1)
end = rep(0, nbr_days)
pollen_emission <-:end] <- as.numeric(pollen * density * maize.proportion_pollen)
pollen_emission[debreturn(pollen_emission)
}
# ADD Column EMISSION To
brk_emission(sf = sfMaize65_GM_Pollen,
sfMaize65_GM_Pollen <-keyTime = "timeline", # Length of the reference timeline
key = "EMISSION", # Name of the new column
# function over each line of sf
FUN = function(i){
funTimePollen(sfMaize65_GM_Pollen$timeline[[i]])
})
## Warning in brk_emission(sf = sfMaize65_GM_Pollen, keyTime = "timeline", : The
## column variable timeline may have changed
seq(from = min(do.call("c", sfMaize65_GM_Pollen[["timeline"]])),
stackTimeline =to = max(do.call("c", sfMaize65_GM_Pollen[["timeline"]])),
by = "days")
brk_exposure(stack_dispersal,
stack_exposure <-
sfMaize65_GM_Pollen,key = "EMISSION", # Name of the new column
keyTime = "timeline", # Length of the reference timeline
loss = 0.1,
beta = 0.2,
quiet = TRUE)
## Step 1/2: Compute global spatio-temporal exposure profile...
## done
## Step 2/2: Convert all matrices to rasters... done
# PLOT ------------------------------------------------------------------------
::plot(stack_exposure[[1:6]]) raster
Plot of exposure out of GM fields
# A MULTIPOLYGON OUT OF GM FIELDS
st_sf(geometry = st_difference(x = st_geometry(squareFrame_sfMaize65),
sfMaize65_outGM <-y = st_union(st_geometry(sfMaize65_GM))))
# POINTS OUT OF GM FIELDS
st_make_grid(squareFrame_sfMaize65, n = 30, what = "centers") # grid n x n !!
gridPOINT_squareFrame <- st_sf(geometry = st_intersection(x = st_geometry(gridPOINT_squareFrame),
gridPOINT_outGM <-y = st_union(st_geometry(sfMaize65_outGM))))
# PLOT ------------------------------------------------------------------------
ggplot() + theme_minimal() +
geom_sf(data = sfMaize65_outGM, fill = "grey30") +
geom_sf(data = gridPOINT_outGM) # point out of GM field
# Create raster
as.data.frame(raster::extract(x = stack_exposure,
df_outGM =y = sf::as_Spatial(gridPOINT_outGM)))
#colnames(df_outGM) = paste0("Time_", gsub("-", "\\1", stackTimeline))
st_as_sf(geometry = st_geometry(gridPOINT_outGM), df_outGM)
sf_outGM =
# PLOT ------------------------------------------------------------------------
ggplot() + theme_minimal() +
labs(title = paste("Exposure at", colnames(df_outGM)[40])) +
scale_color_continuous(low = "green", high = "red",
trans = "log", name = "log scaled") +
geom_sf(data = sf_outGM,
aes(color = df_outGM[,40]))
First of all is to define the receptor area.
We can take any set of place within the area where exposure has been computed. A good way is to consider both receptor and source at the beginning in order to embed both in squareFrame
# Margins around each fields
st_multibuffer(sfMaize65_GM,
sfMaize65_receptor =dist = rep(100, nrow(sfMaize65_GM)))
# PLOT ------------------------------------------------------------------------
plt_GMreceptor <- ggplot() + theme_minimal() +
geom_sf(data = sfMaize65_GM,
fill = "red") +
geom_sf(data = sfMaize65_receptor,
fill = "#669900")
plt_GMreceptor
# 1. Number of site for the first generation
100
nbrSite =# 2. Set eggs
brk_newPoints(sf = sfMaize65_receptor, size = nbrSite) # size = number of sites
sfLarvae <-
# PLOT ------------------------------------------------------------------------
+
plt_GMreceptor geom_sf(data = sfLarvae)
sample(seq(as.Date("01-07-2018", format = "%d-%m-%y"),
DateEmergence =as.Date("01-09-2018", format = "%d-%m-%y"), by = "days"),
size = nbrSite,
replace = TRUE)
brk_timeline( sf = sfLarvae,
sfLarvae =key = "Date",
from = DateEmergence,
to = DateEmergence + 20,
by = "days")
First step is to recover the time line of emission.
sort(unique(do.call("c", sfMaize65_GM_Pollen[["timeline"]]))) stackTimelineEMISSION =
Then we make matching the emission/deposition profile with host
brk_exposureMatch(stackRaster_exposure = stack_exposure,
exposureINDIVIDUAL <-sf = sfLarvae,
stackTimeline = stackTimelineEMISSION,
keyTime = "Date",
key = "EXPOSURE")
Finally we compute a Da
function(x,LC50, slope){
damageLethal =return(1/(1+(x/LC50)^slope))
}
451*10^4
LC50DR = -2.63
slopeDR =
exposureINDIVIDUAL %>%
damageINDIVIDUAL <- dplyr::mutate(DAMAGE = lapply(EXPOSURE, function(expos){damageLethal(expos, LC50DR, slopeDR)}))
data.frame(
DFdamage =DAMAGE = do.call("c", damageINDIVIDUAL[["DAMAGE"]]),
Date = do.call("c", damageINDIVIDUAL[["Date"]]) ) %>%
dplyr::group_by(Date) %>%
dplyr::summarise(mean_DAMAGE = mean(DAMAGE, na.rm = TRUE),
q025_DAMAGE = quantile(DAMAGE, probs = 0.025, na.rm = TRUE),
q975_DAMAGE = quantile(DAMAGE, probs = 0.975, na.rm = TRUE),
min_DAMAGE = min(DAMAGE, na.rm = TRUE),
max_DAMAGE = max(DAMAGE, na.rm = TRUE))
data.frame(Date = do.call("c", damageINDIVIDUAL[["Date"]]))
minDateDAMAGE =
ggplot() +
theme_minimal() +
labs(x = "Time", y = "Probability Distribution of Damage") +
geom_line(data = DFdamage,
aes(x = Date, y = mean_DAMAGE), color = "red") +
geom_ribbon(data = DFdamage,
aes(x = Date, ymin = q025_DAMAGE, ymax = q975_DAMAGE), alpha = 0.5, color = NA, fill = "grey10") +
geom_ribbon(data = DFdamage,
aes(x = Date, ymin = min_DAMAGE, ymax = max_DAMAGE), alpha = 0.5, color = NA, fill = "grey90")