Skip to content

Commit cd8de89

Browse files
committed
regenerated xy scatter for viticulture unweighted
1 parent 72e0da7 commit cd8de89

4 files changed

Lines changed: 208 additions & 15 deletions

File tree

README.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,18 @@ install.packages("blockCV")
4949

5050
### Sitemap
5151

52-
This GitHub project is organized into general sections of our modeling pipeline. Each article can be found in [vignettes](https://github.com/ieco-lab/scari/tree/master/vignettes). Please see this sitemap for navigating both the GitHub repo and our site:
52+
This GitHub project is organized into two groups: vignettes which generate reports for SLF risk to viticulture based on our analysis, and our full modeling pipeline used to create these reports.
53+
54+
Reports can be generated using vignettes 150-152, which contain example usage of our function [create_risk_report()](vignettes/150_create_risk_report.Rmd) (150) to create reports for global countries and states/provinces (151), and for the USA specifically (152).
55+
56+
Please see this sitemap for a guide to our full modeling pipeline:
5357

5458
* vignette 010: Initialize `scari` and usage of `renv` package for dependencies
55-
* 020-030: 1. Retrieve and tidy input data for MaxEnt
56-
* 040-090: 2. SDM modeling pipeline: train global and 3 regional-scale models
57-
* 100-110: 3. Ensemble Regional-scale SDMs
58-
* 120-130: 4. Quantify SLF risk
59-
* 140-142: 5. Quantify Model fit
60-
* 150-152: Example usage of our function [create_risk_report()](vignettes/150_create_risk_report.Rmd) (150) to create reports for global countries and states/provinces (151), and for the USA specifically (152)
61-
* 160: Generation of figures for the companion paper
59+
* 020-030: 1. Retrieve and tidy input data for MaxEnt
60+
* 040-090: 2. SDM modeling pipeline: train global and 3 regional-scale models
61+
* 100-110: 3. Ensemble Regional-scale SDMs
62+
* 120-130, 160: 4. Quantify SLF risk
63+
* 140-142: 5. Quantify Model fit
6264

6365
## How to Use this Project
6466

@@ -70,6 +72,8 @@ Before diving into this project and our modeling workflow, an end user should:
7072
4. Run the first vignette, [010_initialize_renv](vignettes/010_initialize_pkg.Rmd), which initializes `renv` and lists our package's dependencies.
7173
5. See "Get Started" for help in using our package to produce localized reports on SLF risk to viticulture or to recreate our analysis for another invasive species of interest
7274

75+
Once these steps are completed, the end user can get started either generating SLF reports, or following and editing the full modeling pipeline.
76+
7377
### Notes about using this package's code
7478

7579
I use some of the following conventions to ensure that the package's .html files render correctly, the code is not overly cumbersome to run, and that data aren't re-downloaded unnecessarily:

vignettes/110_ensemble_regional_models.Rmd

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2712,7 +2712,7 @@ The weighted mean ensemble is more rigorous because it considers climatic extrap
27122712
```{r unweighted mean pred rasters}
27132713
27142714
# historical
2715-
pred_hist_mean <- terra::app(
2715+
pred_hist_mean_unweighted <- terra::app(
27162716
x = pred_hist_stack,
27172717
fun = "mean",
27182718
filename = file.path(mypath, "models", "slf_regional_ensemble_v2", "ensemble_regional_unweighted_mean_globe_1981-2010.asc"),
@@ -2722,15 +2722,15 @@ pred_hist_mean <- terra::app(
27222722
27232723
# CMIP6
27242724
# ssp126
2725-
pred_126_mean <- terra::app(
2725+
pred_126_mean_unweighted <- terra::app(
27262726
x = pred_126_stack,
27272727
fun = "mean",
27282728
filename = file.path(mypath, "models", "slf_regional_ensemble_v2", "ensemble_regional_unweighted_mean_globe_2041-2070_GFDL_ssp126.asc"),
27292729
filetype = "AAIGrid",
27302730
overwrite = FALSE
27312731
)
27322732
# ssp126
2733-
pred_370_mean <- terra::app(
2733+
pred_370_mean_unweighted <- terra::app(
27342734
x = pred_370_stack,
27352735
fun = "mean",
27362736
filename = file.path(mypath, "models", "slf_regional_ensemble_v2", "ensemble_regional_unweighted_mean_globe_2041-2070_GFDL_ssp370.asc"),
@@ -2739,7 +2739,7 @@ pred_370_mean <- terra::app(
27392739
)
27402740
27412741
# ssp585
2742-
pred_585_mean <- terra::app(
2742+
pred_585_mean_unweighted <- terra::app(
27432743
x = pred_585_stack,
27442744
fun = "mean",
27452745
filename = file.path(mypath, "models", "slf_regional_ensemble_v2", "ensemble_regional_unweighted_mean_globe_2041-2070_GFDL_ssp585.asc"),
@@ -2748,6 +2748,24 @@ pred_585_mean <- terra::app(
27482748
)
27492749
27502750
2751+
```
2752+
2753+
Now I will take an unweighted mean of the above three rasters.
2754+
2755+
```{r take unweighted mean of weighted pred rasters- CMIP6}
2756+
2757+
# stack rasters
2758+
pred_CMIP6_mean_stack_unweighted <- c(pred_126_mean_unweighted, pred_370_mean_unweighted, pred_585_mean_unweighted)
2759+
2760+
# apply mean between layers
2761+
pred_CMIP6_mean_final_unweighted <- terra::app(
2762+
x = pred_CMIP6_mean_stack_unweighted,
2763+
fun = "mean",
2764+
filename = file.path(mypath, "models", "slf_regional_ensemble_v2", "ensemble_regional_unweighted_mean_globe_2041-2070_GFDL_ssp_averaged.asc"),
2765+
filetype = "AAIGrid",
2766+
overwrite = FALSE
2767+
)
2768+
27512769
```
27522770
27532771
I will also take the mean of the MTSS and MTP thresholds

vignettes/130_create_suitability_xy_plots_viticultural.Rmd

Lines changed: 173 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: "Plot shift in SLF risk to important viticultural regions under climate c
33
output: rmarkdown::html_document
44
author:
55
- "Samuel M. Owens^[Temple University, sam.owens@temple.edu, [ORCID](https://orcid.org/0009-0001-2338-7928)]"
6-
date: "2025-08-04"
6+
date: "2026-01-27"
77
---
88

99
# Overview
@@ -14,7 +14,7 @@ In this vignette, I will focus on making more specific predictions for SLF estab
1414

1515
Gallien et al, 2012 originally defined this method for discerning the "stage of invasion" for invasive populations according to different scales of SDM. I will apply this method and re-interpret it as a method for assessing the risk of establishment. These two models will not completely agree on the suitability for a particular location, so agreement between the modeled scales can give us more confidence in that prediction. Where the modeled scales disagree, we might make different interpretations of the biological mechanism at play.
1616

17-
```{r example quadrant plot, echo = FALSE}
17+
```{r example quadrant plot, echo = FALSE, message = FALSE}
1818
1919
library(tidyverse)
2020
@@ -1381,3 +1381,174 @@ We now have risk quadrant plots and tables that we can use to assess the level o
13811381

13821382
2. Smith, T. 2021, August 11. Evaluating Invasion Stage with SDMs - plantarum.ca. <https://plantarum.ca/2021/08/11/invasion-stage/>.
13831383

1384+
<!--
1385+
1386+
# Appendix
1387+
1388+
## plot unweighted mean versions of suitability plots
1389+
1390+
This workflow follows steps 1-3, except that it plots based on the unweighted mean of the calculated regional ensemble (rather than an ensemble created based on AUC and ExDet weights).
1391+
1392+
```{r load in summary files}
1393+
# summary file to extract thresholds from
1394+
1395+
summary_regional_ensemble_unweighted <- read_csv(file = file.path(mypath, "slf_regional_ensemble_v2", "ensemble_threshold_values_unweighted.csv"))
1396+
1397+
1398+
```
1399+
1400+
Finally, I will load in the global and regional ensemble suitability maps. These will be used both for extracting the new xy suitability values and for plotting.
1401+
1402+
```{r load in suitability rasters}
1403+
1404+
# regional_ensemble
1405+
regional_ensemble_1995_unweighted <- terra::rast(
1406+
x = file.path(mypath, "slf_regional_ensemble_v2", "ensemble_regional_unweighted_mean_globe_1981-2010.asc")
1407+
)
1408+
1409+
regional_ensemble_2055_unweighted <- terra::rast(
1410+
x = file.path(mypath, "slf_regional_ensemble_v2", "ensemble_regional_unweighted_mean_globe_2041-2070_GFDL_ssp_averaged.asc")
1411+
)
1412+
1413+
```
1414+
1415+
### Retrieve/Import xy suitability
1416+
1417+
These scatter plots will be based on the suitability for the IVR points in both the global and regional_ensemble models. I have already calculated the xy suitability for the global model based on these points, using the function `slfSpread::predict_xy_suitability()`. This function will not work for the regional_ensemble because it calls for a model object, which we did not use to predict the ensemble suitability. So, I will use `terra::extract()` to perform this action.
1418+
1419+
I will retrieve the suitability values for the regional_ensemble. Instead of returning the coordinates from the map, I will join the coordinates from the original IVR_locations dataset so that the coordinates are exact for joining with other datasets.
1420+
1421+
```{r retrieve xy suitability for regional_ensemble}
1422+
1423+
# 1995
1424+
xy_regional_ensemble_1995_unweighted <- terra::extract(
1425+
x = regional_ensemble_1995_unweighted,
1426+
y = dplyr::select(IVR_locations, x, y), # points
1427+
method = "simple",
1428+
xy = FALSE, # dont return coordinates
1429+
ID = TRUE,
1430+
raw = FALSE # return as df
1431+
)
1432+
1433+
1434+
# 2055
1435+
xy_regional_ensemble_2055_unweighted <- terra::extract(
1436+
x = regional_ensemble_2055_unweighted,
1437+
y = dplyr::select(IVR_locations, x, y), # points
1438+
method = "simple",
1439+
xy = FALSE, # dont return coordinates
1440+
ID = TRUE,
1441+
raw = FALSE # return as df
1442+
)
1443+
1444+
```
1445+
1446+
```{r join xy coordinates}
1447+
1448+
# joining object
1449+
IVR_coordinates <- dplyr::select(IVR_locations, ID, x, y)
1450+
1451+
# perform join
1452+
xy_regional_ensemble_1995_unweighted <- dplyr::left_join(xy_regional_ensemble_1995_unweighted, IVR_coordinates, by = "ID") %>%
1453+
dplyr::select(-ID)
1454+
1455+
xy_regional_ensemble_2055_unweighted <- dplyr::left_join(xy_regional_ensemble_2055_unweighted, IVR_coordinates, by = "ID") %>%
1456+
dplyr::select(-ID)
1457+
1458+
```
1459+
1460+
Now, I will tidy and save the datasets
1461+
1462+
```{r tidy datasets}
1463+
1464+
# regional_ensemble datasets
1465+
xy_regional_ensemble_1995_unweighted <- xy_regional_ensemble_1995_unweighted %>%
1466+
# rename the column for future joining
1467+
dplyr::rename("xy_regional_ensemble_1995_unweighted" = "mean") %>%
1468+
dplyr::filter(!is.na(xy_regional_ensemble_1995_unweighted)) %>%
1469+
dplyr::relocate(x, y) %>%
1470+
dplyr::mutate(
1471+
join_col_x = round(x, 5),
1472+
join_col_y = round(y, 4) # rounding to the 1000s (1km) place to prevent overly sensitive exclusions for UTM data
1473+
) %>%
1474+
dplyr::select(-c(x, y))
1475+
1476+
xy_regional_ensemble_2055_unweighted <- xy_regional_ensemble_2055_unweighted %>%
1477+
# rename the column for future joining
1478+
dplyr::rename("xy_regional_ensemble_2055_unweighted" = "mean") %>%
1479+
dplyr::filter(!is.na(xy_regional_ensemble_2055_unweighted)) %>%
1480+
dplyr::relocate(x, y) %>%
1481+
dplyr::mutate(
1482+
join_col_x = round(x, 5),
1483+
join_col_y = round(y, 4) # rounding to the 1000s (1km) place to prevent overly sensitive exclusions for UTM data
1484+
) %>%
1485+
dplyr::select(-c(x, y))
1486+
1487+
# we lost 1 record because of the NA removal, but that is OK
1488+
1489+
```
1490+
1491+
### plot untransformed suitability
1492+
1493+
```{r join datasets}
1494+
1495+
# join datasets for plotting
1496+
xy_joined_unweighted <- dplyr::full_join(xy_global_1995, xy_regional_ensemble_1995_unweighted, by = c("join_col_x", "join_col_y")) %>%
1497+
# join CC datasets
1498+
dplyr::full_join(., xy_global_2055, by = c("join_col_x", "join_col_y")) %>%
1499+
dplyr::full_join(., xy_regional_ensemble_2055_unweighted, by = c("join_col_x", "join_col_y")) %>%
1500+
# order
1501+
dplyr::relocate(join_col_x, join_col_y, xy_global_1995, xy_global_2055) %>%
1502+
dplyr::select(-c(ID.x, ID.y))
1503+
1504+
```
1505+
1506+
```{r plot SLF suitability values, fig.asp = 1}
1507+
1508+
# figure annotation title
1509+
# "suitability for Lycorma delicatula establishment in globally important viticultural areas, projected for climate change"
1510+
1511+
# plot
1512+
xy_joined_unweighted_plot <- ggplot(data = xy_joined_unweighted) +
1513+
# threshold lines
1514+
# MTSS thresholds
1515+
geom_vline(xintercept = as.numeric(summary_global[42, ncol(summary_global)]), linetype = "dashed", linewidth = 0.7) + # global
1516+
geom_hline(yintercept = as.numeric(summary_regional_ensemble_unweighted[2, 2]), linetype = "dashed", linewidth = 0.7) + # regional_ensemble- there are two MTSS thresholds for this model, but the difference is so small that you will never see it on the plot
1517+
# historical data
1518+
geom_point(
1519+
aes(x = xy_global_1995, y = xy_regional_ensemble_1995_unweighted, shape = "Present"),
1520+
size = 2, stroke = 0.7, color = "black", fill = "orchid1"
1521+
) +
1522+
# GFDL ssp370 data
1523+
geom_point(
1524+
aes(x = xy_global_2055, y = xy_regional_ensemble_2055_unweighted, shape = "Future | GFDL-ESM4\nmean of ssp126/370/585"),
1525+
size = 2, stroke = 0.7, color = "black", fill = "purple3"
1526+
) +
1527+
# axes scaling
1528+
scale_x_continuous(name = "'global' model cloglog suitability", limits = c(0, 1), breaks = breaks) +
1529+
scale_y_continuous(name = "'regional_ensemble' model cloglog suitability", limits = c(0, 1), breaks = breaks) +
1530+
# aesthetics
1531+
scale_shape_manual(name = "Time period", values = c(21, 21)) +
1532+
guides(shape = guide_legend(nrow = 1, override.aes = list(size = 2.5), reverse = TRUE)) +
1533+
theme_bw() +
1534+
theme(legend.position = "bottom", panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
1535+
coord_fixed(ratio = 1)
1536+
1537+
```
1538+
1539+
```{r save scatterplot}
1540+
1541+
ggsave(
1542+
xy_joined_unweighted_plot,
1543+
filename = file.path(
1544+
here::here(), "vignette-outputs", "figures", "IVR_xy_suitability_IVR_regions_global_regional_ensemble_unweighted.jpg"
1545+
),
1546+
height = 8,
1547+
width = 8,
1548+
device = "jpeg",
1549+
dpi = "retina"
1550+
)
1551+
1552+
```
1553+
1554+
-->

vignettes/articles/articles_index.Rmd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Here is the index of articles which outlines the steps in our analysis. Start at
4545
1. [Create suitability maps per model scale](120_create_suitability_maps.html)
4646
2. [Create suitability xy plots for viticultural areas](130_create_suitability_xy_plots_viticultural.html)
4747
3. [Create suitability xy plots for SLF occurrences](131_create_suitability_xy_plots_SLF.html)
48-
4. [Generate and format figures of results](160_generate_format_figures.html)
48+
4. [Create viticultural risk tables](160_generate_format_figures.html)
4949

5050
## Step 6: Validate model fit
5151

0 commit comments

Comments
 (0)