qPRAentry workflow

library(qPRAentry)

Introduction

qPRAentry is a package designed for the quantitative pest risk assessment (PRA) entry step, which is the initial phase of a PRA that evaluates the movement of a plant pest into an area.

Two examples of the process flow in the PRA entry step, and the application of the functions available in the qPRAentry package, are shown below. The example A uses the functions applicable to any country in the world using ISO codes (ISO 3166 Maintenance Agency). The example B uses the functions designed for use with the NUTS code system (NUTS - Nomenclature of territorial units for statistics).

In both cases, trade data are required for the commodity that is considered to be a potential pathway for the pest under assessment. The data required include:

  • Import of the commodity from third countries to the countries of interest in the study, both the total quantity and the quantity imported from third countries where the pest is known to be present.
  • Trade of the commodity between the countries of interest.
  • Internal production of the commodity in the countries of interest.

A. Example using ISO codes

A.1. Trade data preparation

Structure of trade data

This example uses simulated trade data for Northern American countries, consisting of a list of data frames with the required data. These data use country identifiers by ISO 3166-1 (alpha-2) codes. Trade data are arranged in three-months time periods.

The load_csv() function included in the qPRAentry package can be used to import the data from CSV files.

data("datatrade_NorthAm")

Total quantity of commodity imported from third countries.

This data frame must contain the columns: reporter (importing countries, in this case by ISO codes), partner (exporting countries), value (quantity of commodity), and time_period (time period of the trade activity).

Using the example data, we select imports from all third countries (column partner):

extra_total <- datatrade_NorthAm$extra_import
head(extra_total)
#>   reporter partner time_period    value
#> 1       BM  CNTR_1  April-June    73.58
#> 2       BM  CNTR_2  April-June    17.55
#> 3       BM  CNTR_3  April-June    26.61
#> 4       BM  CNTR_4  April-June 19349.36
#> 5       BM  CNTR_5  April-June  8070.73
#> 6       CA  CNTR_1  April-June  6628.23

Quantity of commodity imported from third countries where the pest is present.

This data frame must contain the columns: reporter (importing countries, in this case by ISO codes), partner (exporting countries where the pest is present), value (quantity of commodity), and time_period (time period of the trade activity).

Here, we assume that the pest is present in countries “CNTR_1” and “CNTR_2”:

library(dplyr)
CNTR_pest <- c("CNTR_1", "CNTR_2")
extra_pest <- datatrade_NorthAm$extra_import %>% filter(partner%in%CNTR_pest)
head(extra_pest)
#>   reporter partner time_period   value
#> 1       BM  CNTR_1  April-June   73.58
#> 2       BM  CNTR_2  April-June   17.55
#> 3       CA  CNTR_1  April-June 6628.23
#> 4       CA  CNTR_2  April-June  910.00
#> 5       GL  CNTR_1  April-June 1403.07
#> 6       GL  CNTR_2  April-June 6783.81

Quantity of commodity traded between countries of interest.

This data frame must contain the columns: reporter (importing countries, in this case by ISO codes), partner (exporting countries, in this case by ISO codes), value (quantity of commodity), and time_period (time period of the trade activity):

intra_trade  <- datatrade_NorthAm$intra_trade
head(intra_trade)
#>   reporter partner time_period   value
#> 1       BM      CA  April-June  792.86
#> 2       BM      GL  April-June 1291.80
#> 3       BM      PM  April-June  830.42
#> 4       BM      US  April-June   11.57
#> 5       CA      BM  April-June  608.07
#> 6       CA      GL  April-June 6289.37

Quantity of commodity produced internally in each country of interest.

This data frame must contain the columns: reporter (producing countries, in this case by ISO codes), value (quantity of commodity), and time_period (time period of production):

internal_production  <- datatrade_NorthAm$internal_production
head(internal_production)
#>   reporter   time_period     value
#> 1       BM January-March 119625.01
#> 2       CA January-March  55555.83
#> 3       GL January-March  17790.80
#> 4       PM January-March  70680.64
#> 5       US January-March  45125.31
#> 6       BM    April-June  79240.12

Generation of the TradeData object from the above data frames

The trade_data() function assembles the trade data to generate a TradeData object needed to subsequently calculate the quantity of potentially infested/infected commodity entering each country of interest.

Using the arguments filter_IDs and filter_period we can select the countries and time periods of interest, respectively. If nothing is specified in these arguments, by default all countries and time periods included in the data will be selected. For this example, the United States (US) and Canada (CA) are selected, and for the time periods January-March and April-June.

trade_NorthAm <- trade_data(extra_total = extra_total,
                            extra_pest = extra_pest,
                            intra_trade = intra_trade,
                            internal_production = internal_production,
                            filter_IDs = c("US", "CA"),
                            filter_period = c("January-March", "April-June"))

See total trade:

head(trade_NorthAm$total_trade)
#>   country_IDs   time_period extra_total extra_pest intra_import intra_export
#> 1          US January-March     7796.46    6888.32      5448.33        35.49
#> 2          US    April-June     3567.79    1379.75        12.10      1035.70
#> 3          CA January-March    23129.97     470.94        35.49      5448.33
#> 4          CA    April-June    14003.04    7538.23      1035.70        12.10
#>   internal_production total_available export_prop
#> 1            45125.31        52921.77           1
#> 2            17928.84        21496.63           1
#> 3            55555.83        78685.80           1
#> 4            16840.86        30843.90           1

See trade between countries:

head(trade_NorthAm$intra_trade)
#>   reporter partner   time_period   value export_prop
#> 1       CA      US    April-June 1035.70           1
#> 2       CA      US January-March   35.49           1
#> 3       US      CA    April-June   12.10           1
#> 4       US      CA January-March 5448.33           1

Below is an example of how to visualise data using ISO 3166-1 (alpha-2) country codes, displaying the total quantity of commodity available in each country. The plot_countries() function can be used to display other data organised by using ISO 3166-1 (alpha-2) country codes. This function allows to incorporate other utilities of the ggplot2 package.

library(ggplot2)
plot_countries(data = trade_NorthAm$total_trade,
               iso_col = "country_IDs", 
               values_col = "total_available",
               title = "Total commodity available",
               legend_title = "units") +
  xlim(-180,-20) + ylim(0,90)

A.2. Ntrade - Quantity of potentially infested imported commodity

Calculation of the Ntrade for each time period

ntrade_NorthAm <- ntrade(trade_data = trade_NorthAm)
head(ntrade_NorthAm)
#>   country_IDs Ntrade_January-March Ntrade_April-June
#> 1          US            6916.3092          1316.231
#> 2          CA             442.9508          7601.749

Ntrade summary for the time periods

ntrade_NorthAm_summary <- ntrade(trade_data = trade_NorthAm,
                                 summarise_result = c("mean", "sd", 
                                                      "quantile(0.025)", 
                                                      "median",
                                                      "quantile(0.975)"))
head(ntrade_NorthAm_summary)
#>   country_IDs    mean       sd  median    q0.025   q0.975
#> 1          US 4116.27 3959.853 4116.27 1456.2333 6776.307
#> 2          CA 4022.35 5062.035 4022.35  621.9207 7422.779

Plot the Ntrade median for each country:

plot_countries(data = ntrade_NorthAm_summary,
               iso_col = "country_IDs", 
               values_col = "median",
               title = "Ntrade median",
               legend_title = "units") +
  xlim(-180,-20) + ylim(0,90)

A.3. Ntrade redistribution from country level to principal subdivisions

The redist_iso() function requires an additional data frame with values for each subdivision according to which the redistribution is performed proportionally. The redistribution is shown below using simulated commodity consumption data for each territorial subdivision of the United States (US) and Canada (CA) using ISO 3166-2 codes.

# read data for redistribution and filter subdivisions of US and CA
redist_data <- datatrade_NorthAm$consumption_iso2 %>% 
  filter(substr(iso_3166_2, 1, 2) %in% c("US", "CA"))

data_redist <- redist_iso(data = ntrade_NorthAm_summary,
                          iso_col = "country_IDs",
                          values_col = "median",
                          redist_data = redist_data,
                          redist_iso_col = "iso_3166_2",
                          redist_values_col = "value")

head(data_redist)
#> # A tibble: 6 × 4
#>   ISO_1 ISO_2 proportion median
#>   <chr> <chr>      <dbl>  <dbl>
#> 1 US    US-WA   0.000308   1.27
#> 2 CA    CA-BC   0.0447   180.  
#> 3 US    US-ID   0.0485   199.  
#> 4 US    US-MT   0.00857   35.3 
#> 5 CA    CA-AB   0.217    873.  
#> 6 CA    CA-SK   0.0457   184.

Note: The qPRAentry package currently does not include a built-in function to plot data at the subdivision level using ISO 3166-2 codes, although it is available using NUTS codes (see B.3). However, users can easily combine the output with other packages, such as rnaturalearth and ggplot2, to create maps representing these data.

A.4. Pathway model

The number of potential founder populations (NPFP) of a pest entering a country or region can be estimated using a pathway model. This model combines the Ntrade data with parameters that are relevant in the estimation of the entry of the pest under assessment. Each of these parameters must be assigned a suitable probability distribution. The following shows how the Ntrade data obtained above at the country level are combined with other parameters to set up the pathway model and estimate the NPFP.

First, the conceptual model is designed. Here, three parameters have been added in different ways as an illustrative demonstration: NPFP = Ntrade ⋅ (1/P1) ⋅ ((P2 ⋅ 1000) + P3)

A distribution is then assigned to each parameter and all relevant information, along with the desired number of iterations, is incorporated into the pathway_model() function. Note that Ntrade should not be included in the model expression.

# pathway model (excluding ntrade)
model <- "(1/P1) * ((P2 * 1000) + P3)"

# parameter distributions
parameters_dist <- list(P1 = list(dist = "unif", min = 0, max = 1),
                        P2 = list(dist = "beta", shape1 = 1, shape2 = 5),
                        P3 = list(dist = "norm", mean = 0, sd = 1))


res_pathway <- pathway_model(ntrade_data = ntrade_NorthAm_summary,
                             IDs_col = "country_IDs",
                             values_col = "median",
                             expression = model,
                             parameters = parameters_dist,
                             niter = 100)
head(res_pathway)
#> # A tibble: 3 × 8
#> # Groups:   country_IDs [3]
#>   country_IDs      Mean        SD    Min   Q0.25   Median    Q0.75        Max
#>   <chr>           <dbl>     <dbl>  <dbl>   <dbl>    <dbl>    <dbl>      <dbl>
#> 1 US           5413065. 15295211. 20187. 460142. 1150029. 3157801. 126240286.
#> 2 CA           5289556. 14946221. 19726. 449643. 1123789. 3085750. 123359872.
#> 3 Total       10702621. 30241432. 39913. 909785. 2273817. 6243551. 249600158.

The result also includes the total NPFP for the set of countries considered:

res_pathway[res_pathway$country_IDs == "Total",]
#> # A tibble: 1 × 8
#> # Groups:   country_IDs [1]
#>   country_IDs      Mean        SD    Min   Q0.25   Median    Q0.75        Max
#>   <chr>           <dbl>     <dbl>  <dbl>   <dbl>    <dbl>    <dbl>      <dbl>
#> 1 Total       10702621. 30241432. 39913. 909785. 2273817. 6243551. 249600158.

Plot the NPFP median for each country:

plot_countries(data = res_pathway,
               iso_col = "country_IDs", 
               values_col = "Median",
               colors = c("#DCE319FF", "#55C667FF", "#33638DFF"),
               title = "NPFP median",
               legend_title = "NPFP") +
  xlim(-180,-20) + ylim(0,90)

B. Example using NUTS codes

B.1. Trade data preparation

Structure of trade data

This example uses simulated trade data for EU countries, consisting of a list of data frames containing the required data. These data use country identifiers by NUTS codes. Trade data are arranged into annual periods for 2020 and 2021.

The load_csv() function included in the qPRAentry package can be used to import the data from CSV files.

data("datatrade_EU")

Total quantity of commodity imported from third countries, i.e., non-EU countries.

This data frame must contain the columns: reporter (importing countries, in this case by NUTS0 codes), partner (exporting countries), value (quantity of commodity), and time_period (time period of the trade activity).

Using the example data, we select entries where the column partner is coded as “Extra_Total”:

extra_total <- datatrade_EU$extra_import %>% filter(partner=="Extra_Total")
head(extra_total)
#>   reporter     partner time_period    value
#> 1       AT Extra_Total        2020  8407.20
#> 2       BE Extra_Total        2020  3414.69
#> 3       BG Extra_Total        2020 10589.83
#> 4       CY Extra_Total        2020 12928.32
#> 5       CZ Extra_Total        2020  7788.30
#> 6       DE Extra_Total        2020 18997.89

Quantity of commodity imported from third countries where the pest is present.

This data frame must contain the columns: reporter (importing countries, in this case by NUTS0 codes), partner (exporting countries where the pest is present), value (quantity of commodity), and time_period (time period of the trade activity).

Here, we assume that the pest is present in countries “CNTR_1”, “CNTR_2”, and “CNTR_3”, i.e., those that are not coded as “Extra_Total” in the column partner:

extra_pest <- datatrade_EU$extra_import %>% filter(partner!="Extra_Total")
head(extra_pest)
#>   reporter partner time_period   value
#> 1       AT  CNTR_1        2020 6633.68
#> 2       AT  CNTR_2        2020  358.73
#> 3       AT  CNTR_3        2020   63.57
#> 4       BE  CNTR_1        2020   92.26
#> 5       BE  CNTR_2        2020  217.68
#> 6       BE  CNTR_3        2020 3040.03

Quantity of commodity traded between EU countries.

This data frame must contain the columns: reporter (importing countries, in this case by NUTS0 codes), partner (exporting countries, in this case by NUTS0 codes), value (quantity of commodity), and time_period (time period of the trade activity):

intra_trade  <- datatrade_EU$intra_trade
head(intra_trade)
#>   reporter partner time_period    value
#> 1       AT      BE        2020  2552.55
#> 2       AT      BG        2020     1.86
#> 3       AT      CY        2020  2779.99
#> 4       AT      CZ        2020  2623.18
#> 5       AT      DE        2020 16573.06
#> 6       AT      DK        2020   514.85

Quantity of commodity produced internally in each EU country of interest.

This data frame must contain the columns: reporter (producing countries, in this case by NUTS0 codes), value (quantity of commodity), and time_period (time period of production):

internal_production  <- datatrade_EU$internal_production
head(internal_production)
#>   reporter time_period     value
#> 1       AT        2020 154199.46
#> 2       BE        2020  47394.88
#> 3       BG        2020 106367.69
#> 4       CY        2020  58090.14
#> 5       CZ        2020 102177.68
#> 6       DE        2020  96993.84

Generation of the TradeData object from the above data frames

The trade_data() function assembles the trade data to generate a TradeData object needed to subsequently calculate the quantity of potentially infested/infected commodity entering each EU country.

In this case, all countries and periods included in the data are taken into account, as the default values are used for the filter_IDs and filter_period arguments (see A.1 for other specifications)

trade_EU <- trade_data(extra_total = extra_total,
                       extra_pest = extra_pest,
                       intra_trade = intra_trade,
                       internal_production = internal_production)
#> Note: For countries where Intra Export is greater than total available (Extra Total + Internal Production), Intra Export is considered proportional to the total available.

See total trade:

head(trade_EU$total_trade)
#>   country_IDs time_period extra_total extra_pest intra_import intra_export
#> 1          AT        2020     8407.20    7055.98     61568.35     70569.03
#> 2          AT        2021    18202.96    5496.02     68935.72     47508.63
#> 3          BE        2020     3414.69    3349.97     69398.50     49224.42
#> 4          BE        2021    13012.26   12512.76     61191.53     39433.73
#> 5          BG        2020    10589.83   10549.06     91934.42     52322.74
#> 6          BG        2021     6352.41    1609.16     55453.02     50902.10
#>   internal_production total_available export_prop
#> 1           154199.46       162606.66   1.0000000
#> 2            72406.04        90609.00   1.0000000
#> 3            47394.88        50809.57   1.0000000
#> 4           110732.12       123744.38   1.0000000
#> 5           106367.69       116957.52   1.0000000
#> 6            26423.92        32776.33   0.6439092

See trade between EU countries:

head(trade_EU$intra_trade)
#>   reporter partner time_period     value export_prop
#> 1       AT      BE        2020 2552.5500   1.0000000
#> 2       AT      BE        2021 1097.9300   1.0000000
#> 3       AT      BG        2020    1.8600   1.0000000
#> 4       AT      BG        2021  376.1331   0.6439092
#> 5       AT      CY        2020 2779.9900   1.0000000
#> 6       AT      CY        2021 2212.8455   0.7807875

Below is an example of how to visualise data using NUTS codes, displaying the total quantity of commodity available in each country. The plot_nuts() function can be used to display other data organised by NUTS codes. This function allows to incorporate other utilities of the ggplot2 package.

plot_nuts(data = trade_EU$total_trade, 
          nuts_col = "country_IDs", 
          values_col = "total_available",
          nuts_level = 0,
          title = "Total commodity available",
          legend_title = "units") +
  xlim(-30,50) + ylim(25,70)

B.2. Ntrade - Quantity of potentially infested imported commodity

Ntrade summary for the time periods (see A.2 for other specifications).

ntrade_EU <- ntrade(trade_data = trade_EU,
                    summarise_result = c("mean", "sd"))
head(ntrade_EU)
#>   country_IDs     mean        sd
#> 1          AT 8515.413  644.5668
#> 2          BE 9160.731 5923.4801
#> 3          BG 7175.771 5056.1994
#> 4          CY 4611.218  170.4081
#> 5          CZ 5763.743 1458.0454
#> 6          DE 5997.080 3003.6830

Plot the Ntrade mean for each country:

plot_nuts(data = ntrade_EU, 
          nuts_col="country_IDs", 
          values_col="mean",
          nuts_level = 0,
          title = "Ntrade mean",
          legend_title = "units") +
  xlim(-40,50) + ylim(25,70)

B.3. Ntrade redistribution from country level (NUTS0) to smaller territorial subdivisions

The redist_nuts() function can be used with human population data from Eurostat or with an alternative data frame containing values for each territorial subdivision according to which the redistribution will be performed proportionally.

Redistribution using Eurostat human population data from NUTS0 to NUTS2

The redistribution of the Ntrade mean obtained above from NUTS0 to NUTS2, based on the human population of the years 2020 and 2021 in each NUTS2, is shown below.

ntrade_redist_pop <- redist_nuts(data = ntrade_EU,
                                 nuts_col = "country_IDs",
                                 values_col = "mean",
                                 to_nuts = 2,
                                 redist_data = "population",
                                 population_year = c(2020, 2021))
#> Table demo_r_pjangrp3 cached at /tmp/Rtmp44dJYl/eurostat/0693ea62b4b20335c537e941122e8955.rds
head(ntrade_redist_pop)
#> # A tibble: 6 × 4
#>   NUTS2 NUTS0 proportion  mean
#>   <chr> <chr>      <dbl> <dbl>
#> 1 AT11  AT        0.0331  282.
#> 2 AT12  AT        0.189  1612.
#> 3 AT13  AT        0.215  1830.
#> 4 AT21  AT        0.0630  536.
#> 5 AT22  AT        0.140  1191.
#> 6 AT31  AT        0.167  1426.

Plot the Ntrade mean for each NUTS2 region:

plot_nuts(data = ntrade_redist_pop,
          nuts_col = "NUTS2",
          values_col = "mean",
          nuts_level = 2,
          title = "Ntrade mean",
          legend_title = "units") +
   xlim(-40,50) + ylim(25,70)

Redistribution providing values from NUTS0 to NUTS1

The redistribution of the Ntrade mean obtained above from NUTS0 to NUTS1 using simulated consumption data for each NUTS1 is shown below.

# read data for redistribution
nuts1_data <- datatrade_EU$consumption_nuts1

ntrade_redist_df <- redist_nuts(data = ntrade_EU,
                           nuts_col = "country_IDs",
                           values_col = "mean",
                           to_nuts = 1,
                           redist_data = nuts1_data,
                           redist_nuts_col = "NUTS_ID",
                           redist_values_col = "value")

head(ntrade_redist_df)
#> # A tibble: 6 × 4
#>   NUTS1 NUTS0 proportion  mean
#>   <chr> <chr>      <dbl> <dbl>
#> 1 PT2   PT         0.104 1298.
#> 2 BE1   BE         0.130 1189.
#> 3 BE2   BE         0.128 1175.
#> 4 BE3   BE         0.742 6797.
#> 5 BG3   BG         0.122  872.
#> 6 BG4   BG         0.878 6303.

Plot the Ntrade mean for each NUTS1:

plot_nuts(data = ntrade_redist_df,
          nuts_level = 1,
          nuts_col = "NUTS1",
          values_col = "mean",
          title = "Ntrade mean",
          legend_title = "units") +
   xlim(-40,50) + ylim(25,70)

B.4. Pathway model

As shown in A.4, the pathway model allows the NPFP to be estimated. The following shows its use with Ntrade data obtained at NUTS2 level and a pathway model defined as: NPFP = Ntrade ⋅ (1/P1) ⋅ P2 ⋅ P3

A distribution is then assigned to each parameter and all relevant information, along with the desired number of iterations, is incorporated into the pathway_model() function. Note that Ntrade must not be included in the model expression.

# pathway model (excluding ntrade)
model <- "(1/P1) * P2 * P3"

# parameter distributions
parameters_dist <- list(P1 = list(dist = "beta", shape1 = 0.5, shape2 = 1),
                        P2 = list(dist = "gamma", shape = 1.5, scale = 100),
                        P3 = list(dist = "lnorm", mean = 5, sd = 2))

res_pathway <- pathway_model(ntrade_data = ntrade_redist_pop,
                             IDs_col = "NUTS2",
                             values_col = "mean",
                             expression = model,
                             parameters = parameters_dist,
                             niter = 100)
head(res_pathway)
#> # A tibble: 6 × 8
#> # Groups:   NUTS2 [6]
#>   NUTS2         Mean            SD     Min     Q0.25     Median    Q0.75     Max
#>   <chr>        <dbl>         <dbl>   <dbl>     <dbl>      <dbl>    <dbl>   <dbl>
#> 1 AT11   5074581853.  31538670255.  31903.  4409595.  23380986.   1.67e8 2.83e11
#> 2 AT12  29007828208. 180284475686. 182364. 25206566. 133652712.   9.56e8 1.62e12
#> 3 AT13  32935286380. 204693739702. 207055. 28619360. 151748359.   1.09e9 1.83e12
#> 4 AT21   9654894624.  60005444137.  60698.  8389692.  44484642.   3.18e8 5.38e11
#> 5 AT22  21430118524. 133188794909. 134725. 18621859.  98738638.   7.06e8 1.19e12
#> 6 AT31  25662173993. 159491139770. 161331. 22299335. 118237709.   8.45e8 1.43e12

The result also includes the total NPFP for the set of NUTS2 considered:

res_pathway[res_pathway$NUTS2 == "Total",]
#> # A tibble: 1 × 8
#> # Groups:   NUTS2 [1]
#>   NUTS2    Mean      SD       Min       Q0.25       Median         Q0.75     Max
#>   <chr>   <dbl>   <dbl>     <dbl>       <dbl>        <dbl>         <dbl>   <dbl>
#> 1 Total 3.16e12 1.97e13 19895364. 2749954981. 14581079269. 104261125592. 1.76e14

Plot the NPFP mean for each NUTS2:

plot_nuts(data = res_pathway,
          nuts_level = 2,
          nuts_col = "NUTS2",
          values_col = "Mean",
          colors = c("#DCE319FF", "#55C667FF", "#33638DFF"),
          title = "NPFP mean",
          legend_title = "NPFP") +
   xlim(-40,50) + ylim(25,70)