From 84616dc74310a9ddc09777edc355949e5b2aa711 Mon Sep 17 00:00:00 2001 From: Johannes Koch Date: Thu, 12 Sep 2024 11:29:42 +0200 Subject: [PATCH] Refactor and change default scenarios Replace SSP2EU with a placeholder, as it no longer a desired scenario, but required in the input preparation pipeline. Remove completely in next release. Add ADB sources and scenarios (not returned by default yet). Urban pop share scenarios are improved, so as to never exceed 1, even with bezier extensions. SSP labour scenarios are now also filled in with UN_popDiv data. SSP population scenarios now use short term growth rates from PEAP-UN_PopDiv, instead of PEAP-MI, improving the shorterm projections of the smaller countries. Refactor function arguments that did not comply with lintr rules (fixes #13). Mark "scenario.indicator" naming option as deprecated and remove in next release. Fix all linter warnings. Improve scenario documentation and references in vignette (fixes #56 and fixes #57). Improve and simplify documentation (fixes #16). Remove "unit" from most functions, assuming instead that the default dollar unit is used throughout the package. Clean up use of James data set for filling and backwards extension to 1960. These two functions are now cleanly separated from each other. Also, use of the James2019 dataset is dropped (fixes #62), due to the fact that there is no reference for this dataset. This does not affect the scenarios much since the dataset is mainly used for its growth rates, and they shouldn't differ to much. Refactor toolReduce and toolFillWith. toolFillWith now writes to the log which countries are filled in. Export some of the more useful tool functions. Speed up bezier extension (fixes #78). Remove MI from future datasets and make it clear that we assume constant extrapolation for most of the MI countries. Fixes #52. --- .buildlibrary | 2 +- DESCRIPTION | 10 +- NAMESPACE | 4 +- R/calcDriver.R | 284 ++++++----------- R/calcGDP.R | 100 +++++- R/calcGDPFuture.R | 235 ++++++-------- R/calcGDPHarmonized.R | 72 ----- R/calcGDPPast.R | 165 +++++----- R/calcGDPpc.R | 70 ----- R/calcGDPpcFuture.R | 67 ---- R/calcGDPpcHarmonized.R | 296 ------------------ R/calcGDPpcPast.R | 33 -- R/calcLabour.R | 8 - R/calcLabourFuture.R | 79 ----- R/calcLabourHarmonized.R | 20 -- R/calcLabourPast.R | 40 --- R/calcPopulation.R | 46 ++- R/calcPopulationFuture.R | 146 +++++---- R/calcPopulationHarmonized.R | 58 ---- R/calcPopulationPast.R | 131 ++++---- R/calcRatioPPP2MER.R | 10 +- R/calcUrban.R | 26 -- R/calcUrbanFuture.R | 86 ----- R/calcUrbanHarmonized.R | 27 -- R/calcUrbanPast.R | 24 -- R/mrdrivers-package.R | 5 - R/readADB.R | 73 +++++ R/readEurostatPopGDP.R | 159 ---------- R/readIMF.R | 12 +- R/readJames.R | 53 +++- R/readJames2019.R | 72 ----- R/readMissingIslands.R | 12 +- R/readPEAP.R | 4 +- R/readSSP.R | 48 +-- R/readUN_PopDiv.R | 36 ++- R/readWDI.R | 61 ++-- R/toolCheckUserInput.R | 54 ++-- R/toolCompareProxyMagpie.R | 11 +- R/toolExtend2150.R | 59 ++-- R/toolFillWith.R | 57 +++- R/toolFinishigTouches.R | 22 -- R/toolGeneralConvert.R | 17 +- R/toolGetEUcountries.R | 10 - R/toolGetScenarioDefinition.R | 54 ++-- R/toolGetUnitDollar.R | 2 +- R/toolHarmonizeFuture.R | 89 ++++++ R/toolHarmonizeFutureGrPast.R | 24 -- R/toolHarmonizeGDP.R | 292 +++++++++++++++++ R/toolHarmonizePast.R | 36 ++- R/toolHarmonizePop.R | 38 +++ R/toolInterpolateAndExtrapolate.R | 22 +- R/toolReduce.R | 25 -- inst/README.Rmd | 11 +- inst/README.md | 13 +- man/calcDriver.Rd | 21 +- man/calcFutureData.Rd | 38 --- man/calcGDP.Rd | 19 +- man/calcGDPHarmonized.Rd | 28 -- man/calcGDPPast.Rd | 97 +++--- man/calcGDPpcHarmonized.Rd | 28 -- man/calcHarmonizedData.Rd | 22 +- man/calcLabourHarmonized.Rd | 24 -- man/calcPastData.Rd | 37 --- man/calcPopulation.Rd | 7 +- man/calcPopulationHarmonized.Rd | 24 -- man/calcPopulationPast.Rd | 81 ----- man/calcRatioPPP2MER.Rd | 3 +- man/calcScenarioConstructor.Rd | 50 +-- man/calcUrbanHarmonized.Rd | 24 -- man/compare_proxy.magpie.Rd | 20 ++ man/mrdrivers-package.Rd | 2 - man/readADB.Rd | 36 +++ man/readEurostatPopGDP.Rd | 43 --- man/readJames.Rd | 29 +- man/readJames2019.Rd | 43 --- man/readMissingIslands.Rd | 4 +- man/readSSP.Rd | 16 +- man/readUN_PopDiv.Rd | 8 +- man/readWDI.Rd | 16 +- man/toolCheckUserInput.Rd | 27 ++ man/toolExtend2150.Rd | 27 ++ man/toolFillWith.Rd | 21 ++ man/toolGeneralConvert.Rd | 7 +- man/toolGetScenarioDefinition.Rd | 2 +- man/toolGetUnitDollar.Rd | 2 +- man/toolHarmonizeFuture.Rd | 41 +++ man/toolHarmonizePast.Rd | 5 + man/toolInterpolateAndExtrapolate.Rd | 20 ++ man/toolListFillWith.Rd | 18 ++ tests/testthat.R | 4 +- tests/testthat/setup-madrat_config.R | 2 +- tests/testthat/test-calcOutput_sets.R | 114 +++---- tests/testthat/test-snaphsots.R | 24 +- .../testthat/test-toolGetScenarioDefinition.R | 12 +- vignettes/scenarios.Rmd | 59 ++-- 95 files changed, 1865 insertions(+), 2650 deletions(-) delete mode 100644 R/calcGDPHarmonized.R delete mode 100644 R/calcGDPpc.R delete mode 100644 R/calcGDPpcFuture.R delete mode 100644 R/calcGDPpcHarmonized.R delete mode 100644 R/calcGDPpcPast.R delete mode 100644 R/calcLabour.R delete mode 100644 R/calcLabourFuture.R delete mode 100644 R/calcLabourHarmonized.R delete mode 100644 R/calcLabourPast.R delete mode 100644 R/calcPopulationHarmonized.R delete mode 100644 R/calcUrban.R delete mode 100644 R/calcUrbanFuture.R delete mode 100644 R/calcUrbanHarmonized.R delete mode 100644 R/calcUrbanPast.R create mode 100644 R/readADB.R delete mode 100644 R/readEurostatPopGDP.R delete mode 100644 R/readJames2019.R delete mode 100644 R/toolFinishigTouches.R delete mode 100644 R/toolGetEUcountries.R create mode 100644 R/toolHarmonizeFuture.R delete mode 100644 R/toolHarmonizeFutureGrPast.R create mode 100644 R/toolHarmonizeGDP.R create mode 100644 R/toolHarmonizePop.R delete mode 100644 R/toolReduce.R delete mode 100644 man/calcFutureData.Rd delete mode 100644 man/calcGDPHarmonized.Rd delete mode 100644 man/calcGDPpcHarmonized.Rd delete mode 100644 man/calcLabourHarmonized.Rd delete mode 100644 man/calcPastData.Rd delete mode 100644 man/calcPopulationHarmonized.Rd delete mode 100644 man/calcPopulationPast.Rd delete mode 100644 man/calcUrbanHarmonized.Rd create mode 100644 man/compare_proxy.magpie.Rd create mode 100644 man/readADB.Rd delete mode 100644 man/readEurostatPopGDP.Rd delete mode 100644 man/readJames2019.Rd create mode 100644 man/toolCheckUserInput.Rd create mode 100644 man/toolExtend2150.Rd create mode 100644 man/toolFillWith.Rd create mode 100644 man/toolHarmonizeFuture.Rd create mode 100644 man/toolInterpolateAndExtrapolate.Rd create mode 100644 man/toolListFillWith.Rd diff --git a/.buildlibrary b/.buildlibrary index c3eb1b3..53ff27c 100644 --- a/.buildlibrary +++ b/.buildlibrary @@ -4,6 +4,6 @@ AcceptedWarnings: - 'Warning: package ''.*'' was built under R version' - 'Warning: namespace ''.*'' is not available and has been replaced' AcceptedNotes: ~ -allowLinterWarnings: yes +allowLinterWarnings: no AddInReadme: inst/README.md enforceVersionUpdate: no diff --git a/DESCRIPTION b/DESCRIPTION index c10a7fd..2230fca 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,7 +22,6 @@ Depends: Imports: countrycode, dplyr, - lifecycle, glue, magrittr, purrr, @@ -31,20 +30,17 @@ Imports: rlang, tibble, tidyr, - tidyselect, - zoo + tidyselect Suggests: covr, crayon, - eurostat, - kableExtra, knitr, - pander, rmarkdown, testthat (>= 3.0.0), WDI, withr (>= 2.4.2), - yaml + yaml, + zoo Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.3.2 diff --git a/NAMESPACE b/NAMESPACE index d5686d2..6024ee8 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,12 +1,14 @@ # Generated by roxygen2: do not edit by hand +export(toolGeneralConvert) export(toolGetScenarioDefinition) export(toolGetUnitDollar) +export(toolHarmonizeFuture) +export(toolHarmonizePast) exportPattern("^((calc(GDP|GDPpc|Population|Labour|Urban)(Past|Future|$))|read|download)") import(GDPuc) import(madrat) import(magclass) importFrom(glue,glue) -importFrom(lifecycle,deprecate_soft) importFrom(magrittr,"%>%") importFrom(rlang,.data) diff --git a/R/calcDriver.R b/R/calcDriver.R index b67f93a..d38deb3 100644 --- a/R/calcDriver.R +++ b/R/calcDriver.R @@ -39,7 +39,7 @@ #' @param naming A string giving the naming scheme of the data dimension. Can be either: #' \itemize{ #' \item "indicator_scenario" (default): Returns names of the type "gdp_SSP2", or "pop_SSP2". -#' \item "indicator.scenario": Returns names of the type "gdp.SSP2", or "pop.SSP2". +#' \item "indicator.scenario": (deprecated) Returns names of the type "gdp.SSP2", or "pop.SSP2". #' \item "scenario": Returns names of the type "SSP2". #' } #' Set naming to "scenario" when you want to operate on SSP2 gdp and population data for instance, and not have to @@ -47,7 +47,6 @@ #' #' @param popAsWeight If TRUE, then population data of the same scenario is used as weight. #' -#' @inheritDotParams calcScenarioConstructor #' @inherit madrat::calcOutput return #' @inherit calcHarmonizedData seealso #' @keywords internal @@ -55,73 +54,57 @@ calcDriver <- function(driver, scenario, popAsWeight = FALSE, naming = "indicator_scenario", - extension2150 = "bezier", - ...) { - # Load ... arguments into function environment - list2env(list(...), environment()) - - # Temporary warning left as information. Remove in next release. - if ("FiveYearSteps" %in% ls()) { - warning("FiveYearSteps is deprecated and will throw an error in the next release.") - rm("FiveYearSteps") - } - - # If the pastData, futureData and harmonization arguments are not in ..., then query them using "scenario" and - # load them into the function environment. - if (!any(c("pastData", "futureData", "harmonization") %in% ls())) { - list2env(toolGetScenarioDefinition(driver, scenario, aslist = TRUE), environment()) - } else { - scenario <- "-" - } - + extension2150 = "bezier") { # Create a list of all the arguments l <- as.list(environment()) # Call ScenarioConstructor function the appropriate number of times (map) and combine (reduce) # !! Keep formula syntax for madrat caching to work purrr::pmap(l, ~calcOutput("ScenarioConstructor", aggregate = FALSE, supplementary = TRUE, ...)) %>% - toolReduce() + purrr::reduce(~list(x = mbind(.x$x, .y$x), + weight = mbind(.x$weight, .y$weight), + unit = glue("{.x$unit} || {.y$unit}"), + description = glue("{.x$description} || {.y$description}"))) } -#' ScenarioConstructor +#' Scenario construction #' #' @details # Combining data sources with "-" #' Data sources can be combined with "-" and passed to both the pastData and futureData arguments, i.e. "WDI-MI". This #' signifies that WDI data will be taken first, but missing data will be then be filled in with data from MI. #' -#' @param harmonization A string designating the harmonization function. -#' @param pastData A string passed to the calc'Driver'Past function, e.g. [calcGDPPast()] or [calcPopulationPast()]. -#' @param futureData A string passed to the calc'Driver'Future function, e.g. [calcGDPFuture()] or -#' [calcPopulationFuture()]. -#' @param ... Arguments passed on to the 'driver'Past, 'driver'Future and driver'Harmonization' functions. #' @inheritParams calcDriver #' @inherit calcHarmonizedData seealso #' @inherit madrat::calcOutput return #' @keywords internal -calcScenarioConstructor <- function(driver, - scenario, - pastData, - futureData, - harmonization, - extension2150, - naming, - popAsWeight, - ...) { - - harmonizedData <- calcOutput("HarmonizedData", - driver = driver, - scenario = scenario, - pastData = pastData, - futureData = futureData, - harmonization = harmonization, - aggregate = FALSE, - supplementary = TRUE, - ...) - - harmonizedData$x <- toolFinishingTouches(x = harmonizedData$x, extension2150 = extension2150, naming = naming) +calcScenarioConstructor <- function(driver, scenario, popAsWeight, naming, extension2150) { + + data <- calcOutput("HarmonizedData", driver = driver, scenario = scenario, aggregate = FALSE, supplementary = TRUE) + + if (extension2150 != "none") data <- toolExtend2150(data, extension2150) + + # If required, add indicators (drivers) to names, or as additional dimension + if (naming != "scenario") { + indicator <- switch( + driver, + "GDP" = "gdp", + "GDPpc" = "gdppc", + "Population" = "pop", + "Urban" = "urb", + # Label labour scenarios with "pop". Currently required for REMIND to work. + "Labour" = "pop" + ) + if (naming == "indicator_scenario") { + getNames(data$x) <- paste0(indicator, "_", getNames(data$x)) + } + if (naming == "indicator.scenario") { + warning("The naming option = 'indicator.scenario' is deprecated and will be removed in the next release.") + getNames(data$x) <- paste0(indicator, ".", getNames(data$x)) + getSets(data$x) <- c(getSets(data$x)[1:2], "indicator", "scenario") + } + } - weight <- NULL - description <- harmonizedData$description + # If required, get population as weight if (popAsWeight) { weight <- calcOutput("Population", scenario = scenario, @@ -129,159 +112,90 @@ calcScenarioConstructor <- function(driver, aggregate = FALSE, supplementary = TRUE) # Give weight same names as data, so that aggregate doesn't mess up data dim - getNames(weight$x) <- getNames(harmonizedData$x) - # Make sure weight and harmonizedData have the same yearly resolution. - # Sometimes weght has more years than x, thus the intersect operation. - weight$x <- weight$x[, intersect(getYears(harmonizedData$x), getYears(weight$x)), ] - # If x has more years than weight, add these years and interpolate - missingYears <- getYears(harmonizedData$x)[! getYears(harmonizedData$x) %in% getYears(weight$x)] + getNames(weight$x) <- getNames(data$x) + # Make sure weight and data have the same yearly resolution. + ## Sometimes weght has more years than x, thus the intersect operation. + weight$x <- weight$x[, intersect(getYears(data$x), getYears(weight$x)), ] + ## If x has more years than weight, add these years and interpolate + missingYears <- getYears(data$x)[! getYears(data$x) %in% getYears(weight$x)] weight$x <- add_columns(weight$x, missingYears, dim = 2, fill = 0) weight$x <- weight$x[, sort(getYears(weight$x)), ] - weight$x <- toolInterpolateAndExtrapolate(weight$x, extrapolate = FALSE) - - description <- glue("{description} Associated {weight$description}") - } + weight$x <- toolInterpolateAndExtrapolate(weight$x) - if (extension2150 == "bezier") { - description <- glue("{description} Extended from 2100 to 2150 using bezier curves, resulting in a smooth \\ - flattening of the scenario (the slope in 2150 is equal to half of that in 2100).") - } else if (extension2150 == "constant") { - description <- glue("{description} Extended from 2100 to 2150 using the constant 2100 value.") + data$description <- glue("{data$description} Associated {weight$description}") + } else { + weight <- NULL } - list(x = harmonizedData$x, + list(x = data$x, weight = weight$x, - unit = harmonizedData$unit, - description = glue("{driver} {scenario} scenarios: {description}")) + unit = data$unit, + description = glue("{driver} {scenario} scenarios: {data$description}")) } -#' Get Harmonized Data +#' Get harmonized data #' -#' @param ... Arguments passed on to harmonization functions #' @inheritParams calcScenarioConstructor #' @inherit madrat::calcOutput return -#' @seealso \itemize{ -#' \item [calcGDPPast()], [calcGDPFuture()], [calcGDPpcPast()] and [calcGDPpcFuture()] for the builiding blocks of -#' the GDP and GDPpc scenarios. -#' \item [calcPopulationPast()], [calcPopulationFuture()], [calcLabourPast()], [calcLabourFuture()], [calcUrbanPast()] -#' and [calcUrbanFuture()] for the builiding blocks of the Population, Labor and Urban scenarios. -#' } +#' @seealso [calcGDPPast()] for the scenario builiding blocks. #' @keywords internal -calcHarmonizedData <- function(driver, scenario, pastData, futureData, harmonization, ...) { - # Depending on the setup, the scenario construction either requires 'past' and 'future' scenarios, or not! +calcHarmonizedData <- function(driver, scenario) { + # Query the pastData, futureData and harmonization arguments of the "scenario". + l <- toolGetScenarioDefinition(driver, scenario, aslist = TRUE) + pastData <- l$pastData + futureData <- l$futureData + harmonization <- l$harmonization + + # Depending on the setup, the scenario construction either requires 'past' and 'future' data, or not! # For example, many GDP scenarios are actually constructed as GDPpc scenarios, and then simply multiplied with # population scenarios. past <- if (pastData != "-") { - calcOutput("PastData", driver = driver, pastData = pastData, aggregate = FALSE, supplementary = TRUE, ...) - } else NULL + switch( + driver, + "GDP" = calcOutput("GDPPast", pastData = pastData, aggregate = FALSE, supplementary = TRUE), + "GDPpc" = calcOutput("GDPpcPast", scenario = scenario, aggregate = FALSE, supplementary = TRUE), + "Population" = calcOutput("PopulationPast", pastData = pastData, aggregate = FALSE, supplementary = TRUE), + "Urban" = calcOutput("UrbanPast", pastData = pastData, aggregate = FALSE, supplementary = TRUE), + "Labour" = calcOutput("LabourPast", pastData = pastData, aggregate = FALSE, supplementary = TRUE) + ) %>% toolInterpolateAndExtrapolate() + } future <- if (futureData != "-") { - calcOutput("FutureData", driver = driver, futureData = futureData, aggregate = FALSE, supplementary = TRUE, ...) - } else NULL - - switch( - driver, - "Population" = calcOutput("PopulationHarmonized", - harmonization = harmonization, - past = past, - future = future, - aggregate = FALSE, - supplementary = TRUE, - ...), - "GDP" = calcOutput("GDPHarmonized", - harmonization = harmonization, - past = past, - future = future, - scenario = scenario, - aggregate = FALSE, - supplementary = TRUE, - ...), - "GDPpc" = calcOutput("GDPpcHarmonized",harmonization = harmonization, - past = past, - future = future, - scenario = scenario, - aggregate = FALSE, - supplementary = TRUE, - ...), - "Labour" = calcOutput("LabourHarmonized",harmonization = harmonization, - past = past, - future = future, - aggregate = FALSE, - supplementary = TRUE, - ...), - "Urban" = calcOutput("UrbanHarmonized",harmonization = harmonization, - past = past, - future = future, - aggregate = FALSE, - supplementary = TRUE, - ...) - ) -} + switch( + driver, + "GDP" = calcOutput("GDPFuture", futureData = futureData, aggregate = FALSE, supplementary = TRUE), + "GDPpc" = calcOutput("GDPpcFuture", scenario = scenario, aggregate = FALSE, supplementary = TRUE), + "Population" = calcOutput("PopulationFuture", futureData = futureData, aggregate = FALSE, supplementary = TRUE), + "Labour" = calcOutput("LabourFuture", futureData = futureData, aggregate = FALSE, supplementary = TRUE), + "Urban" = calcOutput("UrbanFuture", futureData = futureData, aggregate = FALSE, supplementary = TRUE), + ) %>% toolInterpolateAndExtrapolate() + } -#' Get Past Data Building Block -#' -#' @inheritParams calcScenarioConstructor -#' @inherit madrat::calcOutput return -#' @inherit calcHarmonizedData seealso -#' @keywords internal -calcPastData <- function(driver, pastData, unit) { - switch( + # Combine "past" and "future" time series. + harmonizedData <- switch( + harmonization, + "pastAndLevel" = toolHarmonizePast(past, future, method = "level"), + "pastAndGrowth" = toolHarmonizePast(past, future, method = "growth"), + "pastAndTransition" = toolHarmonizePast(past, future, method = "transition", yEnd = 2100), + "PopSSPs" = toolHarmonizeWithPEAPandFuture(past, future), + "PopISIMIP" = toolHarmonizePast(past, future, method = "transition", yEnd = 2030), + "GDPpcSSPs" = toolHarmonizeGDPpcSSPs(past, future, yEnd = 2100), + "GDPpcSDPs" = toolBuildGDPpcSDPs(), + "GDPpcADBs" = toolHarmonizeGDPpcADBs(past, future), + "GDPoverPop" = toolDivideGDPbyPop(scenario), + "GDPpcWithPop" = toolMultiplyGDPpcWithPop(scenario), + "LabourADBs" = toolHarmonizeLabourADBs(), + stop(glue("Bad input for calcHarmonizedData Argument harmonization = '{harmonization}' is invalid.")) + ) %>% toolInterpolateAndExtrapolate() + + unit <- switch( driver, - "GDP" = calcOutput("GDPPast", - GDPPast = pastData, - unit = unit, - aggregate = FALSE, - supplementary = TRUE), - "GDPpc" = calcOutput("GDPpcPast", - GDPpcPast = pastData, - unit = unit, - aggregate = FALSE, - supplementary = TRUE), - "Population" = calcOutput("PopulationPast", - PopulationPast = pastData, - aggregate = FALSE, - supplementary = TRUE), - "Urban" = calcOutput("UrbanPast", - UrbanPast = pastData, - aggregate = FALSE, - supplementary = TRUE), - "Labour" = calcOutput("LabourPast", - LabourPast = pastData, - aggregate = FALSE, - supplementary = TRUE) + "GDP" = glue("mil. {toolGetUnitDollar(inPPP = TRUE)}"), + "GDPpc" = toolGetUnitDollar(inPPP = TRUE), + "Population" = "million", + "Urban" = "share of population", + "Labour" = "million" ) -} -#' Get Future Data Building Block -#' -#' @inheritParams calcScenarioConstructor -#' @inherit madrat::calcOutput return -#' @inherit calcHarmonizedData seealso -#' @keywords internal -calcFutureData <- function(driver, futureData, unit) { - switch( - driver, - "Population" = calcOutput("PopulationFuture", - PopulationFuture = futureData, - aggregate = FALSE, - supplementary = TRUE), - "GDP" = calcOutput("GDPFuture", - GDPFuture = futureData, - unit = unit, - aggregate = FALSE, - supplementary = TRUE), - "GDPpc" = calcOutput("GDPpcFuture", - GDPpcFuture = futureData, - unit = unit, - aggregate = FALSE, - supplementary = TRUE), - "Labour" = calcOutput("LabourFuture", - LabourFuture = futureData, - aggregate = FALSE, - supplementary = TRUE), - "Urban" = calcOutput("UrbanFuture", - UrbanFuture = futureData, - aggregate = FALSE, - supplementary = TRUE) - ) + list(x = harmonizedData$x, weight = NULL, unit = unit, description = harmonizedData$description) } diff --git a/R/calcGDP.R b/R/calcGDP.R index f3a027c..fe81e5b 100644 --- a/R/calcGDP.R +++ b/R/calcGDP.R @@ -9,7 +9,6 @@ #' \itemize{ #' \item the SSPs, i.e. SSP1-5 #' \item the SDPs, i.e. SDP, SDP_EI, SDP_RC, and SDP_MC -#' \item SSP2EU #' } #' #' See the vignette: \code{vignette("scenarios")} for scenario options, definitions and references. @@ -18,8 +17,9 @@ #' #' @param unit A string specifying the unit of GDP. Can be either: #' \itemize{ -#' \item "constant 2017 Int$PPP" (default): Scenarios are constructed in constant 2017 Int$PPP. -#' \item "constant 2017 US$MER": Scenarios are constructed in constant 2017 Int$PPP and then converted with +#' \item "`r toolGetUnitDollar(inPPP = TRUE)`" (default): +#' Scenarios are constructed in `r toolGetUnitDollar(inPPP = TRUE)`. +#' \item "`r toolGetUnitDollar()`": Scenarios are constructed in `r toolGetUnitDollar()` and then converted with #' [GDPuc::toolConvertGDP()]. #' } #' In all cases, GDP is returned in millions. @@ -28,7 +28,6 @@ #' the yearly resolution is decreased to 5 year intervals. #' #' @param ... Arguments passed on to [calcDriver()], of which "extension2150" and "naming" are most often of interest. -#' Other [calcDriver()] arguments are used for scenario fine-tuning and by package developers. #' #' @inherit madrat::calcOutput return #' @seealso \itemize{ @@ -43,12 +42,12 @@ #' calcOutput("GDP") #' calcOutput("GDPpc") #' -#' # Return only the SSP2EU GDP scenario -#' calcOutput("GDP", scenario = "SSP2EU") +#' # Return only the SSP2 GDP scenario +#' calcOutput("GDP", scenario = "SSP2") #' } #' calcGDP <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), - unit = "constant 2017 Int$PPP", + unit = toolGetUnitDollar(inPPP = TRUE), average2020 = TRUE, ...) { # Check user input @@ -58,7 +57,6 @@ calcGDP <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), gdp <- calcOutput("Driver", driver = "GDP", scenario = scenario, - unit = "constant 2017 Int$PPP", aggregate = FALSE, supplementary = TRUE, ...) @@ -85,13 +83,87 @@ calcGDP <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), if (grepl("US\\$MER", unit)) { # Convert by interpolating and extrapolating missing conversion factors when possible. gdp$x <- GDPuc::toolConvertGDP(gdp$x, - unit_in = "constant 2017 Int$PPP", - unit_out = "constant 2017 US$MER", - replace_NAs = c("linear", "no_conversion")) + unit_in = toolGetUnitDollar(inPPP = TRUE), + unit_out = toolGetUnitDollar(inPPP = FALSE), + replace_NAs = c("linear", "no_conversion")) + } + # Shifting to non-default-base-year prices, using only the US deflator for all countries, and neglecting any changes + # in PPPs or MERs. + if (!grepl(toolGetUnitDollar(returnOnlyBase = TRUE), unit)) { + gdp$x <- gdp$x * GDPuc::toolConvertSingle(1, "USA", unit_in = toolGetUnitDollar(inPPP = TRUE), unit_out = unit) } - # Temporary shifting to 2005 prices, using only the US deflator for all countries, and neglecting any changes in - # PPPs or MERs. - if (grepl("2005", unit)) gdp$x <- gdp$x * 0.8121123 list(x = gdp$x, weight = gdp$weight, unit = glue("mil. {unit}"), description = gdp$description) } + + +#' @rdname calcGDP +#' @examples \dontrun{ +#' calcOutput("GDPpc") +#' } +#' +calcGDPpc <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), + unit = toolGetUnitDollar(inPPP = TRUE), + average2020 = TRUE, + ...) { + # Check user input + toolCheckUserInput(driver = "GDPpc", args = c(list(...), as.list(environment()))) + + # GDPpc scenarios are constructed in 2017 Int$PPP, and converted, if necessary, at the end. + gdppc <- calcOutput("Driver", + driver = "GDPpc", + scenario = scenario, + popAsWeight = TRUE, + aggregate = FALSE, + supplementary = TRUE, + ...) + + if (average2020) { + # For REMIND, the consensus is to average the 2020 value so as to dampen the effect of the COVID shock. (The + # reasoning being that REMIND uses 5-year time steps, and that the year-in-itself should represent the 2,5 years + # before and after.) + # The dampening is supposed to take place on GDP. So for GDP per capita in 2020 to be consistent with the dampened + # GDP, it has to calculated from GDP and population. (In other words we can't just use the same formula as for GDP, + # since it would lead to inconsistency at the end.) This is a bit hacky... + gdp2020 <- calcOutput("GDP", + scenario = scenario, + naming = "scenario", + extension2150 = "none", + aggregate = FALSE, + years = 2020) + pop2020 <- calcOutput("Population", + scenario = scenario, + naming = "scenario", + extension2150 = "none", + aggregate = FALSE, + years = 2020) + gdppc2020 <- gdp2020 / pop2020 + gdppc2020[is.nan(gdppc2020)] <- 0 + getNames(gdppc2020) <- getNames(gdppc$x) + gdppc$x[, 2020, ] <- gdppc2020 + gdppc$description <- paste(gdppc$description, "|| 2020 value averaged over 2018-2022 time period.") + # Return only 5 year time steps, since the yearly data around 2020 is not connected to the 2020 value anymore. + years5ts <- getYears(gdppc$x, as.integer = TRUE)[getYears(gdppc$x, as.integer = TRUE) %% 5 == 0 & + getYears(gdppc$x, as.integer = TRUE) != 1960] + gdppc$x <- gdppc$x[, years5ts, ] + gdppc$weight <- gdppc$weight[, years5ts, ] + gdppc$description <- paste(gdppc$description, "5 year time steps only.") + message("The 2020 value is an an avergae over the 2018-2022 time period!!") + } + + # Convert to US$MER if required + if (grepl("US\\$MER", unit)) { + # Convert by interpolating and extrapolating missing conversion factors when possible. + gdppc$x <- GDPuc::toolConvertGDP(gdppc$x, + unit_in = toolGetUnitDollar(inPPP = TRUE), + unit_out = toolGetUnitDollar(inPPP = FALSE), + replace_NAs = c("linear", "no_conversion")) + } + # Shifting to non-default-base-year prices, using only the US deflator for all countries, and neglecting any changes + # in PPPs or MERs. + if (!grepl(toolGetUnitDollar(returnOnlyBase = TRUE), unit)) { + gdp$x <- gdp$x * GDPuc::toolConvertSingle(1, "USA", unit_in = toolGetUnitDollar(inPPP = TRUE), unit_out = unit) + } + + list(x = gdppc$x, weight = gdppc$weight, unit = unit, description = gdppc$description) +} diff --git a/R/calcGDPFuture.R b/R/calcGDPFuture.R index 5c2e313..c1a74ce 100644 --- a/R/calcGDPFuture.R +++ b/R/calcGDPFuture.R @@ -1,165 +1,122 @@ -#' @describeIn calcGDPPast Get future GDP projections -#' -#' @param GDPFuture A string designating the source for the future GDP data. Available sources are: -#' \itemize{ -#' \item "SSPs": IIASA [SSP database](https://tntcat.iiasa.ac.at/SspDb/dsd?Action=htmlpage&page=welcome) -#' \item "SSP2EU": Combined SSP2 and Eurostat (for the EU countries) source -#' \item "SDPs": -#' \item "MI": Missing island dataset -#' } -#' See the "Combining data sources with '-'" section below for how to combine data sources. -calcGDPFuture <- function(GDPFuture, unit) { # nolint +#' @rdname calcGDPPast +#' @param futureData A string specifying the sources for future projections. +#' @order 3 +calcGDPFuture <- function(futureData = "SSPs") { # Check user input toolCheckUserInput("GDPFuture", as.list(environment())) # Call calcInternalGDPFuture function the appropriate number of times (map) and combine (reduce) # !! Keep formula syntax for madrat caching to work - purrr::pmap(list("GDPFuture" = unlist(strsplit(GDPFuture, "-")), "unit" = unit), + purrr::pmap(list("futureData" = unlist(strsplit(futureData, "-"))), ~calcOutput("InternalGDPFuture", aggregate = FALSE, supplementary = TRUE, ...)) %>% - toolReduce(mbindOrFillWith = "fillWith") + toolListFillWith() } - -###################################################################################### -# Internal Function -###################################################################################### -calcInternalGDPFuture <- function(GDPFuture, unit) { # nolint +calcInternalGDPFuture <- function(futureData) { data <- switch( - GDPFuture, - "SSPs" = calcOutput("InternalGDPFutureSSPs", unit = unit, aggregate = FALSE, supplementary = TRUE), - "SSP2" = calcOutput("InternalGDPFutureSSP2", unit = unit, aggregate = FALSE, supplementary = TRUE), - "SSP2EU" = calcOutput("InternalGDPFutureSSP2EU", unit = unit, aggregate = FALSE, supplementary = TRUE), - "SDPs" = calcOutput("InternalGDPFutureSDPs", unit = unit, aggregate = FALSE, supplementary = TRUE), - "MI" = calcOutput("InternalGDPMI", unit = unit, aggregate = FALSE, supplementary = TRUE), - stop("Bad input for calcGDPFuture. Invalid 'GDPFuture' argument.") + futureData, + "SSPs" = readSource("SSP", "gdp"), + "SSP2" = readSource("SSP", "gdp", "SSP2"), + "SSP2EU" = setNames(readSource("SSP", "gdp", "SSP2"), "SSP2EU"), + "SDPs" = toolGDPFutureSDPs(), + stop("Bad input for calcGDPFuture. Invalid 'futureData' argument.") ) - data$x <- toolFinishingTouches(data$x) - data + list(x = data, + weight = NULL, + unit = glue("mil. {toolGetUnitDollar(inPPP = TRUE)}"), + description = glue("{futureData} projections")) } +toolGDPFutureSDPs <- function(sdps = c("SDP", "SDP_EI", "SDP_MC", "SDP_RC")) { + gdpSSP1 <- readSource("SSP", "gdp", "SSP1") # nolint: object_usage_linter. + purrr::map(sdps, ~setNames(gdpSSP1, .x)) %>% mbind() +} +#' @rdname calcGDPPast +#' @order 4 +calcGDPpcFuture <- function(scenario = "SSPs") { + # We can not fill data sources as in GDP and Pop, as GDP and pop on their part are filled with MI, and the countries + # which are filled in do not match. (WDI has pop data for some countries, but not GDP.) So to make sure that the + # GDP per capita is consistent, we have to pass it on to the GDP and pop functions. + gdpFutureData <- toolGetScenarioDefinition("GDPpc", scenario, aslist = TRUE)$futureData + popFutureData <- toolGetScenarioDefinition("Population", scenario, aslist = TRUE)$futureData -###################################################################################### -# Functions -###################################################################################### -calcInternalGDPFutureSSPs <- function(unit) { - # Read in gdp SSP projections (in billions) and convert to millions - data <- readSource("SSP", subtype = "gdp") * 1000 - # Add gdp_ to variable dimension - getNames(data) <- paste0("gdp_", getNames(data)) - - # GDPFutureSSP is constructed in PPPs. - if (grepl("^constant .* US\\$MER$", unit)) { - constructUnit <- paste0("constant ", substr(unit, 10, 13), " Int$PPP") - } else { - constructUnit <- unit - } - - # THIS MAY BE DEPRECATED IN THE NEAR FUTURE - # The default construct unit is "constant 2017 Int$PPP". If another unit is - # demanded, then some modifications have to be done. - if (constructUnit != "constant 2017 Int$PPP") { - # Construct SSP pathways in constant YYYY Int$PPP. - # For the near future, convert using current conversion factors. - # After that the scenarios are built by converting the US GDP, and building - # the other countries in relation to the US so that by 2100, they have the - # same ratio as in 2017 Int$PPP. - data2017PPP <- data - - # The near future is defined hear by the next 15 years, or until 10 years after the last imf prediction. - c15 <- max(getYears(readSource("IMF", "GDPpc"), as.integer = TRUE)) + 10 - - y1 <- getYears(data2017PPP)[getYears(data2017PPP, as.integer = TRUE) <= c15] - dataNearFut <- data2017PPP[, y1, ] %>% - GDPuc::toolConvertGDP("constant 2017 Int$PPP", unit, replace_NAs = c("linear", "no_conversion")) - - y2 <- getYears(data2017PPP)[getYears(data2017PPP, as.integer = TRUE) > c15 & - getYears(data2017PPP, as.integer = TRUE) < 2100] - dataFarFut <- data2017PPP[, y2, ] * NA - - # Convert to 2005 Int$PPP using the 2005 value of base 2017 GDP deflator - # (in constant 2005 LCU per constant 2017 LCU) of the USA - # LONGTERM: allow other PPP units - data2100 <- data2017PPP[, 2100, ] * GDPuc::convertSingle(1, "USA", "2010", "constant 2017 LCU", "constant 2005 LCU") - - data2005 <- mbind(dataNearFut, dataFarFut, data2100) - - ratio <- data2017PPP / data2005 - # For interpolation to work, the last and first values have to be non-NA/non-NaN - ratio[, 2100, ][is.na(ratio[, 2100, ])] <- 0 - # The first 2 years of the SSP data set are incomplete. For countries that only lack data in these first 2 years, - # set NaN to 0. - ratio[, 2000, ][is.nan(ratio[, 2000, ]) & !is.nan(ratio[, 2010, ])] <- 0 - - ratio <- as.data.frame(ratio, rev = 2) %>% - dplyr::rename("value" = ".value") %>% - dplyr::arrange(.data$year) %>% - dplyr::group_by(.data$iso3c, .data$variable) %>% - dplyr::mutate(value = zoo::na.approx(.data$value)) %>% - dplyr::ungroup() %>% - as.magpie(tidy = TRUE) - - data2005 <- data2017PPP / ratio - data2005[is.na(data2005)] <- data2017PPP[is.na(data2005)] - # Above should probably be "<- 0" - ################## - data <- data2005 - } - - # If unit was in $MER - if (constructUnit != unit) { - data <- GDPuc::toolConvertGDP(data, constructUnit, unit, replace_NAs = c("linear", "no_conversion")) - } + data <- switch( + scenario, + "ADBs" = toolFillWith(readSource("ADB", "gdppc"), + toolGDPpcFutureFromGDPAndPop(sub("ADBs-", "", gdpFutureData), popFutureData)), + toolGDPpcFutureFromGDPAndPop(gdpFutureData, popFutureData) + ) - list(x = data, weight = NULL, unit = glue("mil. {unit}"), description = "SSP projections") -} + # The weight does go into the weight of the final scenario. So exact matching with GDPpc not necessary... + weight <- calcOutput("PopulationFuture", futureData = popFutureData, aggregate = FALSE) + getNames(weight) <- getNames(data) -calcInternalGDPFutureSSP2 <- function(unit) { - data <- calcOutput("InternalGDPFutureSSPs", unit = unit, aggregate = FALSE)[, , "gdp_SSP2"] - list(x = data, weight = NULL, unit = glue("mil. {unit}"), description = "SSP2 projections") + list(x = data, weight = weight, unit = toolGetUnitDollar(inPPP = TRUE), description = glue("{scenario} projections")) } -calcInternalGDPFutureSDPs <- function(unit) { - dataSSP1 <- calcOutput("InternalGDPFutureSSPs", unit = unit, aggregate = FALSE)[, , "gdp_SSP1"] # nolint - - data <- purrr::map(c("SDP", "SDP_EI", "SDP_RC", "SDP_MC"), - ~ setNames(dataSSP1, gsub("SSP1", .x, getNames(dataSSP1)))) %>% - mbind() - list(x = data, weight = NULL, unit = glue("mil. {unit}"), description = "SDP projections") +toolGDPpcFutureFromGDPAndPop <- function(gdpFutureData, popFutureData) { + gdp <- calcOutput("GDPFuture", futureData = gdpFutureData, aggregate = FALSE) + pop <- calcOutput("PopulationFuture", futureData = popFutureData, aggregate = FALSE) + years <- intersect(getYears(gdp), getYears(pop)) + data <- gdp[, years, ] / pop[, years, ] + data[is.nan(data) | data == Inf] <- 0 + data } -calcInternalGDPFutureSSP2EU <- function(unit) { - euCountries <- toolGetEUcountries() - - dataSSP2EU <- readSource("EurostatPopGDP", "GDP")[euCountries, , ] %>% - GDPuc::toolConvertGDP("constant 2015 Int$PPP", unit, replace_NAs = c("linear", "no_conversion")) - grShort <- readSource("EurostatPopGDP", "GDPgr_projections_short")[euCountries, , ] - grLong <- readSource("EurostatPopGDP", "GDPgr_projections_long")[euCountries, , ] - dataSSP2EU <- add_columns(dataSSP2EU, dim = 2, addnm = getYears(grShort)[!getYears(grShort) %in% getYears(dataSSP2EU)]) - dataSSP2EU <- add_columns(dataSSP2EU, dim = 2, addnm = getYears(grLong)[!getYears(grLong) %in% getYears(dataSSP2EU)]) - for (y in getYears(grShort, as.integer = TRUE)) { - dataSSP2EU[, y, ] <- dataSSP2EU[, y - 1, ] * (1 + grShort[euCountries, y, ] / 100) +# Legacy... +toolGDPFutureOtherUnit <- function(data, baseYear, baseYearDef = 2017, convergeBy = 2100) { + if (baseYear == baseYearDef) { + return(data) } - for (y in getYears(grLong, as.integer = TRUE)) { - dataSSP2EU[, y, ] <- dataSSP2EU[, y - 1, ] * (1 + grLong[euCountries, y, ] / 100) - } - - dataSSP2 <- calcOutput("InternalGDPFutureSSPs", unit = unit, aggregate = FALSE)[, , "gdp_SSP2"] - - # Start with the SSP2 scenario until 2100. Change the name, and overwrite the EUR - # countries with the Eurostat data. - cy <- intersect(getYears(dataSSP2), getYears(dataSSP2EU)) - data <- dataSSP2[, cy, ] %>% setNames("gdp_SSP2EU") - data[euCountries, cy, ] <- dataSSP2EU[, cy, ] - data[is.na(data)] <- 0 - list(x = data, weight = NULL, unit = glue("mil. {unit}"), description = "Eurostat projections") -} -calcInternalGDPMI <- function(unit) { - data <- readSource("MissingIslands", "gdp") %>% - GDPuc::toolConvertGDP("constant 2005 Int$PPP", unit, replace_NAs = c("linear", "no_conversion")) - list(x = data, weight = NULL, unit = glue("mil. {unit}"), description = "MI projections") + # Construct SSP pathways in constant "baseYear" Int$PPP. + # For the near future, convert using current conversion factors. + # After that the scenarios are built by converting the US GDP, and building + # the other countries in relation to the US so that by "convergeBy", they have the same ratio as in the "defUnit". + data2 <- data + + # The near future is defined hear by the next 15 years, or until 10 years after the last imf prediction. + c15 <- max(getYears(readSource("IMF", "GDPpc"), as.integer = TRUE)) + 10 + + y1 <- getYears(data2)[getYears(data2, as.integer = TRUE) <= c15] + dataNearFut <- data2[, y1, ] %>% + GDPuc::toolConvertGDP(glue("constant {baseYearDef} Int$PPP"), + glue("constant {baseYear} Int$PPP"), + replace_NAs = c("linear", "no_conversion")) + + y2 <- getYears(data2)[getYears(data2, as.integer = TRUE) > c15 & getYears(data2, as.integer = TRUE) < 2100] + dataFarFut <- data2[, y2, ] * NA + + # Convert to "baseYear" Int$PPP using the "baseYear" value of base baseYearDef GDP deflator + # (in constant baseYear LCU per constant baseYearDef LCU) of the USA + # LONGTERM: allow other PPP units + dataEnd <- data2[, convergeBy, ] * GDPuc::toolConvertSingle(1, "USA", "2010", + glue("constant {baseYearDef} LCU"), + glue("constant {baseYear} LCU")) + + dataConverted <- mbind(dataNearFut, dataFarFut, dataEnd) + + ratio <- data2 / dataConverted + # For interpolation to work, the last and first values have to be non-NA/non-NaN + ratio[, convergeBy, ][is.na(ratio[, convergeBy, ])] <- 0 + # The first 2 years of the SSP data set are incomplete. For countries that only lack data in these first 2 years, + # set NaN to 0. + ratio[, 2000, ][is.nan(ratio[, 2000, ]) & !is.nan(ratio[, 2010, ])] <- 0 + + ratio <- as.data.frame(ratio, rev = 2) %>% + dplyr::rename("value" = ".value") %>% + dplyr::arrange(.data$year) %>% + dplyr::group_by(.data$iso3c, .data$variable) %>% + dplyr::mutate(value = zoo::na.approx(.data$value)) %>% + dplyr::ungroup() %>% + as.magpie(tidy = TRUE) + + dataConverted <- data2 / ratio + dataConverted[is.na(dataConverted)] <- data2[is.na(dataConverted)] + # Above should probably be "<- 0" + dataConverted } diff --git a/R/calcGDPHarmonized.R b/R/calcGDPHarmonized.R deleted file mode 100644 index 88246fb..0000000 --- a/R/calcGDPHarmonized.R +++ /dev/null @@ -1,72 +0,0 @@ -#' Get Harmonized GDP Data -#' -#' @inheritParams calcGDPpcHarmonized -#' @inherit madrat::calcOutput return -#' @keywords internal -calcGDPHarmonized <- function(harmonization, past, future, scenario, unit, ...) { - harmonizedData <- switch(harmonization, - "GDPpcWithPop" = toolMultiplyGDPpcWithPop(scenario, unit), - "calibSSP2EU" = toolGDPHarmonizeSSP2EU(past, future, unit), - stop(glue("Bad input for calcGDPHarmonized. Argument harmonization = '{harmonization}' is invalid. \\ - Possible values are: 'GDPpcWithPop', 'calibsSSP2EU' or 'past_transition'.")) - ) - list(x = harmonizedData$x, weight = NULL, unit = glue("mil. {unit}"), description = harmonizedData$description) -} - - -###################################################################################### -# GDP Harmonization Functions -###################################################################################### -toolMultiplyGDPpcWithPop <- function(scenario, unit) { - gdppc <- calcOutput("GDPpc", - scenario = scenario, - unit = unit, - extension2150 = "none", - average2020 = FALSE, - aggregate = FALSE, - supplementary = TRUE) - # GDP is equal to GDPpc * population - gdp <- gdppc$x * gdppc$weight - getNames(gdp) <- gsub("gdppc", "gdp", getNames(gdp)) - list(x = gdp, - description = glue("use product of corresponding GDP per capita and population scenarios. \\ - {gdppc$description}")) -} - -toolGDPHarmonizeSSP2EU <- function(past, future, unit) { - # We explicitly use the bezier Extension for SSP2 here, but only for harmonization purposes. - # We return only up until 2100. - ssp2Data <- calcOutput("GDP", - scenario = "SSP2", - unit = "constant 2017 Int$PPP", - extension2150 = "bezier", - average2020 = FALSE, - aggregate = FALSE) - - # For SSP2EU: EU countries are equal to past - euCountries <- toolGetEUcountries() - ssp2EUData <- ssp2Data[euCountries, , ] - ssp2EUData[, , ] <- 0 - ssp2EUData[, getYears(past$x), ] <- past$x[euCountries, , ] - ssp2EUData[, getYears(future$x), ] <- future$x[euCountries, , ] - - # After last year of future, transition to SSP2 values by 2150 - pastYears <- getYears(ssp2EUData)[getYears(ssp2EUData, as.integer = TRUE) <= max(getYears(future$x, as.integer = TRUE))] - combinedSSP2EU <- toolHarmonizePast(ssp2EUData[, pastYears, ], - ssp2Data[euCountries, , ], - method = "transition", - yEnd = 2150) - - combined <- ssp2Data - combined[euCountries, , ] <- 0 - combined[euCountries, getYears(combinedSSP2EU), ] <- combinedSSP2EU[euCountries, , ] - getNames(combined) <- "gdp_SSP2EU" - - combined <- combined[, getYears(combined)[getYears(combined, as.integer = TRUE) <= 2100], ] - - list(x = combined, - description = glue("equal to SSP2 in all countries except for EU countries. \\ - For EU countries use {past$description} until {max(getYears(past$x, as.integer = TRUE))}, \\ - {future$description} until {max(getYears(future$x, as.integer = TRUE))}, \\ - and converge to 2150 (bezier-extended) SSP2 values thereafter.")) -} diff --git a/R/calcGDPPast.R b/R/calcGDPPast.R index 7660354..3792da3 100644 --- a/R/calcGDPPast.R +++ b/R/calcGDPPast.R @@ -1,112 +1,101 @@ -#' Get GDP and GDPpc scenario building blocks +#' Get scenario building blocks #' #' @description -#' Get the past and future GDP scenario building blocks with calcGDPPast and calcGDPFuture, respectively. -#' If GDP data for a scenario is required, even if just for a single year, always use [calcGDP()], as what is returned -#' by calcGDPPast or calcGDPFuture may not end up as is in the scenario, depending on the harmonization function. -#' Use calcGDPPast and calcGDPFuture only when trying to access specific GDP data. +#' Get the past and future scenario building blocks. +#' If scenario data is required, even if just for a single year, always use the calc call to the final scenario, e.g. +#' [calcGDP()] or [calcPopulation()], as what is returned by the calc...Past and calc...Future functions may not end up +#' as is in the scenario, depending on the harmonization function. +#' These functions are only still exported for compatibility with existing code in the PIAM input data pipeline. +#' +#' See the vignette: \code{vignette("scenarios")} for references for the different data sources. #' #' See the "Combining data sources with '-'" section below for how to combine data sources. #' -#' @param GDPPast A string designating the source for the historical GDP data. Available sources are: -#' \itemize{ -#' \item "WDI": World development indicators from the World Bank -#' \item "MI": Missing island dataset -#' \item "Eurostat": Eurostat -#' } -#' @inheritParams calcGDP +#' @param pastData A string specifying the sources for historic data. +#' @param extension1960 A string specifying how the data should be extended backwards to 1960. #' @inheritSection calcScenarioConstructor Combining data sources with "-" #' @keywords internal -calcGDPPast <- function(GDPPast = "WDI-MI", unit = "constant 2017 Int$PPP") { # nolint +#' @order 1 +calcGDPPast <- function(pastData = "WDI-MI-James", extension1960 = "MI-James") { # Check user input toolCheckUserInput("GDPPast", as.list(environment())) + # Call calcInternalGDPPast function the appropriate number of times (map) and combine (reduce) # !! Keep formula syntax for madrat caching to work - purrr::pmap(list("GDPPast" = unlist(strsplit(GDPPast, "-")), "unit" = unit), - ~calcOutput("InternalGDPPast", aggregate = FALSE, supplementary = TRUE, ...)) %>% - toolReduce(mbindOrFillWith = "fillWith") + data <- purrr::pmap(list("pastData" = unlist(strsplit(pastData, "-"))), + ~calcOutput("InternalGDPPast", aggregate = FALSE, supplementary = TRUE, ...)) %>% + toolListFillWith() + + # If required, project GDP series back to 1960 using growth rates from the extension1960 data set. + if (extension1960 != "none") { + data1960 <- calcOutput("GDPPast", + pastData = extension1960, + extension1960 = "none", + aggregate = FALSE, + supplementary = TRUE) + data <- toolHarmonizeFuture(past = data1960, future = data, method = "growth") + data$x <- toolInterpolateAndExtrapolate(data$x) + } + + list(x = data$x, + weight = NULL, + unit = glue("mil. {toolGetUnitDollar(inPPP = TRUE)}"), + description = data$description) } -###################################################################################### -# Internal Function -###################################################################################### -calcInternalGDPPast <- function(GDPPast, unit) { # nolint +calcInternalGDPPast <- function(pastData) { # Call appropriate calcInternalGDPPast function. data <- switch( - GDPPast, - "WDI" = calcOutput("InternalGDPPastWDI", unit = unit, aggregate = FALSE), - "Eurostat" = calcOutput("InternalGDPPastEurostat", unit = unit, aggregate = FALSE), - "MI" = calcOutput("InternalGDPMI", unit = unit, aggregate = FALSE), - stop("Bad input for calcGDPPast. Invalid 'GDPPast' argument.") + pastData, + "WDI" = readSource("WDI", "gdp"), + "MI" = readSource("MissingIslands", "gdp"), + "James" = toolGDPPastJames(), + stop("Bad input for calcGDPPast. Invalid 'pastData' argument.") ) - data <- toolFinishingTouches(data) - - list(x = data, weight = NULL, unit = glue("mil. {unit}"), description = glue("{GDPPast} data")) -} - - - + getNames(data) <- pastData -###################################################################################### -# Functions -###################################################################################### -calcInternalGDPPastWDI <- function(unit) { - # "NY.GDP.MKTP.PP.KD" = GDP in constant 2017 Int$PPP (as of time of writing this function) - data <- readSource("WDI", "NY.GDP.MKTP.PP.KD") %>% - GDPuc::toolConvertGDP("constant 2017 Int$PPP", unit, replace_NAs = c("linear", "no_conversion")) - - data <- fillWithWBFromJames2019(data, unit) - - getNames(data) <- glue("gdp in {unit}") - list(x = data, weight = NULL, unit = unit, description = "WDI data") + list(x = data, + weight = NULL, + unit = glue("mil. {toolGetUnitDollar(inPPP = TRUE)}"), + description = glue("{pastData} data")) } -calcInternalGDPPastEurostat <- function(unit) { - euCountries <- toolGetEUcountries() - - data <- readSource("EurostatPopGDP", "GDP")[euCountries, , ] %>% - GDPuc::toolConvertGDP("constant 2015 Int$PPP", unit, replace_NAs = c("linear", "no_conversion")) - - data <- fillWithWBFromJames2019(data, unit) - data <- data %>% toolCountryFill(fill = 0) %>% suppressMessages() - - getNames(data) <- glue("gdp in {unit}") - list(x = data, weight = NULL, unit = unit, description = "Eurostat data") +toolGDPPastJames <- function() { + gdppc <- readSource("James", "gdp") + pop <- calcOutput("PopulationPast", aggregate = FALSE) + years <- intersect(getYears(gdppc), getYears(pop)) + gdppc[, years, ] * pop[, years, ] } -# Use the James2019 WB_USD05_PPP_pc series to fill in past data until 1960. -# Using mainly growth rates, since conversion of James2019 data into 2005 Int$PPP not certain to be correct. -fillWithWBFromJames2019 <- function(data, unit) { - gdppc <- readSource("James2019", "WB_USD05_PPP_pc") %>% - GDPuc::toolConvertGDP("constant 2005 Int$PPP", unit, replace_NAs = c("linear", "no_conversion")) - pop <- readSource("WDI", "SP.POP.TOTL") - - cy <- intersect(getYears(gdppc), getYears(pop)) - pastGDP <- gdppc[, cy, ] * pop[, cy, ] - getSets(pastGDP) <- c("iso3c", "year", "variable") - getNames(pastGDP) <- "WB_USD05_PPP" - - x <- new.magpie(getItems(data, 1), - 1960:max(getYears(data, as.integer = TRUE)), - getNames(data), - fill = 0) - getSets(x) <- getSets(pastGDP) - for (i in getItems(data, 1)) { - tmp <- data[i, getYears(data)[data[i, , ] != 0], ] - ihmeData <- pastGDP[i, cy[pastGDP[i, , ] != 0], ] - - if (length(tmp) == 0 && length(ihmeData) == 0) { - next - } else if (length(tmp) != 0 && length(ihmeData) == 0) { - x[i, getYears(tmp), ] <- tmp - } else if (length(tmp) == 0 && length(ihmeData) != 0) { - x[i, cy, ] <- toolFillYears(ihmeData, cy) - } else { - r <- toolHarmonizeFutureGrPast(past = toolFillYears(ihmeData, cy), future = tmp) - x[i, getYears(r), ] <- r - } - } - x +#' @rdname calcGDPPast +#' @param scenario A string specifying the scenario, from which the historic GDP and population data sources are taken. +#' @order 2 +calcGDPpcPast <- function(scenario = "SSPs") { + # We can not fill data sources as in GDP and Pop, as GDP and pop on their part are filled with MI, and the countries + # which are filled in do not match. (WDI has pop data for some countries, but not GDP.) So to make sure that the + # GDP per capita is consistent, we have to pass it on to the GDP and pop functions. + gdpPastData <- toolGetScenarioDefinition("GDPpc", scenario, aslist = TRUE)$pastData + popPastData <- toolGetScenarioDefinition("Population", scenario, aslist = TRUE)$pastData + gdp <- calcOutput("GDPPast", pastData = gdpPastData, aggregate = FALSE) + pop <- calcOutput("PopulationPast", pastData = popPastData, aggregate = FALSE) + years <- intersect(getYears(gdp), getYears(pop)) + data <- gdp[, years, ] / pop[, years, ] + data[is.nan(data) | data == Inf] <- 0 + getNames(data) <- paste(gdpPastData, "gdp data", "over", popPastData, "pop data") + + # The weight does not go into the weight of the final scenario. So exact matching with GDPpc not necessary... + weight <- pop + getNames(weight) <- getNames(data) + # Make sure weight and data have the same yearly resolution. + ## Sometimes weght has more years than x, thus the intersect operation. + weight <- weight[, intersect(getYears(data), getYears(weight)), ] + ## If x has more years than weight, add these years and interpolate + missingYears <- getYears(data)[! getYears(data) %in% getYears(weight)] + weight <- add_columns(weight, missingYears, dim = 2, fill = 0) + weight <- weight[, sort(getYears(weight)), ] + weight <- toolInterpolateAndExtrapolate(weight) + + list(x = data, weight = weight, unit = toolGetUnitDollar(inPPP = TRUE), description = glue("{getNames(data)}")) } diff --git a/R/calcGDPpc.R b/R/calcGDPpc.R deleted file mode 100644 index e38e986..0000000 --- a/R/calcGDPpc.R +++ /dev/null @@ -1,70 +0,0 @@ -#' @rdname calcGDP -#' @examples \dontrun{ -#' calcOutput("GDPpc") -#' } -#' -calcGDPpc <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), - unit = "constant 2017 Int$PPP", - average2020 = TRUE, - ...) { - # Check user input - toolCheckUserInput(driver = "GDPpc", args = c(list(...), as.list(environment()))) - - # GDPpc scenarios are constructed in 2017 Int$PPP, and converted, if necessary, at the end. - gdppc <- calcOutput("Driver", - driver = "GDPpc", - scenario = scenario, - unit = "constant 2017 Int$PPP", - popAsWeight = TRUE, - aggregate = FALSE, - supplementary = TRUE, - ...) - - if (average2020) { - # For REMIND, the consensus is to average the 2020 value so as to dampen the effect of the COVID shock. (The - # reasoning being that REMIND uses 5-year time steps, and that the year-in-itself should represent the 2,5 years - # before and after.) - # The dampening is supposed to take place on GDP. So for GDP per capita in 2020 to be consistent with the dampened - # GDP, it has to calculated from GDP and population. (In other words we can't just use the same formula as for GDP, - # since it would lead to inconsistency at the end.) This is a bit hacky... - gdp2020 <- calcOutput("GDP", - scenario = scenario, - unit = "constant 2017 Int$PPP", - average2020 = TRUE, - naming = "scenario", - extension2150 = "none", - aggregate = FALSE, - years = 2020) - pop2020 <- calcOutput("Population", - scenario = scenario, - naming = "scenario", - extension2150 = "none", - aggregate = FALSE, - years = 2020) - gdppc2020 <- gdp2020 / pop2020 - gdppc2020[is.nan(gdppc2020)] <- 0 - getNames(gdppc2020) <- getNames(gdppc$x) - gdppc$x[, 2020, ] <- gdppc2020 - gdppc$description <- paste(gdppc$description, "|| 2020 value averaged over 2018-2022 time period.") - # Return only 5 year time steps, since the yearly data around 2020 is not connected to the 2020 value anymore. - years5ts <- getYears(gdppc$x, as.integer = TRUE)[getYears(gdppc$x, as.integer = TRUE) %% 5 == 0 & - getYears(gdppc$x, as.integer = TRUE) != 1960] - gdppc$x <- gdppc$x[, years5ts, ] - gdppc$weight <- gdppc$weight[, years5ts, ] - gdppc$description <- paste(gdppc$description, "5 year time steps only.") - message("The 2020 value is an an avergae over the 2018-2022 time period!!") - } - - # Convert to US$MER if required - if (grepl("US\\$MER", unit)) { - # Convert by interpolating and extrapolating missing conversion factors when possible. - gdppc$x <- GDPuc::toolConvertGDP(gdppc$x, - unit_in = "constant 2017 Int$PPP", - unit_out = "constant 2017 US$MER", - replace_NAs = c("linear", "no_conversion")) - } - # Temporary shifting to 2005 prices, using only the US deflator - if (grepl("2005", unit)) gdppc$x <- gdppc$x * 0.8121123 - - list(x = gdppc$x, weight = gdppc$weight, unit = unit, description = gdppc$description) -} diff --git a/R/calcGDPpcFuture.R b/R/calcGDPpcFuture.R deleted file mode 100644 index 93541cd..0000000 --- a/R/calcGDPpcFuture.R +++ /dev/null @@ -1,67 +0,0 @@ -#' @describeIn calcGDPPast Get future GDPpc projections -#' -#' @param GDPpcFuture A string designating the source for the future GDP data. Available sources are: -#' \itemize{ -#' \item "SSPs": -#' \item "SDPs": All SDP future projections are set equal to those of SSP1. -#' \item "MI": Missing island dataset -#' } -#' See the "Combining data sources with '-'" section below for how to combine data sources. -calcGDPpcFuture <- function(GDPpcFuture, unit) { # nolint - - data <- switch( - GDPpcFuture, - "SSPs" = toolGDPpcFutureSSPs(unit), - "SSP2" = toolGDPpcFutureSSPs(unit)[, , "gdppc_SSP2"], - "SDPs" = toolGDPpcFutureSDPs(unit), - "SDPs-MI" = toolGDPpcFutureSDPs(unit, mi = TRUE), - "SSPs-MI" = toolGDPpcFutureSSPs(unit, mi = TRUE), - "SSP2-MI" = toolGDPpcFutureSSPs(unit, mi = TRUE)[, , "gdppc_SSP2"], - "MI" = toolGDPpcMI(unit), - stop("Bad input for calcGDPFuture. Invalid 'GDPFuture' argument.") - ) - - data <- toolFinishingTouches(data) - - weight <- calcOutput("PopulationFuture", PopulationFuture = GDPpcFuture, aggregate = FALSE) - # Give weight same names as data, so that aggregate doesn't mess up data dim - getNames(weight) <- gsub("pop", "gdppc", getNames(weight)) - - data <- data[, getYears(weight), ] - - list(x = data, weight = weight, unit = unit, description = glue("{GDPpcFuture} projections")) -} - -toolGDPpcFutureSSPs <- function(unit, mi = FALSE) { - h1 <- if (mi) "SSPs-MI" else "SSPs" - - gdp <- calcOutput("GDPFuture", GDPFuture = h1, unit = unit, aggregate = FALSE) - gdp <- setNames(gdp, c("gdppc_SSP1", "gdppc_SSP2", "gdppc_SSP3", "gdppc_SSP4", "gdppc_SSP5")) - - pop <- calcOutput("PopulationFuture", PopulationFuture = h1, aggregate = FALSE) - pop <- setNames(pop, c("gdppc_SSP1", "gdppc_SSP2", "gdppc_SSP3", "gdppc_SSP4", "gdppc_SSP5")) - - years <- intersect(getYears(gdp), getYears(pop)) - data <- gdp[, years, ] / pop[, years, ] - data[is.nan(data) | data == Inf] <- 0 - data -} - -toolGDPpcFutureSDPs <- function(unit, mi = FALSE) { - dataSSP1 <- toolGDPpcFutureSSPs(unit, mi)[, , "gdppc_SSP1"] - - purrr::map(c("SDP", "SDP_EI", "SDP_RC", "SDP_MC"), - ~ setNames(dataSSP1, gsub("SSP1", .x, getNames(dataSSP1)))) %>% - mbind() -} - -toolGDPpcMI <- function(unit) { - gdp <- calcOutput("GDPFuture", GDPFuture = "MI", unit = unit, aggregate = FALSE) - pop <- calcOutput("PopulationFuture", PopulationFuture = "MI", aggregate = FALSE) - years <- intersect(getYears(gdp), getYears(pop)) - - data <- gdp[, years, ] / pop[, years, ] - data <- setNames(data, "gdppc_MI") - data[is.nan(data) | data == Inf] <- 0 - data -} diff --git a/R/calcGDPpcHarmonized.R b/R/calcGDPpcHarmonized.R deleted file mode 100644 index 58fd8c3..0000000 --- a/R/calcGDPpcHarmonized.R +++ /dev/null @@ -1,296 +0,0 @@ -#' Get Harmonized GDPpc Data -#' -#' @param harmonization description -#' @param past description -#' @param future description -#' @param scenario description -#' @param unit description -#' @inherit madrat::calcOutput return -#' @keywords internal -calcGDPpcHarmonized <- function(harmonization, past, future, scenario, unit, ...) { - harmonizedData <- switch( - harmonization, - "calibSSPs" = toolGDPpcHarmonizeSSP(past, future, unit, yEnd = 2100), - "calibSDPs" = toolGDPpcHarmonizeSDP(unit), - "GDPoverPop" = toolDivideGDPbyPop(scenario, unit), - stop(glue("Bad input for calcGDPpcHarmonized. Argument harmonization = '{harmonization}' is invalid.")) - ) - list(x = harmonizedData$x, weight = NULL, unit = unit, description = harmonizedData$description) -} - - - - -###################################################################################### -# GDPpc Harmonization Functions -###################################################################################### -toolGDPpcHarmonizeSSP <- function(past, future, unit, yEnd) { - # Get IMF short-term income projections and fill missing with SSP2 - imfGDPpc <- readSource("IMF", "GDPpc") - - fill <- calcOutput("GDPpcFuture", GDPpcFuture = "SSPs-MI", unit = unit, aggregate = FALSE)[, , "gdppc_SSP2"] - imfGDPpc <- imfGDPpc %>% - toolFillWith(fill) %>% - toolInterpolateAndExtrapolate() - - # Use short term IMF growth rates (here, as far as possible) - tmpGDPpc <- toolHarmonizePast(past$x, imfGDPpc, method = "growth") - - # Transform into tibble - tmpGDPpc <- tmpGDPpc %>% tibble::as_tibble() %>% dplyr::select(-"variable") - - # Make sure to add the last IMF year to the future SSP data, just in case it's not there. That is the year from which - # convergence begins. Also drop countries with no projection data for now. - yStart <- max(getYears(imfGDPpc, as.integer = TRUE)) - missingC <- where(future$x == 0)$true$regions - futureGDPpcTbl <- future$x %>% - magclass::time_interpolate(yStart, integrate_interpolated_years = TRUE) %>% - dplyr::as_tibble() %>% - dplyr::filter(!.data$iso3c %in% missingC) - - combinedGDPpc <- tidyr::expand_grid(iso3c = unique(futureGDPpcTbl$iso3c), - year = unique(c(tmpGDPpc$year, futureGDPpcTbl$year)), - variable = unique(futureGDPpcTbl$variable)) %>% - dplyr::left_join(tmpGDPpc, by = c("iso3c", "year")) %>% - dplyr::left_join(dplyr::select(futureGDPpcTbl, "iso3c", "year", "variable", "iiasa_gdppc" = "value"), - by = c("iso3c", "year", "variable")) %>% - dplyr::rename("SSP" = "variable") %>% - dplyr::mutate(SSP = sub("^......", "", .data$SSP)) - - # Pass to special convergence function - combinedGDPpc <- convergeSpecial(combinedGDPpc, yearStart = yStart, yearEnd = yEnd) - - # Retransform into magpie - combinedGDPpc <- combinedGDPpc %>% - dplyr::mutate(SSP = paste0("gdppc_", .data$SSP)) %>% - dplyr::select("iso3c", "year", "variable" = "SSP", "value") %>% - tidyr::replace_na(list("value" = 0)) %>% - as.magpie() %>% - toolCountryFill(fill = 0) - - # Add past data for countries with no projection data - combinedGDPpc[missingC, getYears(past$x)] <- past$x[missingC, , ] - - lastPastYear <- max(getYears(past$x, as.integer = TRUE)) - - list(x = combinedGDPpc, - description = glue("use {past$description} until {lastPastYear}, \\ - short term growth rates from IMF until {yStart}, \\ - and transition to {future$description} by {yEnd}.")) -} - -toolGDPpcHarmonizeSDP <- function(unit) { - - gdppcapSSP1 <- calcOutput("GDPpc", - scenario = "SSPs", - unit = unit, - extension2150 = "none", - average2020 = FALSE, - aggregate = FALSE)[, , "gdppc_SSP1"] - - # standard SDP inherits SSP1 GDP - gdppcapSDP <- gdppcapSSP1 - getNames(gdppcapSDP) <- gsub("SSP1", "SDP", getNames(gdppcapSDP)) - # SHAPE SDP_XX variants are calculated as modifications of SSP1 GDP/cap growth rates - combined <- purrr::map(c("gdppc_SDP_EI", "gdppc_SDP_MC", "gdppc_SDP_RC"), - computeSHAPEgrowth, - gdppcapSSP1 = gdppcapSSP1, - startFromYear = 2020) %>% - mbind() %>% - mbind(gdppcapSDP) - - combined[is.nan(combined) | combined == Inf] <- 0 - - list(x = combined, - description = glue("use SSP1 scenario and adapt growth rates.")) -} - -toolDivideGDPbyPop <- function(scenario, unit) { - gdp <- calcOutput("GDP", - scenario = scenario, - unit = unit, - extension2150 = "none", - average2020 = FALSE, - aggregate = FALSE, - supplementary = TRUE) - pop <- calcOutput("Population", - scenario = scenario, - extension2150 = "none", - aggregate = FALSE, - supplementary = TRUE, - years = getYears(gdp$x)) - getNames(gdp$x) <- getNames(pop$x) <- gsub("pop", "gdppc", getNames(pop$x)) - gdppc <- gdp$x / pop$x - list(x = gdppc, - description = glue("use ratio of corresponding GDP and population scenarios. {gdp$description} \\ - {pop$description}")) -} - - - - -######################### -### Helper functions -######################### -convergeSpecial <- function(x, yearStart, yearEnd) { - - # Compute the difference in yearStart. - dif <- x %>% - dplyr::filter(.data$year == yearStart) %>% - dplyr::mutate(d = .data$iiasa_gdppc - .data$value) %>% - dplyr::select("iso3c", "SSP", "d") - - # Define the years marking the start of medium, and slow convergence - # (yearStart being the start for fast convergence) - y1 <- yearStart + 5 - y2 <- yearStart + 10 - - x <- x %>% - dplyr::left_join(dif, by = c("iso3c", "SSP")) %>% - dplyr::mutate( - # Medium convergence - value = dplyr::if_else( - .data$year > yearStart & .data$SSP == "SSP2", - dplyr::if_else( - .data$year <= y1, - .data$iiasa_gdppc - .data$d, - dplyr::if_else( - .data$year <= yearEnd, - .data$iiasa_gdppc - .data$d * (yearEnd - .data$year) / (yearEnd - y1), - .data$iiasa_gdppc - ) - ), - .data$value - ), - # Fast convergence - value = dplyr::if_else( - .data$year > yearStart & - ((.data$SSP %in% c("SSP1", "SSP5") & .data$d >= 0) | - (.data$SSP %in% c("SSP3", "SSP4") & .data$d < 0)), - dplyr::if_else( - .data$year <= yearEnd, - .data$iiasa_gdppc - .data$d * (yearEnd - .data$year) / (yearEnd - yearStart), - .data$iiasa_gdppc - ), - .data$value - ), - # Slow convergence - value = dplyr::if_else( - .data$year > yearStart & - ((.data$SSP %in% c("SSP3", "SSP4") & .data$d >= 0) | - (.data$SSP %in% c("SSP1", "SSP5") & .data$d < 0)), - dplyr::if_else( - .data$year <= y2, - .data$iiasa_gdppc - .data$d, - dplyr::if_else( - .data$year <= yearEnd, - .data$iiasa_gdppc - .data$d * (yearEnd - .data$year) / (yearEnd - y2), - .data$iiasa_gdppc - ) - ), - .data$value - ), - # Add a minimum value for value here. This can occur when the d computed in yearStart is - # so large relative to the original GDPpc value in yearStart, that a further dercease in the - # years y1 and y2 pushes the GDPpc into the negative. - value = pmax(.data$value, 0.01) - ) %>% - dplyr::select(-"d") - x -} - -########################################### -# Additional functions to derive the SHAPE GDP scenarios from the SSP1 scenario - -# Note that here we label the GDP scenarios with their scenario abbreviations, -# and not with the name of the SHAPE economics dimensions. - -# Mapping: Scenario <-> economics dimension -# Economy-driven innovation (SDP_EI) <-> innovation-driven economy -# Resilient communities (SDP_RC) <-> society-driven economy -# Managing the global commons (SDP_MC) <-> service-driven economy - -# The two alternative SHAPE scenarios will re-use these GDP trajectories, so they are not explicitly included here. -# Local solutions (SDP_LS) <-> society-driven economy (same as SDP_RC) -# Green and social market economy (SDP_GS) <-> service-driven economy (same as SDP_MC) - -# for details see the SHAPE scenario spreadsheet -# https://docs.google.com/spreadsheets/d/1v8dlZDj-AW8_oiyd9rdV3rGfVBt_PBCja1_NyEEFRMA/edit?usp=sharing -########################################### - -# calculate modified growth rates and resulting gdp/capita in forward simulation -computeSHAPEgrowth <- function(shapeGDPScenario, gdppcapSSP1, startFromYear) { - - # calculation of growth rates - yrs <- getYears(gdppcapSSP1, as.integer = TRUE) - # flexible timestep - # LONGTERM would be better to always use yearly timesteps in this computation, - # and select years afterwards - timestep <- new.magpie(years = yrs) - timestep[, , ] <- dplyr::lead(yrs) - yrs - # assign average growth rate g_t of period t -> t+ timestep - # this means modifications of growth rate t will affect GDP in t+timestep - yrsShifted <- yrs[2:length(yrs)] - yrsBase <- yrs[1:(length(yrs) - 1)] - growthrateSSP1 <- 100 * - ((setYears(gdppcapSSP1[, yrsShifted, ], yrsBase) / gdppcapSSP1[, yrsBase, ]) ^ - (1. / timestep[, yrsBase, ]) - 1) - - # modified growth rates and gdp/cap - growthrate <- setNames(as.magpie(growthrateSSP1), shapeGDPScenario) - gdppcap <- setNames(as.magpie(gdppcapSSP1), shapeGDPScenario) - gdppcap[, yrs > startFromYear, ] <- NA - - for (yr in yrs[1:(length(yrs) - 1)]) { - # modify growth rates only for future period (default: from 2020 onwards) - if (yr >= startFromYear) { - # innovation-driven (SDP_EI): enhance growth rates for low-income countries by up to 15% - if (shapeGDPScenario == "gdppc_SDP_EI") { - modificationFactor <- logisticTransition( - gdppcap[, yr, ], l0 = 1.15, l = 1, k = 20, x0 = 15e3, useLog10 = TRUE - ) - # service-driven (SDP_MC): growth rate reduced based on relative distance to technology frontier - # (given by the US) - } else if (shapeGDPScenario == "gdppc_SDP_MC") { - # define US as technology frontier - frontier <- gdppcap["USA", yr, ] - getItems(frontier, 1) <- "GLO" - # countries with gdp/cap above US are treated the same as the US -> set diff = 0 - reldiff2frontier <- pmax((frontier[, yr, ] - gdppcap[, yr, ]) / frontier[, yr, ], 0) - modificationFactor <- logisticTransition( - reldiff2frontier[, yr, ], l0 = 1, l = 0.5, k = -30, x0 = 0.2, useLog10 = FALSE - ) - # society-driven (SDP_RC): gradual transition to zero growth for high-income countries - } else if (shapeGDPScenario == "gdppc_SDP_RC") { - modificationFactor <- logisticTransition(gdppcap[, yr, ], l0 = 1, l = 0, k = 10, x0 = 30e3, useLog10 = TRUE) - } else { - stop("cannot create SHAPE GDP scenarios: unknown scenario") - } - - # for service (SDP_MC) and society (SDP_RC) additionally add a smoothing for 2020 and 2025 timesteps - # apply only 1/3 (2020-2024) and 2/3 (2025-2029) of the modification - if (shapeGDPScenario %in% c("gdppc_SDP_MC", "gdppc_SDP_RC")) { - if (yr >= 2020 && yr < 2025) { - modificationFactor[, yr, ] <- 1 / 3. * (modificationFactor[, yr, ] - 1) + 1 - } else if (yr >= 2025 && yr < 2030) { - modificationFactor[, yr, ] <- 2 / 3. * (modificationFactor[, yr, ] - 1) + 1 - } - } - growthrate[, yr, ] <- growthrate[, yr, ] * modificationFactor[, yr, ] - } - - # calculate next gdp/cap based on current value and (modified) growth rate - gdppcap[, yr + as.integer(timestep[, yr, ]), ] <- gdppcap[, yr, ] * (1 + growthrate[, yr, ] / 100.)^timestep[, yr, ] - } - return(gdppcap) -} - -# helper function: smooth transition from lO to l, with steepness k and midpoint x0 -logisticTransition <- function(x, l0, l, k, x0, useLog10 = FALSE) { - if (useLog10) { - x <- log10(x) - x0 <- log10(x0) - } - logistic <- 1. / (1 + exp(-k * (x - x0))) - return(l0 - (l0 - l) * logistic) -} diff --git a/R/calcGDPpcPast.R b/R/calcGDPpcPast.R deleted file mode 100644 index 25b6976..0000000 --- a/R/calcGDPpcPast.R +++ /dev/null @@ -1,33 +0,0 @@ -#' @describeIn calcGDPPast Get historic GDPpc data -#' -#' @param GDPpcPast A string designating the source for the historical GDPpc data. Available sources are: -#' \itemize{ -#' \item "WDI": World development indicators from the World Bank -#' \item "MI": Missing island dataset -#' } -#' See the "Combining data sources with '-'" section below for how to combine data sources. -calcGDPpcPast <- function(GDPpcPast = "WDI-MI", unit = "constant 2017 Int$PPP") { # nolint - # Call appropriate calcGDPPast function. - data <- switch(GDPpcPast, - "WDI" = cGDPpcFromGDPAndPop(GDPpcPast, unit), - "WDI-MI" = cGDPpcFromGDPAndPop(GDPpcPast, unit), - "MI" = cGDPpcFromGDPAndPop(GDPpcPast, unit), - stop("Bad input for calcGDPpcPast. Invalid 'GDPpcPast' argument.")) - - weight <- calcOutput("PopulationPast", - PopulationPast = GDPpcPast, - aggregate = FALSE) - - list(x = data, weight = weight, unit = unit, description = glue("{GDPpcPast} data")) -} - -cGDPpcFromGDPAndPop <- function(GDPpcPast, unit) { # nolint - gdp <- calcOutput("GDPPast", GDPPast = GDPpcPast, unit = unit, aggregate = FALSE) - pop <- calcOutput("PopulationPast", PopulationPast = GDPpcPast, aggregate = FALSE) - years <- intersect(getYears(gdp), getYears(pop)) - - data <- gdp[, years, ] / pop[, years, ] - data <- setNames(data, glue("gdppc_{GDPpcPast}")) - data[is.nan(data) | data == Inf] <- 0 - data -} diff --git a/R/calcLabour.R b/R/calcLabour.R deleted file mode 100644 index adcba12..0000000 --- a/R/calcLabour.R +++ /dev/null @@ -1,8 +0,0 @@ -#' @rdname calcPopulation -#' @examples \dontrun{ -#' calcOutput("Labour") -#' } -calcLabour <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), ...) { - toolCheckUserInput(driver = "Labour", args = c(list(...), as.list(environment()))) - calcOutput("Driver", driver = "Labour", scenario = scenario, aggregate = FALSE, supplementary = TRUE, ...) -} diff --git a/R/calcLabourFuture.R b/R/calcLabourFuture.R deleted file mode 100644 index 0f2cfaf..0000000 --- a/R/calcLabourFuture.R +++ /dev/null @@ -1,79 +0,0 @@ -#' @rdname calcPopulationPast -#' @param LabourFuture A string designating the source for the future working-age population data. -#' Available sources are: -#' \itemize{ -#' \item "SSPs": -#' } -calcLabourFuture <- function(LabourFuture = "SSPs") { # nolint - # Check user input - toolCheckUserInput("LabourFuture", as.list(environment())) - # Call calcInternalPopulationFuture function the appropriate number of times (map) and combine (reduce) - # !! Keep formula syntax for madrat caching to work - purrr::pmap(list("LabourFuture" = unlist(strsplit(LabourFuture, "-"))), - ~calcOutput("InternalLabourFuture", aggregate = FALSE, supplementary = TRUE, ...)) %>% - toolReduce(mbindOrFillWith = "fillWith") -} - -calcInternalLabourFuture <- function(LabourFuture) { # nolint - x <- switch( - LabourFuture, - "SSPs" = calcOutput("InternalLabourFutureSSPs", aggregate = FALSE), - "SSP2" = calcOutput("InternalLabourFutureSSPs", aggregate = FALSE)[, , "lab_SSP2"], - "SDPs" = calcOutput("InternalLabourFutureSDPs", aggregate = FALSE), - "SSP2EU" = calcOutput("InternalLabourFutureSSP2EU", aggregate = FALSE), - stop("Bad input for calcLabour. Invalid 'LabourFuture' argument.") - ) - - # Apply finishing touches to combined time-series - x <- toolFinishingTouches(x) - - # Hopefully temporary: rename lab scnearios pop. Necessary for REMIND to work. - getNames(x) <- sub("lab_", "pop_", getNames(x)) - - list(x = x, - weight = NULL, - unit = "million", - description = glue("Working age population data.")) -} - -###################################################################################### -# Functions -###################################################################################### -calcInternalLabourFutureSSPs <- function() { - x <- readSource("SSP", "lab")[, , c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5")] - # Remove years which only contain 0 - x <- x[, !apply(x, 2, function(y) all(y == 0)), ] - getNames(x) <- paste0("lab_", getNames(x)) - list(x = x, weight = NULL, unit = "million", description = "Labor from SSPs") -} - -calcInternalLabourFutureSDPs <- function() { - labSSP1 <- calcOutput("InternalLabourFutureSSPs", aggregate = FALSE)[, , "lab_SSP1"] # nolint - - data <- purrr::map(c("SDP", "SDP_EI", "SDP_RC", "SDP_MC"), - ~ setNames(labSSP1, gsub("SSP1", .x, getNames(labSSP1)))) %>% - mbind() - list(x = data, weight = NULL, unit = "million", description = "Labor from SDPs") -} - -calcInternalLabourFutureSSP2EU <- function() { - labSSP2 <- calcOutput("InternalLabourFutureSSPs", aggregate = FALSE)[, , "lab_SSP2"] - popSSP2 <- calcOutput("Population", - harmonization = "withPEAPandFuture", - pastData = "WDI", - futureData = "SSPs", - extension2150 = "none", - aggregate = FALSE)[, , "pop_SSP2"] - popSSP2EU <- calcOutput("Population", - harmonization = "calibSSP2EU", - pastData = "Eurostat-WDI", - futureData = "SSP2EU", - extension2150 = "none", - aggregate = FALSE)[, , "pop_SSP2EU"] - - y <- getYears(labSSP2) - getNames(popSSP2) <- getNames(popSSP2EU) <- getNames(labSSP2) <- "lab_SSP2EU" - labSSP2EU <- labSSP2 / popSSP2[, y, ] * popSSP2EU[, y, ] - labSSP2EU[is.na(labSSP2EU)] <- 0 - list(x = labSSP2EU, weight = NULL, unit = "million", description = "Labor from SSP2EU") -} diff --git a/R/calcLabourHarmonized.R b/R/calcLabourHarmonized.R deleted file mode 100644 index 675050f..0000000 --- a/R/calcLabourHarmonized.R +++ /dev/null @@ -1,20 +0,0 @@ -#' Get Harmonized Labour Data -#' -#' @inheritParams calcGDPpcHarmonized -#' @inherit madrat::calcOutput return -#' @keywords internal -calcLabourHarmonized <- function(harmonization, past, future, ...) { - # Combine "past" and "future" time series. - harmonizedData <- switch( - harmonization, - "pastAndLevel" = toolHarmonizePast(past$x, future$x, method = "level"), - stop(glue("Bad input for calcLabourHarmonized Argument harmonization = '{harmonization}' is invalid.")) - ) - # Get description of harmonization function. - description <- switch( - harmonization, - "pastAndLevel" = glue("use {past$description} until {max(getYears(past$x, as.integer = TRUE))} \\ - and then switch directly to {future$description}."), - ) - list(x = harmonizedData, weight = NULL, unit = "million", description = description) -} diff --git a/R/calcLabourPast.R b/R/calcLabourPast.R deleted file mode 100644 index e734c62..0000000 --- a/R/calcLabourPast.R +++ /dev/null @@ -1,40 +0,0 @@ -#' @rdname calcPopulationPast -#' @param LabourPast A string designating the source for the historical working-age population data. -#' Available sources are: -#' \itemize{ -#' \item "WDI": World development indicators from the World Bank -#' } -calcLabourPast <- function(LabourPast = "WDI") { # nolint - # Check user input - toolCheckUserInput("LabourPast", as.list(environment())) - # Call calcInternalPopulationFuture function the appropriate number of times (map) and combine (reduce) - # !! Keep formula syntax for madrat caching to work - purrr::pmap(list("LabourPast" = unlist(strsplit(LabourPast, "-"))), - ~calcOutput("InternalLabourPast", aggregate = FALSE, supplementary = TRUE, ...)) %>% - toolReduce(mbindOrFillWith = "fillWith") -} - -calcInternalLabourPast <- function(LabourPast) { # nolint - x <- switch( - LabourPast, - "WDI" = readSource("WDI", "SP.POP.1564.TO"), - "SSPs" = calcOutput("InternalLabourPastSSPs", aggregate = FALSE), - stop("Bad input for calcLabour. Invalid 'LabourPast' argument.") - ) - - # Apply finishing touches to combined time-series - x <- toolFinishingTouches(x) - - # Hopefully temporary: rename lab scenarios pop. Necessary for REMIND to work. - getNames(x) <- sub("lab_", "pop_", getNames(x)) - - list(x = x, weight = NULL, unit = "million", description = glue("{LabourPast} data.")) -} - -calcInternalLabourPastSSPs <- function() { - x <- readSource("SSP", "lab")[, , "Historical Reference"] - # Remove years which only contain 0 - x <- x[, !apply(x, 2, function(y) all(y == 0)), ] - getNames(x) <- paste0("lab_", getNames(x)) - list(x = x, weight = NULL, unit = "million", description = "Labor from SSPs") -} diff --git a/R/calcPopulation.R b/R/calcPopulation.R index 6b2ac51..45230ef 100644 --- a/R/calcPopulation.R +++ b/R/calcPopulation.R @@ -8,7 +8,6 @@ #' \itemize{ #' \item the SSPs, i.e. SSP1-5 #' \item the SDPs, i.e. SDP, SDP_EI, SDP_RC, and SDP_MC -#' \item SSP2EU #' } #' #' See the vignette: \code{vignette("scenarios")} for scenario options, definitions and references. @@ -23,8 +22,8 @@ #' # Return the default scenarios #' calcOutput("Population") #' -#' # Return the SSP2EU scenario -#' calcOutput("Population", scenario = "SSP2EU") +#' # Return only the SSP2 scenario +#' calcOutput("Population", scenario = "SSP2") #' #' # Return the ISIMIP SSP scenarios #' calcOutput("Population", scenario = "ISIMIP", extension2150 = "none", aggregate = FALSE) @@ -34,3 +33,44 @@ calcPopulation <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), ...) { toolCheckUserInput(driver = "Population", args = c(list(...), as.list(environment()))) calcOutput("Driver", driver = "Population", scenario = scenario, aggregate = FALSE, supplementary = TRUE, ...) } + +#' @rdname calcPopulation +#' @order 2 +#' @examples \dontrun{ +#' calcOutput("Labour") +#' } +calcLabour <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), ...) { + toolCheckUserInput(driver = "Labour", args = c(list(...), as.list(environment()))) + calcOutput("Driver", driver = "Labour", scenario = scenario, aggregate = FALSE, supplementary = TRUE, ...) +} + +#' @rdname calcPopulation +#' @order 3 +#' @param asShare If TRUE (default) urban population shares are returned. If FALSE, then urban population in millions is +#' returned. +#' @examples \dontrun{ +#' calcOutput("Urban") +#' } +#' +calcUrban <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), asShare = TRUE, ...) { + toolCheckUserInput(driver = "Urban", args = c(list(...), as.list(environment()))) + + urb <- calcOutput("Driver", + driver = "Urban", + scenario = scenario, + popAsWeight = TRUE, + aggregate = FALSE, + supplementary = TRUE, + ...) + + # Cap urban share at 99%. + urb$x[urb$x > 0.99] <- 0.99 + + if (!asShare) { + urb$x <- urb$x * urb$weight + urb$weight <- NULL + urb$unit <- "million" + } + + list(x = urb$x, weight = urb$weight, unit = urb$unit, description = urb$description) +} diff --git a/R/calcPopulationFuture.R b/R/calcPopulationFuture.R index 10c7e02..4c278e1 100644 --- a/R/calcPopulationFuture.R +++ b/R/calcPopulationFuture.R @@ -1,97 +1,105 @@ -#' @rdname calcPopulationPast -#' @param PopulationFuture A string designating the source for the future population data. -#' Available sources are: -#' \itemize{ -#' \item "SSPs": From the Wittgenstein Center [here](http://pure.iiasa.ac.at/id/eprint/17550/) and -#' [here](http://pure.iiasa.ac.at/id/eprint/16710/) -#' \item "SSP2EU": Combined SSP2 and Eurostat (for the EU countries) source -#' \item "SDPs": -#' \item "UN_PopDiv": United Nations -#' \item "MI": Missing island dataset -#' } -calcPopulationFuture <- function(PopulationFuture = "SSPs-UN_PopDiv-MI") { # nolint +#' @rdname calcGDPPast +calcPopulationFuture <- function(futureData = "SSPs-UN_PopDiv") { # Check user input toolCheckUserInput("PopulationFuture", as.list(environment())) # Call calcInternalPopulationFuture function the appropriate number of times (map) and combine (reduce) # !! Keep formula syntax for madrat caching to work - purrr::pmap(list("PopulationFuture" = unlist(strsplit(PopulationFuture, "-"))), + purrr::pmap(list("futureData" = unlist(strsplit(futureData, "-"))), ~calcOutput("InternalPopulationFuture", aggregate = FALSE, supplementary = TRUE, ...)) %>% - toolReduce(mbindOrFillWith = "fillWith") + toolListFillWith() } -###################################################################################### -# Internal Function -###################################################################################### -calcInternalPopulationFuture <- function(PopulationFuture) { # nolint +calcInternalPopulationFuture <- function(futureData) { data <- switch( - PopulationFuture, - "SSPs" = calcOutput("InternalPopulationFutureSSPs", aggregate = FALSE, supplementary = TRUE), - "SSP2" = calcOutput("InternalPopulationFutureSSP2", aggregate = FALSE, supplementary = TRUE), - "SSP2EU" = calcOutput("InternalPopulationFutureSSP2EU", aggregate = FALSE, supplementary = TRUE), - "SDPs" = calcOutput("InternalPopulationFutureSDPs", aggregate = FALSE, supplementary = TRUE), - "UN_PopDiv" = calcOutput("InternalPopulationFutureUN_PopDiv", aggregate = FALSE, supplementary = TRUE), - "MI" = calcOutput("InternalPopMI", aggregate = FALSE, supplementary = TRUE), - stop("Bad input for PopulationFuture. Invalid 'PopulationFuture' argument.") + futureData, + "SSPs" = readSource("SSP", "pop"), + "SSP2" = readSource("SSP", "pop", "SSP2"), + "SSP2EU" = setNames(readSource("SSP", "pop", "SSP2"), "SSP2EU"), + "SDPs" = toolPopulationFutureSDPs(), + "UN_PopDiv" = readSource("UN_PopDiv", "pop", "medium"), + "ADBs" = readSource("ADB", "pop"), + stop("Bad input for calcPopulationFuture. Invalid 'futureData' argument.") ) - data$x <- toolFinishingTouches(data$x) - data + list(x = data, weight = NULL, unit = "million", description = glue("{futureData} projections")) } +toolPopulationFutureSDPs <- function(sdps = c("SDP", "SDP_EI", "SDP_MC", "SDP_RC")) { + popSSP1 <- readSource("SSP", "pop", "SSP1") # nolint: object_usage_linter. + purrr::map(sdps, ~setNames(popSSP1, .x)) %>% mbind() +} -###################################################################################### -# Functions -###################################################################################### -calcInternalPopulationFutureSSPs <- function() { # nolint - data <- readSource("SSP", "pop") - getNames(data) <- paste0("pop_", getNames(data)) - list(x = data, weight = NULL, unit = "million", description = "SSP projections") +#' @rdname calcGDPPast +calcLabourFuture <- function(futureData = "SSPs") { + # Check user input + toolCheckUserInput("LabourFuture", as.list(environment())) + # Call calcInternalPopulationFuture function the appropriate number of times (map) and combine (reduce) + # !! Keep formula syntax for madrat caching to work + purrr::pmap(list("futureData" = unlist(strsplit(futureData, "-"))), + ~calcOutput("InternalLabourFuture", aggregate = FALSE, supplementary = TRUE, ...)) %>% + toolListFillWith() } -calcInternalPopulationFutureSSP2 <- function() { # nolint - data <- calcOutput("InternalPopulationFutureSSPs", aggregate = FALSE)[, , "pop_SSP2"] - list(x = data, weight = NULL, unit = "million", description = "SSP2 projections") -} +calcInternalLabourFuture <- function(futureData) { + data <- switch( + futureData, + "SSPs" = readSource("SSP", "lab"), + "SSP2" = readSource("SSP", "lab", "SSP2"), + "SSP2EU" = setNames(readSource("SSP", "lab", "SSP2"), "SSP2EU"), + "SDPs" = toolLabourFutureSDPs(), + "UN_PopDiv" = readSource("UN_PopDiv", "lab", "medium"), + stop("Bad input for calcLabour. Invalid 'futureData' argument.") + ) -calcInternalPopulationFutureSDPs <- function() { # nolint - data_SSP1 <- calcOutput("InternalPopulationFutureSSPs", aggregate = FALSE)[, , "pop_SSP1"] # nolint + list(x = data, weight = NULL, unit = "million", description = glue("{futureData} projections")) +} - data <- purrr::map(c("SDP", "SDP_EI", "SDP_RC", "SDP_MC"), - ~ setNames(data_SSP1, gsub("SSP1", .x, getNames(data_SSP1)))) %>% - mbind() - list(x = data, weight = NULL, unit = "million", description = "SSP1 projections") +toolLabourFutureSDPs <- function(sdps = c("SDP", "SDP_EI", "SDP_MC", "SDP_RC")) { + labSSP1 <- readSource("SSP", "lab", "SSP1") # nolint: object_usage_linter. + purrr::map(sdps, ~setNames(labSSP1, .x)) %>% mbind() } -calcInternalPopulationFutureSSP2EU <- function() { # nolint - dataEurostat <- readSource("EurostatPopGDP", "population_projections") * 1e-6 - dataSSP2 <- calcOutput("InternalPopulationFutureSSPs", aggregate = FALSE)[, , "pop_SSP2"] - # Get EUR countries - GBR. (Great Britatin still in EUR mapping, but no Eurostat projections exist.) - euCountries <- toolGetEUcountries() - # Get common years - cy <- intersect(getYears(dataSSP2), getYears(dataEurostat)) +#' @rdname calcGDPPast +calcUrbanFuture <- function(futureData = "SSPs") { + data <- switch( + futureData, + "SSPs" = toolUrbanFutureSSPs(), + "SSP2" = toolUrbanFutureSSPs("SSP2"), + "SSP2EU" = setNames(toolUrbanFutureSSPs("SSP2"), "SSP2EU"), + "SDPs" = toolUrbanFutureSDPs(), + stop("Bad input for calcUrbanFuture. Invalid 'futureData' argument.") + ) + + # Use population as weight. Give weight same names as data, so that aggregate does not mess up data dim. + weight <- calcOutput("PopulationFuture", futureData = futureData, aggregate = FALSE) + getNames(weight) <- getNames(data) - # Start with the SSP2 scenario until 2100. Change the name, and overwrite the EUR - # countries with the Eurostat data. - data <- dataSSP2[, getYears(dataSSP2)[getYears(dataSSP2, as.integer = TRUE) <= 2100], ] %>% - setNames("pop_SSP2EU") - data[euCountries, , ] <- 0 - data[euCountries, cy, ] <- dataEurostat[euCountries, cy, ] - list(x = data, - weight = NULL, - unit = "million", - description = "SSP2 projections for non-EU countries, and EUROSTAT projections for EU countries") + list(x = data, weight = weight, unit = "share of population", description = glue("{futureData} projections")) } -calcInternalPopulationFutureUN_PopDiv <- function() { # nolint - data <- readSource("UN_PopDiv", "medium") * 1e-3 - getNames(data) <- "pop_medium_variant" - list(x = data, weight = NULL, unit = "million", description = "UN_PopDiv projections") +toolUrbanFutureSSPs <- function(ssps = c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5")) { + data <- readSource("SSP", "urb", ssps) + # Drop 2010 and 2015 values, and add missing years. + data <- data[, c(2010, 2015), , invert = TRUE] + time_interpolate(data, seq(2025, 2095, by = 10), integrate_interpolated_years = TRUE) } -calcInternalPopMI <- function() { - data <- readSource("MissingIslands", "pop") - list(x = data, weight = NULL, unit = "million", description = "MI projections") +# The SDP urban population share scenarios are mapped from the SSP scenarios. +# The SDP, SDP_EI and SDP_MC have high urban pop share from SSP1. The SDP_RC scenario has low urban pop share from +# SSP3 for OECD countries, and medium urban pop share from SSP2 for non-OECD countries. +# The alternative scenario combinations SDP_LS and SDP_GS are not coded explicitly here. +# They will re-use urban population share settings: SDP_LS = SDP_MC (Green cities), SDP_GS = SDP_EI (Tech cities). +toolUrbanFutureSDPs <- function() { + urbSSPs <- toolUrbanFutureSSPs() + # SSP1 for the first 3 SDP scenarios + urbSDPs <- purrr::map(c("SDP", "SDP_EI", "SDP_MC"), ~setNames(urbSSPs[, , "SSP1"], .x)) %>% mbind() + # SSP2 and SSP3 for SDP_RC + urbSDPrc <- setNames(urbSSPs[, , "SSP2"], "SDP_RC") + oecdMapping <- toolGetMapping("regionmappingOECD.csv", type = "regional", where = "mappingfolder") + oecdCountries <- oecdMapping[oecdMapping$RegionCode == "OECD", "CountryCode"] + urbSDPrc[oecdCountries, , ] <- urbSSPs[oecdCountries, , "SSP3"] + mbind(urbSDPs, urbSDPrc) } diff --git a/R/calcPopulationHarmonized.R b/R/calcPopulationHarmonized.R deleted file mode 100644 index 94f74ab..0000000 --- a/R/calcPopulationHarmonized.R +++ /dev/null @@ -1,58 +0,0 @@ -#' Get Harmonized Population Data -#' -#' @inheritParams calcGDPpcHarmonized -#' @inherit madrat::calcOutput return -#' @keywords internal -calcPopulationHarmonized <- function(harmonization, past, future, yEnd, ...) { - # Combine "past" and "future" time series. - harmonizedData <- switch(harmonization, - "withPEAPandFuture" = toolHarmonizeWithPEAPandFuture(past, future), - "calibSSP2EU" = toolHarmonizeSSP2EU(past, future), - "calibISIMIP" = toolHarmonizeISIMIP(past, future, yEnd = if(rlang::is_missing(yEnd)) 2030 else yEnd), - stop(glue("Bad input for calcPopulationHarmonized. Argument harmonization = '{harmonization}' is invalid.")) - ) - list(x = harmonizedData$x, weight = NULL, unit = "million", description = harmonizedData$description) -} - - -toolHarmonizeWithPEAPandFuture <- function(past, future) { - # Get PEAP data and fill in missing islands. Then drop everything that is not - # "short-term", defined as being later than the last year of the IMF WEO data. - shortTerm <- readSource("PEAP") - fill <- readSource("MissingIslands", subtype = "pop", convert = FALSE) - shortTerm <- shortTerm %>% toolFillWith(fill) %>% toolInterpolateAndExtrapolate() - lastYearIMF <- max(getYears(readSource("IMF", "GDPpc"), as.integer = TRUE)) - shortTerm <- shortTerm[, getYears(shortTerm, as.integer = TRUE) <= lastYearIMF, ] - - # Use PEAP growth rates until last year of IMF WEO data, and future growth rates after that - x <- past$x %>% toolHarmonizePast(shortTerm, method = "growth") %>% toolHarmonizePast(future$x, method = "growth") - - lastPastYear <- max(getYears(past$x, as.integer = TRUE)) - list(x = x, - description = glue("use {past$description} until {lastPastYear}, \\ - growth rates from the Wolrld Bank's PEAP until {lastYearIMF}, \\ - and growth rates from {future$description} thereafter.")) -} - -toolHarmonizeSSP2EU <- function(past, future) { - harmonizedData <- toolHarmonizeWithPEAPandFuture(past, future) - - # For EUR countries use only growth rates of EUROSTAT projections (load in fresh: future only has 5 year steps) - euCountries <- toolGetEUcountries() - dataEurostat <- readSource("EurostatPopGDP", "population_projections") * 1e-6 - x <- toolHarmonizePast(past$x[euCountries, , ], dataEurostat[euCountries, , ], method = "growth") - harmonizedData$x[euCountries, , ] <- x[euCountries, getYears(harmonizedData$x), ] - - list(x = harmonizedData$x, - description = glue("equal to SSP2 in all countries except for EU countries. \\ - For EU countries use {past$description} until 2021, \\ - and growth rates from projections ({future$description}) thereafter.")) -} - -toolHarmonizeISIMIP <- function(past, future, yEnd) { - x <- toolHarmonizePast(past$x, future$x, method = "transition", yEnd = yEnd) - - list(x = x, - description = glue("use {past$description} until {max(getYears(past$x, as.integer = TRUE))}, \\ - and converge towards {future$description} by {yEnd}.")) -} diff --git a/R/calcPopulationPast.R b/R/calcPopulationPast.R index 2b26955..69dfbcb 100644 --- a/R/calcPopulationPast.R +++ b/R/calcPopulationPast.R @@ -1,89 +1,76 @@ -#' Get Population and Labour scenario building blocks -#' -#' See the "Combining data sources with '-'" section below for how to combine data sources. -#' -#' @param PopulationPast A string designating the source for the historical population data. -#' Available sources are: -#' \itemize{ -#' \item "WDI": World development indicators from the World Bank -#' \item "UN_PopDiv": United Nations -#' \item "MI": Missing island dataset -#' \item "Eurostat": Eurostat -#' } -#' @inheritSection calcScenarioConstructor Combining data sources with "-" -#' @keywords internal -calcPopulationPast <- function(PopulationPast = "WDI-UN_PopDiv-MI") { # nolint +#' @rdname calcGDPPast +calcPopulationPast <- function(pastData = "WDI-UN_PopDiv-MI") { # Check user input toolCheckUserInput("PopulationPast", as.list(environment())) # Call calcInternalPopulationPast function the appropriate number of times (map) and combine (reduce) # !! Keep formula syntax for madrat caching to work - purrr::pmap(list("PopulationPast" = unlist(strsplit(PopulationPast, "-"))), + purrr::pmap(list("pastData" = unlist(strsplit(pastData, "-"))), ~calcOutput("InternalPopulationPast", aggregate = FALSE, supplementary = TRUE, ...)) %>% - toolReduce(mbindOrFillWith = "fillWith") + toolListFillWith() } - -###################################################################################### -# Internal Function -###################################################################################### -calcInternalPopulationPast <- function(PopulationPast) { # nolint +calcInternalPopulationPast <- function(pastData) { data <- switch( - PopulationPast, - "WDI" = readSource("WDI", "SP.POP.TOTL"), - "UN_PopDiv" = readSource("UN_PopDiv") * 1e-3, + pastData, + "WDI" = readSource("WDI", "pop"), + "UN_PopDiv" = readSource("UN_PopDiv", "pop", "estimates"), "MI" = readSource("MissingIslands", "pop"), - "Eurostat" = calcOutput("InternalPopulationPastEurostat", aggregate = FALSE), - stop("Bad input for PopulationPast. Invalid 'PopulationPast' argument.") + stop("Bad input for calcPopulationPast. Invalid 'pastData' argument.") ) - getNames(data) <- "population" - data <- toolFinishingTouches(data) + getNames(data) <- pastData + + list(x = data, weight = NULL, unit = "million", description = glue("{pastData} data")) +} + + - list(x = data, weight = NULL, unit = "million", description = glue("{PopulationPast} data")) +#' @rdname calcGDPPast +calcLabourPast <- function(pastData = "WDI-UN_PopDiv") { + # Check user input + toolCheckUserInput("LabourPast", as.list(environment())) + # Call calcInternalPopulationFuture function the appropriate number of times (map) and combine (reduce) + # !! Keep formula syntax for madrat caching to work + purrr::pmap(list("pastData" = unlist(strsplit(pastData, "-"))), + ~calcOutput("InternalLabourPast", aggregate = FALSE, supplementary = TRUE, ...)) %>% + toolListFillWith() } +calcInternalLabourPast <- function(pastData) { + data <- switch( + pastData, + "WDI" = readSource("WDI", "lab"), + "UN_PopDiv" = readSource("UN_PopDiv", "lab", "estimates"), + "SSPs" = readSource("SSP", "lab", "Historical Reference"), + stop("Bad input for calcLabourPast. Invalid 'pastData' argument.") + ) + + getNames(data) <- pastData -###################################################################################### -# Functions -###################################################################################### -calcInternalPopulationPastEurostat <- function() { # nolint - # Scale to milions - dataEurostat <- readSource("EurostatPopGDP", "population") * 1e-6 - # Set all eurostat countries with data, but that are not apart of the EUR region or GBR to 0 - euCountries <- toolGetEUcountries() - dataEurostat[!getItems(dataEurostat, 1) %in% euCountries, , ] <- 0 - # Fill in gaps in data (do not extrapolate) - dataEurostat <- toolInterpolateAndExtrapolate(dataEurostat, extrapolate = FALSE) - # Extrapolate missing data for eu countries using wdi growth rates - dataWDI <- readSource("WDI", "SP.POP.TOTL") - for (c in euCountries) { - # Skip countries with no data, or with complete data - if (all(dataEurostat[c, , ] == 0) || all(dataEurostat[c, , ] != 0)) next - # Get WDI years with 0 in dataEurostat - yearsWith0 <- getYears(dataWDI)[dataEurostat[c, getYears(dataWDI), ] == 0] - if (purrr::is_empty(yearsWith0)) next - yearsWithout0 <- getYears(dataWDI)[dataEurostat[c, getYears(dataWDI), ] != 0] - # Extrapolate into the past, in the dataWDI years - if (min(yearsWith0) < min(yearsWithout0)) { - pastYears <- getYears(dataWDI)[getYears(dataWDI) <= max(yearsWithout0)] - pastYearsWithout0 <- pastYears[pastYears %in% yearsWithout0] - dataEurostat[c, pastYears, ] <- toolHarmonizeFutureGrPast( - past = dataWDI[c, , ], - future = dataEurostat[c, pastYearsWithout0, ] - ) - } - # Extrapolate into the future, in the dataWDI years - if (max(yearsWith0) > max(yearsWithout0)) { - futureYears <- getYears(dataWDI)[getYears(dataWDI) >= min(yearsWithout0)] - futureYearsWithou0 <- futureYears[futureYears %in% yearsWithout0] - dataEurostat[c, futureYears, ] <- toolHarmonizePast( - past = dataEurostat[c, futureYearsWithou0, ], - future = dataWDI[c, , ], - method = "growth" - ) - } + list(x = data, weight = NULL, unit = "million", description = glue("{pastData} data")) +} + + +#' @rdname calcGDPPast +calcUrbanPast <- function(pastData = "WDI") { + data <- switch( + pastData, + "WDI" = readSource("WDI", "urb") / 100, + stop("Bad input for calcUrbanPast. Invalid 'pastData' argument.") + ) + + # TWN is missing an urban share. Give it that of HKG. + if (all(data["TWN", , ] == 0)) { + data["TWN", , ] <- data["HKG", , ] } - # Extrapolate in years outside of WDI range - dataEurostat <- toolInterpolateAndExtrapolate(dataEurostat) - list(x = dataEurostat, weight = NULL, unit = "million", description = "Eurostat data") + + getNames(data) <- pastData + + weight <- calcOutput("PopulationPast", pastData = pastData, aggregate = FALSE) + getNames(weight) <- getNames(data) + + list(x = data, + weight = weight, + unit = "share of population", + description = glue("{pastData} data (with missing TWN values set to that of HKG)")) } diff --git a/R/calcRatioPPP2MER.R b/R/calcRatioPPP2MER.R index 073b6e7..be2e520 100644 --- a/R/calcRatioPPP2MER.R +++ b/R/calcRatioPPP2MER.R @@ -1,7 +1,8 @@ #' MER over PPP ratio #' #' Get a conversion factor to convert GDP in constant 2017 Int$PPP into constant 2017 US$MER. -#' Use the when argument to switch the year of the conversion factor. Source = WDI. +#' Use the "when" argument to switch the year of the conversion factor. Source = WDI. Countries with missing data are +#' filled in with 1. Regional aggregation is weighed by GDP from WDI-MI in the year set by "when". #' #' @param when An integer (defaults to 2017) specifying the year of the PPP2MER factor. #' @inherit madrat::calcOutput return @@ -16,12 +17,7 @@ calcRatioPPP2MER <- function(when = 2017) { # Replace 0s with 1s. This was done previously. Other solutions here should be taken into consideration. data[data == 0] <- 1 - weight <- calcOutput("GDPPast", aggregate = FALSE)[, when, ] - - # TMP: have to use old sets and names for now, to not break interfaces - getSets(data) <- c("Region", "year", "d3") - getNames(data) <- NULL - getYears(data) <- NULL + weight <- calcOutput("GDPPast", aggregate = FALSE, years = when) list(x = data, weight = weight, diff --git a/R/calcUrban.R b/R/calcUrban.R deleted file mode 100644 index 301f6c9..0000000 --- a/R/calcUrban.R +++ /dev/null @@ -1,26 +0,0 @@ -#' @rdname calcPopulation -#' @param asShare If TRUE (default) urban population shares are returned. If FALSE, then urban population in millions is -#' returned. -#' @examples \dontrun{ -#' calcOutput("Urban") -#' } -#' -calcUrban <- function(scenario = c("SSPs", "SDPs", "SSP2EU"), asShare = TRUE, ...) { - toolCheckUserInput(driver = "Urban", args = c(list(...), as.list(environment()))) - - urb <- calcOutput("Driver", - driver = "Urban", - scenario = scenario, - popAsWeight = TRUE, - aggregate = FALSE, - supplementary = TRUE, - ...) - - if (!asShare) { - urb$x <- urb$x * urb$weight - urb$weight <- NULL - urb$unit <- "million" - } - - list(x = urb$x, weight = urb$weight, unit = urb$unit, description = urb$description) -} diff --git a/R/calcUrbanFuture.R b/R/calcUrbanFuture.R deleted file mode 100644 index 458d9da..0000000 --- a/R/calcUrbanFuture.R +++ /dev/null @@ -1,86 +0,0 @@ -#' @rdname calcPopulationPast -#' @param UrbanFuture A string designating the source for the future urban population-share data. -#' Available sources are: -#' \itemize{ -#' \item "SSPs": -#' \item "SDPs": -#' \item "SSP2EU": -#' } -calcUrbanFuture <- function(UrbanFuture = "SSPs") { # nolint - - data <- switch( - UrbanFuture, - "SSPs" = calcOutput("InternalUrbanFutureSSPs", aggregate = FALSE), - "SSP2" = calcOutput("InternalUrbanFutureSSPs", aggregate = FALSE)[, , "urb_SSP2"], - "SDPs" = calcOutput("InternalUrbanFutureSDPs", aggregate = FALSE), - "SSP2EU" = calcOutput("InternalUrbanFutureSSP2EU", aggregate = FALSE), - stop("Bad input for UrbanFuture. Invalid 'UrbanFuture' argument.") - ) - - data <- toolFinishingTouches(data) - - wp <- calcOutput("PopulationFuture", PopulationFuture = UrbanFuture, aggregate = FALSE) - # Give weight same names as data, so that aggregate doesn't mess up data dim - getNames(wp) <- gsub("pop", "urb", getNames(wp)) - - data <- data[getItems(wp, 1), getYears(wp), ] - - list(x = data, - weight = wp, - unit = "share of population", - description = paste0("Urban population share from {UrbanFuture}")) -} - - -###################################################################################### -# Functions -###################################################################################### -# Calculates a time series of urban shares, using SSP projections. Currently has some inconsistencies -# with WDI in 2010 -calcInternalUrbanFutureSSPs <- function() { - data <- readSource("SSP", "urb") / 100 - getNames(data) <- paste0("urb_", getNames(data)) - # Add some missing years - data <- time_interpolate(data, seq(2025, 2095, by = 10), integrate_interpolated_years = TRUE) - list(x = data, weight = NULL, unit = "per 1", description = "Urban data from SSP") -} - -calcInternalUrbanFutureSDPs <- function() { - # note on SHAPE SDPs: - # SDP urban population share scenarios are mapped from SSP urban population share, - # (in one case with different SSP choice for OECD and non-OECD countries) - # The alternative scenario combinations are not coded explicitly here. - # They will re-use urban population share settings: - # SDP_LS = SDP_MC (Green cities), SDP_GS = SDP_EI (Tech cities) - - urbanMapping <- c("urb_SDP" = "urb_SSP1", - "urb_SDP_EI" = "urb_SSP1", # = high urban pop share from SSPs for all countries - "urb_SDP_RC" = "urb_SSP3|urb_SSP2", # low urban pop share from SSPs for OECD, med for non-OECD - "urb_SDP_MC" = "urb_SSP1") # = high urban pop share from SSPs for all countries - - sspUrb <- calcOutput("UrbanFuture", UrbanFuture = "SSPs", aggregate = FALSE) # nolint - - data <- purrr::imap(urbanMapping, mapSHAPEurban, sspUrb = sspUrb) %>% mbind() - list(x = data, weight = NULL, unit = "per 1", description = "Urban data from SDP") -} - -mapSHAPEurban <- function(ssp, sdp, sspUrb) { - if (grepl("|", ssp, fixed = TRUE)) { - # distinguish between OECD and non-OECD - ssp <- strsplit(ssp, split = "\\|")[[1]] - oecdMapping <- toolGetMapping("regionmappingOECD.csv", type = "regional", where = "mappingfolder") - oecd <- oecdMapping[oecdMapping$RegionCode == "OECD", "CountryCode"] - nonOECD <- oecdMapping[oecdMapping$RegionCode == "Non-OECD", "CountryCode"] - mbind(setNames(sspUrb[oecd, , ssp[1]], sdp), - setNames(sspUrb[nonOECD, , ssp[2]], sdp)) - } else { - # same for OECD and non-OECD - setNames(sspUrb[, , ssp], sdp) - } -} - -calcInternalUrbanFutureSSP2EU <- function() { - ssp2Urb <- calcOutput("UrbanFuture", UrbanFuture = "SSPs", aggregate = FALSE)[, , "urb_SSP2"] - ssp2Urb <- setNames(ssp2Urb, sub("SSP2", "SSP2EU", getNames(ssp2Urb))) - list(x = ssp2Urb, weight = NULL, unit = "per 1", description = "Urban data from SSP2EU") -} diff --git a/R/calcUrbanHarmonized.R b/R/calcUrbanHarmonized.R deleted file mode 100644 index 448b108..0000000 --- a/R/calcUrbanHarmonized.R +++ /dev/null @@ -1,27 +0,0 @@ -#' Get Harmonized Urban Data -#' -#' @inheritParams calcGDPpcHarmonized -#' @inherit madrat::calcOutput return -#' @keywords internal -calcUrbanHarmonized <- function(harmonization, past, future, ...) { - # Combine "past" and "future" time series. - harmonizedData <- switch( - harmonization, - "pastAndLevel" = toolHarmonizePast(past$x, future$x, method = "level"), - "pastAndGrowth" = toolHarmonizePast(past$x, future$x, method = "growth"), - "pastAndTransition" = toolHarmonizePast(past$x, future$x, method = "transition", yEnd = 2100), - stop(glue("Bad input for calcUrbanHarmonized. Argument harmonization = '{harmonization}' is invalid.")) - ) - # Get description of harmonization function. - description <- switch( - harmonization, - "pastAndLevel" = glue("use {past$description} until {max(getYears(past$x, as.integer = TRUE))} \\ - and then switch directly to {future$description}."), - "" - ) - - # Cap urban share at 99%. - harmonizedData[harmonizedData > 0.99] <- 0.99 - - list(x = harmonizedData, weight = NULL, unit = "share of population", description = description) -} diff --git a/R/calcUrbanPast.R b/R/calcUrbanPast.R deleted file mode 100644 index 9f30e5d..0000000 --- a/R/calcUrbanPast.R +++ /dev/null @@ -1,24 +0,0 @@ -#' @rdname calcPopulationPast -#' @param UrbanPast A string designating the source for the historical urban population-share data. -#' Available sources are: -#' \itemize{ -#' \item "WDI": World development indicators from the World Bank -#' } -calcUrbanPast <- function(UrbanPast = "WDI") { # nolint - - data <- switch( - UrbanPast, - "WDI" = readSource("WDI", "SP.URB.TOTL.IN.ZS") / 100, - stop("Bad input for UrbanPast. Invalid 'UrbanPast' argument.") - ) - - getNames(data) <- "urbanPop" - data <- toolFinishingTouches(data) - - wp <- calcOutput("PopulationPast", PopulationPast = UrbanPast, aggregate = FALSE) - - list(x = data, - weight = wp, - unit = "share of population", - description = glue("Urban population share data from {UrbanPast}")) -} diff --git a/R/mrdrivers-package.R b/R/mrdrivers-package.R index 311e994..c57c3c5 100644 --- a/R/mrdrivers-package.R +++ b/R/mrdrivers-package.R @@ -1,7 +1,6 @@ #' MadRat drivers Input Data Library #' #' @description -#' `r lifecycle::badge('stable')` #' #' Create scenarios of GDP, Population, GDP per capita, and Urban population share #' @@ -14,7 +13,3 @@ #' @exportPattern "^((calc(GDP|GDPpc|Population|Labour|Urban)(Past|Future|$))|read|download)" #' @keywords internal "_PACKAGE" - -# Suppress R CMD check note -#' @importFrom lifecycle deprecate_soft -NULL diff --git a/R/readADB.R b/R/readADB.R new file mode 100644 index 0000000..afdbef9 --- /dev/null +++ b/R/readADB.R @@ -0,0 +1,73 @@ +#' Read ADB data +#' +#' Read-in an ADB data as magclass object +#' +#' @inherit madrat::readSource return +#' @seealso [madrat::readSource()] +#' @examples \dontrun{ +#' readSource("ADB", subtype = "gdppc") +#' } +#' @order 1 +readADB <- function() { + baselineCase <- readxl::read_xlsx("GDP growth projections.xlsx", + sheet = "Summary Sheet", + range = "G3:J20", + col_types = rep.int("numeric", 4), + progress = FALSE) %>% + dplyr::select(3:4) %>% + dplyr::mutate("scenario" = "ADBbaseline", "year" = seq(2020, 2100, 5), "iso3c" = "IND") %>% + tidyr::pivot_longer(1:2, names_to = "variable") + + optimisticCase <- readxl::read_xlsx("GDP growth projections.xlsx", + sheet = "Summary Sheet", + range = "K3:N20", + col_types = rep.int("numeric", 4), + progress = FALSE) %>% + dplyr::select(3:4) %>% + dplyr::mutate("scenario" = "ADBoptimistic", "year" = seq(2020, 2100, 5), "iso3c" = "IND") %>% + tidyr::pivot_longer(1:2, names_to = "variable") + + dplyr::bind_rows(baselineCase, optimisticCase) %>% + as.magpie(spatial = "iso3c", temporal = "year", tidy = TRUE, filter = FALSE) +} + +#' @rdname readADB +#' @order 2 +#' @param x MAgPIE object returned from readADB +#' @param subtype A string, either "all", "gdppc", "pop" +convertADB <- function(x, subtype = "all") { + # Filter for subtype in the convert Function to use common read cache + if (subtype == "gdppc") { + x <- mselect(x, + scenario = c("ADBoptimistic", "ADBbaseline"), + variable = "Per Capita GDP Level (in thousands 2017PPP$)") + # Convert from thousands to $ + x <- x * 1e3 + } + if (subtype == "pop") { + x <- mselect(x, + scenario = c("ADBoptimistic", "ADBbaseline"), + variable = "Population (in million)") + } + + # Reduce dimension by summation when possible + if (subtype != "all") x <- dimSums(x, dim = c("variable")) + + toolGeneralConvert(x, useDefaultSetNames = subtype != "all", note = FALSE) +} + +#' @rdname readADB +#' @order 3 +downloadADB <- function() { + stop("Manual download of ADB data required!") + # Compose meta data + list(url = "", + doi = "-", + title = "ADB projections", + description = "ADB projections", + unit = "-", + author = "ADB", + release_date = "2024", + license = "-", + comment = "Manual download required! Accessed on the 11.09.2024.") +} diff --git a/R/readEurostatPopGDP.R b/R/readEurostatPopGDP.R deleted file mode 100644 index ab95fc6..0000000 --- a/R/readEurostatPopGDP.R +++ /dev/null @@ -1,159 +0,0 @@ -#' Read Eurostat Population and GDP data -#' -#' Download, read and convert Eurostat population and GDP data. -#' -#' @param subtype A string. Available subtypes are: -#' \itemize{ -#' \item "population": Population, ref demo_gind -#' \item "population_projections": Population projections, ref proj_19np -#' \item "GDP": GDP, ref nama_10_gdp -#' \item "GDPgr_projections_short": Projected GDP growth rates, 2023 forecast. -#' \item "GDPgr_projections_long": -#' } -#' @inherit madrat::readSource return -#' @seealso [madrat::readSource()] and [madrat::downloadSource()] -#' @examples \dontrun{ -#' readSource("EurostatPopGDP", subtype = "population") -#' } -#' @order 2 -readEurostatPopGDP <- function(subtype) { - x <- switch( - subtype, - "population" = readr::read_rds("population.rds"), - "population_projections" = readr::read_rds("population_projections.rds"), - "GDP" = readr::read_rds("GDP.rds"), - "GDPgr_projections_short" = readr::read_csv("Economic-Forecast---Winter-2024.csv", col_types = "cddd") %>% - tidyr::pivot_longer(2:4, names_to = "time") %>% - dplyr::rename("geo" = "Category"), - "GDPgr_projections_long" = purrr::map(readxl::excel_sheets("Ageing_Report_2024-Country_fiches_1.xlsx"), - ~readxl::read_xlsx("Ageing_Report_2024-Country_fiches_1.xlsx", - sheet = .x, - range = "E22:BA23") %>% - dplyr::mutate("geo" = .x) %>% - tidyr::pivot_longer(tidyselect::starts_with("2"), names_to = "time")) %>% - purrr::list_rbind(), - stop("Bad input for readEurostatPopGDP. Invalid 'subtype' argument.") - ) - as.magpie(x, spatial = "geo", temporal = "time") -} - -#' @rdname readEurostatPopGDP -#' @order 3 -#' @param x MAgPIE object returned by readEurostatPopGDP -convertEurostatPopGDP <- function(x, subtype) { - switch( - subtype, - "population" = convEurostatPopulation(x), - "population_projections" = convEurostatPopulation(x), - "GDP" = convEurostatGDP(x), - "GDPgr_projections_short" = convEurostatGDPgrProjectionsShort(x), - "GDPgr_projections_long" = convEurostatGDPgrProjectionsLong(x) - ) -} - -convEurostatPopulation <- function(x) { - # Fix names of sets, and of variable - x <- collapseDim(x, dim = 3) - getNames(x) <- "population" - # Use the "DE_TOT" values for Germany, if they exist (DE_TOT = East + West Germany) - x["DE", , ] <- if ("DE_TOT" %in% getItems(x, 1)) x["DE_TOT", , ] else x["DE", , ] - # Drop any countries with more than 2 characters in their Eurostat identifier. Those are aggregates. - myCountries <- getItems(x, 1)[purrr::map_lgl(getItems(x, 1), ~ nchar(.x) == 2)] - x <- x[myCountries, , ] - # Convert the eurostat countrycodes to iso3c codes - getItems(x, 1) <- countrycode::countrycode(getItems(x, 1), "eurostat", "iso3c", warn = FALSE) - # ABOVE Warning: Some values were not matched unambiguously: FX, XK - - toolGeneralConvert(x, note = FALSE) -} - -convEurostatGDP <- function(x) { - # Drop EA, EA12, EA19, EA20, EU15, EU27_2020, EU28, XK - x <- x[getItems(x, 1)[!getItems(x, 1) %in% c("EA", "EA12", "EA19", "EA20", "EU15", "EU27_2020", "EU28", "XK")], , ] - # Convert the eurostat countrycodes to iso3c codes - getItems(x, 1) <- countrycode::countrycode(getItems(x, 1), "eurostat", "iso3c") - - x <- toolGeneralConvert(x, note = FALSE) - - # Convert from constant 2015 LCU to constant 2015 Int$PPP. - getNames(x) <- "GDP" - GDPuc::toolConvertGDP(x, "constant 2015 LCU", "constant 2015 Int$PPP", replace_NAs = c("linear", "no_conversion")) -} - -convEurostatGDPgrProjectionsShort <- function(x) { - # Drop EA and EU country aggregates - x <- x[getItems(x, 1)[!getItems(x, 1) %in% c("EA", "EU")], , ] - # Convert the eurostat countrycodes to iso3c codes - getItems(x, 1) <- countrycode::countrycode(getItems(x, 1), "country.name", "iso3c") - toolGeneralConvert(x, note = FALSE) -} - -convEurostatGDPgrProjectionsLong <- function(x) { - # Drop EA and EU country aggregates - x <- x[getItems(x, 1)[!getItems(x, 1) %in% c("EA", "EU27")], , ] - # Convert the eurostat countrycodes to iso3c codes - getItems(x, 1) <- countrycode::countrycode(getItems(x, 1), "eurostat", "iso3c") - toolGeneralConvert(x, note = FALSE) -} - -#' @rdname readEurostatPopGDP -#' @order 1 -downloadEurostatPopGDP <- function(subtype) { - rlang::check_installed("eurostat") - # By defining the cache_dir in eurostat::get_eurostat the data is saved to the madrat source directory - switch( - subtype, - # Filter for "AVG" = average population. - "population" = eurostat::get_eurostat("demo_gind", filters = list(indic_de = "AVG"), time_format = "num") %>% - readr::write_rds("population.rds"), - # Filter for baseline projection of total population. - "population_projections" = eurostat::get_eurostat("proj_19np", - filters = list(sex = "T", projection = "BSL", age = "TOTAL"), - time_format = "num") %>% - readr::write_rds("population_projections.rds"), - # Filter for GDP at market prices (=B1GQ) in Chained-Linked Volumes in 2015 mil. National Currencies (= CLV15_MNAC) - "GDP" = eurostat::get_eurostat("nama_10_gdp", - filters = list(freq = "A", na_item = "B1GQ", unit = "CLV15_MNAC"), - time_format = "num") %>% - readr::write_rds("GDP.rds"), - "GDPgr_projections_short" = stop("Download EUROSTAT GDP growth rate projections manually."), - "GDPgr_projections_long" = stop("Download EUROSTAT GDP growth rate projections manually.") - ) - - switch( - subtype, - "population" = list( - url = "", - doi = "", - title = "Eurostat Population Data", - description = "", - unit = "", - author = "Eurostat", - release_date = "Updated frequently", - license = "", - comment = "see https://ec.europa.eu/eurostat" - ), - "population_projections" = list( - url = "", - doi = "", - title = "Eurostat Population Projections", - description = "", - unit = "", - author = "Eurostat", - release_date = "Updated frequently", - license = "", - comment = "see https://ec.europa.eu/eurostat" - ), - "GDP" = list( - url = "", - doi = "", - title = "Eurostat GDP Data", - description = "", - unit = "2005 mil. National Currencies", - author = "Eurostat", - release_date = "Updated frequently", - license = "", - comment = "see https://ec.europa.eu/eurostat" - ), - ) -} diff --git a/R/readIMF.R b/R/readIMF.R index 79039e5..d358b2e 100644 --- a/R/readIMF.R +++ b/R/readIMF.R @@ -14,12 +14,12 @@ readIMF <- function() { # Define what data, i.e.which "WEO subject codes", to keep: here GDPpc and current account balance myWEOCodes <- c("NGDPRPPPPC", "BCA") - my_locale <- readr::default_locale() - my_locale$encoding <- "UTF-16LE" + myLocale <- readr::default_locale() + myLocale$encoding <- "UTF-16LE" weoData <- readr::read_tsv("WEOApr2024all.ashx", col_types = c(.default = "c"), - locale = my_locale, + locale = myLocale, na = c("", "n/a", "--"), progress = FALSE) %>% dplyr::filter(.data$`WEO Subject Code` %in% myWEOCodes) %>% @@ -44,9 +44,13 @@ readIMF <- function() { #' @param subtype Use to filter the IMF data #' @order 3 convertIMF <- function(x, subtype = "all") { + if (!subtype %in% c("all", "GDPpc", "BCA")) { + stop("Bad input for readIMF. Invalid 'subtype' argument. Available subtypes are 'all', 'GDPpc', and 'BCA'.") + } + # Use convert function to filter if (subtype == "GDPpc") { - h <-"Gross domestic product per capita, constant prices [Units Purchasing power parity; 2017 international dollar]" + h <- "Gross domestic product per capita, constant prices [Units Purchasing power parity; 2017 international dollar]" x <- x[, , h] } if (subtype == "BCA") x <- x[, , "Current account balance [Billions U.S. dollars]"] diff --git a/R/readJames.R b/R/readJames.R index c35e6c0..d9c00e7 100644 --- a/R/readJames.R +++ b/R/readJames.R @@ -1,29 +1,56 @@ -#' Read James -#' -#' @description -#' `r lifecycle::badge('deprecated')` +#' Read James et al. (2012) dataset #' #' Read-in GDP per-capita data from the publication James, Spencer L., Paul #' Gubbins, Christopher JL Murray, and Emmanuela Gakidou. 2012. "Developing a #' Comprehensive Time Series of GDP per Capita for 210 Countries from 1950 to #' 2015." Population Health Metrics 10 (1): 12. doi:10.1186/1478-7954-10-12. -#' from a .csv file to a magclass object +#' +#' The data is in Annex 3 #' #' @param subtype String indicating the data series -#' @return GDP per capita in USD05 in PPP or MER as magpie object -#' @seealso [madrat::readSource()] +#' @inherit madrat::readSource return +#' @seealso [madrat::readSource()] and [madrat::downloadSource()] #' @examples \dontrun{ -#' readSource("James", subtype = "IHME_USD05_PPP_pc")} -#' @keywords internal +#' readSource("James", subtype = "gdp") +#' } +#' @order 2 readJames <- function(subtype) { + # Add alias for easy referencing + if (subtype == "gdp") subtype <- "WB_USD05_PPP_pc" + utils::read.csv("james.csv", sep = ";", dec = ",") %>% `[`(, c("ISO3", "Year", subtype)) %>% - as.magpie(spatial = 1, temporal = 2) + as.magpie(spatial = 1, temporal = 2, tidy = TRUE) } -#' @describeIn readJames convert function +#' @rdname readJames #' @param x MAgPIE object returned by readJames +#' @order 3 convertJames <- function(x, subtype) { - x <- x[c("ANT", "SUN"), , , invert = TRUE] - toolGeneralConvert(x[, , subtype], useDefaultSetNames = FALSE) + # Add alias for easy referencing + if (subtype == "gdp") subtype <- "WB_USD05_PPP_pc" + if (subtype == "WB_USD05_PPP_pc") { + x <- GDPuc::toolConvertGDP(x, + unit_in = "constant 2005 Int$PPP", + unit_out = toolGetUnitDollar(inPPP = TRUE), + replace_NAs = c("linear", "no_conversion")) + } + # Ignore warning: Data for following unknown country codes removed: ANT, SUN + toolGeneralConvert(x, warn = FALSE) +} + +#' @rdname readJames +#' @order 1 +downloadJames <- function() { + stop("Manual download of James data required!") + # Compose meta data + list(url = "https://static-content.springer.com/esm/art%3A10.1186%2F1478-7954-10-12/MediaObjects/12963_2011_195_MOESM1_ESM.xlsx", # nolint: line_length_linter. + doi = "-", + title = "James GDP per capita dataset", + description = "Developing a comprehensive time series of GDP per capita for 210 countries from 1950 to 2015", + unit = "-", + author = "James, S.L., Gubbins, P., Murray, C.J. et al.", + release_date = "2012", + license = "-", + comment = "Manual download required! Accessed on the 08.10.2024.") } diff --git a/R/readJames2019.R b/R/readJames2019.R deleted file mode 100644 index 199a2f4..0000000 --- a/R/readJames2019.R +++ /dev/null @@ -1,72 +0,0 @@ -#' Read James 2019 updated dataset -#' -#' Read-in GDP per-capita data from the publication James, Spencer L., Paul -#' Gubbins, Christopher JL Murray, and Emmanuela Gakidou. 2012. "Developing a -#' Comprehensive Time Series of GDP per Capita for 210 Countries from 1950 to -#' 2015." Population Health Metrics 10 (1): 12. doi:10.1186/1478-7954-10-12. -#' from a .csv file to a magclass object -#' -#' 2019 dataset from personal communication w/ B Bodirsky -#' -#' @param subtype String indicating the data series -#' @return GDP per capita in USD05 in PPP or MER as magpie object -#' -#' @seealso [madrat::readSource()] and [madrat::downloadSource()] -#' @examples \dontrun{ -#' readSource("James2019", subtype = "IHME_USD05_PPP_pc") -#' } -#' -readJames2019 <- function(subtype) { - readr::read_csv("james2019.csv", - col_types = c("ISO3" = "c", ".default" = "d"), - progress = FALSE) %>% - `[`(, c("ISO3", "Year", subtype)) %>% - as.magpie(spatial = 1, temporal = 2) -} - -#' @describeIn readJames2019 convert function -#' @param x MAgPIE object returned by readJames2019 -convertJames2019 <- function(x, subtype) { - x <- toolGeneralConvert(x, no_remove_warning = c("CHN_354", "CHN_361", "USSR_FRMR"), note = FALSE) - - # fill missing islands not in MissingIslands, using older James - old <- readSource("James", subtype = subtype) - missing <- time_interpolate(old[c("ABW", "PYF", "NCL"), , ], interpolated_year = c(1950:2019)) - x[c("ABW", "PYF", "NCL"), , ] <- missing - - # use old HKG and MAC shares, and subtract from CHN - # new james has much higher (double in earliest time steps) - # historical china values - pop <- readSource("WDI", subtype = "SP.POP.TOTL")[c("CHN", "HKG", "MAC"), , ] - # Drop WDI years not in James2019 - pop <- pop[, intersect(getYears(pop), getYears(x)), ] - - oldyears <- intersect(getYears(pop), getYears(old)) - old <- pop[, oldyears, ] * old[c("CHN", "HKG", "MAC"), oldyears, ] - old <- collapseNames(old) - shr <- old[c("HKG", "MAC"), , ] / dimSums(old[c("CHN", "HKG", "MAC"), , ], dim = 1) - - shr <- time_interpolate(shr, getYears(pop)) - x1 <- x[c("CHN", "HKG", "MAC"), getYears(pop), ] * pop[c("CHN", "HKG", "MAC"), getYears(pop), ] - x1[c("HKG", "MAC"), , ] <- shr * x1["CHN", , ] - x1["CHN", , ] <- x1["CHN", , ] - dimSums(x1[c("HKG", "MAC"), , ], dim = 1) - - # fill 1950-1959 HKG and MAC with 1960 values, don't subtract from CHINA - # for these years because no population data to convert to totals, but very small differnece anyways - x[c("CHN", "HKG", "MAC"), getYears(x1), ] <- x1 / pop[c("CHN", "HKG", "MAC"), , ] - x[c("HKG", "MAC"), 1950:1959, ] <- setYears(x[c("HKG", "MAC"), 1960, ], NULL) - - # South Sudan values are very large, likely inaccurate. In their stead, - # the Missing island gdp values and WDI pop numbers are used. - ssdGDP <- readSource("MissingIslands", "gdp")["SSD", , ] - ssdPop <- readSource("WDI", subtype = "SP.POP.TOTL")["SSD", , ] %>% dimReduce() - - ssdGDP <- time_interpolate(ssdGDP, c(1950:2019)) - ssdPop <- time_interpolate(ssdPop, c(1950:2019)) - - ssdGDPpc <- ssdGDP / ssdPop - - x["SSD", , ] <- ssdGDPpc - - x -} diff --git a/R/readMissingIslands.R b/R/readMissingIslands.R index 862d3cd..2905113 100644 --- a/R/readMissingIslands.R +++ b/R/readMissingIslands.R @@ -7,7 +7,7 @@ #' @inherit madrat::readSource return #' @seealso [madrat::readSource()] and [madrat::downloadSource()] #' @examples \dontrun{ -#' readSource("MissingIslands", subtype = "pop", convert = FALSE) +#' readSource("MissingIslands", subtype = "pop") #' } #' @order 2 readMissingIslands <- function(subtype) { @@ -19,11 +19,17 @@ readMissingIslands <- function(subtype) { } - #' @rdname readMissingIslands #' @param x MAgPIE object returned by readMissingIslands #' @order 3 -convertMissingIslands <- function(x) { +convertMissingIslands <- function(x, subtype) { + if (subtype == "gdp") { + x <- GDPuc::toolConvertGDP(x, + unit_in = "constant 2005 Int$PPP", + unit_out = toolGetUnitDollar(inPPP = TRUE), + replace_NAs = c("linear", "no_conversion")) + } + toolGeneralConvert(x, note = FALSE) } diff --git a/R/readPEAP.R b/R/readPEAP.R index 79ddc61..b4015a3 100644 --- a/R/readPEAP.R +++ b/R/readPEAP.R @@ -36,8 +36,8 @@ convertPEAP <- function(x) { #' @rdname readPEAP #' @order 1 downloadPEAP <- function() { - stop("Manual download of PEAP data required!") - # Compose meta data + stop("Manual download of PEAP data required!") + # Compose meta data list(url = "https://databank.worldbank.org/source/population-estimates-and-projections#", doi = "-", title = "Population Estimates and Projections", diff --git a/R/readSSP.R b/R/readSSP.R index 201742c..1eda592 100644 --- a/R/readSSP.R +++ b/R/readSSP.R @@ -1,6 +1,7 @@ #' Read SSP #' -#' Read-in an SSP data as magclass object +#' Read-in an SSP data as magclass object. Filter for subtype and subset in the convert Function to use common read +#' cache (speeds up the compuations). #' #' @inherit madrat::readSource return #' @seealso [madrat::readSource()] @@ -15,16 +16,16 @@ readSSP <- function() { col_types = myColTypes, progress = FALSE) %>% tidyr::unite("Model.Scenario.Variable.Unit", c("Model", "Scenario", "Variable", "Unit"), sep = ".") %>% - tidyr::pivot_longer(cols = where(is.numeric), names_to = "year") + tidyr::pivot_longer(cols = tidyselect::where(is.numeric), names_to = "year") # The above SSP release 3.0.1 does not have any data on urban population share. So we get that from an older release. myColTypes <- paste(c(rep.int("c", 5), rep.int("d", 41)), collapse = "") - x_urb <- readr::read_csv("SspDb_country_data_2013-06-12.csv.zip", col_types = myColTypes, progress = FALSE) %>% + xUrb <- readr::read_csv("SspDb_country_data_2013-06-12.csv.zip", col_types = myColTypes, progress = FALSE) %>% dplyr::filter(.data$MODEL == "NCAR", .data$VARIABLE == "Population|Urban|Share") %>% tidyr::unite("Model.Scenario.Variable.Unit", c("MODEL", "SCENARIO", "VARIABLE", "UNIT"), sep = ".") %>% # Drop columns (years) with only NAs dplyr::select(tidyselect::vars_select_helpers$where(~ !all(is.na(.x)))) %>% - tidyr::pivot_longer(cols = where(is.numeric), names_to = "year") %>% + tidyr::pivot_longer(cols = tidyselect::where(is.numeric), names_to = "year") %>% # Convert Region codes now (normally only done in convert) to harmonize with region codes in x. Use custom match # with the country.names in x to make sure that when the country.names are converted to iso3c in convert, # no duplicates appear. @@ -42,7 +43,7 @@ readSSP <- function() { "VNM" = "Viet Nam")), .keep = "unused") - dplyr::bind_rows(x, x_urb) %>% + dplyr::bind_rows(x, xUrb) %>% as.magpie(spatial = "Region", temporal = "year", tidy = TRUE, filter = FALSE) } @@ -50,38 +51,39 @@ readSSP <- function() { #' @order 2 #' @param x MAgPIE object returned from readSSP #' @param subtype A string, either "all", "gdp", "pop", "lab", "urb" -convertSSP <- function(x, subtype = "all") { - # Filter for subtype in the convert Function to use common read cache +#' @param subset A vector of strings designating the scenarios. Defaults to c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5"). +#' "Historical Reference" is also available as a scenario. +convertSSP <- function(x, subtype = "all", subset = c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5")) { + if (!subtype %in% c("all", "gdp", "pop", "lab", "urb")) { + stop(glue("Bad input for readSSP. Invalid 'subtype' argument. Available subtypes are 'all', 'gdp', 'pop', 'lab' \\ + and 'urb'.")) + } + if (subtype == "gdp") { x <- mselect(x, Model = "OECD ENV-Growth 2023", - Scenario = c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5"), + Scenario = subset, Variable = "GDP|PPP", Unit = "billion USD_2017/yr") + # Convert from billions to millions + x <- x * 1e3 } if (subtype == "pop") { - x <- mselect(x, - Model = "IIASA-WiC POP 2023", - Scenario = c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5"), - Variable = "Population", - Unit = "million") + x <- mselect(x, Model = "IIASA-WiC POP 2023", Scenario = subset, Variable = "Population", Unit = "million") } if (subtype == "lab") { # Choose only age groups between 15 and 64 agegrps <- getNames(x, dim = "Variable")[grepl("^Population(.*)(19|24|29|34|39|44|49|54|59|64)$", getNames(x, dim = "Variable"))] - x <- mselect(x, - Model = "IIASA-WiC POP 2023", - Variable = agegrps, - Unit = "million") + x <- mselect(x, Model = "IIASA-WiC POP 2023", Scenario = subset, Variable = agegrps, Unit = "million") } if (subtype == "urb") { - x <- mselect(x, - Model = "NCAR", - Variable = "Population|Urban|Share", - Unit = "%") - # Clean up Scenario names + x <- mselect(x, Model = "NCAR", Variable = "Population|Urban|Share", Unit = "%") + # Clean up Scenario names before filtering with subset getNames(x, dim = "Scenario") <- sub("_.*", "", getNames(x, dim = "Scenario")) + x <- mselect(x, Scenario = subset) + # Convert from percentage to share + x <- x / 100 } # Reduce dimension by summation when possible @@ -97,7 +99,7 @@ convertSSP <- function(x, subtype = "all") { } #' @rdname readSSP -#' @order 1 +#' @order 3 downloadSSP <- function() { stop("Manual download of SSP data required!") # Compose meta data diff --git a/R/readUN_PopDiv.R b/R/readUN_PopDiv.R index 8e5842f..69bd89b 100644 --- a/R/readUN_PopDiv.R +++ b/R/readUN_PopDiv.R @@ -1,27 +1,35 @@ #' Read UN Population Division Data #' -#' Read past UN population data. +#' Read UN population data. #' -#' @param subtype String indicating version and sheet +#' @param subtype Either "pop" or "lab". +#' @param subset Either "estimates" or "medium". #' @inherit madrat::readSource return #' @seealso [madrat::readSource()] and [madrat::downloadSource()] #' @order 2 -readUN_PopDiv <- function(subtype = "estimates") { # nolint +readUN_PopDiv <- function(subtype, subset = "estimates") { # nolint: object_name_linter. # Check function input - if (!subtype %in% c("estimates", "medium")) { + if (!subtype %in% c("pop", "lab")) { stop("Bad input for readUN_PopDiv. Invalid 'subtype' argument.") } + if (!subset %in% c("estimates", "medium")) { + stop("Bad input for readUN_PopDiv. Invalid 'subset' argument.") + } + file <- "WPP2022_POP_F01_1_POPULATION_SINGLE_AGE_BOTH_SEXES.xlsx" - sheet <- if (subtype == "estimates") "Estimates" else "Medium variant" + sheet <- if (subset == "estimates") "Estimates" else "Medium variant" + + ageRange <- if (subtype == "pop") c(0:99, "100+") else 15:64 + readxl::read_xlsx(file, sheet = sheet, skip = 16, col_types = "text", progress = FALSE) %>% - dplyr::select("ISO3 Alpha-code", "year" = "Year", dplyr::matches("^[0-9]*$")) %>% + dplyr::select("Variant", "ISO3 Alpha-code", "year" = "Year", dplyr::matches("^[0-9]")) %>% dplyr::filter(!is.na(.data$`ISO3 Alpha-code`)) %>% - tidyr::pivot_longer(cols = dplyr::matches("^[0-9]*$"), + tidyr::pivot_longer(cols = dplyr::matches("^[0-9]"), names_to = "age", values_transform = c("value" = as.numeric)) %>% - dplyr::group_by(.data$`ISO3 Alpha-code`, .data$year) %>% - dplyr::summarise(value = sum(.data$value), .groups = "drop") %>% - as.magpie(spatial = "ISO3 Alpha-code") + dplyr::filter(.data$age %in% ageRange) %>% + dplyr::summarise(value = sum(.data$value), .by = c("Variant", "ISO3 Alpha-code", "year")) %>% + as.magpie(spatial = "ISO3 Alpha-code", temporal = "year", tidy = TRUE) } @@ -29,14 +37,16 @@ readUN_PopDiv <- function(subtype = "estimates") { # nolint #' @rdname readUN_PopDiv #' @order 3 #' @param x MAgPIE object returned from readUN_PopDiv -convertUN_PopDiv <- function(x) { # nolint +convertUN_PopDiv <- function(x) { # nolint: object_name_linter. + # Convert from thousands to millions + x <- x * 1e-3 toolGeneralConvert(x, no_remove_warning = "XKX") } #' @rdname readUN_PopDiv #' @order 1 -downloadUN_PopDiv <- function() { # nolint - url <- "https://population.un.org/wpp/Download/Files/1_Indicators%20(Standard)/EXCEL_FILES/2_Population/WPP2022_POP_F01_1_POPULATION_SINGLE_AGE_BOTH_SEXES.xlsx" # nolint +downloadUN_PopDiv <- function() { # nolint: object_name_linter. + url <- "https://population.un.org/wpp/Download/Files/1_Indicators%20(Standard)/EXCEL_FILES/2_Population/WPP2022_POP_F01_1_POPULATION_SINGLE_AGE_BOTH_SEXES.xlsx" # nolint: line_length_linter. utils::download.file(url, basename(url), quiet = TRUE) # Compose meta data diff --git a/R/readWDI.R b/R/readWDI.R index 6e18621..bbc6fd3 100644 --- a/R/readWDI.R +++ b/R/readWDI.R @@ -5,13 +5,13 @@ #' @param subtype A string. Type of WDI data that should be read. Use the #' World Bank indicator abbreviation. Available subtypes are: #' \itemize{ -#' \item \code{"SP.POP.TOTL"}: Population, total -#' \item \code{"SP.POP.1564.TO"}: Working age population (15-64 years old) -#' \item \code{"SP.URB.TOTL.IN.ZS"}: Urban Population (% of total) -#' \item \code{"NY.GDP.MKTP.PP.KD"}: GDP,PPP (constant 2017 international Dollar) -#' \item \code{"NV.AGR.TOTL.KD"}: Ag GDP, MER, (2010 US$) -#' \item \code{"PA.NUS.PPPC.RF"}: Price level ratio of PPP conversion factor (GDP) to market exchange rate -#' \item \code{"AG.SRF.TOTL.K2"}: Surface area (in square kms) +#' \item "pop" or "SP.POP.TOTL": Population, total +#' \item "lab" or "SP.POP.1564.TO": Working age population (15-64 years old) +#' \item "urb" or "SP.URB.TOTL.IN.ZS": Urban Population (% of total) +#' \item "gdp" or "NY.GDP.MKTP.PP.KD": GDP, PPP (constant 2017 international Dollar) +#' \item "NV.AGR.TOTL.KD": Ag GDP, MER, (2010 US$) +#' \item "PA.NUS.PPPC.RF": Price level ratio of PPP conversion factor (GDP) to market exchange rate +#' \item "AG.SRF.TOTL.K2": Surface area (in square kms) #' } #' #' @details @@ -24,15 +24,26 @@ #' @seealso [madrat::readSource()] and [madrat::downloadSource()] #' #' @examples \dontrun{ -#' readSource("WDI", subtype = "SP.POP.TOTL") +#' readSource("WDI", subtype = "pop") #' } #' @order 2 readWDI <- function(subtype) { + # Add some aliases for easier referencing + subtype <- switch( + subtype, + "gdp" = "NY.GDP.MKTP.PP.KD", + "pop" = "SP.POP.TOTL", + "lab" = "SP.POP.1564.TO", + "urb" = "SP.URB.TOTL.IN.ZS", + subtype + ) + x <- readr::read_rds("WDI_15_04_2024.Rds") + possibleSubtypes <- colnames(x)[!colnames(x) %in% c("iso3c", "iso2c", "country", "year")] if (!subtype %in% possibleSubtypes) { - stop(glue("Bad subtype. Possible subtypes are: \n{paste0(possibleSubtypes, collapse = '\n')}.")) + stop(glue("Bad subtype. Possible subtypes are: \n{paste0(possibleSubtypes, collapse = '\n')}.")) } x[, c("iso2c", "year", subtype)] %>% @@ -46,6 +57,15 @@ readWDI <- function(subtype) { #' @param x MAgPIE object returned by readWDI #' @order 3 convertWDI <- function(x, subtype) { + # Add some aliases for easier referencing + subtype <- switch( + subtype, + "gdp" = "NY.GDP.MKTP.PP.KD", + "pop" = "SP.POP.TOTL", + "lab" = "SP.POP.1564.TO", + "urb" = "SP.URB.TOTL.IN.ZS", + subtype + ) if (subtype %in% c("SP.POP.TOTL", "SP.POP.1564.TO", "NY.GDP.MKTP.PP.KD", "NV.AGR.TOTL.KD")) { # Change scale of indicators @@ -62,11 +82,7 @@ convertWDI <- function(x, subtype) { custom_match = c("JG" = "JEY"), warn = FALSE) - x <- toolGeneralConvert(x) - - # Remove years which only contain 0s as entries - x <- x[, !apply(x, 2, function(y) all(y == 0)), ] - x + toolGeneralConvert(x) } @@ -76,14 +92,15 @@ downloadWDI <- function() { rlang::check_installed("WDI") # The WDI data is updated with the function "WDISearch(cache = WDIcache())" WDI::WDIsearch(cache = WDI::WDIcache()) - indicator <- c("SP.POP.TOTL", # Total population - "SP.POP.1564.TO", # Working age population (15-64 years old) - "SP.URB.TOTL.IN.ZS", # Urban Population (% of total) - "PA.NUS.PPPC.RF", # Price Level Ration (PPP/MER) - "NY.GDP.MKTP.PP.KD", # GDP [constant 2017 Int$PPP] - "NV.AGR.TOTL.KD", # For mrvalidation: AgFF value added [constant 2015 US$MER] - "AG.SRF.TOTL.K2" # For mredgebuildings: surface area [square kms] - ) + indicator <- c( + "SP.POP.TOTL", # Total population + "SP.POP.1564.TO", # Working age population (15-64 years old) + "SP.URB.TOTL.IN.ZS", # Urban Population (% of total) + "PA.NUS.PPPC.RF", # Price Level Ration (PPP/MER) + "NY.GDP.MKTP.PP.KD", # GDP [constant 2017 Int$PPP] + "NV.AGR.TOTL.KD", # For mrvalidation: AgFF value added [constant 2015 US$MER] + "AG.SRF.TOTL.K2" # For mredgebuildings: surface area [square kms] + ) endYear <- as.numeric(strsplit(as.character(Sys.Date()), "-")[[1]][1]) - 1 wdi <- WDI::WDI(indicator = indicator, start = 1960, end = endYear) readr::write_rds(wdi, "WDI.Rds") diff --git a/R/toolCheckUserInput.R b/R/toolCheckUserInput.R index 5d5fd48..ab435c4 100644 --- a/R/toolCheckUserInput.R +++ b/R/toolCheckUserInput.R @@ -1,51 +1,57 @@ -toolCheckUserInput <- function(driver, args) { - permitted_args <- c("pastData", "futureData", "harmonization", "scenario", "unit", "yearEnd", "extension2150", - "average2020", "naming", "popAsWeight", "asShare", "GDPPast", "GDPFuture", "GDPpcPast", "GDPpcFuture", - "PopulationPast", "PopulationFuture", "LabourPast", "LabourFuture", "UrbanPast", "UrbanFuture") - if (!all(names(args) %in% permitted_args)) { - stop(glue("Bad argument to calc{driver}: '{names(args)[! names(args) %in% permitted_args]}'.")) +#' Check user input +#' +#' toolCheckUserInput checks the user input. +#' +#' @param args A list with all the arguments passed to the parent function +#' @inheritParams calcDriver +#' @keywords internal +#' @return TRUE +toolCheckUserInput <- function(driver, args) { # nolint: cyclocomp_linter. + permittedArgs <- c("scenario", "unit", "extension2150", "extension1960", "average2020", "naming", "popAsWeight", + "asShare", "pastData", "futureData", "harmonization") + if (!all(names(args) %in% permittedArgs)) { + stop(glue("Bad argument to calc{driver}: '{names(args)[! names(args) %in% permittedArgs]}'.")) } - # Check existence of pastData, futureData and harmonization - if (!all(c("pastData", "futureData", "harmonization") %in% names(args)) && - any(c("pastData", "futureData", "harmonization") %in% names(args))) { - stop("If you intend to overide the scenario argument, you must set pastData, futureData and hamrmonization.") - } - overrideScen <- if (all(c("pastData", "futureData", "harmonization") %in% names(args))) TRUE else FALSE - # Check population scenario availability for any GDPpc scenario - if (!overrideScen && driver == "GDPpc" && - !all(args$scenario %in% toolGetScenarioDefinition("Population")$scenario)) { + if (driver == "GDPpc" && !all(args$scenario %in% toolGetScenarioDefinition("Population")$scenario)) { stop("GDPpc scenarios require equivalent population scenarios to use as weight.") } # Check 'extension2150' argument if ("extension2150" %in% names(args) && !args$extension2150 %in% c("none", "bezier", "constant")) { - stop(glue("Bad argument to calc{driver}. 'extension2150' has to be either 'none', 'bezier' or 'constant', \\ + stop(glue("Bad argument to calc{driver}. 'extension2150' has to be either 'none', 'bezier' or 'constant', \\ not '{args$extension2150}'.")) } + # Check 'extension1960' argument + if ("extension1960" %in% names(args) && !args$extension1960 %in% c("none", "MI-James", "MI", "James")) { + stop(glue("Bad argument to calc{driver}. 'extension1960' has to be either 'none', 'MI', 'James', or a \\ + combination of both, e.g. 'MI-James', not '{args$extension2150}'.")) + } + # Check 'naming' argument if ("naming" %in% names(args) && !args$naming %in% c("indicator_scenario", "indicator.scenario", "scenario")) { - stop(glue("Bad argument to calc{driver}. 'naming' has to be either 'indicator_scenario', 'indicator.scenario' \\ - or 'scenario', not '{args$naming}'.")) + stop(glue("Bad argument to calc{driver}. 'naming' has to be either 'indicator_scenario', 'indicator.scenario' \\ + or 'scenario', not '{args$naming}'.")) } - # Check 'unit' argument - if ("unit" %in% names(args) && (length(args$unit) != 1 || !grepl("^constant (2017|2005) ", args$unit))) { - stop(glue("Bad argument to calc{driver}. Currently, only constant 2017 dollars are accepted.")) + # Check 'unit' argument. Only constant dollars are allowed. + if ("unit" %in% names(args) && (length(args$unit) != 1 || !grepl("^constant ", args$unit))) { + stop(glue("Bad argument to calc{driver}. Only constant dollars are accepted.")) } # Check 'average2020' argument if ("average2020" %in% names(args) && (length(args$average2020) != 1 || !is.logical(args$average2020))) { - stop(glue("Bad argument to calc{driver}. 'average2020' has to be TRUE of FALSE.")) + stop(glue("Bad argument to calc{driver}. 'average2020' has to be TRUE of FALSE.")) } # Check parallel map-reduce compatibility if (any(purrr::map_lgl(args, ~ !is.null(.x) && - length(.x) != 1 && - length(.x) != max(purrr::map_dbl(args, length))))) { + length(.x) != 1 && + length(.x) != max(purrr::map_dbl(args, length))))) { stop(glue("Arguments to calc{driver} need to be either length 1 or equal to the length of the longest argument.")) } + invisible(TRUE) } diff --git a/R/toolCompareProxyMagpie.R b/R/toolCompareProxyMagpie.R index 8d5e1b8..dcc59a2 100644 --- a/R/toolCompareProxyMagpie.R +++ b/R/toolCompareProxyMagpie.R @@ -1,6 +1,15 @@ -compare_proxy.magpie <- function(x, path = "x") { # nolint +#' Magpie proxy for waldo::compare +#' +#' Magpie proxy for waldo::compare +#' +#' @param x x +#' @param path "x" +#' @keywords internal +#' @return list +compare_proxy.magpie <- function(x, path = "x") { # nolint: object_name_linter. if (any(grepl("^ (origin:|creation date:)", comment(x)))) { comment(x) <- comment(x)[!grepl("^ (origin:|creation date:)", comment(x))] } + list(object = as.vector(x), path = paste0("as.vector(", path, ")")) } diff --git a/R/toolExtend2150.R b/R/toolExtend2150.R index aee9e5e..a7e5929 100644 --- a/R/toolExtend2150.R +++ b/R/toolExtend2150.R @@ -1,24 +1,32 @@ -# Extend until 2150 in 5 year time steps. Either with bezierExtension or constant. +#' Extend until 2150 in 5 year time steps +#' +#' toolExtend2150 extends a magpit object until 2150 in 5 year time steps. Either with bezierExtension or constant. +#' +#' @param data A list with "x", a magpie object, and "description" elements +#' @inheritParams calcDriver +#' @keywords internal +#' @return The modified data list. toolExtend2150 <- function(data, extension2150) { - if (extension2150 != "none") { - # The bezier extension is only possible if there is data until 2100, and only affects years between 2100 and 2150. - # It extends the time series in such a way as for the slope in 2105 to be half of that in 2100. - if (extension2150 == "bezier" && "y2100" %in% getYears(data)) { - data <- toolBezierExtension(data, seq(2105, 2150, 5)) - } else { - helper <- getSets(data) - data <- time_interpolate(data, - seq(2005, 2150, 5), - extrapolation_type = "constant", - integrate_interpolated_years = TRUE) - # Time_interpolate destroys the setNames for some reason... - getSets(data) <- helper - } + # The bezier extension is only possible if there is data until 2100, and only affects years between 2100 and 2150. + # It extends the time series in such a way as for the slope in 2105 to be half of that in 2100. + if (extension2150 == "bezier" && "y2100" %in% getYears(data$x)) { + data$x <- toolBezierExtension(data$x, seq(2105, 2150, 5)) + data$description <- glue("{data$description} Extended from 2100 to 2150 using bezier curves, resulting in a \\ + smooth flattening of the scenario (the slope in 2150 is equal to half of that in \\ + 2100).") + } else { + helper <- getSets(data$x) + data <- time_interpolate(data$x, + seq(2005, 2150, 5), + extrapolation_type = "constant", + integrate_interpolated_years = TRUE) + # Time_interpolate destroys the setNames for some reason... + getSets(data$x) <- helper + data$description <- glue("{data$description} Extended from 2100 to 2150 using the constant 2100 value.") } data } - toolBezierExtension <- function(data, timeExtend) { # Define bezier coordinates bc <- new.magpie(getItems(data, 1), c(2100, 2110, 2140, 2150), getNames(data), fill = 0) @@ -35,8 +43,17 @@ toolBezierExtension <- function(data, timeExtend) { nd <- ndata(data) # If Bezier extension would lead to negative GDP, set bezier coordinates equal to start point - # (comes down to a constant extension instead) - for (i in 1:nr) for (j in 1:nd) if (bc[i, 2100, j] == 0 || bc[i, 2150, j] < 0) bc[i, , j] <- bc[i, 2100, j] + # (comes down to a constant extension instead). + # Magpie implementation would look like this: + # for (i in 1:nr) for (j in 1:nd) if (bc[i, 2100, j] == 0 || bc[i, 2150, j] < 0) bc[i, , j] <- bc[i, 2100, j] # nolint + # but it is faster to transform into tibble, do the operation there, and transform back + bc <- bc %>% + tibble::as_tibble() %>% + tidyr::pivot_wider(names_from = "year", names_prefix = "y") %>% + dplyr::mutate(dplyr::across(tidyselect::starts_with("y"), + ~dplyr::if_else(.data$y2150 < 0 | .data$y2100 == 0, .data$y2100, .x))) %>% + tidyr::pivot_longer(tidyselect::starts_with("y"), names_to = "year", names_transform = ~sub("y", "", .x)) %>% + as.magpie(spatial = "region", temporal = "year", tidy = TRUE) x <- rep(c(2100, 2110, 2140, 2150), nr * nd) y <- purrr::reduce(purrr::map(1:nd, ~purrr::reduce(purrr::map(1:nr, function(y) bc[y, , .x]), c)), c) @@ -55,7 +72,9 @@ toolBezierExtension <- function(data, timeExtend) { closestYear <- function(x) purrr::map_int(x, ~timeExtend[which.min(abs(.x - timeExtend))]) extension <- purrr::map2(bezierPoints, id, - ~.x %>% tibble::as_tibble() %>% dplyr::mutate(id = .y)) %>% + ~.x %>% + tibble::as_tibble() %>% + dplyr::mutate(id = .y)) %>% purrr::list_rbind() %>% # Complicated / elegant use of function factories to get closest points to timeExtend coordinates # First create columns with distance to timeExtend points @@ -65,7 +84,7 @@ toolBezierExtension <- function(data, timeExtend) { dplyr::mutate(year = closestYear(x)) %>% tidyr::separate_wider_delim("id", names = c("data", "iso3c"), delim = "-") %>% dplyr::select("iso3c", "year", "data", "y") %>% - as.magpie() + as.magpie(spatial = "iso3c", temporal = "year", tidy = TRUE) mbind(data, extension) } diff --git a/R/toolFillWith.R b/R/toolFillWith.R index e662b4c..8ab5c8b 100644 --- a/R/toolFillWith.R +++ b/R/toolFillWith.R @@ -1,22 +1,53 @@ -# For countries in "data" with missing values, complete with values from "fill" -toolFillWith <- function(data, fill) { - # Return if one of the inputs is null - if (is.null(fill) || is.null(data)) { - return(data) +#' toolListFillWith +#' +#' Reduce list by filling the magpie objects with the following element of the list. +#' +#' @param x list of objects returned by caclOutput(..., supplementary = TRUE) +#' @keywords internal +#' @return The completed magpie object +toolListFillWith <- function(x) { + if (length(x) == 1) { + return(x[[1]]) } - # Fill out the "fill" object - fill <- time_interpolate(fill, interpolated_year = getYears(data), extrapolation_type = "constant") + sep <- if (length(x) == 2) " (completed with" else c(" (completed with", c(rep(",", length(x) - 3), " and")) + closer <- c(rep("", length(sep) - 1), ")") + helper <- purrr::map2(sep, closer, c) + + purrr::reduce2(x, helper, + ~ list(x = toolFillWith(.x$x, .y$x, .x$description, .y$description, verbose = TRUE), + weight = if (!is.null(.x$weight)) toolFillWith(.x$weight, .y$weight), + unit = glue("{.x$unit}"), + description = glue("{.x$description}{..3[1]} {.y$description}{..3[2]}"))) +} + + +#' toolFillWith +#' +#' Fill in countries in "data" with no values, with values from "fill". Only countries with no data at all get filled +#' in! +#' +#' @param data magpie object to fill +#' @param fill magpie object to fill data with +#' @keywords internal +#' @return The completed magpie object +toolFillWith <- function(data, fill, dataName = "data", fillName = "fill", verbose = FALSE) { + # Get countries with missing data (only zeros) - missing <- where(setYears(dimSums(data, dim = 2), "y0000") == 0)$true$regions + missing <- where(dimSums(data, dim = 2) == 0)$true$regions + + # Get countries with data (not only zeros) + withData <- where(dimSums(fill, dim = 2) != 0)$true$regions + + replace <- intersect(missing, withData) - if (!all(missing %in% getItems(fill, 1))) { - leftOver <- setdiff(missing, getItems(fill, 1)) # nolint - message(glue("NOTE: The following countries have not been filled: {paste0(leftOver, collapse = ', ')}.")) - missing <- intersect(missing, getItems(fill, 1)) + if (verbose) { + message(glue("Data for the following countries is missing in {dataName}, and is taken instead from {fillName}: \\ + {paste0(replace, collapse = ', ')}.")) } # Use fill for countries with only zeros - data[missing, , ] <- fill[missing, , ] + years <- intersect(getYears(data), getYears(fill)) + data[replace, years, ] <- fill[replace, years, ] data } diff --git a/R/toolFinishigTouches.R b/R/toolFinishigTouches.R deleted file mode 100644 index f67a6c4..0000000 --- a/R/toolFinishigTouches.R +++ /dev/null @@ -1,22 +0,0 @@ -toolFinishingTouches <- function(x, extension2150 = "none", naming = "indicator_scenario") { - x <- toolInterpolateAndExtrapolate(x) - - # Extend to 2150, if opted for - x <- toolExtend2150(x, extension2150) - - # Order by names - x <- x[, , order(getNames(x))] - - # Split indicator from scenario - if (naming == "indicator.scenario") { - getNames(x) <- sub("_", ".", getNames(x)) - getSets(x) <- c(getSets(x)[1], getSets(x)[2], "indicator", "scenario") - } - - # Drop indicator - if (naming == "scenario") { - getNames(x) <- sub(".*?_", "", getNames(x)) - } - - x -} diff --git a/R/toolGeneralConvert.R b/R/toolGeneralConvert.R index 1f667ca..70a4dd8 100644 --- a/R/toolGeneralConvert.R +++ b/R/toolGeneralConvert.R @@ -3,8 +3,8 @@ #' The most important and common "convert" operations are: #' \itemize{ #' \item removing undefined countries, -#' \item using default set names "iso3c", "year", and "variable", #' \item substituting NAs, see the "substituteNAsWith" argument, +#' \item using default set names "iso3c", "year", and "variable", #' \item fill in countries, #' \item sort in chronological order. #' } @@ -18,6 +18,11 @@ #' @param ... Arguments passed on to [madrat::toolCountryFill()] #' #' @return A magpie object. +#' @export +#' +#' @examples \dontrun{ +#' toolGeneralConvert(x) +#' } toolGeneralConvert <- function(x, useDefaultSetNames = TRUE, countryFillWith = 0, @@ -29,15 +34,15 @@ toolGeneralConvert <- function(x, # Remove any NA-countries x <- x[!is.na(getCells(x)), , ] - # Remove years which only contain NAs - x <- x[, !apply(x, 2, function(y) all(is.na(y))), ] + # Substitute NAs + x[is.na(x)] <- substituteNAsWith + + # Remove years which only 0s or substituteNAsWith + x <- x[, purrr::map_lgl(getYears(x), ~!all(x[, .x, ] == substituteNAsWith) & !all(x[, .x, ] == 0)), ] # Use default setNames if (useDefaultSetNames) getSets(x) <- c("iso3c", "year", "variable") - # Substitute NAs - x[is.na(x)] <- substituteNAsWith - # Check whether the country list agrees with the list of countries in the madrat library # and remove unrequired data, add missing data if (warn && note) { diff --git a/R/toolGetEUcountries.R b/R/toolGetEUcountries.R deleted file mode 100644 index 5db8aa3..0000000 --- a/R/toolGetEUcountries.R +++ /dev/null @@ -1,10 +0,0 @@ -# These countries are the ones (essential the EU-27) that receive special treatment -# in the SSP2EU scenario. -toolGetEUcountries <- function() { - x <- toolGetMapping("regionmappingH12.csv", type = "regional", where = "mappingfolder") %>% - tibble::as_tibble() %>% - dplyr::filter(.data$RegionCode == "EUR", .data$CountryCode != "GBR") %>% - dplyr::pull(.data$CountryCode) - - x -} diff --git a/R/toolGetScenarioDefinition.R b/R/toolGetScenarioDefinition.R index ca7a352..63dccf4 100644 --- a/R/toolGetScenarioDefinition.R +++ b/R/toolGetScenarioDefinition.R @@ -25,42 +25,46 @@ #' @examples #' toolGetScenarioDefinition() #' toolGetScenarioDefinition(driver = "GDP") -#' toolGetScenarioDefinition(scen = "SSP2EU") +#' toolGetScenarioDefinition(scen = "SSP2") #' toolGetScenarioDefinition(driver = "Population", scen = "SSPs", aslist = TRUE) #' toolGetScenarioDefinition <- function(driver = NULL, scen = NULL, aslist = FALSE) { # Start of scenario-design section: Developers can modify this section! scenarios <- tibble::tribble( - ~driver, ~scenario, ~pastData, ~futureData, ~harmonization, + ~driver, ~scenario, ~pastData, ~futureData, ~harmonization, # GDPpc scenarios - "GDPpc", "SSPs", "WDI-MI", "SSPs-MI", "calibSSPs", - "GDPpc", "SSP2", "WDI-MI", "SSP2-MI", "calibSSPs", - "GDPpc", "SDPs", "-", "-", "calibSDPs", - "GDPpc", "SSP2EU", "-", "-", "GDPoverPop", - "GDPpc", "ISIMIP", "WDI-MI", "SSPs-MI", "calibSSPs", + "GDPpc", "SSPs", "WDI-MI-James", "SSPs", "GDPpcSSPs", + "GDPpc", "SSP2", "WDI-MI-James", "SSP2", "GDPpcSSPs", + "GDPpc", "SSP2EU", "WDI-MI-James", "SSP2EU", "GDPpcSSPs", + "GDPpc", "SDPs", "-", "-", "GDPpcSDPs", + "GDPpc", "ISIMIP", "WDI-MI-James", "SSPs", "GDPpcSSPs", + "GDPpc", "ADBs", "WDI-MI-James", "ADBs-SSP2", "GDPpcADBs", # GDP scenarios - "GDP", "SSPs", "-", "-", "GDPpcWithPop", - "GDP", "SSP2", "-", "-", "GDPpcWithPop", - "GDP", "SDPs", "-", "-", "GDPpcWithPop", - "GDP", "ISIMIP", "-", "-", "GDPpcWithPop", - "GDP", "SSP2EU", "Eurostat-WDI-MI", "SSP2EU-MI", "calibSSP2EU", + "GDP", "SSPs", "-", "-", "GDPpcWithPop", + "GDP", "SSP2", "-", "-", "GDPpcWithPop", + "GDP", "SSP2EU", "-", "-", "GDPpcWithPop", + "GDP", "SDPs", "-", "-", "GDPpcWithPop", + "GDP", "ISIMIP", "-", "-", "GDPpcWithPop", + "GDP", "ADBs", "-", "-", "GDPpcWithPop", # Population Scenarios - "Population", "SSPs", "WDI-UN_PopDiv-MI", "SSPs-UN_PopDiv-MI", "withPEAPandFuture", - "Population", "SSP2", "WDI-UN_PopDiv-MI", "SSP2-UN_PopDiv-MI", "withPEAPandFuture", - "Population", "SDPs", "WDI-UN_PopDiv-MI", "SDPs-UN_PopDiv-MI", "withPEAPandFuture", - "Population", "SSP2EU", "Eurostat-WDI-UN_PopDiv-MI", "SSP2EU-UN_PopDiv-MI", "calibSSP2EU", - "Population", "ISIMIP", "UN_PopDiv-MI", "SSPs-UN_PopDiv-MI", "calibISIMIP", + "Population", "SSPs", "WDI-UN_PopDiv-MI", "SSPs-UN_PopDiv", "PopSSPs", + "Population", "SSP2", "WDI-UN_PopDiv-MI", "SSP2-UN_PopDiv", "PopSSPs", + "Population", "SSP2EU", "WDI-UN_PopDiv-MI", "SSP2EU-UN_PopDiv", "PopSSPs", + "Population", "SDPs", "WDI-UN_PopDiv-MI", "SDPs-UN_PopDiv", "PopSSPs", + "Population", "ISIMIP", "UN_PopDiv-MI", "SSPs-UN_PopDiv", "PopISIMIP", + "Population", "ADBs", "WDI-UN_PopDiv-MI", "ADBs-SSP2-UN_PopDiv", "PopSSPs", # Labour Scenarios - "Labour", "SSPs", "WDI", "SSPs", "pastAndLevel", - "Labour", "SSP2", "WDI", "SSP2", "pastAndLevel", - "Labour", "SDPs", "WDI", "SDPs", "pastAndLevel", - "Labour", "SSP2EU", "WDI", "SSP2EU", "pastAndLevel", + "Labour", "SSPs", "WDI-UN_PopDiv", "SSPs-UN_PopDiv", "pastAndLevel", + "Labour", "SSP2", "WDI-UN_PopDiv", "SSP2-UN_PopDiv", "pastAndLevel", + "Labour", "SSP2EU", "WDI-UN_PopDiv", "SSP2EU-UN_PopDiv", "pastAndLevel", + "Labour", "SDPs", "WDI-UN_PopDiv", "SDPs-UN_PopDiv", "pastAndLevel", + "Labour", "ADBs", "-", "-", "LabourADBs", # Urban population scenarios - "Urban", "SSPs", "WDI", "SSPs", "pastAndGrowth", - "Urban", "SSP2", "WDI", "SSP2", "pastAndGrowth", - "Urban", "SDPs", "WDI", "SDPs", "pastAndGrowth", - "Urban", "SSP2EU", "WDI", "SSP2EU", "pastAndGrowth" + "Urban", "SSPs", "WDI", "SSPs", "pastAndGrowth", + "Urban", "SSP2", "WDI", "SSP2", "pastAndGrowth", + "Urban", "SSP2EU", "WDI", "SSP2EU", "pastAndGrowth", + "Urban", "SDPs", "WDI", "SDPs", "pastAndGrowth", ) # End of scenario-design section diff --git a/R/toolGetUnitDollar.R b/R/toolGetUnitDollar.R index 9bad885..b32fa2e 100644 --- a/R/toolGetUnitDollar.R +++ b/R/toolGetUnitDollar.R @@ -5,7 +5,7 @@ #' @param returnOnlyBase TRUE or FALSE (default). If true only the base year is returned (as string). #' @param inPPP TRUE or FALSE (default). If TRUE the the string ends in 'Int$PPP', instead of 'Int$MER'. #' -#' @return A string with the monetary unit: 'constant 2017 US$MER'. +#' @return A string with the monetary unit: `r toolGetUnitDollar()`. #' @export #' #' @examples diff --git a/R/toolHarmonizeFuture.R b/R/toolHarmonizeFuture.R new file mode 100644 index 0000000..f8e7a91 --- /dev/null +++ b/R/toolHarmonizeFuture.R @@ -0,0 +1,89 @@ +#' Harmonization tool Future +#' +#' Like all harmonization tools in mrdrivers, toolHarmonizeFuture takes two magpie objects, 'past' and 'future', +#' and returns a single magpie object, i.e. the harmonized time-series. In this case, the harmonized time-series is +#' always equal to 'future', in the years of 'future'. After that the harmonized time-series depends on the 'method' +#' argument chosen. +#' +#' @details # Dimensions of 'past' and 'future' +#' If the 'past' object has multiple scenarios/datatypes, i.e. the length of the third dimension is larger than 1, +#' then the a harmonized time-series is created for every scenario/datatype in past. The same 'future' object is used +#' in every case - hence the requirement that 'future' only have one scenario/datatype. +#' +#' @param past A magpie object. +#' @param future A magpie object with only one scenario/datatype, i.e. the length of the third dimension should be 1. +#' @param method A string defining the harmonization method: +#' \itemize{ +#' \item "level": the harmonized time-series is exactly equal to 'past' in the years before the first year +#' of 'future'. +#' \item "growth": the harmonized time-series follows the same growth rates as 'past', in the years +#' before the first year of 'future'. +#' } +#' +#' @return A magpie object with the same dimensions as 'past'. +#' @export +#' +#' @examples \dontrun{ +#' toolHarmonizePast(past, future) +#' } +toolHarmonizeFuture <- function(past, future, method = "level") { + if (!is.magpie(past) && !is.magpie(future)) { + pastDescription <- past$description + past <- past$x + futureDescription <- future$description + future <- future$x + } + + # Check dimensions of past + if (dim(future)[3] != 1) { + stop("The future data may only have one datatype, i.e. dim(future)[3] needs to be 1.") + } + + # Check time overlap + lastPastYear <- max(getYears(past, as.integer = TRUE)) + firstFutureYear <- min(getYears(future, as.integer = TRUE)) + if (lastPastYear < firstFutureYear) { + stop("The past and future data need to have some overlap.") + } + + # If firstFutureYear is not in future data, then create past data for firstFutureYear + # by linear interpolation. That way the return object really has all the past data. + if (!firstFutureYear %in% getYears(past, as.integer = TRUE)) { + past <- time_interpolate(past, firstFutureYear, integrate_interpolated_years = TRUE) + } + + # Create future data for all past scenarios + tmpFuture <- future[, , 1:ndata(past)] + tmpFuture <- setNames(tmpFuture, getNames(past)) + tmpFuture[is.nan(tmpFuture)] <- 0 + + # Create transition magpie object for all past scenarios + yearsPast <- getYears(past, as.integer = TRUE)[which(getYears(past, as.integer = TRUE) < firstFutureYear)] + tmpPast <- new.magpie(getItems(past, 1), yearsPast, getNames(past), fill = 0) + + if (method == "level") { + tmpPast[, , ] <- past[, yearsPast, ] + } + if (method == "growth") { + tmpPast[, , ] <- tmpFuture[, firstFutureYear, ] * past[, yearsPast, ] / past[, firstFutureYear, ] + tmpPast[is.nan(tmpPast)] <- 0 + } + + x <- mbind(tmpFuture, tmpPast) + x <- x[, sort(getYears(x)), ] + + if (!(exists("pastDescription", inherits = FALSE) && exists("futureDescription", inherits = FALSE))) { + return(x) + } + + description <- switch( + method, + "level" = glue("use {futureDescription} after {min(getYears(future, as.integer = TRUE))} and {pastDescription} \\ + before then."), + "growth" = glue("use {futureDescription} after {min(getYears(future, as.integer = TRUE))} and follow the growth \\ + of {pastDescription} before then."), + stop("Unkwown method.") + ) + + list(x = x, description = description) +} diff --git a/R/toolHarmonizeFutureGrPast.R b/R/toolHarmonizeFutureGrPast.R deleted file mode 100644 index ae3b50f..0000000 --- a/R/toolHarmonizeFutureGrPast.R +++ /dev/null @@ -1,24 +0,0 @@ -toolHarmonizeFutureGrPast <- function(past, future) { - firstFutureYear <- min(intersect(getYears(past, as.integer = TRUE), - getYears(future, as.integer = TRUE))) - lastPastYear <- max(getYears(past, as.integer = TRUE)) - if (lastPastYear < firstFutureYear) { - stop("The past and future data need to have some overlap") - } - - # Create future data for all past scenarios - yearsFuture <- getYears(future)[which(getYears(future, as.integer = TRUE) >= firstFutureYear)] - tmpFuture <- future[, yearsFuture, 1:ndata(past)] - tmpFuture <- setNames(tmpFuture, getNames(past)) - tmpFuture[is.nan(tmpFuture)] <- 0 - - # Create transition magpie object for all future scenarios - yearsPast <- getYears(past)[which(getYears(past, as.integer = TRUE) < firstFutureYear)] - tmpPast <- new.magpie(getItems(past, 1), yearsPast, getNames(past), fill = 0) - - # Use growth rates of future object - tmpPast[, , ] <- tmpFuture[, firstFutureYear, ] * past[, yearsPast, ] / past[, firstFutureYear, ] - tmpPast[is.nan(tmpPast)] <- 0 - - mbind(tmpPast, tmpFuture) -} diff --git a/R/toolHarmonizeGDP.R b/R/toolHarmonizeGDP.R new file mode 100644 index 0000000..9c4f67b --- /dev/null +++ b/R/toolHarmonizeGDP.R @@ -0,0 +1,292 @@ +toolMultiplyGDPpcWithPop <- function(scenario) { + gdppc <- calcOutput("GDPpc", + scenario = scenario, + extension2150 = "none", + average2020 = FALSE, + naming = "scenario", + aggregate = FALSE, + supplementary = TRUE) + # GDP is equal to GDPpc * population + gdp <- gdppc$x * gdppc$weight + list(x = gdp, + description = glue("use product of corresponding GDP per capita and population scenarios. \\ + {gdppc$description}")) +} + +toolHarmonizeGDPpcSSPs <- function(past, future, yEnd) { + # Get IMF short-term income projections and fill missing with SSP2 (the SSP2 values need to be extrapolated until + # the last year of the IMF data. Constant extrapolation assumed.) + shortTerm <- readSource("IMF", "GDPpc") %>% + toolFillWith(calcOutput("GDPpcFuture", scenario = "SSP2", aggregate = FALSE)) %>% + toolInterpolateAndExtrapolate() + + # Use short term IMF growth rates (here, as far as possible) + tmpGDPpc <- toolHarmonizePast(past$x, shortTerm, method = "growth") + + lastYearIMF <- max(getYears(shortTerm, as.integer = TRUE)) + # Make sure to add the last IMF year to the future data, just in case it is not there. + future$x <- time_interpolate(future$x, lastYearIMF, integrate_interpolated_years = TRUE) + # Compute difference in last IMF year + delta <- setNames(tmpGDPpc[, lastYearIMF, ], NULL) - future$x[, lastYearIMF, ] + + # Define the years marking the start of medium (y1), and slow convergence (y2) (lastYearIMF marking the start of + # fast convergence). + y1 <- lastYearIMF + 5 + y2 <- lastYearIMF + 10 + + # Magpie implementation would look like this (super slow, but shorter, and left here for clarity with #c do avoid + # linter warnings): + #c extraYearsIn <- all(c(y1, y2) %in% getYears(future$x, as.integer = TRUE)) + #c if (!extraYearsIn) future$x <- time_interpolate(future$x, c(y1, y2), integrate_interpolated_years = TRUE) + #c years1 <- getYears(future$x)[getYears(future$x, as.integer = TRUE) <= y1] + #c years2 <- getYears(future$x)[getYears(future$x, as.integer = TRUE) <= y2] + #c # Placeholder + #c x <- toolHarmonizePast(tmpGDPpc, future$x, method = "level") + #c # Split countries with and without projection data + #c cWithProj <- where(future$x[, lastYearIMF, ] != 0)$true$regions + #c # Loop over countries (only those with projection data) and scenarios + #c for (i in cWithProj) { + #c for (j in getItems(x, 3)) { + #c if (j == "SSP2") { + #c x[i, , j] <- tmpGDPpc[i, , ] %>% + #c toolHarmonizePast(future$x[i, years1, j], method = "parallel") %>% + #c toolHarmonizePast(future$x[i, , j], method = "transition", yEnd = 2100) + #c } + #c if ((j %in% c("SSP1", "SSP5") && delta[i, lastYearIMF, j] >= 0) || + #c j %in% c("SSP3", "SSP4") && delta[i, lastYearIMF, j] < 0) { + #c x[i, , j] <- toolHarmonizePast(tmpGDPpc[i, , ], future$x[i, , j], method = "transition", yEnd = 2100) + #c } + #c if ((j %in% c("SSP1", "SSP5") && delta[i, lastYearIMF, j] < 0) || + #c j %in% c("SSP3", "SSP4") && delta[i, lastYearIMF, j] >= 0) { + #c x[i, , j] <- tmpGDPpc[i, , ] %>% + #c toolHarmonizePast(future$x[i, years2, j], method = "parallel") %>% + #c toolHarmonizePast(future$x[i, , j], method = "transition", yEnd = 2100) + #c } + #c } + #c } + #c if (!extraYearsIn) x <- x[, extraYears, , invert = TRUE] + + # The following is much faster, with the operation performed in a tibble. + # Placeholder + x <- toolHarmonizePast(tmpGDPpc, future$x, method = "level") + # Split countries with and without projection data + cWithProj <- where(future$x[, lastYearIMF, ] != 0)$true$regions + cWithoutProj <- where(future$x[, lastYearIMF, ] == 0)$true$regions + x <- toolFastConvergeSSP(x[cWithProj, , ], delta, lastYearIMF, y1, y2, 2100) %>% + mbind(x[cWithoutProj, , ]) %>% + magpiesort() + + x <- toolInterpolateAndExtrapolate(x) + lastPastYear <- max(getYears(past$x, as.integer = TRUE)) + list(x = x, + description = glue("use {past$description} until {lastPastYear}, short term growth rates from IMF until \\ + {lastYearIMF}, and transition to {future$description} by {yEnd}.")) +} + +toolBuildGDPpcSDPs <- function() { + gdppcapSSP1 <- calcOutput("GDPpc", + scenario = "SSPs", + average2020 = FALSE, + extension2150 = "none", + naming = "scenario", + aggregate = FALSE)[, , "SSP1"] + + # Standard SDP inherits SSP1 GDP + gdppcapSDP <- setNames(gdppcapSSP1, "SDP") + # SHAPE SDP_XX variants are calculated as modifications of SSP1 GDP/cap growth rates + combined <- purrr::map(c("SDP_EI", "SDP_MC", "SDP_RC"), + toolSHAPEgrowth, + gdppcapSSP1 = gdppcapSSP1, + startFromYear = 2020) %>% + mbind() + combined <- mbind(gdppcapSDP, combined) + + combined[is.nan(combined) | combined == Inf] <- 0 + + list(x = combined, + description = glue("use SSP1 scenario and adapt growth rates.")) +} + +toolDivideGDPbyPop <- function(scenario) { + gdp <- calcOutput("GDP", + scenario = scenario, + extension2150 = "none", + average2020 = FALSE, + naming = "scenario", + aggregate = FALSE, + supplementary = TRUE) + pop <- calcOutput("Population", + scenario = scenario, + extension2150 = "none", + naming = "scenario", + aggregate = FALSE, + supplementary = TRUE, + years = getYears(gdp$x)) + gdppc <- gdp$x / pop$x + list(x = gdppc, + description = glue("use ratio of corresponding GDP and population scenarios. {gdp$description} \\ + {pop$description}")) +} + +toolHarmonizeGDPpcADBs <- function(past, future) { + ssp2Data <- calcOutput("GDPpc", scenario = "SSP2", extension2150 = "none", average2020 = FALSE, aggregate = FALSE) + + # For ADBs: transition IND from past to future by 2030 + dataIND <- toolHarmonizePast(past, future, method = "transition", yEnd = 2030) + + combined <- purrr::map(getNames(dataIND$x), function(x) { + y <- setNames(ssp2Data, x) + y["IND", , ] <- 0 + y["IND", getYears(dataIND$x), ] <- dataIND$x["IND", , x] + y + }) %>% + mbind() + + list(x = combined, + description = glue("equal to SSP2 in all countries except for IND. \\ + For IND use {past$description} until {max(getYears(past$x, as.integer = TRUE))}, \\ + and converge to {future$description} by 2030.")) +} + + +toolFastConvergeSSP <- function(x, delta, yearStart, y1, y2, yearEnd) { + x <- x %>% tibble::as_tibble() %>% dplyr::rename("SSP" = "variable") + delta <- delta %>% tibble::as_tibble() %>% dplyr::select("iso3c", "SSP" = "d3", "d" = "value") + + x <- x %>% + dplyr::left_join(delta, by = c("iso3c", "SSP")) %>% + dplyr::mutate( + # Medium convergence + value = dplyr::if_else(.data$year > yearStart & .data$SSP == "SSP2", + dplyr::if_else( # nolint: indentation_linter. + .data$year <= y1, + .data$value + .data$d, + dplyr::if_else( + .data$year <= yearEnd, + .data$value + .data$d * (yearEnd - .data$year) / (yearEnd - y1), + .data$value + ) + ), + .data$value + ), + # Fast convergence + value = dplyr::if_else(.data$year > yearStart & + ((.data$SSP %in% c("SSP1", "SSP5") & .data$d < 0) | # nolint: indentation_linter. + (.data$SSP %in% c("SSP3", "SSP4") & .data$d >= 0)), + dplyr::if_else( # nolint: indentation_linter. + .data$year <= yearEnd, + .data$value + .data$d * (yearEnd - .data$year) / (yearEnd - yearStart), + .data$value + ), + .data$value + ), + # Slow convergence + value = dplyr::if_else(.data$year > yearStart & + ((.data$SSP %in% c("SSP3", "SSP4") & .data$d < 0) | # nolint: indentation_linter. + (.data$SSP %in% c("SSP1", "SSP5") & .data$d >= 0)), + dplyr::if_else( # nolint: indentation_linter. + .data$year <= y2, + .data$value + .data$d, + dplyr::if_else( + .data$year <= yearEnd, + .data$value + .data$d * (yearEnd - .data$year) / (yearEnd - y2), + .data$value + ) + ), + .data$value + ), + # Add a minimum value for value here. This can occur when the delta computed in yearStart is + # so large relative to the original GDPpc value in yearStart, that a further decrease in the + # years y1 and y2 pushes the GDPpc into the negative. + value = pmax(.data$value, 0.01) + ) %>% + dplyr::select(-"d") + x %>% + dplyr::rename("variable" = "SSP") %>% + as.magpie(spatial = "iso3c", temporal = "year", tidy = TRUE) +} + +# Note that here we label the GDP scenarios with their scenario abbreviations, and not with the name of the SHAPE +# economics dimensions. Mapping (Scenario <-> economics dimension): +# - Economy-driven Innovation (SDP_EI) <-> innovation-driven economy +# - Resilient Communities (SDP_RC) <-> society-driven economy +# - Managing the global Commons (SDP_MC) <-> service-driven economy +# The two alternative SHAPE scenarios will re-use these GDP trajectories, so they are not explicitly included here. +# - Local Solutions (SDP_LS) <-> society-driven economy (same as SDP_RC) +# - Green and Social market economy (SDP_GS) <-> service-driven economy (same as SDP_MC) +# Calculate modified growth rates and resulting gdp/capita in forward simulation +toolSHAPEgrowth <- function(shapeGDPScenario, gdppcapSSP1, startFromYear) { + + # calculation of growth rates + yrs <- getYears(gdppcapSSP1, as.integer = TRUE) + # flexible timestep + # LONGTERM would be better to always use yearly timesteps in this computation, and select years afterwards + timestep <- new.magpie(years = yrs) + timestep[, , ] <- dplyr::lead(yrs) - yrs + # assign average growth rate g_t of period t -> t+ timestep + # this means modifications of growth rate t will affect GDP in t+timestep + yrsShifted <- yrs[2:length(yrs)] + yrsBase <- yrs[1:(length(yrs) - 1)] + growthrateSSP1 <- 100 * + ((setYears(gdppcapSSP1[, yrsShifted, ], yrsBase) / gdppcapSSP1[, yrsBase, ]) ^ + (1. / timestep[, yrsBase, ]) - 1) + + # modified growth rates and gdp/cap + growthrate <- setNames(as.magpie(growthrateSSP1), shapeGDPScenario) + gdppcap <- setNames(as.magpie(gdppcapSSP1), shapeGDPScenario) + gdppcap[, yrs > startFromYear, ] <- NA + + for (yr in yrs[1:(length(yrs) - 1)]) { + # modify growth rates only for future period (default: from 2020 onwards) + if (yr >= startFromYear) { + # innovation-driven (SDP_EI): enhance growth rates for low-income countries by up to 15% + if (shapeGDPScenario == "SDP_EI") { + modificationFactor <- logisticTransition( + gdppcap[, yr, ], l0 = 1.15, l = 1, k = 20, x0 = 15e3, useLog10 = TRUE + ) + # service-driven (SDP_MC): growth rate reduced based on relative distance to technology frontier + # (given by the US) + } else if (shapeGDPScenario == "SDP_MC") { + # define US as technology frontier + frontier <- gdppcap["USA", yr, ] + getItems(frontier, 1) <- "GLO" + # countries with gdp/cap above US are treated the same as the US -> set diff = 0 + reldiff2frontier <- pmax((frontier[, yr, ] - gdppcap[, yr, ]) / frontier[, yr, ], 0) + modificationFactor <- logisticTransition( + reldiff2frontier[, yr, ], l0 = 1, l = 0.5, k = -30, x0 = 0.2, useLog10 = FALSE + ) + # society-driven (SDP_RC): gradual transition to zero growth for high-income countries + } else if (shapeGDPScenario == "SDP_RC") { + modificationFactor <- logisticTransition(gdppcap[, yr, ], l0 = 1, l = 0, k = 10, x0 = 30e3, useLog10 = TRUE) + } else { + stop("cannot create SHAPE GDP scenarios: unknown scenario") + } + + # for service (SDP_MC) and society (SDP_RC) additionally add a smoothing for 2020 and 2025 timesteps + # apply only 1/3 (2020-2024) and 2/3 (2025-2029) of the modification + if (shapeGDPScenario %in% c("SDP_MC", "SDP_RC")) { + if (yr >= 2020 && yr < 2025) { + modificationFactor[, yr, ] <- 1 / 3. * (modificationFactor[, yr, ] - 1) + 1 + } else if (yr >= 2025 && yr < 2030) { + modificationFactor[, yr, ] <- 2 / 3. * (modificationFactor[, yr, ] - 1) + 1 + } + } + growthrate[, yr, ] <- growthrate[, yr, ] * modificationFactor[, yr, ] + } + + # calculate next gdp/cap based on current value and (modified) growth rate + gdppcap[, yr + as.integer(timestep[, yr, ]), ] <- gdppcap[, yr, ] * (1 + growthrate[, yr, ] / 100.)^timestep[, yr, ] + } + + gdppcap +} + +# Smooth transition from lO to l, with steepness k and midpoint x0 +logisticTransition <- function(x, l0, l, k, x0, useLog10 = FALSE) { + if (useLog10) { + x <- log10(x) + x0 <- log10(x0) + } + logistic <- 1. / (1 + exp(-k * (x - x0))) + return(l0 - (l0 - l) * logistic) +} diff --git a/R/toolHarmonizePast.R b/R/toolHarmonizePast.R index d8c5c62..d22f20b 100644 --- a/R/toolHarmonizePast.R +++ b/R/toolHarmonizePast.R @@ -26,7 +26,19 @@ #' @param yEnd Additional input for "transition" method. Year by which the transition period is completed. #' #' @return A magpie object with the same dimensions as 'future'. +#' @export +#' +#' @examples \dontrun{ +#' toolHarmonizePast(past, future) +#' } toolHarmonizePast <- function(past, future, method = "level", yEnd = 2100) { + if (!is.magpie(past) && !is.magpie(future)) { + pastDescription <- past$description + past <- past$x + futureDescription <- future$description + future <- future$x + } + # Check dimensions of past if (dim(past)[3] != 1) { stop("The past data may only have one datatype, i.e. dim(past)[3] needs to be 1.") @@ -42,7 +54,7 @@ toolHarmonizePast <- function(past, future, method = "level", yEnd = 2100) { # If lastPastYear is not in future data, then create future data for lastPastYear # by linear interpolation. That way the return object really has all the past data. if (!lastPastYear %in% getYears(future, as.integer = TRUE)) { - future <- magclass::time_interpolate(future, lastPastYear, integrate_interpolated_years = TRUE) + future <- time_interpolate(future, lastPastYear, integrate_interpolated_years = TRUE) } # Create past data for all future scenarios @@ -61,6 +73,9 @@ toolHarmonizePast <- function(past, future, method = "level", yEnd = 2100) { tmpFuture[, , ] <- tmpPast[, lastPastYear, ] * future[, yearsFuture, ] / future[, lastPastYear, ] tmpFuture[is.nan(tmpFuture)] <- 0 } + if (method == "parallel") { + tmpFuture[, , ] <- future[, yearsFuture, ] + (tmpPast[, lastPastYear, ] - future[, lastPastYear, ]) + } if (method == "transition") { yearsTrans <- yearsFuture[which(yearsFuture <= yEnd)] tmpTrans <- new.magpie(getItems(future, 1), yearsTrans, getNames(future), fill = 0) @@ -77,5 +92,22 @@ toolHarmonizePast <- function(past, future, method = "level", yEnd = 2100) { # Answer is yes! } - mbind(tmpPast, tmpFuture) + x <- mbind(tmpPast, tmpFuture) + + if (!(exists("pastDescription", inherits = FALSE) && exists("futureDescription", inherits = FALSE))) { + return(x) + } + + description <- switch( + method, + "level" = glue("use {pastDescription} until {max(getYears(past, as.integer = TRUE))} and then switch directly \\ + to {futureDescription}."), + "growth" = glue("use {pastDescription} until {max(getYears(past, as.integer = TRUE))} and then follow the \\ + growth of {futureDescription}."), + "transition" = glue("use {pastDescription} until {max(getYears(past, as.integer = TRUE))} and converge towards \\ + {futureDescription} by {yEnd}."), + stop("Unkwown method.") + ) + + list(x = x, description = description) } diff --git a/R/toolHarmonizePop.R b/R/toolHarmonizePop.R new file mode 100644 index 0000000..1d8d11b --- /dev/null +++ b/R/toolHarmonizePop.R @@ -0,0 +1,38 @@ +toolHarmonizeWithPEAPandFuture <- function(past, future) { + # Get PEAP data (and fill with UN_PopDiv) and drop everything that is not "short-term", defined as being later than + # the last year of the IMF WEO data (the UN_PopDiv values need to be extrapolated until the last year of the IMF + # data. Constant extrapolation assumed.) + shortTerm <- readSource("PEAP") %>% + toolFillWith(readSource("UN_PopDiv", "pop", "medium")) %>% + toolInterpolateAndExtrapolate() + lastYearIMF <- max(getYears(readSource("IMF", "GDPpc"), as.integer = TRUE)) + shortTerm <- shortTerm[, getYears(shortTerm, as.integer = TRUE) <= lastYearIMF, ] + + # Use PEAP growth rates until last year of IMF WEO data, and future growth rates after that + x <- past$x %>% + toolHarmonizePast(shortTerm, method = "growth") %>% + toolHarmonizePast(future$x, method = "growth") %>% + # For any countries with missing projections, extrapolate (constant values assumed into the future). + toolInterpolateAndExtrapolate() + + lastPastYear <- max(getYears(past$x, as.integer = TRUE)) + list(x = x, + description = glue("use {past$description} until {lastPastYear}, \\ + growth rates from the Wolrld Bank's PEAP until {lastYearIMF}, \\ + and growth rates from {future$description} thereafter.")) +} + +toolHarmonizeLabourADBs <- function() { + pop2 <- calcOutput("Population", scenario = "SSP2", naming = "scenario", extension2150 = "none", aggregate = FALSE) + lab2 <- calcOutput("Labour", scenario = "SSP2", naming = "scenario", extension2150 = "none", aggregate = FALSE) + pop <- calcOutput("Population", scenario = "ADBs", extension2150 = "none", aggregate = FALSE) + + combined <- purrr::map(getNames(pop), function(x) { + labShareSSP2 <- lab2 / pop2[, getYears(lab2), ] + getNames(labShareSSP2) <- x + pop[, getYears(lab2), x] * labShareSSP2 + }) %>% + mbind() + + list(x = combined, description = glue("labour to population ratio equal to that in SSP2.")) +} diff --git a/R/toolInterpolateAndExtrapolate.R b/R/toolInterpolateAndExtrapolate.R index 7de9bce..ded6497 100644 --- a/R/toolInterpolateAndExtrapolate.R +++ b/R/toolInterpolateAndExtrapolate.R @@ -1,6 +1,19 @@ +#' toolInterpolateAndExtrapolate +#' +#' Fill in years of partially missing countries through inter- and extrapolation. +#' +#' @param data A magpie object +#' @param extrapolate TRUE or FALSE +#' @keywords internal +#' @return list toolInterpolateAndExtrapolate <- function(data, extrapolate = TRUE) { + if (!is.magpie(data)) { + dataHelper <- data + data <- data$x + } + # Get countries with partially missing values (exclude those that are still completely missing) - stillMissing <- where(setYears(dimSums(data, dim = 2), "y0000") == 0)$true$regions + stillMissing <- where(dimSums(data, dim = 2) == 0)$true$regions partiallyMissing <- setdiff(where(data == 0)$true$regions, stillMissing) # Interpolate and extrapolate for (i in partiallyMissing) { @@ -15,5 +28,10 @@ toolInterpolateAndExtrapolate <- function(data, extrapolate = TRUE) { interpolated_year = missingyears, extrapolation_type = "constant") } - data + + if (!(exists("dataHelper", inherits = FALSE))) { + return(data) + } + + list(x = data, weight = dataHelper$weight, unit = dataHelper$unit, description = dataHelper$description) } diff --git a/R/toolReduce.R b/R/toolReduce.R deleted file mode 100644 index 0beb8e7..0000000 --- a/R/toolReduce.R +++ /dev/null @@ -1,25 +0,0 @@ -toolReduce <- function(x, mbindOrFillWith = "mbind") { - # Combine list elements using mbind and glue. - if (mbindOrFillWith == "mbind") { - x %>% - purrr::reduce(~ list(x = mbind(.x$x, .y$x), - weight = mbind(.x$weight, .y$weight), - unit = glue("{.x$unit} || {.y$unit}"), - description = glue("{.x$description} || {.y$description}"))) - } else if (mbindOrFillWith == "fillWith") { - - if (length(x) > 1) { - sep <- if (length(x) == 2) " (completed with" else c(" (completed with", c(rep(",", length(x) - 3), " and")) - closer <- c(rep("", length(sep) - 1), ")") - helper <- purrr::map2(sep, closer, c) - } else { - helper <- NULL - } - - purrr::reduce2(x, helper, - ~ list(x = toolFillWith(.x$x, .y$x), - weight = toolFillWith(.x$weight, .y$weight), - unit = glue("{.x$unit}"), - description = glue("{.x$description}{..3[1]} {.y$description}{..3[2]}"))) - } -} diff --git a/inst/README.Rmd b/inst/README.Rmd index be26760..56e611d 100644 --- a/inst/README.Rmd +++ b/inst/README.Rmd @@ -53,24 +53,21 @@ The key `madrat::readSource()` and `madrat::calcOutput()` functions provided by readSource: ```{r, echo=FALSE} -c("readWDI", "readIMF", "readEurostatPopGDP", "readUN_PopDiv", "readPEAP", "readSSP", "readMissingIslands", - "readJames2019") +c("readSSP", "readWDI", "readIMF", "readUN_PopDiv", "readPEAP") ``` calcOutput: ```{r, echo=FALSE} -c("calcGDP", "calcGDPpc", "calcPopulation", "calcLabour", "calcUrban") +c("calcGDP", "calcGDPpc", "calcPopulation", "calcLabour", "calcUrban", "calcRatioPPP2MER") ``` ## Scenarios -The current default scenarios returned for all drivers (i.e. GDP, GDP per capita, Population, Labour, and Urban Population Share) are: +The current default scenarios returned for all drivers (i.e. GDP, GDP per capita, Population, Labour, and Urban Population Share) are: - the SSPs, i.e. SSP1-5 -- the SDPs, i.e. SDP, SDP_EI, SDP_RC, and SDP_MC - -- SSP2EU +- the SDPs, i.e. SDP, SDP_EI, SDP_MC and SDP_RC see `vignette("scenarios")` for more information on available scenarios and references of the default scenarios. diff --git a/inst/README.md b/inst/README.md index b323d8e..f37ce89 100644 --- a/inst/README.md +++ b/inst/README.md @@ -33,14 +33,13 @@ provided by this package are listed below. readSource: - #> [1] "readWDI" "readIMF" "readEurostatPopGDP" - #> [4] "readUN_PopDiv" "readPEAP" "readSSP" - #> [7] "readMissingIslands" "readJames2019" + #> [1] "readSSP" "readWDI" "readIMF" "readUN_PopDiv" + #> [5] "readPEAP" calcOutput: - #> [1] "calcGDP" "calcGDPpc" "calcPopulation" "calcLabour" - #> [5] "calcUrban" + #> [1] "calcGDP" "calcGDPpc" "calcPopulation" "calcLabour" + #> [5] "calcUrban" "calcRatioPPP2MER" ## Scenarios @@ -49,9 +48,7 @@ per capita, Population, Labour, and Urban Population Share) are: - the SSPs, i.e. SSP1-5 -- the SDPs, i.e. SDP, SDP_EI, SDP_RC, and SDP_MC - -- SSP2EU +- the SDPs, i.e. SDP, SDP_EI, SDP_MC and SDP_RC see `vignette("scenarios")` for more information on available scenarios and references of the default scenarios. diff --git a/man/calcDriver.Rd b/man/calcDriver.Rd index 55a1dc0..16d754c 100644 --- a/man/calcDriver.Rd +++ b/man/calcDriver.Rd @@ -9,8 +9,7 @@ calcDriver( scenario, popAsWeight = FALSE, naming = "indicator_scenario", - extension2150 = "bezier", - ... + extension2150 = "bezier" ) } \arguments{ @@ -31,7 +30,7 @@ calcDriver( \item{naming}{A string giving the naming scheme of the data dimension. Can be either: \itemize{ \item "indicator_scenario" (default): Returns names of the type "gdp_SSP2", or "pop_SSP2". -\item "indicator.scenario": Returns names of the type "gdp.SSP2", or "pop.SSP2". +\item "indicator.scenario": (deprecated) Returns names of the type "gdp.SSP2", or "pop.SSP2". \item "scenario": Returns names of the type "SSP2". } Set naming to "scenario" when you want to operate on SSP2 gdp and population data for instance, and not have to @@ -45,15 +44,6 @@ their last year. \item "constant": The last value of the scenarios is taken as constant until 2150. \item "none": No extension. }} - -\item{...}{ - Arguments passed on to \code{\link[=calcScenarioConstructor]{calcScenarioConstructor}} - \describe{ - \item{\code{harmonization}}{A string designating the harmonization function.} - \item{\code{pastData}}{A string passed to the calc'Driver'Past function, e.g. \code{\link[=calcGDPPast]{calcGDPPast()}} or \code{\link[=calcPopulationPast]{calcPopulationPast()}}.} - \item{\code{futureData}}{A string passed to the calc'Driver'Future function, e.g. \code{\link[=calcGDPFuture]{calcGDPFuture()}} or -\code{\link[=calcPopulationFuture]{calcPopulationFuture()}}.} - }} } \value{ magpie object with the requested output data either on country or on @@ -77,11 +67,6 @@ only one futuredata element is provided. } \seealso{ -\itemize{ -\item \code{\link[=calcGDPPast]{calcGDPPast()}}, \code{\link[=calcGDPFuture]{calcGDPFuture()}}, \code{\link[=calcGDPpcPast]{calcGDPpcPast()}} and \code{\link[=calcGDPpcFuture]{calcGDPpcFuture()}} for the builiding blocks of -the GDP and GDPpc scenarios. -\item \code{\link[=calcPopulationPast]{calcPopulationPast()}}, \code{\link[=calcPopulationFuture]{calcPopulationFuture()}}, \code{\link[=calcLabourPast]{calcLabourPast()}}, \code{\link[=calcLabourFuture]{calcLabourFuture()}}, \code{\link[=calcUrbanPast]{calcUrbanPast()}} -and \code{\link[=calcUrbanFuture]{calcUrbanFuture()}} for the builiding blocks of the Population, Labor and Urban scenarios. -} +\code{\link[=calcGDPPast]{calcGDPPast()}} for the scenario builiding blocks. } \keyword{internal} diff --git a/man/calcFutureData.Rd b/man/calcFutureData.Rd deleted file mode 100644 index 8afde32..0000000 --- a/man/calcFutureData.Rd +++ /dev/null @@ -1,38 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcDriver.R -\name{calcFutureData} -\alias{calcFutureData} -\title{Get Future Data Building Block} -\usage{ -calcFutureData(driver, futureData, unit) -} -\arguments{ -\item{driver}{A string designating the driver. Available drivers are: -\itemize{ -\item GDP -\item Population -\item GDPpc -\item Labour -\item Urban -}} - -\item{futureData}{A string passed to the calc'Driver'Future function, e.g. \code{\link[=calcGDPFuture]{calcGDPFuture()}} or -\code{\link[=calcPopulationFuture]{calcPopulationFuture()}}.} -} -\value{ -magpie object with the requested output data either on country or on -regional level depending on the choice of argument "aggregate" or a list of information -if supplementary is set to TRUE. -} -\description{ -Get Future Data Building Block -} -\seealso{ -\itemize{ -\item \code{\link[=calcGDPPast]{calcGDPPast()}}, \code{\link[=calcGDPFuture]{calcGDPFuture()}}, \code{\link[=calcGDPpcPast]{calcGDPpcPast()}} and \code{\link[=calcGDPpcFuture]{calcGDPpcFuture()}} for the builiding blocks of -the GDP and GDPpc scenarios. -\item \code{\link[=calcPopulationPast]{calcPopulationPast()}}, \code{\link[=calcPopulationFuture]{calcPopulationFuture()}}, \code{\link[=calcLabourPast]{calcLabourPast()}}, \code{\link[=calcLabourFuture]{calcLabourFuture()}}, \code{\link[=calcUrbanPast]{calcUrbanPast()}} -and \code{\link[=calcUrbanFuture]{calcUrbanFuture()}} for the builiding blocks of the Population, Labor and Urban scenarios. -} -} -\keyword{internal} diff --git a/man/calcGDP.Rd b/man/calcGDP.Rd index fc35641..3766551 100644 --- a/man/calcGDP.Rd +++ b/man/calcGDP.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcGDP.R, R/calcGDPpc.R +% Please edit documentation in R/calcGDP.R \name{calcGDP} \alias{calcGDP} \alias{calcGDPpc} @@ -7,14 +7,14 @@ \usage{ calcGDP( scenario = c("SSPs", "SDPs", "SSP2EU"), - unit = "constant 2017 Int$PPP", + unit = toolGetUnitDollar(inPPP = TRUE), average2020 = TRUE, ... ) calcGDPpc( scenario = c("SSPs", "SDPs", "SSP2EU"), - unit = "constant 2017 Int$PPP", + unit = toolGetUnitDollar(inPPP = TRUE), average2020 = TRUE, ... ) @@ -25,8 +25,9 @@ calcGDPpc( \item{unit}{A string specifying the unit of GDP. Can be either: \itemize{ -\item "constant 2017 Int$PPP" (default): Scenarios are constructed in constant 2017 Int$PPP. -\item "constant 2017 US$MER": Scenarios are constructed in constant 2017 Int$PPP and then converted with +\item "constant 2017 Int$PPP" (default): +Scenarios are constructed in constant 2017 Int$PPP. +\item "constant 2017 US$MER": Scenarios are constructed in constant 2017 US$MER and then converted with \code{\link[GDPuc:convertGDP]{GDPuc::toolConvertGDP()}}. } In all cases, GDP is returned in millions.} @@ -34,8 +35,7 @@ In all cases, GDP is returned in millions.} \item{average2020}{If TRUE (default), then the 2020 value is replaced by the 2018-2022 average. To be consistent, the yearly resolution is decreased to 5 year intervals.} -\item{...}{Arguments passed on to \code{\link[=calcDriver]{calcDriver()}}, of which "extension2150" and "naming" are most often of interest. -Other \code{\link[=calcDriver]{calcDriver()}} arguments are used for scenario fine-tuning and by package developers.} +\item{...}{Arguments passed on to \code{\link[=calcDriver]{calcDriver()}}, of which "extension2150" and "naming" are most often of interest.} } \value{ magpie object with the requested output data either on country or on @@ -51,7 +51,6 @@ By default the following scenarios are returned: \itemize{ \item the SSPs, i.e. SSP1-5 \item the SDPs, i.e. SDP, SDP_EI, SDP_RC, and SDP_MC -\item SSP2EU } See the vignette: \code{vignette("scenarios")} for scenario options, definitions and references. @@ -62,8 +61,8 @@ See the vignette: \code{vignette("scenarios")} for scenario options, definitions calcOutput("GDP") calcOutput("GDPpc") -# Return only the SSP2EU GDP scenario -calcOutput("GDP", scenario = "SSP2EU") +# Return only the SSP2 GDP scenario +calcOutput("GDP", scenario = "SSP2") } \dontrun{ diff --git a/man/calcGDPHarmonized.Rd b/man/calcGDPHarmonized.Rd deleted file mode 100644 index 7b4ab05..0000000 --- a/man/calcGDPHarmonized.Rd +++ /dev/null @@ -1,28 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcGDPHarmonized.R -\name{calcGDPHarmonized} -\alias{calcGDPHarmonized} -\title{Get Harmonized GDP Data} -\usage{ -calcGDPHarmonized(harmonization, past, future, scenario, unit, ...) -} -\arguments{ -\item{harmonization}{description} - -\item{past}{description} - -\item{future}{description} - -\item{scenario}{description} - -\item{unit}{description} -} -\value{ -magpie object with the requested output data either on country or on -regional level depending on the choice of argument "aggregate" or a list of information -if supplementary is set to TRUE. -} -\description{ -Get Harmonized GDP Data -} -\keyword{internal} diff --git a/man/calcGDPPast.Rd b/man/calcGDPPast.Rd index d73e151..7c44e13 100644 --- a/man/calcGDPPast.Rd +++ b/man/calcGDPPast.Rd @@ -1,78 +1,59 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcGDPFuture.R, R/calcGDPPast.R, -% R/calcGDPpcFuture.R, R/calcGDPpcPast.R -\name{calcGDPFuture} -\alias{calcGDPFuture} +% Please edit documentation in R/calcGDPPast.R, R/calcGDPFuture.R, +% R/calcPopulationFuture.R, R/calcPopulationPast.R +\name{calcGDPPast} \alias{calcGDPPast} -\alias{calcGDPpcFuture} \alias{calcGDPpcPast} -\title{Get GDP and GDPpc scenario building blocks} +\alias{calcGDPFuture} +\alias{calcGDPpcFuture} +\alias{calcPopulationFuture} +\alias{calcLabourFuture} +\alias{calcUrbanFuture} +\alias{calcPopulationPast} +\alias{calcLabourPast} +\alias{calcUrbanPast} +\title{Get scenario building blocks} \usage{ -calcGDPFuture(GDPFuture, unit) +calcGDPPast(pastData = "WDI-MI-James", extension1960 = "MI-James") -calcGDPPast(GDPPast = "WDI-MI", unit = "constant 2017 Int$PPP") +calcGDPpcPast(scenario = "SSPs") -calcGDPpcFuture(GDPpcFuture, unit) +calcGDPFuture(futureData = "SSPs") -calcGDPpcPast(GDPpcPast = "WDI-MI", unit = "constant 2017 Int$PPP") -} -\arguments{ -\item{GDPFuture}{A string designating the source for the future GDP data. Available sources are: -\itemize{ -\item "SSPs": IIASA \href{https://tntcat.iiasa.ac.at/SspDb/dsd?Action=htmlpage&page=welcome}{SSP database} -\item "SSP2EU": Combined SSP2 and Eurostat (for the EU countries) source -\item "SDPs": -\item "MI": Missing island dataset -} -See the "Combining data sources with '-'" section below for how to combine data sources.} +calcGDPpcFuture(scenario = "SSPs") -\item{unit}{A string specifying the unit of GDP. Can be either: -\itemize{ -\item "constant 2017 Int$PPP" (default): Scenarios are constructed in constant 2017 Int$PPP. -\item "constant 2017 US$MER": Scenarios are constructed in constant 2017 Int$PPP and then converted with -\code{\link[GDPuc:convertGDP]{GDPuc::toolConvertGDP()}}. -} -In all cases, GDP is returned in millions.} +calcPopulationFuture(futureData = "SSPs-UN_PopDiv") -\item{GDPPast}{A string designating the source for the historical GDP data. Available sources are: -\itemize{ -\item "WDI": World development indicators from the World Bank -\item "MI": Missing island dataset -\item "Eurostat": Eurostat -}} +calcLabourFuture(futureData = "SSPs") -\item{GDPpcFuture}{A string designating the source for the future GDP data. Available sources are: -\itemize{ -\item "SSPs": -\item "SDPs": All SDP future projections are set equal to those of SSP1. -\item "MI": Missing island dataset -} -See the "Combining data sources with '-'" section below for how to combine data sources.} +calcUrbanFuture(futureData = "SSPs") + +calcPopulationPast(pastData = "WDI-UN_PopDiv-MI") -\item{GDPpcPast}{A string designating the source for the historical GDPpc data. Available sources are: -\itemize{ -\item "WDI": World development indicators from the World Bank -\item "MI": Missing island dataset +calcLabourPast(pastData = "WDI-UN_PopDiv") + +calcUrbanPast(pastData = "WDI") } -See the "Combining data sources with '-'" section below for how to combine data sources.} +\arguments{ +\item{pastData}{A string specifying the sources for historic data.} + +\item{extension1960}{A string specifying how the data should be extended backwards to 1960.} + +\item{scenario}{A string specifying the scenario, from which the historic GDP and population data sources are taken.} + +\item{futureData}{A string specifying the sources for future projections.} } \description{ -Get the past and future GDP scenario building blocks with calcGDPPast and calcGDPFuture, respectively. -If GDP data for a scenario is required, even if just for a single year, always use \code{\link[=calcGDP]{calcGDP()}}, as what is returned -by calcGDPPast or calcGDPFuture may not end up as is in the scenario, depending on the harmonization function. -Use calcGDPPast and calcGDPFuture only when trying to access specific GDP data. +Get the past and future scenario building blocks. +If scenario data is required, even if just for a single year, always use the calc call to the final scenario, e.g. +\code{\link[=calcGDP]{calcGDP()}} or \code{\link[=calcPopulation]{calcPopulation()}}, as what is returned by the calc...Past and calc...Future functions may not end up +as is in the scenario, depending on the harmonization function. +These functions are only still exported for compatibility with existing code in the PIAM input data pipeline. + +See the vignette: \code{vignette("scenarios")} for references for the different data sources. See the "Combining data sources with '-'" section below for how to combine data sources. } -\section{Functions}{ -\itemize{ -\item \code{calcGDPFuture()}: Get future GDP projections - -\item \code{calcGDPpcFuture()}: Get future GDPpc projections - -\item \code{calcGDPpcPast()}: Get historic GDPpc data - -}} \section{Combining data sources with "-"}{ Data sources can be combined with "-" and passed to both the pastData and futureData arguments, i.e. "WDI-MI". This signifies that WDI data will be taken first, but missing data will be then be filled in with data from MI. diff --git a/man/calcGDPpcHarmonized.Rd b/man/calcGDPpcHarmonized.Rd deleted file mode 100644 index 3be63c8..0000000 --- a/man/calcGDPpcHarmonized.Rd +++ /dev/null @@ -1,28 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcGDPpcHarmonized.R -\name{calcGDPpcHarmonized} -\alias{calcGDPpcHarmonized} -\title{Get Harmonized GDPpc Data} -\usage{ -calcGDPpcHarmonized(harmonization, past, future, scenario, unit, ...) -} -\arguments{ -\item{harmonization}{description} - -\item{past}{description} - -\item{future}{description} - -\item{scenario}{description} - -\item{unit}{description} -} -\value{ -magpie object with the requested output data either on country or on -regional level depending on the choice of argument "aggregate" or a list of information -if supplementary is set to TRUE. -} -\description{ -Get Harmonized GDPpc Data -} -\keyword{internal} diff --git a/man/calcHarmonizedData.Rd b/man/calcHarmonizedData.Rd index c47a2f2..427b7ee 100644 --- a/man/calcHarmonizedData.Rd +++ b/man/calcHarmonizedData.Rd @@ -2,9 +2,9 @@ % Please edit documentation in R/calcDriver.R \name{calcHarmonizedData} \alias{calcHarmonizedData} -\title{Get Harmonized Data} +\title{Get harmonized data} \usage{ -calcHarmonizedData(driver, scenario, pastData, futureData, harmonization, ...) +calcHarmonizedData(driver, scenario) } \arguments{ \item{driver}{A string designating the driver. Available drivers are: @@ -18,15 +18,6 @@ calcHarmonizedData(driver, scenario, pastData, futureData, harmonization, ...) \item{scenario}{A string (or vector of strings) designating the scenario(s) to be returned. Use \code{\link[=toolGetScenarioDefinition]{toolGetScenarioDefinition()}} to learn what scenarios are available.} - -\item{pastData}{A string passed to the calc'Driver'Past function, e.g. \code{\link[=calcGDPPast]{calcGDPPast()}} or \code{\link[=calcPopulationPast]{calcPopulationPast()}}.} - -\item{futureData}{A string passed to the calc'Driver'Future function, e.g. \code{\link[=calcGDPFuture]{calcGDPFuture()}} or -\code{\link[=calcPopulationFuture]{calcPopulationFuture()}}.} - -\item{harmonization}{A string designating the harmonization function.} - -\item{...}{Arguments passed on to harmonization functions} } \value{ magpie object with the requested output data either on country or on @@ -34,14 +25,9 @@ regional level depending on the choice of argument "aggregate" or a list of info if supplementary is set to TRUE. } \description{ -Get Harmonized Data +Get harmonized data } \seealso{ -\itemize{ -\item \code{\link[=calcGDPPast]{calcGDPPast()}}, \code{\link[=calcGDPFuture]{calcGDPFuture()}}, \code{\link[=calcGDPpcPast]{calcGDPpcPast()}} and \code{\link[=calcGDPpcFuture]{calcGDPpcFuture()}} for the builiding blocks of -the GDP and GDPpc scenarios. -\item \code{\link[=calcPopulationPast]{calcPopulationPast()}}, \code{\link[=calcPopulationFuture]{calcPopulationFuture()}}, \code{\link[=calcLabourPast]{calcLabourPast()}}, \code{\link[=calcLabourFuture]{calcLabourFuture()}}, \code{\link[=calcUrbanPast]{calcUrbanPast()}} -and \code{\link[=calcUrbanFuture]{calcUrbanFuture()}} for the builiding blocks of the Population, Labor and Urban scenarios. -} +\code{\link[=calcGDPPast]{calcGDPPast()}} for the scenario builiding blocks. } \keyword{internal} diff --git a/man/calcLabourHarmonized.Rd b/man/calcLabourHarmonized.Rd deleted file mode 100644 index 8162a01..0000000 --- a/man/calcLabourHarmonized.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcLabourHarmonized.R -\name{calcLabourHarmonized} -\alias{calcLabourHarmonized} -\title{Get Harmonized Labour Data} -\usage{ -calcLabourHarmonized(harmonization, past, future, ...) -} -\arguments{ -\item{harmonization}{description} - -\item{past}{description} - -\item{future}{description} -} -\value{ -magpie object with the requested output data either on country or on -regional level depending on the choice of argument "aggregate" or a list of information -if supplementary is set to TRUE. -} -\description{ -Get Harmonized Labour Data -} -\keyword{internal} diff --git a/man/calcPastData.Rd b/man/calcPastData.Rd deleted file mode 100644 index 608c31f..0000000 --- a/man/calcPastData.Rd +++ /dev/null @@ -1,37 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcDriver.R -\name{calcPastData} -\alias{calcPastData} -\title{Get Past Data Building Block} -\usage{ -calcPastData(driver, pastData, unit) -} -\arguments{ -\item{driver}{A string designating the driver. Available drivers are: -\itemize{ -\item GDP -\item Population -\item GDPpc -\item Labour -\item Urban -}} - -\item{pastData}{A string passed to the calc'Driver'Past function, e.g. \code{\link[=calcGDPPast]{calcGDPPast()}} or \code{\link[=calcPopulationPast]{calcPopulationPast()}}.} -} -\value{ -magpie object with the requested output data either on country or on -regional level depending on the choice of argument "aggregate" or a list of information -if supplementary is set to TRUE. -} -\description{ -Get Past Data Building Block -} -\seealso{ -\itemize{ -\item \code{\link[=calcGDPPast]{calcGDPPast()}}, \code{\link[=calcGDPFuture]{calcGDPFuture()}}, \code{\link[=calcGDPpcPast]{calcGDPpcPast()}} and \code{\link[=calcGDPpcFuture]{calcGDPpcFuture()}} for the builiding blocks of -the GDP and GDPpc scenarios. -\item \code{\link[=calcPopulationPast]{calcPopulationPast()}}, \code{\link[=calcPopulationFuture]{calcPopulationFuture()}}, \code{\link[=calcLabourPast]{calcLabourPast()}}, \code{\link[=calcLabourFuture]{calcLabourFuture()}}, \code{\link[=calcUrbanPast]{calcUrbanPast()}} -and \code{\link[=calcUrbanFuture]{calcUrbanFuture()}} for the builiding blocks of the Population, Labor and Urban scenarios. -} -} -\keyword{internal} diff --git a/man/calcPopulation.Rd b/man/calcPopulation.Rd index c16f106..0309ce7 100644 --- a/man/calcPopulation.Rd +++ b/man/calcPopulation.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcPopulation.R, R/calcLabour.R, R/calcUrban.R +% Please edit documentation in R/calcPopulation.R \name{calcPopulation} \alias{calcPopulation} \alias{calcLabour} @@ -35,7 +35,6 @@ By default the following scenarios are returned: \itemize{ \item the SSPs, i.e. SSP1-5 \item the SDPs, i.e. SDP, SDP_EI, SDP_RC, and SDP_MC -\item SSP2EU } See the vignette: \code{vignette("scenarios")} for scenario options, definitions and references. @@ -45,8 +44,8 @@ See the vignette: \code{vignette("scenarios")} for scenario options, definitions # Return the default scenarios calcOutput("Population") -# Return the SSP2EU scenario -calcOutput("Population", scenario = "SSP2EU") +# Return only the SSP2 scenario +calcOutput("Population", scenario = "SSP2") # Return the ISIMIP SSP scenarios calcOutput("Population", scenario = "ISIMIP", extension2150 = "none", aggregate = FALSE) diff --git a/man/calcPopulationHarmonized.Rd b/man/calcPopulationHarmonized.Rd deleted file mode 100644 index 18dd1f2..0000000 --- a/man/calcPopulationHarmonized.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcPopulationHarmonized.R -\name{calcPopulationHarmonized} -\alias{calcPopulationHarmonized} -\title{Get Harmonized Population Data} -\usage{ -calcPopulationHarmonized(harmonization, past, future, yEnd, ...) -} -\arguments{ -\item{harmonization}{description} - -\item{past}{description} - -\item{future}{description} -} -\value{ -magpie object with the requested output data either on country or on -regional level depending on the choice of argument "aggregate" or a list of information -if supplementary is set to TRUE. -} -\description{ -Get Harmonized Population Data -} -\keyword{internal} diff --git a/man/calcPopulationPast.Rd b/man/calcPopulationPast.Rd deleted file mode 100644 index e36a379..0000000 --- a/man/calcPopulationPast.Rd +++ /dev/null @@ -1,81 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcLabourFuture.R, R/calcLabourPast.R, -% R/calcPopulationFuture.R, R/calcPopulationPast.R, R/calcUrbanFuture.R, -% R/calcUrbanPast.R -\name{calcLabourFuture} -\alias{calcLabourFuture} -\alias{calcLabourPast} -\alias{calcPopulationFuture} -\alias{calcPopulationPast} -\alias{calcUrbanFuture} -\alias{calcUrbanPast} -\title{Get Population and Labour scenario building blocks} -\usage{ -calcLabourFuture(LabourFuture = "SSPs") - -calcLabourPast(LabourPast = "WDI") - -calcPopulationFuture(PopulationFuture = "SSPs-UN_PopDiv-MI") - -calcPopulationPast(PopulationPast = "WDI-UN_PopDiv-MI") - -calcUrbanFuture(UrbanFuture = "SSPs") - -calcUrbanPast(UrbanPast = "WDI") -} -\arguments{ -\item{LabourFuture}{A string designating the source for the future working-age population data. -Available sources are: -\itemize{ -\item "SSPs": -}} - -\item{LabourPast}{A string designating the source for the historical working-age population data. -Available sources are: -\itemize{ -\item "WDI": World development indicators from the World Bank -}} - -\item{PopulationFuture}{A string designating the source for the future population data. -Available sources are: -\itemize{ -\item "SSPs": From the Wittgenstein Center \href{http://pure.iiasa.ac.at/id/eprint/17550/}{here} and -\href{http://pure.iiasa.ac.at/id/eprint/16710/}{here} -\item "SSP2EU": Combined SSP2 and Eurostat (for the EU countries) source -\item "SDPs": -\item "UN_PopDiv": United Nations -\item "MI": Missing island dataset -}} - -\item{PopulationPast}{A string designating the source for the historical population data. -Available sources are: -\itemize{ -\item "WDI": World development indicators from the World Bank -\item "UN_PopDiv": United Nations -\item "MI": Missing island dataset -\item "Eurostat": Eurostat -}} - -\item{UrbanFuture}{A string designating the source for the future urban population-share data. -Available sources are: -\itemize{ -\item "SSPs": -\item "SDPs": -\item "SSP2EU": -}} - -\item{UrbanPast}{A string designating the source for the historical urban population-share data. -Available sources are: -\itemize{ -\item "WDI": World development indicators from the World Bank -}} -} -\description{ -See the "Combining data sources with '-'" section below for how to combine data sources. -} -\section{Combining data sources with "-"}{ -Data sources can be combined with "-" and passed to both the pastData and futureData arguments, i.e. "WDI-MI". This -signifies that WDI data will be taken first, but missing data will be then be filled in with data from MI. -} - -\keyword{internal} diff --git a/man/calcRatioPPP2MER.Rd b/man/calcRatioPPP2MER.Rd index e5dd8c8..3b19ac6 100644 --- a/man/calcRatioPPP2MER.Rd +++ b/man/calcRatioPPP2MER.Rd @@ -16,7 +16,8 @@ if supplementary is set to TRUE. } \description{ Get a conversion factor to convert GDP in constant 2017 Int$PPP into constant 2017 US$MER. -Use the when argument to switch the year of the conversion factor. Source = WDI. +Use the "when" argument to switch the year of the conversion factor. Source = WDI. Countries with missing data are +filled in with 1. Regional aggregation is weighed by GDP from WDI-MI in the year set by "when". } \examples{ \dontrun{ diff --git a/man/calcScenarioConstructor.Rd b/man/calcScenarioConstructor.Rd index 4f9dbc0..6f669dc 100644 --- a/man/calcScenarioConstructor.Rd +++ b/man/calcScenarioConstructor.Rd @@ -2,19 +2,9 @@ % Please edit documentation in R/calcDriver.R \name{calcScenarioConstructor} \alias{calcScenarioConstructor} -\title{ScenarioConstructor} +\title{Scenario construction} \usage{ -calcScenarioConstructor( - driver, - scenario, - pastData, - futureData, - harmonization, - extension2150, - naming, - popAsWeight, - ... -) +calcScenarioConstructor(driver, scenario, popAsWeight, naming, extension2150) } \arguments{ \item{driver}{A string designating the driver. Available drivers are: @@ -29,12 +19,16 @@ calcScenarioConstructor( \item{scenario}{A string (or vector of strings) designating the scenario(s) to be returned. Use \code{\link[=toolGetScenarioDefinition]{toolGetScenarioDefinition()}} to learn what scenarios are available.} -\item{pastData}{A string passed to the calc'Driver'Past function, e.g. \code{\link[=calcGDPPast]{calcGDPPast()}} or \code{\link[=calcPopulationPast]{calcPopulationPast()}}.} - -\item{futureData}{A string passed to the calc'Driver'Future function, e.g. \code{\link[=calcGDPFuture]{calcGDPFuture()}} or -\code{\link[=calcPopulationFuture]{calcPopulationFuture()}}.} +\item{popAsWeight}{If TRUE, then population data of the same scenario is used as weight.} -\item{harmonization}{A string designating the harmonization function.} +\item{naming}{A string giving the naming scheme of the data dimension. Can be either: +\itemize{ +\item "indicator_scenario" (default): Returns names of the type "gdp_SSP2", or "pop_SSP2". +\item "indicator.scenario": (deprecated) Returns names of the type "gdp.SSP2", or "pop.SSP2". +\item "scenario": Returns names of the type "SSP2". +} +Set naming to "scenario" when you want to operate on SSP2 gdp and population data for instance, and not have to +worry about the conflicting names.} \item{extension2150}{A string specifying if/how the scenarios should be extended until 2150. Can be either: \itemize{ @@ -44,19 +38,6 @@ their last year. \item "constant": The last value of the scenarios is taken as constant until 2150. \item "none": No extension. }} - -\item{naming}{A string giving the naming scheme of the data dimension. Can be either: -\itemize{ -\item "indicator_scenario" (default): Returns names of the type "gdp_SSP2", or "pop_SSP2". -\item "indicator.scenario": Returns names of the type "gdp.SSP2", or "pop.SSP2". -\item "scenario": Returns names of the type "SSP2". -} -Set naming to "scenario" when you want to operate on SSP2 gdp and population data for instance, and not have to -worry about the conflicting names.} - -\item{popAsWeight}{If TRUE, then population data of the same scenario is used as weight.} - -\item{...}{Arguments passed on to the 'driver'Past, 'driver'Future and driver'Harmonization' functions.} } \value{ magpie object with the requested output data either on country or on @@ -64,7 +45,7 @@ regional level depending on the choice of argument "aggregate" or a list of info if supplementary is set to TRUE. } \description{ -ScenarioConstructor +Scenario construction } \section{Combining data sources with "-"}{ Data sources can be combined with "-" and passed to both the pastData and futureData arguments, i.e. "WDI-MI". This @@ -72,11 +53,6 @@ signifies that WDI data will be taken first, but missing data will be then be fi } \seealso{ -\itemize{ -\item \code{\link[=calcGDPPast]{calcGDPPast()}}, \code{\link[=calcGDPFuture]{calcGDPFuture()}}, \code{\link[=calcGDPpcPast]{calcGDPpcPast()}} and \code{\link[=calcGDPpcFuture]{calcGDPpcFuture()}} for the builiding blocks of -the GDP and GDPpc scenarios. -\item \code{\link[=calcPopulationPast]{calcPopulationPast()}}, \code{\link[=calcPopulationFuture]{calcPopulationFuture()}}, \code{\link[=calcLabourPast]{calcLabourPast()}}, \code{\link[=calcLabourFuture]{calcLabourFuture()}}, \code{\link[=calcUrbanPast]{calcUrbanPast()}} -and \code{\link[=calcUrbanFuture]{calcUrbanFuture()}} for the builiding blocks of the Population, Labor and Urban scenarios. -} +\code{\link[=calcGDPPast]{calcGDPPast()}} for the scenario builiding blocks. } \keyword{internal} diff --git a/man/calcUrbanHarmonized.Rd b/man/calcUrbanHarmonized.Rd deleted file mode 100644 index 438fcb0..0000000 --- a/man/calcUrbanHarmonized.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/calcUrbanHarmonized.R -\name{calcUrbanHarmonized} -\alias{calcUrbanHarmonized} -\title{Get Harmonized Urban Data} -\usage{ -calcUrbanHarmonized(harmonization, past, future, ...) -} -\arguments{ -\item{harmonization}{description} - -\item{past}{description} - -\item{future}{description} -} -\value{ -magpie object with the requested output data either on country or on -regional level depending on the choice of argument "aggregate" or a list of information -if supplementary is set to TRUE. -} -\description{ -Get Harmonized Urban Data -} -\keyword{internal} diff --git a/man/compare_proxy.magpie.Rd b/man/compare_proxy.magpie.Rd new file mode 100644 index 0000000..eec71a2 --- /dev/null +++ b/man/compare_proxy.magpie.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolCompareProxyMagpie.R +\name{compare_proxy.magpie} +\alias{compare_proxy.magpie} +\title{Magpie proxy for waldo::compare} +\usage{ +compare_proxy.magpie(x, path = "x") +} +\arguments{ +\item{x}{x} + +\item{path}{"x"} +} +\value{ +list +} +\description{ +Magpie proxy for waldo::compare +} +\keyword{internal} diff --git a/man/mrdrivers-package.Rd b/man/mrdrivers-package.Rd index d9585a4..96da7ea 100644 --- a/man/mrdrivers-package.Rd +++ b/man/mrdrivers-package.Rd @@ -6,8 +6,6 @@ \alias{mrdrivers} \title{MadRat drivers Input Data Library} \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#stable}{\figure{lifecycle-stable.svg}{options: alt='[Stable]'}}}{\strong{[Stable]}} - Create scenarios of GDP, Population, GDP per capita, and Urban population share } \seealso{ diff --git a/man/readADB.Rd b/man/readADB.Rd new file mode 100644 index 0000000..f9ce243 --- /dev/null +++ b/man/readADB.Rd @@ -0,0 +1,36 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/readADB.R +\name{readADB} +\alias{readADB} +\alias{convertADB} +\alias{downloadADB} +\title{Read ADB data} +\usage{ +readADB() + +convertADB(x, subtype = "all") + +downloadADB() +} +\arguments{ +\item{x}{MAgPIE object returned from readADB} + +\item{subtype}{A string, either "all", "gdppc", "pop"} +} +\value{ +The read-in data, usually a magpie object. If supplementary is TRUE a list including +the data and metadata is returned instead. The temporal and data dimensionality +should match the source data. The spatial dimension should either match the source data or, +if the convert argument is set to TRUE, should be on ISO code country level. +} +\description{ +Read-in an ADB data as magclass object +} +\examples{ +\dontrun{ +readSource("ADB", subtype = "gdppc") +} +} +\seealso{ +\code{\link[madrat:readSource]{madrat::readSource()}} +} diff --git a/man/readEurostatPopGDP.Rd b/man/readEurostatPopGDP.Rd deleted file mode 100644 index 3259bf8..0000000 --- a/man/readEurostatPopGDP.Rd +++ /dev/null @@ -1,43 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/readEurostatPopGDP.R -\name{downloadEurostatPopGDP} -\alias{downloadEurostatPopGDP} -\alias{readEurostatPopGDP} -\alias{convertEurostatPopGDP} -\title{Read Eurostat Population and GDP data} -\usage{ -downloadEurostatPopGDP(subtype) - -readEurostatPopGDP(subtype) - -convertEurostatPopGDP(x, subtype) -} -\arguments{ -\item{subtype}{A string. Available subtypes are: -\itemize{ -\item "population": Population, ref demo_gind -\item "population_projections": Population projections, ref proj_19np -\item "GDP": GDP, ref nama_10_gdp -\item "GDPgr_projections_short": Projected GDP growth rates, 2023 forecast. -\item "GDPgr_projections_long": -}} - -\item{x}{MAgPIE object returned by readEurostatPopGDP} -} -\value{ -The read-in data, usually a magpie object. If supplementary is TRUE a list including -the data and metadata is returned instead. The temporal and data dimensionality -should match the source data. The spatial dimension should either match the source data or, -if the convert argument is set to TRUE, should be on ISO code country level. -} -\description{ -Download, read and convert Eurostat population and GDP data. -} -\examples{ -\dontrun{ -readSource("EurostatPopGDP", subtype = "population") -} -} -\seealso{ -\code{\link[madrat:readSource]{madrat::readSource()}} and \code{\link[madrat:downloadSource]{madrat::downloadSource()}} -} diff --git a/man/readJames.Rd b/man/readJames.Rd index ea183ad..e282c90 100644 --- a/man/readJames.Rd +++ b/man/readJames.Rd @@ -1,10 +1,13 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/readJames.R -\name{readJames} +\name{downloadJames} +\alias{downloadJames} \alias{readJames} \alias{convertJames} -\title{Read James} +\title{Read James et al. (2012) dataset} \usage{ +downloadJames() + readJames(subtype) convertJames(x, subtype) @@ -15,27 +18,25 @@ convertJames(x, subtype) \item{x}{MAgPIE object returned by readJames} } \value{ -GDP per capita in USD05 in PPP or MER as magpie object +The read-in data, usually a magpie object. If supplementary is TRUE a list including +the data and metadata is returned instead. The temporal and data dimensionality +should match the source data. The spatial dimension should either match the source data or, +if the convert argument is set to TRUE, should be on ISO code country level. } \description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - Read-in GDP per-capita data from the publication James, Spencer L., Paul Gubbins, Christopher JL Murray, and Emmanuela Gakidou. 2012. "Developing a Comprehensive Time Series of GDP per Capita for 210 Countries from 1950 to 2015." Population Health Metrics 10 (1): 12. doi:10.1186/1478-7954-10-12. -from a .csv file to a magclass object } -\section{Functions}{ -\itemize{ -\item \code{convertJames()}: convert function - -}} +\details{ +The data is in Annex 3 +} \examples{ \dontrun{ -readSource("James", subtype = "IHME_USD05_PPP_pc")} +readSource("James", subtype = "gdp") +} } \seealso{ -\code{\link[madrat:readSource]{madrat::readSource()}} +\code{\link[madrat:readSource]{madrat::readSource()}} and \code{\link[madrat:downloadSource]{madrat::downloadSource()}} } -\keyword{internal} diff --git a/man/readJames2019.Rd b/man/readJames2019.Rd deleted file mode 100644 index d5401e9..0000000 --- a/man/readJames2019.Rd +++ /dev/null @@ -1,43 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/readJames2019.R -\name{readJames2019} -\alias{readJames2019} -\alias{convertJames2019} -\title{Read James 2019 updated dataset} -\usage{ -readJames2019(subtype) - -convertJames2019(x, subtype) -} -\arguments{ -\item{subtype}{String indicating the data series} - -\item{x}{MAgPIE object returned by readJames2019} -} -\value{ -GDP per capita in USD05 in PPP or MER as magpie object -} -\description{ -Read-in GDP per-capita data from the publication James, Spencer L., Paul -Gubbins, Christopher JL Murray, and Emmanuela Gakidou. 2012. "Developing a -Comprehensive Time Series of GDP per Capita for 210 Countries from 1950 to -2015." Population Health Metrics 10 (1): 12. doi:10.1186/1478-7954-10-12. -from a .csv file to a magclass object -} -\details{ -2019 dataset from personal communication w/ B Bodirsky -} -\section{Functions}{ -\itemize{ -\item \code{convertJames2019()}: convert function - -}} -\examples{ -\dontrun{ -readSource("James2019", subtype = "IHME_USD05_PPP_pc") -} - -} -\seealso{ -\code{\link[madrat:readSource]{madrat::readSource()}} and \code{\link[madrat:downloadSource]{madrat::downloadSource()}} -} diff --git a/man/readMissingIslands.Rd b/man/readMissingIslands.Rd index 9e25196..5c1f3c5 100644 --- a/man/readMissingIslands.Rd +++ b/man/readMissingIslands.Rd @@ -10,7 +10,7 @@ downloadMissingIslands() readMissingIslands(subtype) -convertMissingIslands(x) +convertMissingIslands(x, subtype) } \arguments{ \item{subtype}{pop for population, or gdp for gdp} @@ -29,7 +29,7 @@ data set that gets data from a variety of sources (e.g. CIA World Factbook, Inse } \examples{ \dontrun{ -readSource("MissingIslands", subtype = "pop", convert = FALSE) +readSource("MissingIslands", subtype = "pop") } } \seealso{ diff --git a/man/readSSP.Rd b/man/readSSP.Rd index 96fcd7f..a3316a5 100644 --- a/man/readSSP.Rd +++ b/man/readSSP.Rd @@ -2,20 +2,27 @@ % Please edit documentation in R/readSSP.R \name{readSSP} \alias{readSSP} -\alias{downloadSSP} \alias{convertSSP} +\alias{downloadSSP} \title{Read SSP} \usage{ readSSP() -downloadSSP() +convertSSP( + x, + subtype = "all", + subset = c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5") +) -convertSSP(x, subtype = "all") +downloadSSP() } \arguments{ \item{x}{MAgPIE object returned from readSSP} \item{subtype}{A string, either "all", "gdp", "pop", "lab", "urb"} + +\item{subset}{A vector of strings designating the scenarios. Defaults to c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5"). +"Historical Reference" is also available as a scenario.} } \value{ The read-in data, usually a magpie object. If supplementary is TRUE a list including @@ -24,7 +31,8 @@ should match the source data. The spatial dimension should either match the sour if the convert argument is set to TRUE, should be on ISO code country level. } \description{ -Read-in an SSP data as magclass object +Read-in an SSP data as magclass object. Filter for subtype and subset in the convert Function to use common read +cache (speeds up the compuations). } \examples{ \dontrun{ diff --git a/man/readUN_PopDiv.Rd b/man/readUN_PopDiv.Rd index dbf6bfc..825b5b9 100644 --- a/man/readUN_PopDiv.Rd +++ b/man/readUN_PopDiv.Rd @@ -8,12 +8,14 @@ \usage{ downloadUN_PopDiv() -readUN_PopDiv(subtype = "estimates") +readUN_PopDiv(subtype, subset = "estimates") convertUN_PopDiv(x) } \arguments{ -\item{subtype}{String indicating version and sheet} +\item{subtype}{Either "pop" or "lab".} + +\item{subset}{Either "estimates" or "medium".} \item{x}{MAgPIE object returned from readUN_PopDiv} } @@ -24,7 +26,7 @@ should match the source data. The spatial dimension should either match the sour if the convert argument is set to TRUE, should be on ISO code country level. } \description{ -Read past UN population data. +Read UN population data. } \seealso{ \code{\link[madrat:readSource]{madrat::readSource()}} and \code{\link[madrat:downloadSource]{madrat::downloadSource()}} diff --git a/man/readWDI.Rd b/man/readWDI.Rd index 8ec5325..f92bd6f 100644 --- a/man/readWDI.Rd +++ b/man/readWDI.Rd @@ -16,13 +16,13 @@ convertWDI(x, subtype) \item{subtype}{A string. Type of WDI data that should be read. Use the World Bank indicator abbreviation. Available subtypes are: \itemize{ -\item \code{"SP.POP.TOTL"}: Population, total -\item \code{"SP.POP.1564.TO"}: Working age population (15-64 years old) -\item \code{"SP.URB.TOTL.IN.ZS"}: Urban Population (\% of total) -\item \code{"NY.GDP.MKTP.PP.KD"}: GDP,PPP (constant 2017 international Dollar) -\item \code{"NV.AGR.TOTL.KD"}: Ag GDP, MER, (2010 US$) -\item \code{"PA.NUS.PPPC.RF"}: Price level ratio of PPP conversion factor (GDP) to market exchange rate -\item \code{"AG.SRF.TOTL.K2"}: Surface area (in square kms) +\item "pop" or "SP.POP.TOTL": Population, total +\item "lab" or "SP.POP.1564.TO": Working age population (15-64 years old) +\item "urb" or "SP.URB.TOTL.IN.ZS": Urban Population (\% of total) +\item "gdp" or "NY.GDP.MKTP.PP.KD": GDP, PPP (constant 2017 international Dollar) +\item "NV.AGR.TOTL.KD": Ag GDP, MER, (2010 US$) +\item "PA.NUS.PPPC.RF": Price level ratio of PPP conversion factor (GDP) to market exchange rate +\item "AG.SRF.TOTL.K2": Surface area (in square kms) }} \item{x}{MAgPIE object returned by readWDI} @@ -43,7 +43,7 @@ the past data isn't changed between users. } \examples{ \dontrun{ -readSource("WDI", subtype = "SP.POP.TOTL") +readSource("WDI", subtype = "pop") } } \seealso{ diff --git a/man/toolCheckUserInput.Rd b/man/toolCheckUserInput.Rd new file mode 100644 index 0000000..bdd8f8b --- /dev/null +++ b/man/toolCheckUserInput.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolCheckUserInput.R +\name{toolCheckUserInput} +\alias{toolCheckUserInput} +\title{Check user input} +\usage{ +toolCheckUserInput(driver, args) +} +\arguments{ +\item{driver}{A string designating the driver. Available drivers are: +\itemize{ +\item GDP +\item Population +\item GDPpc +\item Labour +\item Urban +}} + +\item{args}{A list with all the arguments passed to the parent function} +} +\value{ +TRUE +} +\description{ +toolCheckUserInput checks the user input. +} +\keyword{internal} diff --git a/man/toolExtend2150.Rd b/man/toolExtend2150.Rd new file mode 100644 index 0000000..bb072fb --- /dev/null +++ b/man/toolExtend2150.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolExtend2150.R +\name{toolExtend2150} +\alias{toolExtend2150} +\title{Extend until 2150 in 5 year time steps} +\usage{ +toolExtend2150(data, extension2150) +} +\arguments{ +\item{data}{A list with "x", a magpie object, and "description" elements} + +\item{extension2150}{A string specifying if/how the scenarios should be extended until 2150. Can be either: +\itemize{ +\item "bezier" (default): A bezier curve extension that leads to a smooth flattening of the scenario: the +slope in the last year of the scenario is halved by 2150. Currently only works for scenarios with 2100 as +their last year. +\item "constant": The last value of the scenarios is taken as constant until 2150. +\item "none": No extension. +}} +} +\value{ +The modified data list. +} +\description{ +toolExtend2150 extends a magpit object until 2150 in 5 year time steps. Either with bezierExtension or constant. +} +\keyword{internal} diff --git a/man/toolFillWith.Rd b/man/toolFillWith.Rd new file mode 100644 index 0000000..ed164ae --- /dev/null +++ b/man/toolFillWith.Rd @@ -0,0 +1,21 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolFillWith.R +\name{toolFillWith} +\alias{toolFillWith} +\title{toolFillWith} +\usage{ +toolFillWith(data, fill, dataName = "data", fillName = "fill", verbose = FALSE) +} +\arguments{ +\item{data}{magpie object to fill} + +\item{fill}{magpie object to fill data with} +} +\value{ +The completed magpie object +} +\description{ +Fill in countries in "data" with no values, with values from "fill". Only countries with no data at all get filled +in! +} +\keyword{internal} diff --git a/man/toolGeneralConvert.Rd b/man/toolGeneralConvert.Rd index 64dd644..1e079cb 100644 --- a/man/toolGeneralConvert.Rd +++ b/man/toolGeneralConvert.Rd @@ -40,9 +40,14 @@ A magpie object. The most important and common "convert" operations are: \itemize{ \item removing undefined countries, -\item using default set names "iso3c", "year", and "variable", \item substituting NAs, see the "substituteNAsWith" argument, +\item using default set names "iso3c", "year", and "variable", \item fill in countries, \item sort in chronological order. } } +\examples{ +\dontrun{ +toolGeneralConvert(x) +} +} diff --git a/man/toolGetScenarioDefinition.Rd b/man/toolGetScenarioDefinition.Rd index a623b6e..cefab15 100644 --- a/man/toolGetScenarioDefinition.Rd +++ b/man/toolGetScenarioDefinition.Rd @@ -33,7 +33,7 @@ are constructed, i.e. what past data, future data and harmonization methods are \examples{ toolGetScenarioDefinition() toolGetScenarioDefinition(driver = "GDP") -toolGetScenarioDefinition(scen = "SSP2EU") +toolGetScenarioDefinition(scen = "SSP2") toolGetScenarioDefinition(driver = "Population", scen = "SSPs", aslist = TRUE) } diff --git a/man/toolGetUnitDollar.Rd b/man/toolGetUnitDollar.Rd index b050b3b..2936eae 100644 --- a/man/toolGetUnitDollar.Rd +++ b/man/toolGetUnitDollar.Rd @@ -12,7 +12,7 @@ toolGetUnitDollar(returnOnlyBase = FALSE, inPPP = FALSE) \item{inPPP}{TRUE or FALSE (default). If TRUE the the string ends in 'Int$PPP', instead of 'Int$MER'.} } \value{ -A string with the monetary unit: 'constant 2017 US$MER'. +A string with the monetary unit: constant 2017 US$MER. } \description{ toolGetUnitDollar returns unit used for monetary values. diff --git a/man/toolHarmonizeFuture.Rd b/man/toolHarmonizeFuture.Rd new file mode 100644 index 0000000..9a53946 --- /dev/null +++ b/man/toolHarmonizeFuture.Rd @@ -0,0 +1,41 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolHarmonizeFuture.R +\name{toolHarmonizeFuture} +\alias{toolHarmonizeFuture} +\title{Harmonization tool Future} +\usage{ +toolHarmonizeFuture(past, future, method = "level") +} +\arguments{ +\item{past}{A magpie object.} + +\item{future}{A magpie object with only one scenario/datatype, i.e. the length of the third dimension should be 1.} + +\item{method}{A string defining the harmonization method: +\itemize{ +\item "level": the harmonized time-series is exactly equal to 'past' in the years before the first year +of 'future'. +\item "growth": the harmonized time-series follows the same growth rates as 'past', in the years +before the first year of 'future'. +}} +} +\value{ +A magpie object with the same dimensions as 'past'. +} +\description{ +Like all harmonization tools in mrdrivers, toolHarmonizeFuture takes two magpie objects, 'past' and 'future', +and returns a single magpie object, i.e. the harmonized time-series. In this case, the harmonized time-series is +always equal to 'future', in the years of 'future'. After that the harmonized time-series depends on the 'method' +argument chosen. +} +\section{Dimensions of 'past' and 'future'}{ +If the 'past' object has multiple scenarios/datatypes, i.e. the length of the third dimension is larger than 1, +then the a harmonized time-series is created for every scenario/datatype in past. The same 'future' object is used +in every case - hence the requirement that 'future' only have one scenario/datatype. +} + +\examples{ +\dontrun{ +toolHarmonizePast(past, future) +} +} diff --git a/man/toolHarmonizePast.Rd b/man/toolHarmonizePast.Rd index 7fc1238..83a371f 100644 --- a/man/toolHarmonizePast.Rd +++ b/man/toolHarmonizePast.Rd @@ -40,3 +40,8 @@ then the a harmonized time-series is created for every scenario/datatype in futu in every case - hence the requirement that 'past' only have one scenario/datatype. } +\examples{ +\dontrun{ +toolHarmonizePast(past, future) +} +} diff --git a/man/toolInterpolateAndExtrapolate.Rd b/man/toolInterpolateAndExtrapolate.Rd new file mode 100644 index 0000000..73a40d6 --- /dev/null +++ b/man/toolInterpolateAndExtrapolate.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolInterpolateAndExtrapolate.R +\name{toolInterpolateAndExtrapolate} +\alias{toolInterpolateAndExtrapolate} +\title{toolInterpolateAndExtrapolate} +\usage{ +toolInterpolateAndExtrapolate(data, extrapolate = TRUE) +} +\arguments{ +\item{data}{A magpie object} + +\item{extrapolate}{TRUE or FALSE} +} +\value{ +list +} +\description{ +Fill in years of partially missing countries through inter- and extrapolation. +} +\keyword{internal} diff --git a/man/toolListFillWith.Rd b/man/toolListFillWith.Rd new file mode 100644 index 0000000..771c102 --- /dev/null +++ b/man/toolListFillWith.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/toolFillWith.R +\name{toolListFillWith} +\alias{toolListFillWith} +\title{toolListFillWith} +\usage{ +toolListFillWith(x) +} +\arguments{ +\item{x}{list of objects returned by caclOutput(..., supplementary = TRUE)} +} +\value{ +The completed magpie object +} +\description{ +Reduce list by filling the magpie objects with the following element of the list. +} +\keyword{internal} diff --git a/tests/testthat.R b/tests/testthat.R index d95ee47..38c3dd4 100644 --- a/tests/testthat.R +++ b/tests/testthat.R @@ -1,4 +1,4 @@ -library(testthat) -library(mrdrivers) +library(testthat) # nolint +library(mrdrivers) # nolint test_check("mrdrivers") diff --git a/tests/testthat/setup-madrat_config.R b/tests/testthat/setup-madrat_config.R index b77b936..dc7e247 100644 --- a/tests/testthat/setup-madrat_config.R +++ b/tests/testthat/setup-madrat_config.R @@ -11,5 +11,5 @@ madrat_mainfolder <- "/home/johannes/madrat_GDP_update" # nolint if (dir.exists(madrat_mainfolder)) { oldCfg <- madrat::getConfig() madrat::setConfig(mainfolder = madrat_mainfolder, cachefolder = "test_mrdrivers", .verbose = FALSE) - withr::defer(options(madrat_cfg = oldCfg), teardown_env()) + withr::defer(options(madrat_cfg = oldCfg), teardown_env()) # nolint } diff --git a/tests/testthat/test-calcOutput_sets.R b/tests/testthat/test-calcOutput_sets.R index 179f404..22d04c2 100644 --- a/tests/testthat/test-calcOutput_sets.R +++ b/tests/testthat/test-calcOutput_sets.R @@ -24,65 +24,71 @@ test_that("set names", { expectCorrectSetNames(calcOutput("Urban", extension2150 = "none")) expectCorrectSetNames(calcOutput("Labour", extension2150 = "none")) expectCorrectSetNames(calcOutput("GDPPast")) - expectCorrectSetNames(calcOutput("GDPFuture", GDPFuture = "SSPs", unit = "constant 2017 Int$PPP")) + expectCorrectSetNames(calcOutput("GDPFuture", futureData = "SSPs")) expectCorrectSetNames(calcOutput("GDPpcPast")) - expectCorrectSetNames(calcOutput("GDPpcFuture", GDPpcFuture = "SSPs", unit = "constant 2017 Int$PPP")) + expectCorrectSetNames(calcOutput("GDPpcFuture")) expectCorrectSetNames(calcOutput("GDP", extension2150 = "none")) expectCorrectSetNames(calcOutput("GDPpc", extension2150 = "none")) - # I want to keep; expectCorrectSetNames(calcOutput("RatioPPP2MER")) + expectCorrectSetNames(calcOutput("RatioPPP2MER")) }) # Save all calcOutputs for later use -calcs <- list("PopulationPast" = calcOutput("PopulationPast"), - "PopulationFuture" = calcOutput("PopulationFuture"), - "Population" = calcOutput("Population", extension2150 = "none"), - "UrbanPast" = calcOutput("UrbanPast"), - "UrbanFuture" = calcOutput("UrbanFuture"), - "Urban" = calcOutput("Urban", extension2150 = "none"), - "GDPpcPast" = calcOutput("GDPpcPast"), - "GDPpcFuture" = calcOutput("GDPpcFuture", GDPpcFuture = "SSPs", unit = "constant 2017 Int$PPP"), - "GDPpc" = calcOutput("GDPpc", extension2150 = "none"), - "GDPPast" = calcOutput("GDPPast"), - "GDPFuture" = calcOutput("GDPFuture", GDPFuture = "SSPs", unit = "constant 2017 Int$PPP"), - "GDP" = calcOutput("GDP", extension2150 = "none"), - "Labour" = calcOutput("Labour", extension2150 = "none")) - -calcs2 <- list("PopulationPast" = calcOutput("PopulationPast", aggregate = FALSE), - "PopulationFuture" = calcOutput("PopulationFuture", aggregate = FALSE), - "Population" = calcOutput("Population", extension2150 = "none", aggregate = FALSE), - "UrbanPast" = calcOutput("UrbanPast", aggregate = FALSE), - "UrbanFuture" = calcOutput("UrbanFuture", aggregate = FALSE), - "Urban" = calcOutput("Urban", extension2150 = "none", aggregate = FALSE), - "GDPpcPast" = calcOutput("GDPpcPast", aggregate = FALSE), - "GDPpcFuture" = calcOutput("GDPpcFuture", GDPpcFuture = "SSPs", unit = "constant 2017 Int$PPP", aggregate = FALSE), - "GDPpc" = calcOutput("GDPpc", extension2150 = "none", aggregate = FALSE), - "GDPPast" = calcOutput("GDPPast", aggregate = FALSE), - "GDPFuture" = calcOutput("GDPFuture", GDPFuture = "SSPs", unit = "constant 2017 Int$PPP", aggregate = FALSE), - "GDP" = calcOutput("GDP", extension2150 = "none", aggregate = FALSE), - "Labour" = calcOutput("Labour", extension2150 = "none", aggregate = FALSE)) - -calcs3 <- list("PopulationPast" = calcOutput("PopulationPast", supplementary = TRUE), - "PopulationFuture" = calcOutput("PopulationFuture", supplementary = TRUE), - "Population" = calcOutput("Population", extension2150 = "none", supplementary = TRUE), - "UrbanPast" = calcOutput("UrbanPast", supplementary = TRUE), - "UrbanFuture" = calcOutput("UrbanFuture", supplementary = TRUE), - "Urban" = calcOutput("Urban", extension2150 = "none", supplementary = TRUE), - "GDPpcPast" = calcOutput("GDPpcPast", supplementary = TRUE), - "GDPpcFuture" = calcOutput("GDPpcFuture", GDPpcFuture = "SSPs", unit = "constant 2017 Int$PPP", supplementary = TRUE), - "GDPpc" = calcOutput("GDPpc", extension2150 = "none", supplementary = TRUE), - "GDPPast" = calcOutput("GDPPast", supplementary = TRUE), - "GDPFuture" = calcOutput("GDPFuture", GDPFuture = "SSPs", unit = "constant 2017 Int$PPP", supplementary = TRUE), - "GDP" = calcOutput("GDP", extension2150 = "none", supplementary = TRUE), - "Labour" = calcOutput("Labour", extension2150 = "none", supplementary = TRUE)) +calcs <- list( + "PopulationPast" = calcOutput("PopulationPast"), + "PopulationFuture" = calcOutput("PopulationFuture"), + "Population" = calcOutput("Population", extension2150 = "none"), + "UrbanPast" = calcOutput("UrbanPast"), + "UrbanFuture" = calcOutput("UrbanFuture"), + "Urban" = calcOutput("Urban", extension2150 = "none"), + "GDPpcPast" = calcOutput("GDPpcPast"), + "GDPpcFuture" = calcOutput("GDPpcFuture"), + "GDPpc" = calcOutput("GDPpc", extension2150 = "none"), + "GDPPast" = calcOutput("GDPPast"), + "GDPFuture" = calcOutput("GDPFuture", futureData = "SSPs"), + "GDP" = calcOutput("GDP", extension2150 = "none"), + "Labour" = calcOutput("Labour", extension2150 = "none") +) + +calcs2 <- list( + "PopulationPast" = calcOutput("PopulationPast", aggregate = FALSE), + "PopulationFuture" = calcOutput("PopulationFuture", aggregate = FALSE), + "Population" = calcOutput("Population", extension2150 = "none", aggregate = FALSE), + "UrbanPast" = calcOutput("UrbanPast", aggregate = FALSE), + "UrbanFuture" = calcOutput("UrbanFuture", aggregate = FALSE), + "Urban" = calcOutput("Urban", extension2150 = "none", aggregate = FALSE), + "GDPpcPast" = calcOutput("GDPpcPast", aggregate = FALSE), + "GDPpcFuture" = calcOutput("GDPpcFuture", aggregate = FALSE), + "GDPpc" = calcOutput("GDPpc", extension2150 = "none", aggregate = FALSE), + "GDPPast" = calcOutput("GDPPast", aggregate = FALSE), + "GDPFuture" = calcOutput("GDPFuture", aggregate = FALSE), + "GDP" = calcOutput("GDP", extension2150 = "none", aggregate = FALSE), + "Labour" = calcOutput("Labour", extension2150 = "none", aggregate = FALSE) +) + +calcs3 <- list( + "PopulationPast" = calcOutput("PopulationPast", supplementary = TRUE), + "PopulationFuture" = calcOutput("PopulationFuture", supplementary = TRUE), + "Population" = calcOutput("Population", extension2150 = "none", supplementary = TRUE), + "UrbanPast" = calcOutput("UrbanPast", supplementary = TRUE), + "UrbanFuture" = calcOutput("UrbanFuture", supplementary = TRUE), + "Urban" = calcOutput("Urban", extension2150 = "none", supplementary = TRUE), + "GDPpcPast" = calcOutput("GDPpcPast", supplementary = TRUE), + "GDPpcFuture" = calcOutput("GDPpcFuture", supplementary = TRUE), + "GDPpc" = calcOutput("GDPpc", extension2150 = "none", supplementary = TRUE), + "GDPPast" = calcOutput("GDPPast", supplementary = TRUE), + "GDPFuture" = calcOutput("GDPFuture", supplementary = TRUE), + "GDP" = calcOutput("GDP", extension2150 = "none", supplementary = TRUE), + "Labour" = calcOutput("Labour", extension2150 = "none", supplementary = TRUE) +) test_that("variable names", { expectCorrectVariableNames <- function(x, y) { correctNames <- paste0(y, "_", - c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5", - "SDP", "SDP_EI", "SDP_MC", "SDP_RC", "SSP2EU")) + c("SSP1", "SSP2", "SSP3", "SSP4", "SSP5", + "SDP", "SDP_EI", "SDP_MC", "SDP_RC", "SSP2EU")) expect_equal(getNames(calcs[[x]]), correctNames) expect_equal(getNames(calcs2[[x]]), correctNames) } @@ -115,8 +121,8 @@ test_that("GDPpc is equal to GDP divided by pop", { x <- calcOutput("GDPpc", extension2150 = "none", naming = "scenario", aggregate = FALSE) y <- { calcOutput("GDP", extension2150 = "none", naming = "scenario", aggregate = FALSE) / - calcOutput("Population", extension2150 = "none", naming = "scenario", aggregate = FALSE, years = getYears(x)) - } + calcOutput("Population", extension2150 = "none", naming = "scenario", aggregate = FALSE, years = getYears(x)) + } # Remove comments before comparing comment(x) <- NULL expect_equal(x, y) @@ -164,7 +170,7 @@ test_that("GDPpc factored by its weight is equal to GDP, in MER", { l <- calcOutput("GDPpc", extension2150 = "none", naming = "scenario", - unit = "constant 2005 US$MER", + unit = "constant 2017 US$MER", aggregate = FALSE, supplementary = TRUE) x <- l$x * l$weight @@ -172,7 +178,7 @@ test_that("GDPpc factored by its weight is equal to GDP, in MER", { y <- calcOutput("GDP", extension2150 = "none", naming = "scenario", - unit = "constant 2005 US$MER", + unit = "constant 2017 US$MER", aggregate = FALSE) # Remove comments before comparing @@ -183,18 +189,18 @@ test_that("GDPpc factored by its weight is equal to GDP, in MER", { test_that("ppp2mer is consistent with GDP in PPP and MER", { gdp1 <- calcOutput("GDP", unit = "constant 2017 US$MER", aggregate = FALSE) gdp2 <- calcOutput("GDP", unit = "constant 2017 Int$PPP", aggregate = FALSE) - ppp2mer_def <- calcOutput("RatioPPP2MER", aggregate = FALSE) + ppp2merDef <- calcOutput("RatioPPP2MER", aggregate = FALSE) - diff <- gdp1 / gdp2 - ppp2mer_def + diff <- gdp1 / gdp2 - ppp2merDef expect_lt(max(diff), 1e-12) # On regional level gdp1 <- calcOutput("GDP", unit = "constant 2017 US$MER") gdp2 <- calcOutput("GDP", unit = "constant 2017 Int$PPP") - ppp2mer_def <- calcOutput("RatioPPP2MER") + ppp2merDef <- calcOutput("RatioPPP2MER") - diff <- gdp1 / gdp2 - ppp2mer_def + diff <- gdp1 / gdp2 - ppp2merDef expect_lt(max(diff[, 2020, ]), 1e-2) }) diff --git a/tests/testthat/test-snaphsots.R b/tests/testthat/test-snaphsots.R index 8414363..e167b4a 100644 --- a/tests/testthat/test-snaphsots.R +++ b/tests/testthat/test-snaphsots.R @@ -1,3 +1,4 @@ +# # skip(message = "Skipped for clarity. Comment out line 1 in test-snapshots.R to run the test.") # nolint skip_on_ci() skip_on_covr() skip_on_cran() @@ -10,33 +11,30 @@ skip_if_not(dir.exists(madrat_mainfolder), withr::local_file("tmp_messages.txt") withr::local_message_sink(new = file("tmp_messages.txt", "w"), append = TRUE) +fh <- function(x) { + tibble::as_tibble(x) %>% + dplyr::filter(.data$year %in% seq(1960, 2140, 30)) %>% + tidyr::unite(tidyselect::everything(), col = "all") +} test_that("Default calcOutput Population calls", { - expect_snapshot_value(calcOutput("PopulationFuture"), style = "json2") - expect_snapshot_value(calcOutput("PopulationPast"), style = "json2") - expect_snapshot_value(calcOutput("Population"), style = "json2") + expect_snapshot_value(fh(calcOutput("Population")), style = "json2") }) test_that("Default calcOutput GDP calls", { - expect_snapshot_value(calcOutput("GDPPast"), style = "json2") - expect_snapshot_value(calcOutput("GDP"), style = "json2") + expect_snapshot_value(fh(calcOutput("GDP")), style = "json2") }) test_that("Default calcOutput GDPpc calls", { - expect_snapshot_value(calcOutput("GDPpcPast"), style = "json2") - expect_snapshot_value(calcOutput("GDPpc"), style = "json2") + expect_snapshot_value(fh(calcOutput("GDPpc")), style = "json2") }) test_that("Default calcOutput Urban calls", { - expect_snapshot_value(calcOutput("UrbanPast"), style = "json2") - expect_snapshot_value(calcOutput("UrbanFuture"), style = "json2") - expect_snapshot_value(calcOutput("Urban"), style = "json2") + expect_snapshot_value(fh(calcOutput("Urban")), style = "json2") }) test_that("Default calcOutput Labour calls", { - expect_snapshot_value(calcOutput("LabourPast"), style = "json2") - expect_snapshot_value(calcOutput("LabourFuture"), style = "json2") - expect_snapshot_value(calcOutput("Labour"), style = "json2") + expect_snapshot_value(fh(calcOutput("Labour")), style = "json2") }) test_that("Default calcOutput RatioPPP2MER call", { diff --git a/tests/testthat/test-toolGetScenarioDefinition.R b/tests/testthat/test-toolGetScenarioDefinition.R index 81101e5..a111107 100644 --- a/tests/testthat/test-toolGetScenarioDefinition.R +++ b/tests/testthat/test-toolGetScenarioDefinition.R @@ -17,17 +17,17 @@ test_that("toolGetScenarioDefinition works", { c("driver", "scenario", "pastData", "futureData", "harmonization")) expect_s3_class(toolGetScenarioDefinition(scen = "ISIMIP"), "tbl") - x <- toolGetScenarioDefinition("GDP", c("SSPs", "SDPs", "SSP2EU")) + x <- toolGetScenarioDefinition("GDP", c("SSPs", "SDPs")) expect_s3_class(x, "tbl") expect_length(x, 5) expect_named(x, c("driver", "scenario", "pastData", "futureData", "harmonization")) expect_type(x[[1]], "character") - expect_length(x[[1]], 3) + expect_length(x[[1]], 2) expect_type(x[[2]], "character") - expect_length(x[[2]], 3) + expect_length(x[[2]], 2) expect_type(x[[3]], "character") - expect_length(x[[3]], 3) + expect_length(x[[3]], 2) - expect_false(identical(toolGetScenarioDefinition("GDP", c("SSPs", "SDPs", "SSP2EU"), aslist = TRUE), - toolGetScenarioDefinition("GDP", c("SDPs", "SSPs", "SSP2EU"), aslist = TRUE))) + expect_false(identical(toolGetScenarioDefinition("GDP", c("SSPs", "SDPs"), aslist = TRUE), + toolGetScenarioDefinition("GDP", c("SDPs", "SSPs"), aslist = TRUE))) }) diff --git a/vignettes/scenarios.Rmd b/vignettes/scenarios.Rmd index eb14f78..353f46b 100644 --- a/vignettes/scenarios.Rmd +++ b/vignettes/scenarios.Rmd @@ -21,26 +21,24 @@ knitr::opts_chunk$set( ``` ```{r setup, echo=FALSE, message=FALSE} -library(mrdrivers) -library(magrittr) +library(mrdrivers) # nolint +library(magrittr) # nolint ``` ```{r} toolGetScenarioDefinition() %>% print(n = 200) ``` -So for example, there are currently 4 GDPpc scenarios available: the SSPs, SSP2, the SDPs, and SSP2EU. - # User Defined Scenarios The user can create custom scenarios by creating a tibble called "mrdivers_scenarios" in the global environment, and filling it with the desired scenario definitions. The structure of the "mrdivers_scenarios" object should be identical to that of the return object of `toolGetScenarioDefinition()`, and the scenario building blocks have to be available. For example, say the user wanted to create SSP scenarios, but without using the Missing Islands data-set. The following command executed in the global environment would make the "nomi" (no-missing islands) scenario available. ```{r} -mrdrivers_scenarios <- tibble::tribble( - ~driver, ~scenario, ~pastData, ~futureData, ~harmonization, - "GDPpc", "nomi", "WDI", "SSPs", "calibSSPs", - "Population", "nomi", "WDI", "SSPs", "withPEAPandFuture", - "GDP", "nomi", "-", "-", "GDPpcWithPop" +mrdrivers_scenarios <- tibble::tribble( # nolint + ~driver, ~scenario, ~pastData, ~futureData, ~harmonization, + "GDPpc", "nomi", "WDI", "SSPs", "GDPpcSSPs", + "Population", "nomi", "WDI", "SSPs", "PopSSPs", + "GDP", "nomi", "-", "-", "GDPpcWithPop" ) ``` @@ -50,39 +48,52 @@ mrdrivers_scenarios <- tibble::tribble( By default, the following scenarios are returned for all drivers: - the SSPs, i.e. SSP1-5 -- the SDPs, i.e. SDP, SDP_EI, SDP_RC, and SDP_MC -- SSP2EU +- the SDPs, i.e. SDP, SDP_EI, SDP_MC and SDP_RC + +The scenarios span from 1960 to 2150, with yearly data until 2030, and data every 5 years thereafter. # References -## GDP and GDPpc scenarios +## GDP per capita and GDP scenarios ### SSPs -Suggested overall reference: Koch and Leimbach 2023 ([link](https://doi.org/10.1016/j.ecolecon.2023.107751)). +Suggested overall reference for the scenario construction: Koch and Leimbach 2023 ([link](https://doi.org/10.1016/j.ecolecon.2023.107751)). -Detailed references: the SSP GDP per capita scenarios are constructed using past WDI data ([link](https://databank.worldbank.org/source/world-development-indicators)) (filled in with MI data ([link](https://zenodo.org/record/4421504/files/MissingIslands.zip)), and growth rates from James2019-WB data (DOI of previous version of data: doi:10.1186/1478-7954-10-12)) and SSP GDP projections (filled in with MI projections ([link](https://zenodo.org/record/4421504/files/MissingIslands.zip))). The harmonization makes use of short term growth rates from IMF ([link](https://www.imf.org/-/media/Files/Publications/WEO/WEO-Database/2022/WEOOct2022all.ashx)). For more details on the harmonization, see Koch and Leimbach 2023 ([link](https://doi.org/10.1016/j.ecolecon.2023.107751)). - -### SDPs +The SSP GDP per capita scenarios are constructed using past WDI data ([link](https://databank.worldbank.org/source/world-development-indicators)) from 1990 to 2022 (missing country data filled in with MI data ([link](https://doi.org/10.5281/zenodo.4421504)) and James data ([link](https://pophealthmetrics.biomedcentral.com/articles/10.1186/1478-7954-10-12), specifically the WB_ID series), extended backwards until 1960 using growth rates from MI and James), growth rates from IMF GDP per capita projections ([link](https://www.imf.org/-/media/Files/Publications/WEO/WEO-Database/2022/WEOOct2022all.ashx)) until 2029, and SSP GDP per capita projections (SSP OECD projections [link](https://data.ece.iiasa.ac.at/ssp/#/about), release 3.0.1 (March 2024)) until 2100. The scenarios are extended until 2150 using a bezier curve method that assumes that the slope in 2100 is flattened by half by 2150. For countries lacking projection data, the last historical data point is used in all future years. For more details on the harmonization, see Koch and Leimbach 2023 ([link](https://doi.org/10.1016/j.ecolecon.2023.107751)). -The SDPs are all based off of SSP1, with different harmonization functions for the different SDPs. No citable reference available. +The SSP GDP scenarios are the product of the GDP per capita and population scenarios. -### SSP2EU +### SDPs -SSP2EU is based off of SSP2, but for EUR-Region countries, Eurostat data and short-term projections ([link](https://ec.europa.eu/eurostat)) are used instead of WDI and IMF data. +The SDPs are all based off of SSP1, with different harmonization functions for the different SDPs. (Reference needed.) The SDP GDP scenarios are the product of the GDP per capita and population scenarios. ## Population scenarios ### SSPs -Suggested overall references: K. C., S, 2020 ([link](https://pure.iiasa.ac.at/16710)) and Lutz et al., 2018 ([link](https://pure.iiasa.ac.at/id/eprint/15226/1/lutz_et_al_2018_demographic_and_human_capital.pdf)). +The SSP population scenarios are constructed using past WDI data ([link](https://databank.worldbank.org/source/world-development-indicators)) from 1960 to 2022 (missing country data filled in with UN_PopDiv data ([link](https://population.un.org/wpp/), 2022 revision)) and MI data ([link](https://doi.org/10.5281/zenodo.4421504))), growth rates from the World Bank's Population and Projections database ([link](https://databank.worldbank.org/source/population-estimates-and-projections#)) until 2029, and growth rates from from the SSP population projections (release 3.0.1 (March 2024) [link](https://data.ece.iiasa.ac.at/ssp/#/about) and [link](https://doi.org/10.5281/zenodo.10618931)), filled in with UN_PopDiv data ([link](https://population.un.org/wpp/), 2022 revision)) until 2100. The scenarios are extended until 2150 using a bezier curve method that assumes that the slope in 2100 is flattened by half by 2150. For countries lacking projection data, the last historical data point is used in all future years. For more details on the harmonization, see Koch and Leimbach 2023 ([link](https://doi.org/10.1016/j.ecolecon.2023.107751)). + +### SDPs + +The SDP scenarios are all equal to the SSP1 scenario. -Detailed references: the SSP population scenarios are constructed using past WDI data ([link](https://databank.worldbank.org/source/world-development-indicators)) (filled in with UN_PopDiv data ([link](https://population.un.org/wpp/Download/Files/1_Indicators%20(Standard)/EXCEL_FILES/2_Population/WPP2022_POP_F01_1_POPULATION_SINGLE_AGE_BOTH_SEXES.xlsx)) and MI data ([link](https://zenodo.org/record/4421504/files/MissingIslands.zip)), and SSP population projections (filled in with UN_PopDiv data ([link](https://population.un.org/wpp/Download/Files/1_Indicators%20(Standard)/EXCEL_FILES/2_Population/WPP2022_POP_F01_1_POPULATION_SINGLE_AGE_BOTH_SEXES.xlsx)) and MI data ([link](https://zenodo.org/record/4421504/files/MissingIslands.zip)). The harmonization makes use of short term growth rates from the World Bank's Population and Projections database ([link](https://databank.worldbank.org/source/population-estimates-and-projections#)). For more details on the harmonization, see Koch and Leimbach 2023 ([link](https://doi.org/10.1016/j.ecolecon.2023.107751)). +## Labour scenarios + +### SSPs + +The SSPs labour scenarios are constructed using past WDI data ([link](https://databank.worldbank.org/source/world-development-indicators)) starting in 1960 (missing country data filled in with UN_PopDiv data ([link](https://population.un.org/wpp/), 2022 revision)), and SSP labour projections ([link](https://doi.org/10.5281/zenodo.10618931)). The SSP labour projections harmonize perfectly with the WDI data, no further steps necessary. ### SDPs -The SDPs are all based off of SSP1, with different harmonization functions for the different SDPs. No citable reference available. +The SDP scenarios are all equal to the SSP1 scenario. + +## Urban population share scenarios -### SSP2EU +### SSPs + +The SSPs urban population share scenarios are constructed using past WDI data starting in 1960 ([link](https://databank.worldbank.org/source/world-development-indicators)), and SSP urban population share projections (2108 Release [link](https://data.ece.iiasa.ac.at/ssp/#/about)). The harmonization uses the past levels, and future growth rates. + +### SDPs -SSP2EU is based off of SSP2, but for EUR-Region countries, Eurostat data and short-term projections ([link](https://ec.europa.eu/eurostat)) are used instead of WDI and UN_PopDiv data. +The SDP, SDP_EI, and SDP_MC scenarios are all equal to the SSP1 scenario. The SDP_RC is equal to the SSP3 for OECD countries, and SSP2 for non-OECD countries.