diff --git a/.Rbuildignore b/.Rbuildignore index b3d8220f..0c8b97dd 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -12,3 +12,5 @@ TEMP/ ^docs$ ^pkgdown$ CONTRIBUTING.md +^doc$ +^Meta$ diff --git a/.gitignore b/.gitignore index b1204fe3..07ea1435 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,10 @@ TEMP/ TEMP.R renv/ .Rprofile -inst/doc tests/testdata/app_data/ .Renviron -docs logs/ /sessionInfoLog +demo.duckdb* +/doc/ +/Meta/ diff --git a/DESCRIPTION b/DESCRIPTION index 9b289a31..75972c3d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -26,7 +26,6 @@ Suggests: covr, testthat, spelling, - knitr, rmarkdown, markdown, assertthat, @@ -36,7 +35,9 @@ Suggests: lintr, withr, devtools, - stringr + stringr, + knitr, + dplyr Language: en-US Imports: data.table, @@ -58,7 +59,11 @@ Imports: joyn, yaml, purrr, - future + future, + glue, + DBI, + duckdb, + duckplyr Remotes: PIP-Technical-Team/wbpip@DEV Depends: diff --git a/NAMESPACE b/NAMESPACE index 77762c0e..976cf64f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -27,6 +27,7 @@ export(pip_grp) export(pip_grp_logic) export(pipgd_lorenz_curve) export(return_correct_version) +export(return_if_exists) export(select_off_alt_agg) export(select_reporting_level) export(select_user_aggs) @@ -39,6 +40,7 @@ export(ui_hp_stacked) export(ui_pc_charts) export(ui_pc_regional) export(ui_svy_meta) +export(update_master_file) export(valid_years) export(validate_input_grouped_stats) export(version_dataframe) diff --git a/R/add_agg_stats.R b/R/add_agg_stats.R index f1cf6309..8ae40fe7 100644 --- a/R/add_agg_stats.R +++ b/R/add_agg_stats.R @@ -46,7 +46,7 @@ ag_average_poverty_stats <- function(df, return_cols) { national_cols <- return_cols$national_cols # This should be removed eventually - assertthat::assert_that(assertthat::are_equal(length(df$reporting_level), 2)) + # assertthat::assert_that(assertthat::are_equal(length(df$reporting_level), 2)) # STEP 1: Identify groups of variables that will be handled differently ------ ## original names diff --git a/R/copy_functions.R b/R/copy_functions.R index efd9769d..018b3609 100644 --- a/R/copy_functions.R +++ b/R/copy_functions.R @@ -494,7 +494,6 @@ gd_compute_headcount_lq <- function( #' By default, the best fitting Lorenz parameterization (quadratic or beta) is #' selected. #' -#' @param params list of parameters #' @param welfare numeric vector of cumulative share of welfare (income/consumption) #' @param weight numeric vector of cumulative share of the population #' @param lorenz either "lb" or "lq" diff --git a/R/create_countries_vctr.R b/R/create_countries_vctr.R index 1399bf65..230118c4 100644 --- a/R/create_countries_vctr.R +++ b/R/create_countries_vctr.R @@ -209,7 +209,7 @@ get_user_alt_gt <- function(user_gt, off_gt) { return(out) } -#' Helper function to define user_{var}_code +#' Helper function to define user_\{var\}_code #' #' @param x character: Grouping type needed by user #' diff --git a/R/duckdb_func.R b/R/duckdb_func.R new file mode 100644 index 00000000..8960c821 --- /dev/null +++ b/R/duckdb_func.R @@ -0,0 +1,202 @@ +#' Return the rows of the table if they exist in master file +#' +#' @inheritParams subset_lkup +#' @param con Connection object to duckdb table +#' +#' @return Dataframe +#' @export +#' +return_if_exists <- function(lkup, povline, con, fill_gaps) { + # It is not possible to append to parquet file https://stackoverflow.com/questions/39234391/how-to-append-data-to-an-existing-parquet-file + # Writing entire data will be very costly as data keeps on growing, better is to save data in duckdb and append to it. + if (!getOption("pipapi.query_live_data")) { + target_file <- if (fill_gaps) "fg_master_file" else "rg_master_file" + + master_file <- DBI::dbGetQuery(con, + glue::glue("select * from {target_file}")) |> + duckplyr::as_duckplyr_tibble() + + data_present_in_master <- + dplyr::inner_join( + x = master_file, + y = lkup |> + collapse::fselect(country_code, reporting_year, is_interpolated), + by = c("country_code", "reporting_year", "is_interpolated")) |> + dplyr::filter(poverty_line == povline) + + keep <- TRUE + if (nrow(data_present_in_master) > 0) { + # Remove the rows from lkup that are present in master + keep <- !with(lkup, paste(country_code, reporting_year, is_interpolated)) %in% + with(data_present_in_master, paste(country_code, reporting_year, is_interpolated)) + + lkup <- lkup[keep, ] + + message("Returning data from cache.") + } + } else { + data_present_in_master <- NULL + } + # nrow(data_present_in_master) should be equal to sum(keep) + return(list(data_present_in_master = data_present_in_master, lkup = lkup)) +} + +#' Update master file with the contents of the dataframe +#' @inheritParams pip +#' @param dat Dataframe to be appended +#' @param cache_file_path path where cache file is saved +#' +#' @return number of rows updated +#' @export +#' +update_master_file <- function(dat, cache_file_path, fill_gaps) { + write_con <- duckdb::dbConnect(duckdb::duckdb(), dbdir = cache_file_path) + target_file <- if (fill_gaps) "fg_master_file" else "rg_master_file" + + duckdb::duckdb_register(write_con, "append_data", dat, overwrite = TRUE) + DBI::dbExecute(write_con, glue::glue("INSERT INTO {target_file} SELECT * FROM append_data;")) + duckdb::dbDisconnect(write_con) + message(glue::glue("{target_file} is updated.")) + + return(nrow(dat)) +} + + +#' Reset the cache. Only to be used internally +#' +#' @noRd +reset_cache <- function(pass = Sys.getenv('PIP_CACHE_LOCAL_KEY'), type = c("both", "rg", "fg"), lkup) { + # lkup will be passed through API and will not be an argument to endpoint, same as pip call + # Checks if the keys match across local and server before reseting the cache + if (pass != Sys.getenv('PIP_CACHE_SERVER_KEY')) { + rlang::abort("Either key not set or incorrect key!") + } + + cache_file_path <- fs::path(lkup$data_root, 'cache', ext = "duckdb") + write_con <- duckdb::dbConnect(duckdb::duckdb(), dbdir = cache_file_path) + + type <- match.arg(type) + if(type == "both") type = c("rg", "fg") + if("rg" %in% type) { + DBI::dbExecute(write_con, "DELETE from rg_master_file") + } + if("fg" %in% type) { + DBI::dbExecute(write_con, "DELETE from fg_master_file") + } + duckdb::dbDisconnect(write_con) +} + +create_duckdb_file <- function(cache_file_path) { + con <- duckdb::dbConnect(duckdb::duckdb(), dbdir = cache_file_path) + DBI::dbExecute(con, "CREATE OR REPLACE table rg_master_file ( + country_code VARCHAR, + survey_id VARCHAR, + cache_id VARCHAR, + wb_region_code VARCHAR, + reporting_year DOUBLE, + surveyid_year VARCHAR, + survey_year DOUBLE, + survey_time VARCHAR, + survey_acronym VARCHAR, + survey_coverage VARCHAR, + survey_comparability DOUBLE, + comparable_spell VARCHAR, + welfare_type VARCHAR, + reporting_level VARCHAR, + survey_mean_lcu DOUBLE, + survey_mean_ppp DOUBLE, + survey_median_ppp DOUBLE, + survey_median_lcu DOUBLE, + predicted_mean_ppp DOUBLE, + ppp DOUBLE, + cpi DOUBLE, + reporting_pop DOUBLE, + reporting_gdp DOUBLE, + reporting_pce DOUBLE, + pop_data_level VARCHAR, + gdp_data_level VARCHAR, + pce_data_level VARCHAR, + cpi_data_level VARCHAR, + ppp_data_level VARCHAR, + distribution_type VARCHAR, + gd_type VARCHAR, + is_interpolated BOOLEAN, + is_used_for_line_up BOOLEAN, + is_used_for_aggregation BOOLEAN, + estimation_type VARCHAR, + display_cp DOUBLE, + path VARCHAR, + country_name VARCHAR, + africa_split VARCHAR, + africa_split_code VARCHAR, + region_name VARCHAR, + region_code VARCHAR, + world VARCHAR, + world_code VARCHAR, + poverty_line DOUBLE, + mean DOUBLE, + median DOUBLE, + headcount DOUBLE, + poverty_gap DOUBLE, + poverty_severity DOUBLE, + watts DOUBLE + + )") + + DBI::dbExecute(con, "CREATE OR REPLACE table fg_master_file ( + country_code VARCHAR, + survey_id VARCHAR, + cache_id VARCHAR, + wb_region_code VARCHAR, + reporting_year DOUBLE, + surveyid_year VARCHAR, + survey_year DOUBLE, + survey_time VARCHAR, + survey_acronym VARCHAR, + survey_coverage VARCHAR, + survey_comparability DOUBLE, + comparable_spell VARCHAR, + welfare_type VARCHAR, + reporting_level VARCHAR, + survey_mean_lcu DOUBLE, + survey_mean_ppp DOUBLE, + survey_median_ppp DOUBLE, + survey_median_lcu DOUBLE, + predicted_mean_ppp DOUBLE, + ppp DOUBLE, + cpi DOUBLE, + reporting_pop DOUBLE, + reporting_gdp DOUBLE, + reporting_pce DOUBLE, + pop_data_level VARCHAR, + gdp_data_level VARCHAR, + pce_data_level VARCHAR, + cpi_data_level VARCHAR, + ppp_data_level VARCHAR, + distribution_type VARCHAR, + gd_type VARCHAR, + is_interpolated BOOLEAN, + is_used_for_line_up BOOLEAN, + is_used_for_aggregation BOOLEAN, + estimation_type VARCHAR, + interpolation_id VARCHAR, + display_cp DOUBLE, + country_name VARCHAR, + africa_split VARCHAR, + africa_split_code VARCHAR, + region_name VARCHAR, + region_code VARCHAR, + world VARCHAR, + world_code VARCHAR, + path VARCHAR, + data_interpolation_id VARCHAR, + poverty_line DOUBLE, + mean DOUBLE, + median DOUBLE, + headcount DOUBLE, + poverty_gap DOUBLE, + poverty_severity DOUBLE, + watts DOUBLE + )") + DBI::dbDisconnect(con) +} diff --git a/R/fg_pip.R b/R/fg_pip.R index 979ecadc..15518f4e 100644 --- a/R/fg_pip.R +++ b/R/fg_pip.R @@ -3,6 +3,7 @@ #' Compute the main PIP poverty and inequality statistics for imputed years. #' #' @inheritParams pip +#' @param con duckdb connection object #' @return data.frame #' @keywords internal fg_pip <- function(country, @@ -12,14 +13,14 @@ fg_pip <- function(country, welfare_type, reporting_level, ppp, - lkup) { + lkup, + con) { valid_regions <- lkup$query_controls$region$values interpolation_list <- lkup$interpolation_list data_dir <- lkup$data_root ref_lkup <- lkup$ref_lkup - # Handle interpolation metadata <- subset_lkup( country = country, @@ -28,8 +29,14 @@ fg_pip <- function(country, reporting_level = reporting_level, lkup = ref_lkup, valid_regions = valid_regions, - data_dir = data_dir + data_dir = data_dir, + povline = povline, + con = con, + fill_gaps = TRUE ) + + data_present_in_master <- metadata$data_present_in_master + metadata <- metadata$lkup # Remove aggregate distribution if popshare is specified # TEMPORARY FIX UNTIL popshare is supported for aggregate distributions metadata <- filter_lkup(metadata = metadata, @@ -38,7 +45,7 @@ fg_pip <- function(country, # Return empty dataframe if no metadata is found if (nrow(metadata) == 0) { - return(pipapi::empty_response) + return(list(main_data = empty_response, data_in_cache = data_present_in_master)) } unique_survey_files <- unique(metadata$data_interpolation_id) @@ -54,7 +61,6 @@ fg_pip <- function(country, # Extract country-years for which stats will be computed from the same files # tmp_metadata <- interpolation_list[[unique_survey_files[svy_id]]]$tmp_metadata iteration <- interpolation_list[[unique_survey_files[svy_id]]] - svy_data <- get_svy_data(svy_id = iteration$cache_ids, reporting_level = iteration$reporting_level, path = iteration$paths) @@ -66,10 +72,14 @@ fg_pip <- function(country, valid_regions = valid_regions, data_dir = data_dir) + # Join because some data might be coming from cache so it might be absent in metadata + ctry_years <- collapse::join(ctry_years, metadata |> + collapse::fselect(intersect(names(ctry_years), names(metadata))), + verbose = 0,how = "inner") + results_subset <- vector(mode = "list", length = nrow(ctry_years)) for (ctry_year_id in seq_along(ctry_years$interpolation_id)) { - # Extract records to be used for a single country-year estimation interp_id <- ctry_years[["interpolation_id"]][ctry_year_id] tmp_metadata <- metadata[metadata$interpolation_id == interp_id, ] @@ -96,19 +106,14 @@ fg_pip <- function(country, } # # tmp_metadata <- unique(tmp_metadata) - # Add stats columns to data frame for (stat in seq_along(tmp_stats)) { tmp_metadata[[names(tmp_stats)[stat]]] <- tmp_stats[[stat]] } - - results_subset[[ctry_year_id]] <- tmp_metadata } - out[[svy_id]] <- results_subset } - out <- unlist(out, recursive = FALSE) out <- data.table::rbindlist(out) @@ -124,7 +129,7 @@ fg_pip <- function(country, poverty_line := round(poverty_line, digits = 3) ] - return(out) + return(list(main_data = out, data_in_cache = data_present_in_master)) } #' Remove duplicated rows created during the interpolation process diff --git a/R/pip.R b/R/pip.R index c71fdb7f..cfd3504b 100644 --- a/R/pip.R +++ b/R/pip.R @@ -69,7 +69,6 @@ pip <- function(country = "ALL", # set up ------------- - welfare_type <- match.arg(welfare_type) reporting_level <- match.arg(reporting_level) group_by <- match.arg(group_by) @@ -103,175 +102,195 @@ pip <- function(country = "ALL", valid_years = lkup$valid_years, aux_files = lkup$aux_files ) - - # mains estimates --------------- - if (fill_gaps) { - ## lineup years----------------- - out <- fg_pip( - country = lcv$est_ctrs, - year = year, - povline = povline, - popshare = popshare, - welfare_type = welfare_type, - reporting_level = reporting_level, - ppp = ppp, - lkup = lkup - ) - } else { - ## survey years ------------------ - out <- rg_pip( - country = lcv$est_ctrs, - year = year, - povline = povline, - popshare = popshare, - welfare_type = welfare_type, - reporting_level = reporting_level, - ppp = ppp, - lkup = lkup - ) - } - - # Eary return for empty table--------------- - if (nrow(out) == 0) { - return(out) + # lcv$est_ctrs has all the country_code that we are interested in + # Integrate return_if_exists for following scenario + # 1) country = "AGO" year = 2000 pl = 1.9 should return from master file + # 2) country = "AGO" year = 2019 pl = 1.9 should return pip call + # 3) country = c("CHN", "IND"), year = 2019, 2017 should return half from master file and half from pip call + # + # 4) country = "all" year = 2019 + # 5) country = "AGO" year = "all" + # 6) country = "all" year = "all" + + cache_file_path <- fs::path(lkup$data_root, 'cache', ext = "duckdb") + if (!file.exists(cache_file_path)) { + # Create an empty duckdb file + create_duckdb_file(cache_file_path) } - - # aggregate distributions ------------------ - if (reporting_level %in% c("national", "all")) { - out <- add_agg_stats( - df = out, - return_cols = lkup$return_cols$ag_average_poverty_stats + read_con <- duckdb::dbConnect(duckdb::duckdb(), dbdir = cache_file_path, read_only = TRUE) + # mains estimates --------------- + if (fill_gaps) { + ## lineup years----------------- + out <- fg_pip( + country = lcv$est_ctrs, + year = year, + povline = povline, + popshare = popshare, + welfare_type = welfare_type, + reporting_level = reporting_level, + ppp = ppp, + lkup = lkup, + con = read_con + ) + } else { + ## survey years ------------------ + out <- rg_pip( + country = lcv$est_ctrs, + year = year, + povline = povline, + popshare = popshare, + welfare_type = welfare_type, + reporting_level = reporting_level, + ppp = ppp, + lkup = lkup, + con = read_con ) - if (reporting_level == "national") { - out <- out[reporting_level == "national"] } - } - - # Add extra variables -------------- - - # ## Add SPL and SPR --------------- - # out <- add_spl(df = out, - # fill_gaps = fill_gaps, - # data_dir = lkup$data_root) - # - # ## Add prosperity Gap ----------- - # - # out <- add_pg(df = out, - # fill_gaps = fill_gaps, - # data_dir = lkup$data_root) - # - # ## add distribution type ------------- - # # based on info in framework data, rather than welfare data - # add_distribution_type(df = out, - # lkup = lkup, - # fill_gaps = fill_gaps) + # It is important to close the read connection before you open a write connection because + # duckdb kind of inherits read_only flag from previous connection object if it is not closed + # More details here https://app.clickup.com/t/868cdpe3q + duckdb::dbDisconnect(read_con) + cached_data <- out$data_in_cache + main_data <- out$main_data + + if (nrow(main_data) > 0) { + out <- main_data |> + collapse::fmutate(path = as.character(path)) |> + collapse::rowbind(cached_data) + # cached_data is NULL when we are querying live data in which case we don't update cache + # This will be used only for development purpose and we don't have any intention to use it in production. + if(!is.null(cached_data)) { + # Update cache with data + update_master_file(main_data, cache_file_path, fill_gaps) + } + } else { + out <- cached_data + } + if (!data.table::is.data.table(out)) { + setDT(out) + } + # Early return for empty table--------------- + if (nrow(out) == 0) return(pipapi::empty_response) + + # aggregate distributions ------------------ + if (reporting_level %in% c("national", "all")) { + out <- add_agg_stats( + df = out, + return_cols = lkup$return_cols$ag_average_poverty_stats + ) + if (reporting_level == "national") { + out <- out[reporting_level == "national"] + } + } - add_vars_out_of_pipeline(out, fill_gaps = fill_gaps, lkup = lkup) + add_vars_out_of_pipeline(out, fill_gaps = fill_gaps, lkup = lkup) + # **** TO BE REMOVED **** REMOVAL STARTS HERE + # Once `pip-grp` has been integrated in ingestion pipeline + # Handles grouped aggregations + if (group_by != "none") { + # Handle potential (insignificant) difference in poverty_line values that + # may mess-up the grouping + out$poverty_line <- povline - # **** TO BE REMOVED **** REMOVAL STARTS HERE - # Once `pip-grp` has been integrated in ingestion pipeline - # Handles grouped aggregations - if (group_by != "none") { - # Handle potential (insignificant) difference in poverty_line values that - # may mess-up the grouping - out$poverty_line <- povline - - out <- pip_aggregate_by( - df = out, - group_lkup = lkup[["pop_region"]], - return_cols = lkup$return_cols$pip_grp - ) - # Censor regional values - if (censor) { - out <- censor_rows(out, lkup[["censored"]], type = "regions") + out <- pip_aggregate_by( + df = out, + group_lkup = lkup[["pop_region"]], + return_cols = lkup$return_cols$pip_grp + ) + # Censor regional values + if (censor) { + out <- censor_rows(out, lkup[["censored"]], type = "regions") + } + + out <- out[, c("region_name", + "region_code", + "reporting_year", + "reporting_pop", + "poverty_line", + "headcount", + "poverty_gap", + "poverty_severity", + "watts", + "mean", + "pop_in_poverty")] + + return(out) } - - out <- out[, c("region_name", - "region_code", - "reporting_year", - "reporting_pop", - "poverty_line", - "headcount", - "poverty_gap", - "poverty_severity", - "watts", - "mean", - "pop_in_poverty")] - - return(out) - } - # **** TO BE REMOVED **** REMOVAL ENDS HERE + # **** TO BE REMOVED **** REMOVAL ENDS HERE - # pre-computed distributional stats --------------- - crr_names <- names(out) # current variables - names2keep <- lkup$return_cols$pip$cols # all variables + # pre-computed distributional stats --------------- + crr_names <- names(out) # current variables + names2keep <- lkup$return_cols$pip$cols # all variables - out <- add_dist_stats( - df = out, - dist_stats = lkup[["dist_stats"]] - ) + out <- add_dist_stats( + df = out, + dist_stats = lkup[["dist_stats"]] + ) - # Add aggregate medians ---------------- - out <- add_agg_medians( - df = out, - fill_gaps = fill_gaps, - data_dir = lkup$data_root - ) + # Add aggregate medians ---------------- + out <- add_agg_medians( + df = out, + fill_gaps = fill_gaps, + data_dir = lkup$data_root + ) - # format ---------------- + # format ---------------- - if (fill_gaps) { + if (fill_gaps) { - ## Inequality indicators to NA for lineup years ---- - dist_vars <- names2keep[!(names2keep %in% crr_names)] - out[, - (dist_vars) := NA_real_] + ## Inequality indicators to NA for lineup years ---- + dist_vars <- names2keep[!(names2keep %in% crr_names)] + out[, + (dist_vars) := NA_real_] - ## estimate_var ----- - out <- estimate_type_ctr_lnp(out, lkup) + ## estimate_var ----- + out <- estimate_type_ctr_lnp(out, lkup) - } else { - out[, estimate_type := NA_character_] - } - ## Handle survey coverage ------------ - if (reporting_level != "all") { - keep <- out$reporting_level == reporting_level - out <- out[keep, ] - } + } else { + out[, estimate_type := NA_character_] + } + ## Handle survey coverage ------------ + if (reporting_level != "all") { + keep <- out$reporting_level == reporting_level + out <- out[keep, ] + } - # Censor country values - if (censor) { - out <- censor_rows(out, lkup[["censored"]], type = "countries") - } + # Censor country values + if (censor) { + out <- censor_rows(out, lkup[["censored"]], type = "countries") + } - # Select columns - if (additional_ind) { - get_additional_indicators(out) - added_names <- attr(out, "new_indicators_names") - names2keep <- c(names2keep, added_names) + # Select columns + if (additional_ind) { + get_additional_indicators(out) + added_names <- attr(out, "new_indicators_names") + names2keep <- c(names2keep, added_names) - } - # Keep relevant variables - out <- out[, .SD, .SDcols = names2keep] + } + # Keep relevant variables + out <- out[, .SD, .SDcols = names2keep] - # make sure we always report the same precision in all numeric variables - doub_vars <- - names(out)[unlist(lapply(out, is.double))] |> - data.table::copy() + # make sure we always report the same precision in all numeric variables + doub_vars <- + names(out)[unlist(lapply(out, is.double))] |> + data.table::copy() - out[, (doub_vars) := lapply(.SD, round, digits = 12), - .SDcols = doub_vars] + out[, (doub_vars) := lapply(.SD, round, digits = 12), + .SDcols = doub_vars] - # Order rows by country code and reporting year - data.table::setorder(out, country_code, reporting_year, reporting_level, welfare_type) + # Order rows by country code and reporting year + data.table::setorder(out, country_code, reporting_year, reporting_level, welfare_type) + #} + # Make sure no duplicate remains + out <- out |> collapse::funique() # return ------------- return(out) } diff --git a/R/pip_grp.R b/R/pip_grp.R index 94aa98a4..87a149db 100644 --- a/R/pip_grp.R +++ b/R/pip_grp.R @@ -59,7 +59,8 @@ pip_grp <- function(country = "ALL", reporting_level = reporting_level, ppp = NULL, lkup = lkup) - + # For now just rowbinding two dataframes, but we would need to use it more smartly in the future + out <- collapse::rowbind(out) # return empty dataframe if no metadata is found if (nrow(out) == 0) { return(pipapi::empty_response_grp) diff --git a/R/pip_grp_logic.R b/R/pip_grp_logic.R index c21e43ea..60369816 100644 --- a/R/pip_grp_logic.R +++ b/R/pip_grp_logic.R @@ -84,6 +84,8 @@ pip_grp_logic <- function(country = "ALL", lkup = lkup ) + # For now just rowbinding two dataframes, but we would need to use it more smartly in the future + fg_pip_master <- collapse::rowbind(fg_pip_master) add_vars_out_of_pipeline(fg_pip_master, fill_gaps = TRUE, lkup = lkup) if (lcv$off_alt_agg == "both") { diff --git a/R/pipapi.R b/R/pipapi.R index f8151529..85cdb186 100644 --- a/R/pipapi.R +++ b/R/pipapi.R @@ -105,6 +105,7 @@ utils::globalVariables( "use_bin", "use_groupdata", "use_imputed", - "use_microdata" + "use_microdata", + "path" ) ) diff --git a/R/rg_pip.R b/R/rg_pip.R index 1bd84225..26dfbb5e 100644 --- a/R/rg_pip.R +++ b/R/rg_pip.R @@ -3,6 +3,7 @@ #' Compute the main PIP poverty and inequality statistics for survey years. #' #' @inheritParams pip +#' @param con duckdb connection object #' @return data.frame #' @keywords internal rg_pip <- function(country, @@ -12,14 +13,13 @@ rg_pip <- function(country, welfare_type, reporting_level, ppp, - lkup) { - + lkup, + con) { # get values from lkup valid_regions <- lkup$query_controls$region$values svy_lkup <- lkup$svy_lkup data_dir <- lkup$data_root - metadata <- subset_lkup( country = country, year = year, @@ -27,8 +27,13 @@ rg_pip <- function(country, reporting_level = reporting_level, lkup = svy_lkup, valid_regions = valid_regions, - data_dir = data_dir + data_dir = data_dir, + povline = povline, + con = con, + fill_gaps = FALSE ) + data_present_in_master <- metadata$data_present_in_master + metadata <- metadata$lkup # Remove aggregate distribution if popshare is specified # TEMPORARY FIX UNTIL popshare is supported for aggregate distributions @@ -37,7 +42,7 @@ rg_pip <- function(country, # return empty dataframe if no metadata is found if (nrow(metadata) == 0) { - return(empty_response) + return(list(main_data = empty_response, data_in_cache = data_present_in_master)) } out <- vector(mode = "list", length = nrow(metadata)) @@ -64,7 +69,6 @@ rg_pip <- function(country, ppp = ppp, distribution_type = tmp_metadata$distribution_type ) - # Add stats columns to data frame for (j in seq_along(tmp_stats)) { tmp_metadata[[names(tmp_stats)[j]]] <- tmp_stats[[j]] @@ -72,7 +76,8 @@ rg_pip <- function(country, out[[i]] <- tmp_metadata } + #browser() out <- data.table::rbindlist(out) - return(out) + return(list(main_data = out, data_in_cache = data_present_in_master)) } diff --git a/R/utils-plumber.R b/R/utils-plumber.R index 01babe3a..a5c5d2fd 100644 --- a/R/utils-plumber.R +++ b/R/utils-plumber.R @@ -112,7 +112,9 @@ validate_query_parameters <- "mean", "times_mean", "lorenz", - "n_bins" + "n_bins", + "pass", + "type" )) { params$argsQuery <- params$argsQuery[names(params$argsQuery) %in% valid_params] diff --git a/R/utils.R b/R/utils.R index 59f98453..ba7dd9e1 100644 --- a/R/utils.R +++ b/R/utils.R @@ -1,5 +1,6 @@ #' Subset look-up data #' @inheritParams pip +#' @inheritParams rg_pip #' @param valid_regions character: List of valid region codes that can be used #' for region selection #' @param data_dir character: directory path from lkup$data_root @@ -11,7 +12,11 @@ subset_lkup <- function(country, reporting_level, lkup, valid_regions, - data_dir = NULL) { + data_dir = NULL, + povline, + con, + fill_gaps + ) { # STEP 1 - Keep every row by default keep <- rep(TRUE, nrow(lkup)) @@ -37,9 +42,12 @@ subset_lkup <- function(country, keep = keep, reporting_level = reporting_level[1]) + lkup <- lkup[keep, ] - return(lkup) + cached_data <- return_if_exists(lkup, povline, con, fill_gaps) + + return(list(lkup = cached_data$lkup, data_present_in_master = cached_data$data_present_in_master)) } #' select_country @@ -90,8 +98,6 @@ select_years <- function(lkup, grepl("pip_grp", caller_names) |> any() - - dtmp <- lkup year <- toupper(year) @@ -404,7 +410,7 @@ censor_stats <- function(df, censored_table) { #' It also censors specific stats #' #' @param df data.table: Table to censor. -#' @param censored_table data.table: Censor table +#' @param lkup lkup value #' @keywords internal estimate_type_var <- function(df, lkup) { @@ -586,13 +592,18 @@ create_query_controls <- function(svy_lkup, type = "character") # Tables table <- list(values = aux_tables, type = "character") + + # type + type <- list(values = c("both", "rg", "fg"), type = "character") + + pass <- list(values = Sys.getenv('PIP_CACHE_SERVER_KEY'), type = "character") # parameters parameter <- list(values = c("country", "year", "povline", "popshare", "fill_gaps", "aggregate", "group_by", "welfare_type", "reporting_level", "ppp", "version", - "format", "table", "long_format"), + "format", "table", "long_format", "type", "pass"), type = "character") # cum_welfare @@ -668,7 +679,9 @@ create_query_controls <- function(svy_lkup, times_mean = times_mean, lorenz = lorenz, n_bins = n_bins, - endpoint = endpoint + endpoint = endpoint, + type = type, + pass = pass ) return(query_controls) @@ -713,7 +726,7 @@ subset_ctry_years <- function(country, } else { keep_regions <- rep(FALSE, length(lkup$region_code)) } - keep_countries <- lkup$country_code %chin% country + keep_countries <- lkup$country_code %chin% as.character(country) keep <- keep & (keep_countries | keep_regions) } diff --git a/R/zzz.R b/R/zzz.R index 86ebb03c..bbba132e 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,3 +1,8 @@ +pipapi_default_options <- list( + pipapi.query_live_data = FALSE +) + + .onLoad <- function(libname, pkgname) { if (Sys.getenv("PIPAPI_APPLY_CACHING") == "TRUE") { d <- rappdirs::user_cache_dir("pipapi") @@ -10,7 +15,7 @@ logfile = NULL, max_size = as.numeric(Sys.getenv("PIPAPI_CACHE_MAX_SIZE")), prune_rate = 50) - pip <<- memoise::memoise(pip, cache = cd, omit_args = "lkup") + #pip <<- memoise::memoise(pip, cache = cd, omit_args = "lkup") ui_hp_stacked <<- memoise::memoise(ui_hp_stacked, cache = cd, omit_args = "lkup") pip_grp_logic <<- memoise::memoise(pip_grp_logic, cache = cd, omit_args = "lkup") pip_grp <<- memoise::memoise(pip_grp, cache = cd, omit_args = "lkup") @@ -21,5 +26,12 @@ assign("cd", cd, envir = as.environment(pos)) packageStartupMessage("Info: Disk based caching is enabled.") } + + op <- options() + toset <- !(names(pipapi_default_options) %in% names(op)) + if (any(toset)) options(pipapi_default_options[toset]) + + invisible() + } diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 00000000..00f29df8 --- /dev/null +++ b/docs/404.html @@ -0,0 +1,121 @@ + + + + + + + +Page not found (404) • pipapi + + + + + + + + + + + +
+
+ + + + +
+
+ + +Content not found. Please use links in the navbar. + +
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/CONTRIBUTING.html b/docs/CONTRIBUTING.html new file mode 100644 index 00000000..d890b0ca --- /dev/null +++ b/docs/CONTRIBUTING.html @@ -0,0 +1,127 @@ + +Contributing • pipapi + + +
+
+ + + +
+
+ + +
+ +

Development is a community effort, and we welcome participation.

+
+

Issues

+
  • Before posting a new issue or discussion topic, please take a moment to search for existing similar threads in order to avoid duplication.
  • +
  • For bug reports: if you can, please install the latest GitHub version of pipapi (i.e. remotes::install_github("PIP-Technical-Team/pipapi")) and verify that the issue still persists.
  • +
  • Describe your issue in prose as clearly and concisely as possible.
  • +
  • For any problem you identify, post a minimal reproducible example so the maintainer can troubleshoot. A reproducible example is: +
    • +Runnable: post enough R code and data so any onlooker can create the error on their own computer.
    • +
    • +Minimal: reduce runtime wherever possible and remove complicated details that are irrelevant to the issue at hand.
    • +
    • +Readable: format your code according to the tidyverse style guide.
    • +
  • +
+
+

Development

+

External code contributions are extremely helpful in the right circumstances. Here are the recommended steps.

+
  1. Prior to contribution, please propose your idea in a discussion topic or issue thread so you and the maintainer can define the intent and scope of your work.
  2. +
  3. +Clone or fork the repository.
  4. +
  5. Follow the GitHub flow to create a new branch, add commits, and open a pull request.
  6. +
  7. Discuss your code with the maintainer in the pull request thread.
  8. +
  9. If everything looks good, the maintainer will merge your code into the project.
  10. +

Please also follow these additional guidelines.

+
  • Respect the architecture and reasoning of the package.
  • +
  • If possible, keep contributions small enough to easily review manually. It is okay to split up your work into multiple pull requests.
  • +
  • For new features or functionality, add tests in tests. Tests that can be automated should go in tests/testthat/.
  • +
  • Format your code according to the tidyverse style guide and check your formatting with the lint_package() function from the lintr package.
  • +
  • Check code coverage with covr::package_coverage(). Automated tests should cover all the new or changed functionality in your pull request.
  • +
  • Run overall package checks with devtools::check().
  • +
+
+ +
+ + + +
+ + + +
+ + + + + + + + diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html new file mode 100644 index 00000000..1fdea57f --- /dev/null +++ b/docs/LICENSE-text.html @@ -0,0 +1,95 @@ + +License • pipapi + + +
+
+ + + +
+
+ + +
YEAR: 2020
+COPYRIGHT HOLDER: World Bank
+
+ +
+ + + +
+ + + +
+ + + + + + + + diff --git a/docs/LICENSE.html b/docs/LICENSE.html new file mode 100644 index 00000000..ec5770de --- /dev/null +++ b/docs/LICENSE.html @@ -0,0 +1,99 @@ + +MIT License • pipapi + + +
+
+ + + +
+
+ + +
+ +

Copyright (c) 2020 World Bank

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
+ +
+ + + +
+ + + +
+ + + + + + + + diff --git a/docs/PULL_REQUEST_TEMPLATE.html b/docs/PULL_REQUEST_TEMPLATE.html new file mode 100644 index 00000000..91f84d87 --- /dev/null +++ b/docs/PULL_REQUEST_TEMPLATE.html @@ -0,0 +1,107 @@ + +Prework • pipapi + + +
+
+ + + +
+
+ + + +
+ +
+
+

Related GitHub issues and pull requests

+
  • Ref: #
  • +
+
+

Summary

+

Please explain the purpose and scope of your contribution.

+
+ + +
+ + + +
+ + + +
+ + + + + + + + diff --git a/docs/articles/debug-caching.html b/docs/articles/debug-caching.html new file mode 100644 index 00000000..25bec325 --- /dev/null +++ b/docs/articles/debug-caching.html @@ -0,0 +1,237 @@ + + + + + + + +Debug caching and API endpoints • pipapi + + + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

How caching works? +

+

In pipapi package in file zzz.R we have +.onLoad function which looks like the following -

+
+.onLoad <- function(libname, pkgname) {
+  if (Sys.getenv("PIPAPI_APPLY_CACHING") == "TRUE") {
+    d <- rappdirs::user_cache_dir("pipapi")
+    # log <- sprintf("%s/cache.log", d)
+    cd <- cachem::cache_disk(d,
+                             read_fn = qs::qread,
+                             write_fn = qs::qsave,
+                             extension = ".qs",
+                             evict = "lru",
+                             logfile = NULL,
+                             max_size = as.numeric(Sys.getenv("PIPAPI_CACHE_MAX_SIZE")),
+                             prune_rate = 50)
+    pip <<- memoise::memoise(pip, cache = cd, omit_args = "lkup")
+    ui_hp_stacked <<- memoise::memoise(ui_hp_stacked, cache = cd, omit_args = "lkup")
+    pip_grp_logic <<- memoise::memoise(pip_grp_logic, cache = cd, omit_args = "lkup")
+    ui_cp_charts <<- memoise::memoise(ui_cp_charts, cache = cd, omit_args = "lkup")
+    ui_cp_download <<- memoise::memoise(ui_cp_download, cache = cd, omit_args = "lkup")
+    ui_cp_key_indicators <<- memoise::memoise(ui_cp_key_indicators, cache = cd, omit_args = "lkup")
+    assign("cd", cd, envir = .GlobalEnv)
+    packageStartupMessage("Info: Disk based caching is enabled.")
+  }
+}
+

What this means is that if this environment variable is set +Sys.getenv("PIPAPI_APPLY_CACHING") we create a caching file +which saves the result on our disk. This disk is your local computer if +you are working locally or server if the package is deployed there. This +caching file is generated at location d i.e +rappdirs::user_cache_dir("pipapi") in this case however, +you can change it to any local folder while debugging. Rest of the lines +include the functions that we are caching like pip, +ui_hp_stacked, pip_grp_logic and so on.

+

So how this works is that we let’s say call any function which is +cached, for example - pip.

+
+pip(country = "CHN", year = 2017, lkup = lkup)
+

Now a file is created at the cache location which has it’s output and +looks like this.

+

+

This is the file whose name is hashed based on the arguments passed +to the cached function (pip) and the log file has all the +logs of caching operation.

+

Now if a new call is made like :

+
+pip(country = "all", year = "all", lkup = lkup)
+

then a 2nd file is generated whereas the log file is updated.

+

If you call the 1st pip call again :

+
+pip(country = "CHN", year = 2017, lkup = lkup)
+

then this time it will use the cached result and give the output +instantly. No processing is done at all in this. No new file is +generated this time around but the log file is updated.

+
+
+

Debugging caching +

+

In pip-precaching-script repository, I have created a +branch called debug-ronak and in this branch if you look at +the file main.R you will see the exact script that I used +to debug the API. Note that there are two levels where we need to check +caching or any general PIP issue. One is when you are using +pip directly as a function like how we showed above like +pip(country = "all", year = "all", lkup = lkup) and another +one is via the API like how it is shown in main.R file. +Also note that I am using pip function as a general example +here. This is true for all the functions in pipapi package. +The API calls the functions from pipapi package so the +basic code is the same across both the levels. However, API has some +additional layers on top of these functions which might make them +different.

+

The recent case of caching not working only for country = “all” and +year = “all” was visible via API, however when we used the +pip call directly caching was working perfectly fine. So in +this case it was something in the API that was causing the trouble. It +is very rare but it does happen every now and then. And just to conclude +the topic the issue was that for intensive calculation like country = +“all” and year = “all” we were using +promises::future_promise function for asynchronous calling +and we forgot to include promises package in the +DESCRIPTION file of pipapi package so +promises package was not available and it did not work when +using country = “all” and year = “all”.

+

Moreover, it is very important to kill the API you +are launching if you are using the same port for debugging +(apis$kill()). We are using callr to launch +the API in new session so we can’t actually “see” that a session has +been launched so it is important to understand about this. For example, +if we launch the API on port 8080 with callr, the session +is busy in the background. In the current session that we have access to +is working normal and we can execute our code. If we do some changes and +run the same code to launch the API it would not reflect the changes +because the background session is still busy with the previous code and +has not been killed yet. In such scenario we have couple of options +:

+
    +
  1. Use new port number to run code in different session
  2. +
  3. Kill the previous session and launch the API again to see the +changes
  4. +
+

Step 2 is what apis$kill() is doing.

+

All the best!

+
+
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/articles/duckdb-caching.html b/docs/articles/duckdb-caching.html new file mode 100644 index 00000000..a0263d04 --- /dev/null +++ b/docs/articles/duckdb-caching.html @@ -0,0 +1,356 @@ + + + + + + + +duckdb-caching • pipapi + + + + + + + + + + + + +
+
+ + + + +
+
+ + + + +
+

Introduction +

+

Current caching mechanism for pip uses traditional caching where +basically a hash is created based on the value of the arguments passed +in the function and if someone calls the same function with the same +arguments again the cached result is returned instead of doing the same +calculation again. For pip we used the packages +cachem and memoise to implement this system of +caching. This traditional caching strategy works well in general +however, pip is a special case and it would benefit much +more if it had a custom strategy for caching.

+
+
+

How caching currently works? +

+

Consider these pip functions

+
+# 1.
+pip(country = "all", year = 2000, lkup = lkup)
+
+# 2.
+pip(country = "AGO", year = 2000, lkup = lkup)
+

Now since these are separate set of arguments 2 files of caching are +created and saved on the disk. Now if a call to pip is made +again pip(country = "AGO", year = 2000, lkup = lkup) which +is same as 2) then it would return the result from the cached file +stored on the disk without doing any calculation. Needless to say, this +result is much faster.

+

However, notice that the 2nd call is subset of the 1st one. What I +mean by that is the result of 2) is already present in result of 1). We +have done the calculations for all the countries for the year 2000 in 1) +we just need output of “AGO” from it to get the result for 2).

+
+
+

Custom caching for pipapi. +

+

What if we could take subset of an existing cache like how we need it +as above. However, this is not how traditional caching systems work. We +would need to implement something custom if we want to make this +work.

+

We came up with an idea to implement this custom caching using +duckdb in a table. Basically, all the queries that are +called till now are saved in this table and whenever a new call is made +it checks if the query is already called, if yes then it returns the +result immediately or else it will do the calculation and then save the +result to the table for next use and return the result. There are +various scenarios that we need to consider and let’s take help of an +example to understand each one of them.

+

Consider that we are just starting out and there is nothing saved in +the table.

+
+

Scenario 1 - +

+
+pip(country = c("AGO", "USA"), year = 2000, lkup = lkup)
+

Now since nothing is saved in the table this will go through the +whole round of calculation and save the result in the table for future +use and return the output.

+
+
+

Scenario 2 - +

+
+pip(country = "USA", year = 2000, lkup = lkup)
+

Now this is something which we have already calculated in our +previous call. In traditional caching this would be treated as a +separate call and the calculation would have been performed again. +However, in our custom caching it goes through the existing table and +checks if we already have the result for this call. Since we do have it +saved in our table we will just return the result in this case as it is +from the table without doing any calculation.

+
+
+

Scenario 3 - +

+
+pip(country = c("ARG", "USA"), year = 2000, lkup = lkup)
+

Notice this time it is combination of scenario 1 and 2 where one part +of the calculation we already have (“USA”) and another part we don’t +(“ARG”). In this case, we return the result for the country that we have +in the table and send rest of the arguments for the calculation. We save +the result from calculation in the table and return the output by +combining both the result.

+
+
+

Scenario 4 - +

+
+pip(country = "all", year = 2000, lkup = lkup)
+

In this scenario before we check in the table we need to decode this +“all” argument to list of actual country names because in the table we +save the data with actual country names. Once we have the list of +country names we check which of those values are already available in +the table. If we consider the 3 scenarios above then we already have +result for c("ARG", "AGO", "USA") and we need to find +result for the remaining countries. After saving the data for the +remaining countries in the table, we return the result by combining the +two.

+
+
+

Scenario 5 - +

+
+pip(country = "AGO", year = "all", lkup = lkup)
+

This is similar to scenario 4 but instead of having +country = "all" we have here year = "all" so +in this case we need to decode the year parameter. However, +the sequence of operation remains the same as above.

+
+
+

Scenario 6 - +

+
+pip(country = "all", year = "all", lkup = lkup)
+

This is combination of scenario 4 and 5 where we need to decode both +country and year parameter, check the values +that are present in the table, query the data that does not exist, save +it into the table, combine the result and return the output.

+

These are 6 different scenarios that can occur. Note that I have not +used all the arguments here in the pip call. We are using +the default povline i.e 1.9 here but it can be something +else. In which case, it will become scenario 1 where nothing is found in +the table and the output is calculated and result is saved in the table. +Similarly, we can also have situations where fill_gaps is +set to TRUE which would also follow the same process.

+
+
+
+

Code overview +

+

We are creating a duckdb file to save our table. The location of this +file is saved in an environment variable PIP_CACHE_FILE +(Example Sys.setenv(PIP_CACHE_FILE = "demo.duckdb")). A +table called master_file is created inside it where we save +our cache.

+

Based on fill_gaps parameter we call either the function +fg_pip or rg_pip. Both the functions call the +subset_lkup function to filter the data that from +lkup that is relevant to our call. In +subset_lkup function we call the function +return_if_exists which as the name suggests returns the +data from cache if it exists. A new file called +duckdb_fun.R has been added to manage all the functions +related to duckdb.

+

A named list is returned from return_if_exists function +where it returns the final output (if it exists) from the master file +and subsetted lkup (Scenario 3 where we have a part of data +in master file). The partial (or full) final output is again returned as +a named list from subset_lkup function which is used at the +end to combine the two outputs. If lkup is non-empty then +after all the calculation is done we use the function +update_master_file to append the master file with new +data.

+
+
+

Speed comparison +

+
+microbenchmark::microbenchmark(
+  duckdb_caching = pip(country = c("AGO", "USA"), year = 2000, lkup = lkup)
+)
+
+#Unit: milliseconds
+#          expr     min       lq     mean   median       uq      max neval
+#duckdb_caching 102.745 107.2221 112.5106 109.2035 114.8544 146.8841   100
+
+microbenchmark::microbenchmark(
+     pip_DEV = pip(country = c("AGO", "USA"), year = 2000, lkup = lkup)
+)
+
+#Unit: milliseconds
+#    expr      min       lq     mean   median       uq      max neval
+#pip_DEV 51.01007 53.67546 62.35531 56.08937 60.12046 354.7717   100
+
+microbenchmark::microbenchmark(
+  duckdb_caching = pip(country = "all", year = "all", lkup = lkup)
+)
+
+#Unit: milliseconds
+#           expr      min       lq     mean   median       uq      max neval
+# duckdb_caching 110.0725 115.0695 129.6408 118.4356 122.2621 494.3855   100
+
+microbenchmark::microbenchmark(
+  pip_DEV = pip(country = "all", year = "all", lkup = lkup)
+)
+
+#Unit: seconds
+#    expr      min       lq     mean   median       uq      max neval
+ #pip_DEV 14.42378 14.78717 14.98249 14.96088 15.11043 17.44418   100
+
+country_list <- c("AGO", "ARG", "AUT", "BEL", "BGD", "BLR", "BOL", "CAN", "CHE", 
+  "CHL", "COL", "CRI", "DEU", "DNK", "DOM", "ECU", "ESP", "EST", 
+  "FIN", "FRA", "FSM", "GBR", "GEO", "GRC", "GTM", "HRV", "HUN", 
+  "IDN", "IDN", "IDN", "IRL", "ITA", "KGZ", "LTU", "LUX", "MAR", 
+  "MDA", "MEX", "MKD", "MRT", "NOR", "PAN", "PER", "PHL", "PHL", 
+  "POL", "ROU", "RUS", "RWA", "SLV", "STP", "SWE", "SWZ", "THA", 
+  "TON", "TUN", "TWN", "TZA", "URY", "USA", "UZB", "ZAF")
+
+tictoc::tic()
+
+for(i in seq_along(country_list)) {
+  out <- pip(country = country_list[seq_len(i)], year = 2000, lkup = lkup)
+}
+
+tictoc::toc()
+
+## For Duckdb
+#16.69 sec elapsed
+
+## For DEV version
+#9.26 sec elapsed
+
+tictoc::tic()
+
+for(i in seq_along(country_list)) {
+  out <- pip(country = country_list[seq_len(i)], year = "all", lkup = lkup)
+}
+
+tictoc::toc()
+## DEV
+#178.97 sec elapsed
+
+## Duckdb caching
+#6.96 sec elapsed
+
+
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/articles/images/clipboard-2235948010.png b/docs/articles/images/clipboard-2235948010.png new file mode 100644 index 00000000..47f4e915 Binary files /dev/null and b/docs/articles/images/clipboard-2235948010.png differ diff --git a/docs/articles/index.html b/docs/articles/index.html new file mode 100644 index 00000000..0ebb8782 --- /dev/null +++ b/docs/articles/index.html @@ -0,0 +1,96 @@ + +Articles • pipapi + + +
+
+ + + +
+
+ + + +
+
+ + +
+ + + + + + + + diff --git a/docs/articles/new-endpoints.html b/docs/articles/new-endpoints.html new file mode 100644 index 00000000..0a4bbf83 --- /dev/null +++ b/docs/articles/new-endpoints.html @@ -0,0 +1,163 @@ + + + + + + + +How to include new endpoints in pipapi • pipapi + + + + + + + + + + + + +
+
+ + + + +
+
+ + + + +

In the recent update to pipapi we added three new +endpoints grouped-stats, regression-params and +lorenz-curve. The goal of this post is to share the process +of adding new endpoints in pipapi as there are lot of +checks in place in the code and it can be quite challenging to do +so.

+

Arguments : Every argument and it’s value passed to +the API is validated. This enhances the security of the API by making +sure only expected arguments and it’s value are passed through API.

+

The arguments are validated in function +validate_query_parameters which has a list of all valid +arguments for all the endpoints. If your endpoint is using an existing +argument then you don’t need to do anything since both the argument and +it’s value is already validated. For eg - If your endpoint has an +argument ppp which is an existing argument in the API then +you don’t need to do any changes since ppp is already +validated.

+

Values : Validate your input values in +create_query_controls function by adding range or list of +accepted values. If the arguments is character then you need to give all +possible values that it can take. If the argument is numeric, then you +need to supply min and max values to ensure +that the numeric values stays in range. Based on the type of argument, +check_param_chr, check_param_num or +check_param_lgl is called. This also ensures that the +argument name should mean the same everywhere. So it is not possible +that the same argument can have two different meaning. For example, it +is not possible that the argument requested_mean accepts +value 0 to 1 in one endpoint and c("yes"/"no") in another +endpoint again ensuring consistency.

+

Another thing to note is that the argument and values are available +in both req$args as well as req$argsQuery +however, all the validation is performed only on argsQuery +and only argsQuery is used the entire API. So we suggest to +continue using argsQuery for consistency purposes.

+
+ + + +
+ + + + +
+ + + + + + + + diff --git a/docs/authors.html b/docs/authors.html new file mode 100644 index 00000000..99139eb2 --- /dev/null +++ b/docs/authors.html @@ -0,0 +1,122 @@ + +Authors and Citation • pipapi + + +
+
+ + + +
+
+
+ + + +
  • +

    Tony Fujs. Author, maintainer. +

    +
  • +
  • +

    Aleksander Eilertsen. Author. +

    +
  • +
  • +

    World Bank. Copyright holder. +

    +
  • +
+
+
+

Citation

+ Source: DESCRIPTION +
+
+ + +

Fujs T, Eilertsen A (2025). +pipapi: API for the Poverty and Inequality Platform. +R package version 1.3.11.9000, https://github.com/PIP-Technical-Team/pipapi, https://pip-technical-team.github.io/pipapi. +

+
@Manual{,
+  title = {pipapi: API for the Poverty and Inequality Platform},
+  author = {Tony Fujs and Aleksander Eilertsen},
+  year = {2025},
+  note = {R package version 1.3.11.9000, https://github.com/PIP-Technical-Team/pipapi},
+  url = {https://pip-technical-team.github.io/pipapi},
+}
+ +
+ +
+ + + +
+ + + + + + + + diff --git a/docs/bootstrap-toc.css b/docs/bootstrap-toc.css new file mode 100644 index 00000000..5a859415 --- /dev/null +++ b/docs/bootstrap-toc.css @@ -0,0 +1,60 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ + +/* modified from https://github.com/twbs/bootstrap/blob/94b4076dd2efba9af71f0b18d4ee4b163aa9e0dd/docs/assets/css/src/docs.css#L548-L601 */ + +/* All levels of nav */ +nav[data-toggle='toc'] .nav > li > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; +} +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; +} +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; +} + +/* Nav: second level (shown on .active) */ +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} +nav[data-toggle='toc'] .nav .nav > li > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; +} +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 29px; +} +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 28px; + font-weight: 500; +} + +/* from https://github.com/twbs/bootstrap/blob/e38f066d8c203c3e032da0ff23cd2d6098ee2dd6/docs/assets/css/src/docs.css#L631-L634 */ +nav[data-toggle='toc'] .nav > .active > ul { + display: block; +} diff --git a/docs/bootstrap-toc.js b/docs/bootstrap-toc.js new file mode 100644 index 00000000..1cdd573b --- /dev/null +++ b/docs/bootstrap-toc.js @@ -0,0 +1,159 @@ +/*! + * Bootstrap Table of Contents v0.4.1 (http://afeld.github.io/bootstrap-toc/) + * Copyright 2015 Aidan Feldman + * Licensed under MIT (https://github.com/afeld/bootstrap-toc/blob/gh-pages/LICENSE.md) */ +(function() { + 'use strict'; + + window.Toc = { + helpers: { + // return all matching elements in the set, or their descendants + findOrFilter: function($el, selector) { + // http://danielnouri.org/notes/2011/03/14/a-jquery-find-that-also-finds-the-root-element/ + // http://stackoverflow.com/a/12731439/358804 + var $descendants = $el.find(selector); + return $el.filter(selector).add($descendants).filter(':not([data-toc-skip])'); + }, + + generateUniqueIdBase: function(el) { + var text = $(el).text(); + var anchor = text.trim().toLowerCase().replace(/[^A-Za-z0-9]+/g, '-'); + return anchor || el.tagName.toLowerCase(); + }, + + generateUniqueId: function(el) { + var anchorBase = this.generateUniqueIdBase(el); + for (var i = 0; ; i++) { + var anchor = anchorBase; + if (i > 0) { + // add suffix + anchor += '-' + i; + } + // check if ID already exists + if (!document.getElementById(anchor)) { + return anchor; + } + } + }, + + generateAnchor: function(el) { + if (el.id) { + return el.id; + } else { + var anchor = this.generateUniqueId(el); + el.id = anchor; + return anchor; + } + }, + + createNavList: function() { + return $(''); + }, + + createChildNavList: function($parent) { + var $childList = this.createNavList(); + $parent.append($childList); + return $childList; + }, + + generateNavEl: function(anchor, text) { + var $a = $(''); + $a.attr('href', '#' + anchor); + $a.text(text); + var $li = $('
  • '); + $li.append($a); + return $li; + }, + + generateNavItem: function(headingEl) { + var anchor = this.generateAnchor(headingEl); + var $heading = $(headingEl); + var text = $heading.data('toc-text') || $heading.text(); + return this.generateNavEl(anchor, text); + }, + + // Find the first heading level (`

    `, then `

    `, etc.) that has more than one element. Defaults to 1 (for `

    `). + getTopLevel: function($scope) { + for (var i = 1; i <= 6; i++) { + var $headings = this.findOrFilter($scope, 'h' + i); + if ($headings.length > 1) { + return i; + } + } + + return 1; + }, + + // returns the elements for the top level, and the next below it + getHeadings: function($scope, topLevel) { + var topSelector = 'h' + topLevel; + + var secondaryLevel = topLevel + 1; + var secondarySelector = 'h' + secondaryLevel; + + return this.findOrFilter($scope, topSelector + ',' + secondarySelector); + }, + + getNavLevel: function(el) { + return parseInt(el.tagName.charAt(1), 10); + }, + + populateNav: function($topContext, topLevel, $headings) { + var $context = $topContext; + var $prevNav; + + var helpers = this; + $headings.each(function(i, el) { + var $newNav = helpers.generateNavItem(el); + var navLevel = helpers.getNavLevel(el); + + // determine the proper $context + if (navLevel === topLevel) { + // use top level + $context = $topContext; + } else if ($prevNav && $context === $topContext) { + // create a new level of the tree and switch to it + $context = helpers.createChildNavList($prevNav); + } // else use the current $context + + $context.append($newNav); + + $prevNav = $newNav; + }); + }, + + parseOps: function(arg) { + var opts; + if (arg.jquery) { + opts = { + $nav: arg + }; + } else { + opts = arg; + } + opts.$scope = opts.$scope || $(document.body); + return opts; + } + }, + + // accepts a jQuery object, or an options object + init: function(opts) { + opts = this.helpers.parseOps(opts); + + // ensure that the data attribute is in place for styling + opts.$nav.attr('data-toggle', 'toc'); + + var $topContext = this.helpers.createChildNavList(opts.$nav); + var topLevel = this.helpers.getTopLevel(opts.$scope); + var $headings = this.helpers.getHeadings(opts.$scope, topLevel); + this.helpers.populateNav($topContext, topLevel, $headings); + } + }; + + $(function() { + $('nav[data-toggle="toc"]').each(function(i, el) { + var $nav = $(el); + Toc.init($nav); + }); + }); +})(); diff --git a/docs/docsearch.css b/docs/docsearch.css new file mode 100644 index 00000000..e5f1fe1d --- /dev/null +++ b/docs/docsearch.css @@ -0,0 +1,148 @@ +/* Docsearch -------------------------------------------------------------- */ +/* + Source: https://github.com/algolia/docsearch/ + License: MIT +*/ + +.algolia-autocomplete { + display: block; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1 +} + +.algolia-autocomplete .ds-dropdown-menu { + width: 100%; + min-width: none; + max-width: none; + padding: .75rem 0; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .1); + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); +} + +@media (min-width:768px) { + .algolia-autocomplete .ds-dropdown-menu { + width: 175% + } +} + +.algolia-autocomplete .ds-dropdown-menu::before { + display: none +} + +.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { + padding: 0; + background-color: rgb(255,255,255); + border: 0; + max-height: 80vh; +} + +.algolia-autocomplete .ds-dropdown-menu .ds-suggestions { + margin-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion { + padding: 0; + overflow: visible +} + +.algolia-autocomplete .algolia-docsearch-suggestion--category-header { + padding: .125rem 1rem; + margin-top: 0; + font-size: 1.3em; + font-weight: 500; + color: #00008B; + border-bottom: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--wrapper { + float: none; + padding-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { + float: none; + width: auto; + padding: 0; + text-align: left +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content { + float: none; + width: auto; + padding: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content::before { + display: none +} + +.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { + padding-top: .75rem; + margin-top: .75rem; + border-top: 1px solid rgba(0, 0, 0, .1) +} + +.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { + display: block; + padding: .1rem 1rem; + margin-bottom: 0.1; + font-size: 1.0em; + font-weight: 400 + /* display: none */ +} + +.algolia-autocomplete .algolia-docsearch-suggestion--title { + display: block; + padding: .25rem 1rem; + margin-bottom: 0; + font-size: 0.9em; + font-weight: 400 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--text { + padding: 0 1rem .5rem; + margin-top: -.25rem; + font-size: 0.8em; + font-weight: 400; + line-height: 1.25 +} + +.algolia-autocomplete .algolia-docsearch-footer { + width: 110px; + height: 20px; + z-index: 3; + margin-top: 10.66667px; + float: right; + font-size: 0; + line-height: 0; +} + +.algolia-autocomplete .algolia-docsearch-footer--logo { + background-image: url("data:image/svg+xml;utf8,"); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; + overflow: hidden; + text-indent: -9000px; + width: 100%; + height: 100%; + display: block; + transform: translate(-8px); +} + +.algolia-autocomplete .algolia-docsearch-suggestion--highlight { + color: #FF8C00; + background: rgba(232, 189, 54, 0.1) +} + + +.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { + box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) +} + +.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { + background-color: rgba(192, 192, 192, .15) +} diff --git a/docs/docsearch.js b/docs/docsearch.js new file mode 100644 index 00000000..b35504cd --- /dev/null +++ b/docs/docsearch.js @@ -0,0 +1,85 @@ +$(function() { + + // register a handler to move the focus to the search bar + // upon pressing shift + "/" (i.e. "?") + $(document).on('keydown', function(e) { + if (e.shiftKey && e.keyCode == 191) { + e.preventDefault(); + $("#search-input").focus(); + } + }); + + $(document).ready(function() { + // do keyword highlighting + /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ + var mark = function() { + + var referrer = document.URL ; + var paramKey = "q" ; + + if (referrer.indexOf("?") !== -1) { + var qs = referrer.substr(referrer.indexOf('?') + 1); + var qs_noanchor = qs.split('#')[0]; + var qsa = qs_noanchor.split('&'); + var keyword = ""; + + for (var i = 0; i < qsa.length; i++) { + var currentParam = qsa[i].split('='); + + if (currentParam.length !== 2) { + continue; + } + + if (currentParam[0] == paramKey) { + keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); + } + } + + if (keyword !== "") { + $(".contents").unmark({ + done: function() { + $(".contents").mark(keyword); + } + }); + } + } + }; + + mark(); + }); +}); + +/* Search term highlighting ------------------------------*/ + +function matchedWords(hit) { + var words = []; + + var hierarchy = hit._highlightResult.hierarchy; + // loop to fetch from lvl0, lvl1, etc. + for (var idx in hierarchy) { + words = words.concat(hierarchy[idx].matchedWords); + } + + var content = hit._highlightResult.content; + if (content) { + words = words.concat(content.matchedWords); + } + + // return unique words + var words_uniq = [...new Set(words)]; + return words_uniq; +} + +function updateHitURL(hit) { + + var words = matchedWords(hit); + var url = ""; + + if (hit.anchor) { + url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; + } else { + url = hit.url + '?q=' + escape(words.join(" ")); + } + + return url; +} diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 00000000..9ef5d646 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,233 @@ + + + + + + + +API for the Poverty and Inequality Platform • pipapi + + + + + + + + + + + + +
    +
    + + + + +
    +
    +
    + + + + +

    The goal of pipapi is to provide a high level API to the computations and methods that power the Poverty and Inequality Platform (PIP).

    +

    World Bank staff who have read access to the PIP data can use the functions from this package directly, without hitting the PIP API.

    +
    +

    Installation +

    +

    You can install the development version from GitHub with:

    +
    +# install.packages("devtools")
    +devtools::install_github("PIP-Technical-Team/pipapi")
    +
    +
    +

    Getting started +

    +

    The main function from the pipapi package is the pip() function. See ?pip for more information.

    +
    +

    Data access +

    +

    In order to use pip() you’ll need to have access to a PIP data_folder. The folder structure looks like this:

    +
    data-folder-root/
    +├─ _aux/
    +  ├─ pop_regions.fst
    +  ├─ pop.fst
    +  ├─ ...
    +├─ estimations/
    +  ├─ prod_svy_estimation.fst
    +  ├─ prod_ref_estimation.fst
    +├─ survey_data/
    +  ├─ survey_1.fst
    +  ├─ ...
    +  ├─ survey_n.fst
    +
    +# Create a list of look-up tables from the root data folder
    +lkups <- create_lkups("<data-folder>")
    +
    +
    +

    Usage +

    +

    Pass the lkups list to the main pip() function to compute poverty and inequality statistics in your R session.

    +
    +library(pipapi)
    +
    +pip(country = "AGO",
    +    year = 2000,
    +    povline = 1.9,
    +    lkup = lkups)
    +#>    region_code country_code reporting_year survey_acronym survey_coverage
    +#> 1:         SSA          AGO           2000            HBS        national
    +#>    survey_year welfare_type survey_comparability comparable_spell poverty_line
    +#> 1:     2000.21  consumption                    0             2000          1.9
    +#>    headcount poverty_gap poverty_severity     mean   median       mld      gini
    +#> 1: 0.3637448   0.1636806       0.09982393 4.100014 2.593394 0.5125765 0.5195689
    +#>    polarization     watts    decile1    decile2    decile3    decile4
    +#> 1:    0.4643401 0.2811239 0.00983246 0.02195307 0.03342455 0.04495307
    +#>       decile5    decile6    decile7   decile8  decile9  decile10
    +#> 1: 0.05662774 0.07048758 0.08808485 0.1134946 0.158687 0.4024552
    +#>    survey_mean_lcu survey_mean_ppp predicted_mean_ppp        cpi cpi_data_level
    +#> 1:        11.23264        4.100014                 NA 0.03385145       national
    +#>        ppp ppp_data_level reporting_pop pop_data_level reporting_gdp
    +#> 1: 80.9318       national      16395473       national      2195.631
    +#>    gdp_data_level reporting_pce pce_data_level is_interpolated
    +#> 1:       national            NA       national           FALSE
    +#>    is_used_for_aggregation distribution_type estimation_type
    +#> 1:                   FALSE             micro          survey
    +
    +
    +
    +
    + + +
    + + +
    + +
    +

    +

    Site built with pkgdown 2.0.7.

    +
    + +
    +
    + + + + + + + + diff --git a/docs/link.svg b/docs/link.svg new file mode 100644 index 00000000..88ad8276 --- /dev/null +++ b/docs/link.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/docs/news/index.html b/docs/news/index.html new file mode 100644 index 00000000..8707338a --- /dev/null +++ b/docs/news/index.html @@ -0,0 +1,283 @@ + +Changelog • pipapi + + +
    +
    + + + +
    +
    + + +
    + +
    • Hot fix with future dependency.
    • +
    +
    + +
    • fix bug for not including key_values into Lorenz quadratic function.
    • +
    +
    + +
    • update esimate_type filter for fillgaps at cl
    • +
    +
    + +
    • remove censoring and apply filter at the UI level.
    • +
    +
    + +
    • Add Prosperity Gap to both svy and lnp years.

    • +
    • Implement nowcast up to 2024

    • +
    • Add estimate_type variable to pip() and pip_grp*() calls

    • +
    • Add new aux file, metaregion

    • +
    • Change algorithms for MRV calls to return up to lineup year.

    • +
    • Modify unit tests to account for the changes above.

    • +
    • Fix distribution_type variables for both svy and lnp years.

    • +
    • improve algorithm of add_*() functions

    • +
    • Fix aggregation of medians

    • +
    • Update empty responses.

    • +
    • add end point wld-lineup-year to return nowcast year and tooltip text

    • +
    +
    + +

    remove censoring of official regions to account for cases like GNQ in which they are not counted as part of the total population of AFE and AFW

    +
    +
    + +
    +
    + +
    +
    + +
    +

    New features

    +
    • Add new SPR and SPL indicators
    • +
    • Add new endpoint grouped-stats to return grouped data
    • +
    +
    +

    Enhancements

    +
    • Address some linting issues
    • +
    • Increase test coverage
    • +
    • Improve caching for ui_cp_ki_headcount and ui_cp_poverty_charts +
    • +
    +
    +
    + +
    • Fix bug with ag_average_poverty_stats
    • +
    • Better control of returned columns
    • +
    • Fix bug that was causing wrong aggregates to be returned in some instances
    • +
    +
    + +
    +
    + +
    +
    + +
    +
    + +
    +

    New features

    +
    • New indicators available. Optional with additional_ind = TRUE +
    • +
    • /citation endpoint now returns additional information: version_id and accessed_date +
    • +
    • Limit accepted poverty lines to 3 decimals
    • +
    • Add new /version parameter that returns information about a specific data version
    • +
    • Povline is now limited to a maximum value of $2700 PPP (daily value)
    • +
    • +/aux endpoints now return tables in long_format by default
    • +
    • A new /ui_aux endpoint has been created with the opposite behavior: tables are returned in wide format by default.
    • +
    • +/pip-info returns additional information
    • +
    • New “etag” and “max-age” headers returned by the API to facilitate caching of API responses
    • +
    +
    +

    Enhancements

    +
    +
    +

    Bug fixes

    +
    • Hot fix to handle failing of create_vector_countries() when country="ALL" +
    • +
    • Fix cp-download
    • +
    • Fix creation of duplicated responses for some regional aggregates
    • +
    • Fix year selection for /pip-grp
    • +
    +
    + +
    + + +
    +

    New features

    +
    +
    +
    + +
    +

    New features

    +
    • Add /pip-grp as a new endpoint for aggregated statistics
    • +
    • Soft deprecate group_by argument in /pip
    • +
    • Change parameter version_length for vintage_pattern in extract_data_dirs(). The algorithm for extracting valid versions has been modified.
    • +
    • Add option to enable disk based caching of pip() and pip_grp() +
    • +
    • Add asynchronous processing of slow API requests
    • +
    +
    +

    Enhancements

    +
    • Increase maximum limit for povline parameter from 100 to 10 000
    • +
    • Remove unnecessary columns from API response
    • +
    • Add estimation_type and distribution_type to the API response when fill_gaps=TRUE +
    • +
    • Use pip_grp() to calculate aggregated statistics in UI functions; ui_hp_stacked() and ui_pc_regional() +
    • +
    • Add unit tests for pip_grp() +
    • +
    • Improve filtering of data version directories in create_versioned_lkups() +
    • +
    • Add country and region name to /pip response
    • +
    • Make sure latest data version is available as a specific version (not just as “latest_release”)
    • +
    • Use fs functions rather than base R’s.
    • +
    +
    +

    Bug fixes

    +
    • Duplicates are no longer created when fill_gaps=TRUE +
    • +
    • Add povline=NULL option for /cp-key-indicators endpoint. This fixes an issue with the UI ingestion.
    • +
    • Fix bug where distributional stats were incorrectly returned as missing for extrapolated surveys when fill_gaps=TRUE +
    • +
    • Add reporting_level to the output of ui_cp_poverty_charts() +
    • +
    • Make sure ui_cp_poverty_charts() only returns non-national observations when a country has no surveys with national coverage
    • +
    • Fix a bug in the application of censoring within pip_grp() +
    • +
    • Add a specific empty response for pip_grp() to ensure that the response is consistent when no data is available
    • +
    • Fix a bug in the selection of most recent value (year="MRV") when country="ALL" +
    • +
    +
    +
    + +

    Initial release of the API that powered the PIP soft-launch on February 9, 2022

    +
    +
    + +
    • Added a NEWS.md file to track changes to the package.
    • +
    +
    + + + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/pkgdown.css b/docs/pkgdown.css new file mode 100644 index 00000000..80ea5b83 --- /dev/null +++ b/docs/pkgdown.css @@ -0,0 +1,384 @@ +/* Sticky footer */ + +/** + * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ + * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css + * + * .Site -> body > .container + * .Site-content -> body > .container .row + * .footer -> footer + * + * Key idea seems to be to ensure that .container and __all its parents__ + * have height set to 100% + * + */ + +html, body { + height: 100%; +} + +body { + position: relative; +} + +body > .container { + display: flex; + height: 100%; + flex-direction: column; +} + +body > .container .row { + flex: 1 0 auto; +} + +footer { + margin-top: 45px; + padding: 35px 0 36px; + border-top: 1px solid #e5e5e5; + color: #666; + display: flex; + flex-shrink: 0; +} +footer p { + margin-bottom: 0; +} +footer div { + flex: 1; +} +footer .pkgdown { + text-align: right; +} +footer p { + margin-bottom: 0; +} + +img.icon { + float: right; +} + +/* Ensure in-page images don't run outside their container */ +.contents img { + max-width: 100%; + height: auto; +} + +/* Fix bug in bootstrap (only seen in firefox) */ +summary { + display: list-item; +} + +/* Typographic tweaking ---------------------------------*/ + +.contents .page-header { + margin-top: calc(-60px + 1em); +} + +dd { + margin-left: 3em; +} + +/* Section anchors ---------------------------------*/ + +a.anchor { + display: none; + margin-left: 5px; + width: 20px; + height: 20px; + + background-image: url(./link.svg); + background-repeat: no-repeat; + background-size: 20px 20px; + background-position: center center; +} + +h1:hover .anchor, +h2:hover .anchor, +h3:hover .anchor, +h4:hover .anchor, +h5:hover .anchor, +h6:hover .anchor { + display: inline-block; +} + +/* Fixes for fixed navbar --------------------------*/ + +.contents h1, .contents h2, .contents h3, .contents h4 { + padding-top: 60px; + margin-top: -40px; +} + +/* Navbar submenu --------------------------*/ + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu>.dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover>.dropdown-menu { + display: block; +} + +.dropdown-submenu>a:after { + display: block; + content: " "; + float: right; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; + border-width: 5px 0 5px 5px; + border-left-color: #cccccc; + margin-top: 5px; + margin-right: -10px; +} + +.dropdown-submenu:hover>a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left>.dropdown-menu { + left: -100%; + margin-left: 10px; + border-radius: 6px 0 6px 6px; +} + +/* Sidebar --------------------------*/ + +#pkgdown-sidebar { + margin-top: 30px; + position: -webkit-sticky; + position: sticky; + top: 70px; +} + +#pkgdown-sidebar h2 { + font-size: 1.5em; + margin-top: 1em; +} + +#pkgdown-sidebar h2:first-child { + margin-top: 0; +} + +#pkgdown-sidebar .list-unstyled li { + margin-bottom: 0.5em; +} + +/* bootstrap-toc tweaks ------------------------------------------------------*/ + +/* All levels of nav */ + +nav[data-toggle='toc'] .nav > li > a { + padding: 4px 20px 4px 6px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; +} + +nav[data-toggle='toc'] .nav > li > a:hover, +nav[data-toggle='toc'] .nav > li > a:focus { + padding-left: 5px; + color: inherit; + border-left: 1px solid #878787; +} + +nav[data-toggle='toc'] .nav > .active > a, +nav[data-toggle='toc'] .nav > .active:hover > a, +nav[data-toggle='toc'] .nav > .active:focus > a { + padding-left: 5px; + font-size: 1.5rem; + font-weight: 400; + color: inherit; + border-left: 2px solid #878787; +} + +/* Nav: second level (shown on .active) */ + +nav[data-toggle='toc'] .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; +} + +nav[data-toggle='toc'] .nav .nav > li > a { + padding-left: 16px; + font-size: 1.35rem; +} + +nav[data-toggle='toc'] .nav .nav > li > a:hover, +nav[data-toggle='toc'] .nav .nav > li > a:focus { + padding-left: 15px; +} + +nav[data-toggle='toc'] .nav .nav > .active > a, +nav[data-toggle='toc'] .nav .nav > .active:hover > a, +nav[data-toggle='toc'] .nav .nav > .active:focus > a { + padding-left: 15px; + font-weight: 500; + font-size: 1.35rem; +} + +/* orcid ------------------------------------------------------------------- */ + +.orcid { + font-size: 16px; + color: #A6CE39; + /* margins are required by official ORCID trademark and display guidelines */ + margin-left:4px; + margin-right:4px; + vertical-align: middle; +} + +/* Reference index & topics ----------------------------------------------- */ + +.ref-index th {font-weight: normal;} + +.ref-index td {vertical-align: top; min-width: 100px} +.ref-index .icon {width: 40px;} +.ref-index .alias {width: 40%;} +.ref-index-icons .alias {width: calc(40% - 40px);} +.ref-index .title {width: 60%;} + +.ref-arguments th {text-align: right; padding-right: 10px;} +.ref-arguments th, .ref-arguments td {vertical-align: top; min-width: 100px} +.ref-arguments .name {width: 20%;} +.ref-arguments .desc {width: 80%;} + +/* Nice scrolling for wide elements --------------------------------------- */ + +table { + display: block; + overflow: auto; +} + +/* Syntax highlighting ---------------------------------------------------- */ + +pre, code, pre code { + background-color: #f8f8f8; + color: #333; +} +pre, pre code { + white-space: pre-wrap; + word-break: break-all; + overflow-wrap: break-word; +} + +pre { + border: 1px solid #eee; +} + +pre .img, pre .r-plt { + margin: 5px 0; +} + +pre .img img, pre .r-plt img { + background-color: #fff; +} + +code a, pre a { + color: #375f84; +} + +a.sourceLine:hover { + text-decoration: none; +} + +.fl {color: #1514b5;} +.fu {color: #000000;} /* function */ +.ch,.st {color: #036a07;} /* string */ +.kw {color: #264D66;} /* keyword */ +.co {color: #888888;} /* comment */ + +.error {font-weight: bolder;} +.warning {font-weight: bolder;} + +/* Clipboard --------------------------*/ + +.hasCopyButton { + position: relative; +} + +.btn-copy-ex { + position: absolute; + right: 0; + top: 0; + visibility: hidden; +} + +.hasCopyButton:hover button.btn-copy-ex { + visibility: visible; +} + +/* headroom.js ------------------------ */ + +.headroom { + will-change: transform; + transition: transform 200ms linear; +} +.headroom--pinned { + transform: translateY(0%); +} +.headroom--unpinned { + transform: translateY(-100%); +} + +/* mark.js ----------------------------*/ + +mark { + background-color: rgba(255, 255, 51, 0.5); + border-bottom: 2px solid rgba(255, 153, 51, 0.3); + padding: 1px; +} + +/* vertical spacing after htmlwidgets */ +.html-widget { + margin-bottom: 10px; +} + +/* fontawesome ------------------------ */ + +.fab { + font-family: "Font Awesome 5 Brands" !important; +} + +/* don't display links in code chunks when printing */ +/* source: https://stackoverflow.com/a/10781533 */ +@media print { + code a:link:after, code a:visited:after { + content: ""; + } +} + +/* Section anchors --------------------------------- + Added in pandoc 2.11: https://github.com/jgm/pandoc-templates/commit/9904bf71 +*/ + +div.csl-bib-body { } +div.csl-entry { + clear: both; +} +.hanging-indent div.csl-entry { + margin-left:2em; + text-indent:-2em; +} +div.csl-left-margin { + min-width:2em; + float:left; +} +div.csl-right-inline { + margin-left:2em; + padding-left:1em; +} +div.csl-indent { + margin-left: 2em; +} diff --git a/docs/pkgdown.js b/docs/pkgdown.js new file mode 100644 index 00000000..6f0eee40 --- /dev/null +++ b/docs/pkgdown.js @@ -0,0 +1,108 @@ +/* http://gregfranko.com/blog/jquery-best-practices/ */ +(function($) { + $(function() { + + $('.navbar-fixed-top').headroom(); + + $('body').css('padding-top', $('.navbar').height() + 10); + $(window).resize(function(){ + $('body').css('padding-top', $('.navbar').height() + 10); + }); + + $('[data-toggle="tooltip"]').tooltip(); + + var cur_path = paths(location.pathname); + var links = $("#navbar ul li a"); + var max_length = -1; + var pos = -1; + for (var i = 0; i < links.length; i++) { + if (links[i].getAttribute("href") === "#") + continue; + // Ignore external links + if (links[i].host !== location.host) + continue; + + var nav_path = paths(links[i].pathname); + + var length = prefix_length(nav_path, cur_path); + if (length > max_length) { + max_length = length; + pos = i; + } + } + + // Add class to parent
  • , and enclosing
  • if in dropdown + if (pos >= 0) { + var menu_anchor = $(links[pos]); + menu_anchor.parent().addClass("active"); + menu_anchor.closest("li.dropdown").addClass("active"); + } + }); + + function paths(pathname) { + var pieces = pathname.split("/"); + pieces.shift(); // always starts with / + + var end = pieces[pieces.length - 1]; + if (end === "index.html" || end === "") + pieces.pop(); + return(pieces); + } + + // Returns -1 if not found + function prefix_length(needle, haystack) { + if (needle.length > haystack.length) + return(-1); + + // Special case for length-0 haystack, since for loop won't run + if (haystack.length === 0) { + return(needle.length === 0 ? 0 : -1); + } + + for (var i = 0; i < haystack.length; i++) { + if (needle[i] != haystack[i]) + return(i); + } + + return(haystack.length); + } + + /* Clipboard --------------------------*/ + + function changeTooltipMessage(element, msg) { + var tooltipOriginalTitle=element.getAttribute('data-original-title'); + element.setAttribute('data-original-title', msg); + $(element).tooltip('show'); + element.setAttribute('data-original-title', tooltipOriginalTitle); + } + + if(ClipboardJS.isSupported()) { + $(document).ready(function() { + var copyButton = ""; + + $("div.sourceCode").addClass("hasCopyButton"); + + // Insert copy buttons: + $(copyButton).prependTo(".hasCopyButton"); + + // Initialize tooltips: + $('.btn-copy-ex').tooltip({container: 'body'}); + + // Initialize clipboard: + var clipboardBtnCopies = new ClipboardJS('[data-clipboard-copy]', { + text: function(trigger) { + return trigger.parentNode.textContent.replace(/\n#>[^\n]*/g, ""); + } + }); + + clipboardBtnCopies.on('success', function(e) { + changeTooltipMessage(e.trigger, 'Copied!'); + e.clearSelection(); + }); + + clipboardBtnCopies.on('error', function() { + changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); + }); + }); + } +})(window.jQuery || window.$) diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml new file mode 100644 index 00000000..c232a2e4 --- /dev/null +++ b/docs/pkgdown.yml @@ -0,0 +1,12 @@ +pandoc: '3.2' +pkgdown: 2.0.7 +pkgdown_sha: ~ +articles: + debug-caching: debug-caching.html + duckdb-caching: duckdb-caching.html + new-endpoints: new-endpoints.html +last_built: 2025-01-13T15:48Z +urls: + reference: https://pip-technical-team.github.io/pipapi/reference + article: https://pip-technical-team.github.io/pipapi/articles + diff --git a/docs/reference/Rplot001.png b/docs/reference/Rplot001.png new file mode 100644 index 00000000..17a35806 Binary files /dev/null and b/docs/reference/Rplot001.png differ diff --git a/docs/reference/add_agg_medians.html b/docs/reference/add_agg_medians.html new file mode 100644 index 00000000..0785a723 --- /dev/null +++ b/docs/reference/add_agg_medians.html @@ -0,0 +1,121 @@ + +Add Aggregate medians — add_agg_medians • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add Aggregate medians

    +
    + +
    +
    add_agg_medians(df, fill_gaps, data_dir)
    +
    + +
    +

    Arguments

    +
    df
    +

    data frame from either fg_pip or rg_pip

    + + +
    fill_gaps
    +

    logical: If set to TRUE, will interpolate / extrapolate +values for missing years

    + + +
    data_dir
    +

    character: Directory path of auxiliary data. Usually +lkup$data_root

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/add_dist_stats.html b/docs/reference/add_dist_stats.html new file mode 100644 index 00000000..3f175285 --- /dev/null +++ b/docs/reference/add_dist_stats.html @@ -0,0 +1,115 @@ + +Add pre-computed distributional stats — add_dist_stats • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add pre-computed distributional stats

    +
    + +
    +
    add_dist_stats(df, dist_stats)
    +
    + +
    +

    Arguments

    +
    df
    +

    data.table: Data frame of poverty statistics

    + + +
    dist_stats
    +

    data.table: Distributional stats lookup

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/add_distribution_type.html b/docs/reference/add_distribution_type.html new file mode 100644 index 00000000..185c116e --- /dev/null +++ b/docs/reference/add_distribution_type.html @@ -0,0 +1,120 @@ + +Add Distribution type — add_distribution_type • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add Distribution type

    +
    + +
    +
    add_distribution_type(df, lkup, fill_gaps)
    +
    + +
    +

    Arguments

    +
    df
    +

    data frame from fg_pip or rg_pip

    + + +
    lkup
    +

    list: lookup table

    + + +
    fill_gaps
    +

    logical: If set to TRUE, will interpolate / extrapolate +values for missing years

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/add_pg.html b/docs/reference/add_pg.html new file mode 100644 index 00000000..de112e20 --- /dev/null +++ b/docs/reference/add_pg.html @@ -0,0 +1,121 @@ + +Add Prosperity Gap — add_pg • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add Prosperity Gap

    +
    + +
    +
    add_pg(df, fill_gaps, data_dir)
    +
    + +
    +

    Arguments

    +
    df
    +

    data frame inside fg_pip or rg_pip

    + + +
    fill_gaps
    +

    logical: If set to TRUE, will interpolate / extrapolate +values for missing years

    + + +
    data_dir
    +

    character: Directory path of auxiliary data. Usually +lkup$data_root

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/add_spl.html b/docs/reference/add_spl.html new file mode 100644 index 00000000..7cd4c3c3 --- /dev/null +++ b/docs/reference/add_spl.html @@ -0,0 +1,121 @@ + +Add SPL indicators to either fg* or rg PIP output — add_spl • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add SPL indicators to either fg* or rg PIP output

    +
    + +
    +
    add_spl(df, fill_gaps, data_dir)
    +
    + +
    +

    Arguments

    +
    df
    +

    data frame inside fg_pip or rg_pip

    + + +
    fill_gaps
    +

    logical: If set to TRUE, will interpolate / extrapolate +values for missing years

    + + +
    data_dir
    +

    character: Directory path of auxiliary data. Usually +lkup$data_root

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/add_vars_out_of_pipeline.html b/docs/reference/add_vars_out_of_pipeline.html new file mode 100644 index 00000000..d3d7c306 --- /dev/null +++ b/docs/reference/add_vars_out_of_pipeline.html @@ -0,0 +1,118 @@ + +Add all the variables that are estimated outside the pipelines — add_vars_out_of_pipeline • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    This includes variables such as the SPL, SPR, PG, and distribution +type. Any other variables will be included here

    +
    + +
    +
    add_vars_out_of_pipeline(out, fill_gaps, lkup)
    +
    + +
    +

    Arguments

    +
    fill_gaps
    +

    logical: If set to TRUE, will interpolate / extrapolate +values for missing years

    + + +
    lkup
    +

    list: lookup table

    + +
    +
    +

    Value

    + + +

    data.table from pip or pip_grp functions.

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/assign_serializer.html b/docs/reference/assign_serializer.html new file mode 100644 index 00000000..c1d1e852 --- /dev/null +++ b/docs/reference/assign_serializer.html @@ -0,0 +1,111 @@ + +Helper function to return correct serializer — assign_serializer • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to return correct serializer

    +
    + +
    +
    assign_serializer(format)
    +
    + +
    +

    Arguments

    +
    format
    +

    characer: Response format. Options are "json", "csv", or "rds"

    + +
    +
    +

    Value

    + + +

    serializer function

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/available_versions.html b/docs/reference/available_versions.html new file mode 100644 index 00000000..acfc36b1 --- /dev/null +++ b/docs/reference/available_versions.html @@ -0,0 +1,111 @@ + +Sorted available PIP versions in data directory — available_versions • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Sorted available PIP versions in data directory

    +
    + +
    +
    available_versions(data_dir)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: data directory

    + +
    +
    +

    Value

    + + +

    character vector of sorted available PIP versions in data directory

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/censor_stats.html b/docs/reference/censor_stats.html new file mode 100644 index 00000000..79c08891 --- /dev/null +++ b/docs/reference/censor_stats.html @@ -0,0 +1,109 @@ + +Censor stats — censor_stats • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Censor stats

    +
    + +
    +
    censor_stats(df, censored_table)
    +
    + +
    +

    Arguments

    +
    df
    +

    data.table: Table to censor.

    + + +
    censored_table
    +

    data.table: Censor table

    + +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/change_grouped_stats_to_csv.html b/docs/reference/change_grouped_stats_to_csv.html new file mode 100644 index 00000000..853b3632 --- /dev/null +++ b/docs/reference/change_grouped_stats_to_csv.html @@ -0,0 +1,111 @@ + +Change the list-output to dataframe — change_grouped_stats_to_csv • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Change the list-output to dataframe

    +
    + +
    +
    change_grouped_stats_to_csv(out)
    +
    + +
    +

    Arguments

    +
    out
    +

    output from wbpip::gd_compute_pip_stats

    + +
    +
    +

    Value

    + + +

    dataframe

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/citation_from_version.html b/docs/reference/citation_from_version.html new file mode 100644 index 00000000..5d6c05d8 --- /dev/null +++ b/docs/reference/citation_from_version.html @@ -0,0 +1,111 @@ + +Return citation from the version — citation_from_version • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return citation from the version

    +
    + +
    +
    citation_from_version(version)
    +
    + +
    +

    Arguments

    +
    version
    +

    character vector of data version

    + +
    +
    +

    Value

    + + +

    character. Text containing citation for the version passed.

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/clear_cache.html b/docs/reference/clear_cache.html new file mode 100644 index 00000000..08d42251 --- /dev/null +++ b/docs/reference/clear_cache.html @@ -0,0 +1,116 @@ + +Clear cache +Clear cache directory if available — clear_cache • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Clear cache +Clear cache directory if available

    +
    + +
    +
    clear_cache(cd)
    +
    + +
    +

    Arguments

    +
    cd
    +

    A cachem::cache_disk() object

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/create_countries_vctr.html b/docs/reference/create_countries_vctr.html new file mode 100644 index 00000000..15ccdbae --- /dev/null +++ b/docs/reference/create_countries_vctr.html @@ -0,0 +1,128 @@ + +Create countries vectors — create_countries_vctr • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    This functions selects the correct countries to be used in the aggregates +selected by the user, either official or alternative aggregates.

    +
    + +
    +
    create_countries_vctr(country, year, valid_years, aux_files)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    valid_years
    +

    list: Valid years information provided through lkup object

    + + +
    aux_files
    +

    list: List of auxiliary tables provided through lkup object

    + +
    +
    +

    Value

    + + +

    a list of vectors with countries and regions code to be used in +pip() and pip_grp()

    + + +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/create_etag_header.html b/docs/reference/create_etag_header.html new file mode 100644 index 00000000..ce6c97c6 --- /dev/null +++ b/docs/reference/create_etag_header.html @@ -0,0 +1,119 @@ + +create_etag_header — create_etag_header • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    helper function that creates a unique hash of code + data +this hash value will be used as the value of the etag header +to facilitate caching of PIP API responses

    +
    + +
    +
    create_etag_header(req, lkups)
    +
    + +
    +

    Arguments

    +
    req
    +

    R6 object: Plumber API request

    + + +
    lkups
    +

    list: pipapi master lkups

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/create_lkups.html b/docs/reference/create_lkups.html new file mode 100644 index 00000000..70ad52ee --- /dev/null +++ b/docs/reference/create_lkups.html @@ -0,0 +1,115 @@ + +Create look-up tables — create_lkups • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Create look-up tables that can be passed to pip().

    +
    + +
    +
    create_lkups(data_dir, versions)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Path to PIP data root folder.

    + + +
    versions
    +

    character: Available data versions

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/create_return_cols.html b/docs/reference/create_return_cols.html new file mode 100644 index 00000000..620f3a2c --- /dev/null +++ b/docs/reference/create_return_cols.html @@ -0,0 +1,111 @@ + +helper function to create a list of return columns for various pipapi functions — create_return_cols • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    helper function to create a list of return columns for various pipapi functions

    +
    + +
    +
    create_return_cols(...)
    +
    + +
    +

    Arguments

    +
    ...
    +

    Named vectors of columns to be returned

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/create_versioned_lkups.html b/docs/reference/create_versioned_lkups.html new file mode 100644 index 00000000..0ab325b1 --- /dev/null +++ b/docs/reference/create_versioned_lkups.html @@ -0,0 +1,116 @@ + +Create one list of lookups per data version — create_versioned_lkups • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Create one list of lookups per data version

    +
    + +
    +
    create_versioned_lkups(data_dir, vintage_pattern = NULL)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Path to the main data directory

    + + +
    vintage_pattern
    +

    character: regex that identifies the name pattern of +vintage folders

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/create_vintage_pattern_call.html b/docs/reference/create_vintage_pattern_call.html new file mode 100644 index 00000000..ec7c3cf3 --- /dev/null +++ b/docs/reference/create_vintage_pattern_call.html @@ -0,0 +1,131 @@ + +create vintage call to be parsed into get_vintage_pattern_regex() — create_vintage_pattern_call • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    create vintage call to be parsed into get_vintage_pattern_regex()

    +
    + +
    +
    create_vintage_pattern_call(vintage_pattern = NULL)
    +
    + +
    +

    Arguments

    +
    vintage_pattern
    +

    either NULL, chracter with regex or list of arguments +for get_vintage_pattern_regex()

    + +
    +
    +

    Value

    + + +

    list to be parses t get_vintage_pattern_regex()

    + + +
    + +
    +

    Examples

    +
    if (FALSE) {
    +vintage_pattern <- NULL
    +create_vintage_pattern_call(vintage_pattern)
    +
    +vintage_pattern <- list("r.*", "", "^hjkhj\\.d")
    +create_vintage_pattern_call(vintage_pattern)
    +
    +vintage_pattern <- c("r.*", "", "^hjkhj\\.d")
    +create_vintage_pattern_call(vintage_pattern)
    +
    +vintage_pattern <- c(vintage_pattern = "r.*", test_regex = "", int_regex =  "^hjkhj\\.d")
    +create_vintage_pattern_call(vintage_pattern)
    +}
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/empty_response.html b/docs/reference/empty_response.html new file mode 100644 index 00000000..bfe3ac52 --- /dev/null +++ b/docs/reference/empty_response.html @@ -0,0 +1,103 @@ + +Empty response schema — empty_response • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    A template for empty responses

    +
    + +
    +
    empty_response
    +
    + +
    +

    Format

    +

    An object of class data.table (inherits from data.frame) with 0 rows and 44 columns.

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/empty_response_cp_poverty.html b/docs/reference/empty_response_cp_poverty.html new file mode 100644 index 00000000..9a341507 --- /dev/null +++ b/docs/reference/empty_response_cp_poverty.html @@ -0,0 +1,103 @@ + +List of two datasets pov_trend and pov_mrv — empty_response_cp_poverty • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    List of two datasets pov_trend and pov_mrv

    +
    + +
    +
    data(empty_response_cp_poverty)
    +
    + +
    +

    Format

    +

    A list with 2 dataframes

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/empty_response_grp.html b/docs/reference/empty_response_grp.html new file mode 100644 index 00000000..45523957 --- /dev/null +++ b/docs/reference/empty_response_grp.html @@ -0,0 +1,103 @@ + +Dataframe for grouped empty response — empty_response_grp • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Dataframe for grouped empty response

    +
    + +
    +
    data(empty_response_grp)
    +
    + +
    +

    Format

    +

    Data frame with 0 rows and 12 columns

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/estimate_type_ctr_lnp.html b/docs/reference/estimate_type_ctr_lnp.html new file mode 100644 index 00000000..74b3e20c --- /dev/null +++ b/docs/reference/estimate_type_ctr_lnp.html @@ -0,0 +1,115 @@ + +Add estimate_type var to lineup at the country level — estimate_type_ctr_lnp • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add estimate_type var to lineup at the country level

    +
    + +
    +
    estimate_type_ctr_lnp(out, lkup)
    +
    + +
    +

    Arguments

    +
    out
    +

    current data base

    + + +
    lkup
    +

    lkup list

    + +
    +
    +

    Value

    + + +

    out database with estimate_type variable

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/estimate_type_var.html b/docs/reference/estimate_type_var.html new file mode 100644 index 00000000..771cae1c --- /dev/null +++ b/docs/reference/estimate_type_var.html @@ -0,0 +1,109 @@ + +projection variables — estimate_type_var • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    It also censors specific stats

    +
    + +
    +
    estimate_type_var(df, lkup)
    +
    + +
    +

    Arguments

    +
    df
    +

    data.table: Table to censor.

    + + +
    censored_table
    +

    data.table: Censor table

    + +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/extract_identity.html b/docs/reference/extract_identity.html new file mode 100644 index 00000000..ab5d72b2 --- /dev/null +++ b/docs/reference/extract_identity.html @@ -0,0 +1,111 @@ + +Return identity from the version of the data — extract_identity • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return identity from the version of the data

    +
    + +
    +
    extract_identity(version)
    +
    + +
    +

    Arguments

    +
    version
    +

    character vector of data version

    + +
    +
    +

    Value

    + + +

    character vector of identity

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/extract_ppp_date.html b/docs/reference/extract_ppp_date.html new file mode 100644 index 00000000..6a40e19f --- /dev/null +++ b/docs/reference/extract_ppp_date.html @@ -0,0 +1,111 @@ + +Return the ppp date from the version of the data — extract_ppp_date • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return the ppp date from the version of the data

    +
    + +
    +
    extract_ppp_date(version)
    +
    + +
    +

    Arguments

    +
    version
    +

    character vector of data version

    + +
    +
    +

    Value

    + + +

    Date of ppp

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/extract_release_date.html b/docs/reference/extract_release_date.html new file mode 100644 index 00000000..9793f846 --- /dev/null +++ b/docs/reference/extract_release_date.html @@ -0,0 +1,111 @@ + +Return the release date from the version of the data — extract_release_date • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return the release date from the version of the data

    +
    + +
    +
    extract_release_date(version)
    +
    + +
    +

    Arguments

    +
    version
    +

    character vector of data version

    + +
    +
    +

    Value

    + + +

    Date of release

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/fg_assign_nas_values_to_dup_cols.html b/docs/reference/fg_assign_nas_values_to_dup_cols.html new file mode 100644 index 00000000..7a6a061a --- /dev/null +++ b/docs/reference/fg_assign_nas_values_to_dup_cols.html @@ -0,0 +1,115 @@ + +Coerce variable causing potential duplicates to NAs — fg_assign_nas_values_to_dup_cols • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Coerce variable causing potential duplicates to NAs

    +
    + +
    +
    fg_assign_nas_values_to_dup_cols(df, cols)
    +
    + +
    +

    Arguments

    +
    df
    +

    data.table: Table of results created in fg_pip()

    + + +
    cols
    +

    character: Columns with potential duplicate values

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/fg_pip.html b/docs/reference/fg_pip.html new file mode 100644 index 00000000..10e07ad5 --- /dev/null +++ b/docs/reference/fg_pip.html @@ -0,0 +1,154 @@ + +Compute imputed year stats — fg_pip • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Compute the main PIP poverty and inequality statistics for imputed years.

    +
    + +
    +
    fg_pip(
    +  country,
    +  year,
    +  povline,
    +  popshare,
    +  welfare_type,
    +  reporting_level,
    +  ppp,
    +  lkup,
    +  con
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    popshare
    +

    numeric: Proportion of the population living below the +poverty line

    + + +
    welfare_type
    +

    character: Welfare type

    + + +
    reporting_level
    +

    character: Geographical reporting level

    + + +
    ppp
    +

    numeric: Custom Purchase Power Parity value

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    con
    +

    duckdb connection object

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/fg_remove_duplicates.html b/docs/reference/fg_remove_duplicates.html new file mode 100644 index 00000000..efce9685 --- /dev/null +++ b/docs/reference/fg_remove_duplicates.html @@ -0,0 +1,122 @@ + +Remove duplicated rows created during the interpolation process — fg_remove_duplicates • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Remove duplicated rows created during the interpolation process

    +
    + +
    +
    fg_remove_duplicates(
    +  df,
    +  cols = c("comparable_spell", "cpi", "display_cp", "gd_type", "interpolation_id",
    +    "path", "predicted_mean_ppp", "survey_acronym", "survey_comparability",
    +    "survey_coverage", "survey_id", "survey_mean_lcu", "survey_mean_ppp",
    +    "survey_median_lcu", "survey_median_ppp", "survey_time", "survey_year",
    +    "surveyid_year")
    +)
    +
    + +
    +

    Arguments

    +
    df
    +

    data.table: Table of results created in fg_pip()

    + + +
    cols
    +

    character: Columns with potential duplicate values

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/fg_standardize_cache_id.html b/docs/reference/fg_standardize_cache_id.html new file mode 100644 index 00000000..6f48b67b --- /dev/null +++ b/docs/reference/fg_standardize_cache_id.html @@ -0,0 +1,119 @@ + +Standardize cache_id format to avoid duplication of rows — fg_standardize_cache_id • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Standardize cache_id format to avoid duplication of rows

    +
    + +
    +
    fg_standardize_cache_id(cache_id, interpolation_id, reporting_level)
    +
    + +
    +

    Arguments

    +
    cache_id
    +

    character

    + + +
    interpolation_id
    +

    character

    + + +
    reporting_level
    +

    character

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/fillin_list.html b/docs/reference/fillin_list.html new file mode 100644 index 00000000..32488f41 --- /dev/null +++ b/docs/reference/fillin_list.html @@ -0,0 +1,141 @@ + +Populate list in parent frame — fillin_list • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Fill in maned objects of a list with the value of named objects in the +parent frame in which the list has been created. This objects must have the +same names as the objects of the list

    +
    + +
    +
    fillin_list(l, assign = TRUE)
    +
    + +
    +

    Arguments

    +
    l
    +

    list to populate with names objects

    + + +
    assign
    +

    logical: whether to assign to parent frame

    + +
    +
    +

    Value

    + + +

    invisible list l populated with objects of the same frame

    +
    + +
    +

    Examples

    +
    l <- list(x = NULL,
    +y = NULL,
    +z = NULL)
    +
    +x <-  2
    +y <-  "f"
    +z <- TRUE
    +fillin_list(l)
    +l
    +#> $x
    +#> [1] 2
    +#> 
    +#> $y
    +#> [1] "f"
    +#> 
    +#> $z
    +#> [1] TRUE
    +#> 
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/filter_lkup.html b/docs/reference/filter_lkup.html new file mode 100644 index 00000000..67c3322d --- /dev/null +++ b/docs/reference/filter_lkup.html @@ -0,0 +1,130 @@ + +Helper to filter metadata +aggregate distribution need to be filtered out when popshare is not null +This is a temporary function until a full fix is implemented, and popshare is +supported for all distributions — filter_lkup • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper to filter metadata +aggregate distribution need to be filtered out when popshare is not null +This is a temporary function until a full fix is implemented, and popshare is +supported for all distributions

    +
    + +
    +
    filter_lkup(metadata, popshare)
    +
    + +
    +

    Arguments

    +
    metadata
    +

    data.frame: Output of subset_lkup()

    + + +
    popshare
    +

    numeric: popshare value passed to pip()

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/filter_md.html b/docs/reference/filter_md.html new file mode 100644 index 00000000..fe21dc3c --- /dev/null +++ b/docs/reference/filter_md.html @@ -0,0 +1,119 @@ + +Helper function to filter missing data table — filter_md • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to filter missing data table

    +
    + +
    +
    filter_md(md, ctr_alt_agg, year)
    +
    + +
    +

    Arguments

    +
    md
    +

    data.frame: Table of countries with missing data

    + + +
    ctr_alt_agg
    +

    character: Countries from alternate aggregates

    + + +
    year
    +

    character: year

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_additional_indicators.html b/docs/reference/get_additional_indicators.html new file mode 100644 index 00000000..1d111e38 --- /dev/null +++ b/docs/reference/get_additional_indicators.html @@ -0,0 +1,111 @@ + +Add set of extra indicators to pip output — get_additional_indicators • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add set of extra indicators to pip output

    +
    + +
    +
    get_additional_indicators(dt)
    +
    + +
    +

    Arguments

    +
    dt
    +

    data.frame: country level out from PIP

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_additional_indicators_grp.html b/docs/reference/get_additional_indicators_grp.html new file mode 100644 index 00000000..8060b685 --- /dev/null +++ b/docs/reference/get_additional_indicators_grp.html @@ -0,0 +1,111 @@ + +Add set of extra indicators to pip output in aggregate data. — get_additional_indicators_grp • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Add set of extra indicators to pip output in aggregate data.

    +
    + +
    +
    get_additional_indicators_grp(dt)
    +
    + +
    +

    Arguments

    +
    dt
    +

    data.frame: global/regional level from PIP-grp

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_aux_table.html b/docs/reference/get_aux_table.html new file mode 100644 index 00000000..397d250e --- /dev/null +++ b/docs/reference/get_aux_table.html @@ -0,0 +1,119 @@ + +Return specified auxiliary data — get_aux_table • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return specified auxiliary data

    +
    + +
    +
    get_aux_table(data_dir, table, long_format = FALSE)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Data directory

    + + +
    table
    +

    character: Name of auxiliary table

    + + +
    long_format
    +

    logical: do you want data long format ? (default FALSE)

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_aux_table_ui.html b/docs/reference/get_aux_table_ui.html new file mode 100644 index 00000000..e5489978 --- /dev/null +++ b/docs/reference/get_aux_table_ui.html @@ -0,0 +1,120 @@ + +Return specified auxiliary data in wide format +Helper function to the UI — get_aux_table_ui • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return specified auxiliary data in wide format +Helper function to the UI

    +
    + +
    +
    get_aux_table_ui(data_dir, table)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Data directory

    + + +
    table
    +

    character: Name of auxiliary table

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_caller_names.html b/docs/reference/get_caller_names.html new file mode 100644 index 00000000..238ac6d0 --- /dev/null +++ b/docs/reference/get_caller_names.html @@ -0,0 +1,105 @@ + +Get functions names in call stack — get_caller_names • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Get functions names in call stack

    +
    + +
    +
    get_caller_names()
    +
    + +
    +

    Value

    + + +

    character vector of calls

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_ctr_alt_agg.html b/docs/reference/get_ctr_alt_agg.html new file mode 100644 index 00000000..36b86a86 --- /dev/null +++ b/docs/reference/get_ctr_alt_agg.html @@ -0,0 +1,158 @@ + +Helper function to retrieve the required countries +needed to compute alternative aggregates requested by user +Get countries that belong to aggregates requested by the user that are NOT +official but alternative aggregates. We need to find out missing data +estimates only for those countries. For instance, if the user requested LAC +and AFE, we don't care about the the countries with missing data in the LAC +because their estimates are done implicitly. We DO care about the estimates +of the missing countries in AFE because we need the explicit SSA estimates. — get_ctr_alt_agg • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to retrieve the required countries +needed to compute alternative aggregates requested by user +Get countries that belong to aggregates requested by the user that are NOT +official but alternative aggregates. We need to find out missing data +estimates only for those countries. For instance, if the user requested LAC +and AFE, we don't care about the the countries with missing data in the LAC +because their estimates are done implicitly. We DO care about the estimates +of the missing countries in AFE because we need the explicit SSA estimates.

    +
    + +
    +
    get_ctr_alt_agg(user_alt_gt, user_alt_gt_code, user_alt_agg, cl)
    +
    + +
    +

    Arguments

    +
    user_alt_gt
    +

    character: Grouping type needed by user

    + + +
    user_alt_gt_code
    +

    character: Grouping type code

    + + +
    user_alt_agg
    +

    character: Alternate aggregates requested by user

    + + +
    cl
    +

    data.frame: Countries lookup table

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_grp_to_compute.html b/docs/reference/get_grp_to_compute.html new file mode 100644 index 00000000..57c05bbe --- /dev/null +++ b/docs/reference/get_grp_to_compute.html @@ -0,0 +1,123 @@ + +Helper function to retrieve the country/year pairs to be computed — get_grp_to_compute • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to retrieve the country/year pairs to be computed

    +
    + +
    +
    get_grp_to_compute(user_off_reg, md_off_reg, year, md_year)
    +
    + +
    +

    Arguments

    +
    user_off_reg
    +

    character: Official regions requested by user

    + + +
    md_off_reg
    +

    character: Missing data for official regions

    + + +
    year
    +

    character: Years

    + + +
    md_year
    +

    character: Years with missing data

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_impl_ctrs.html b/docs/reference/get_impl_ctrs.html new file mode 100644 index 00000000..31b9341f --- /dev/null +++ b/docs/reference/get_impl_ctrs.html @@ -0,0 +1,128 @@ + +Helper function to retrieve the implicit country surveys present in both +alternative and official aggregates — get_impl_ctrs • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to retrieve the implicit country surveys present in both +alternative and official aggregates

    +
    + +
    +
    get_impl_ctrs(user_gt, user_gt_code, user_aggs, ctrs)
    +
    + +
    +

    Arguments

    +
    user_gt
    +

    character: Grouping type

    + + +
    user_gt_code
    +

    character: Grouping type code

    + + +
    user_aggs
    +

    character: Aggregates selected by user

    + + +
    ctrs
    +

    data.frame: Countries lookup table

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_md_vars.html b/docs/reference/get_md_vars.html new file mode 100644 index 00000000..cbca9f99 --- /dev/null +++ b/docs/reference/get_md_vars.html @@ -0,0 +1,133 @@ + +Helper function to retrieve variables needed to handle imputation of +missing data — get_md_vars • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to retrieve variables needed to handle imputation of +missing data

    +
    + +
    +
    get_md_vars(md, ctr_alt_agg, year, off_alt_agg, user_off_reg)
    +
    + +
    +

    Arguments

    +
    md
    +

    data.frame: Table of country/year with missing data

    + + +
    ctr_alt_agg
    +

    character: Countries in alternative aggregate

    + + +
    year
    +

    character: Years

    + + +
    off_alt_agg
    +

    character: Instruction about how to handle official and +alternate aggregates

    + + +
    user_off_reg
    +

    character: Official regions requested by user

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_metaregion_table.html b/docs/reference/get_metaregion_table.html new file mode 100644 index 00000000..2f60f1a7 --- /dev/null +++ b/docs/reference/get_metaregion_table.html @@ -0,0 +1,111 @@ + +load metaregion from aux data — get_metaregion_table • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    If there is no data available, return an empty data.frame

    +
    + +
    +
    get_metaregion_table(data_dir)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Data directory

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_param_values.html b/docs/reference/get_param_values.html new file mode 100644 index 00000000..764c79d9 --- /dev/null +++ b/docs/reference/get_param_values.html @@ -0,0 +1,122 @@ + +Get valid query parameter values +Get vector of accepted query parameter values for the API — get_param_values • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Get valid query parameter values +Get vector of accepted query parameter values for the API

    +
    + +
    +
    get_param_values(
    +  lkup,
    +  version,
    +  endpoint = c("all", "aux", "pip", "pip-grp", "pip-info", "valid-params")
    +)
    +
    + +
    +

    Arguments

    +
    lkup
    +

    list: A list of lkup tables

    + + +
    version
    +

    character: Data version. Defaults to most recent version.

    + + +
    endpoint
    +

    character: the endpoint for which to return valid parameters

    + +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_pg_table.html b/docs/reference/get_pg_table.html new file mode 100644 index 00000000..464b99b8 --- /dev/null +++ b/docs/reference/get_pg_table.html @@ -0,0 +1,115 @@ + +Load prosperity gap table from aux data — get_pg_table • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    If there is no data available, return an empty data.frame

    +
    + +
    +
    get_pg_table(data_dir, table = c("pg_svy", "pg_lnp"))
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Data directory

    + + +
    table
    +

    character: Name of auxiliary table

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_pip_version.html b/docs/reference/get_pip_version.html new file mode 100644 index 00000000..c99fd156 --- /dev/null +++ b/docs/reference/get_pip_version.html @@ -0,0 +1,115 @@ + +Return the versions of the pip packages used for computations — get_pip_version • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return the versions of the pip packages used for computations

    +
    + +
    +
    get_pip_version(pip_packages = c("pipapi", "wbpip"), data_versions)
    +
    + +
    +

    Arguments

    +
    pip_packages
    +

    character: Custom packages powering the API

    + + +
    data_versions
    +

    character: Available data_versions

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_spr_table.html b/docs/reference/get_spr_table.html new file mode 100644 index 00000000..76be2dc5 --- /dev/null +++ b/docs/reference/get_spr_table.html @@ -0,0 +1,115 @@ + +load SPR table from aux data — get_spr_table • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    If there is no data available, return an empty data.frame

    +
    + +
    +
    get_spr_table(data_dir, table = c("spr_svy", "spr_lnp"))
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Data directory

    + + +
    table
    +

    character: Name of auxiliary table

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_svy_data.html b/docs/reference/get_svy_data.html new file mode 100644 index 00000000..3bce1cf7 --- /dev/null +++ b/docs/reference/get_svy_data.html @@ -0,0 +1,119 @@ + +Read survey data — get_svy_data • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Read survey data

    +
    + +
    +
    get_svy_data(svy_id, reporting_level, path)
    +
    + +
    +

    Arguments

    +
    svy_id
    +

    character: Survey ID

    + + +
    reporting_level
    +

    character: geographical reporting level

    + + +
    path
    +

    character: Path to survey data

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_user_alt_gt.html b/docs/reference/get_user_alt_gt.html new file mode 100644 index 00000000..f0b11bc8 --- /dev/null +++ b/docs/reference/get_user_alt_gt.html @@ -0,0 +1,115 @@ + +Helper function to define user_alt_gt — get_user_alt_gt • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to define user_alt_gt

    +
    + +
    +
    get_user_alt_gt(user_gt, off_gt)
    +
    + +
    +

    Arguments

    +
    user_gt
    +

    character: Grouping type needed by user

    + + +
    off_gt
    +

    character: Official grouping type

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_user_x_code.html b/docs/reference/get_user_x_code.html new file mode 100644 index 00000000..b0018181 --- /dev/null +++ b/docs/reference/get_user_x_code.html @@ -0,0 +1,111 @@ + +Helper function to define user_var_code — get_user_x_code • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to define user_var_code

    +
    + +
    +
    get_user_x_code(x)
    +
    + +
    +

    Arguments

    +
    x
    +

    character: Grouping type needed by user

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/get_valid_aux_long_format_tables.html b/docs/reference/get_valid_aux_long_format_tables.html new file mode 100644 index 00000000..5a7b9f36 --- /dev/null +++ b/docs/reference/get_valid_aux_long_format_tables.html @@ -0,0 +1,105 @@ + +Returns all auxiliary tables that support the long_format=TRUE parameter — get_valid_aux_long_format_tables • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Returns all auxiliary tables that support the long_format=TRUE parameter

    +
    + +
    +
    get_valid_aux_long_format_tables()
    +
    + +
    +

    Value

    + + +

    character vector

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ifel_isnull.html b/docs/reference/ifel_isnull.html new file mode 100644 index 00000000..01c1c3e8 --- /dev/null +++ b/docs/reference/ifel_isnull.html @@ -0,0 +1,115 @@ + +Efficient "if" "else" evaluation of null. — ifel_isnull • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Efficient "if" "else" evaluation of null.

    +
    + +
    +
    ifel_isnull(x, y)
    +
    + +
    +

    Arguments

    +
    x
    +

    object to evaluate

    + + +
    y
    +

    in case x null. If X is not null, then x.

    + +
    +
    +

    Value

    + + +

    object of class(x)

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/index.html b/docs/reference/index.html new file mode 100644 index 00000000..4a9dca68 --- /dev/null +++ b/docs/reference/index.html @@ -0,0 +1,378 @@ + +Function reference • pipapi + + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    All functions

    +

    +
    +

    add_agg_medians()

    +

    Add Aggregate medians

    +

    add_dist_stats()

    +

    Add pre-computed distributional stats

    +

    assign_serializer()

    +

    Helper function to return correct serializer

    +

    available_versions()

    +

    Sorted available PIP versions in data directory

    +

    change_grouped_stats_to_csv()

    +

    Change the list-output to dataframe

    +

    citation_from_version()

    +

    Return citation from the version

    +

    create_countries_vctr()

    +

    Create countries vectors

    +

    create_etag_header()

    +

    create_etag_header

    +

    create_return_cols()

    +

    helper function to create a list of return columns for various pipapi functions

    +

    create_versioned_lkups()

    +

    Create one list of lookups per data version

    +

    create_vintage_pattern_call()

    +

    create vintage call to be parsed into get_vintage_pattern_regex()

    +

    empty_response

    +

    Empty response schema

    +

    empty_response_cp_poverty

    +

    List of two datasets pov_trend and pov_mrv

    +

    empty_response_grp

    +

    Dataframe for grouped empty response

    +

    extract_identity()

    +

    Return identity from the version of the data

    +

    extract_ppp_date()

    +

    Return the ppp date from the version of the data

    +

    extract_release_date()

    +

    Return the release date from the version of the data

    +

    fg_assign_nas_values_to_dup_cols()

    +

    Coerce variable causing potential duplicates to NAs

    +

    fg_remove_duplicates()

    +

    Remove duplicated rows created during the interpolation process

    +

    fg_standardize_cache_id()

    +

    Standardize cache_id format to avoid duplication of rows

    +

    fillin_list()

    +

    Populate list in parent frame

    +

    filter_lkup()

    +

    Helper to filter metadata +aggregate distribution need to be filtered out when popshare is not null +This is a temporary function until a full fix is implemented, and popshare is +supported for all distributions

    +

    filter_md()

    +

    Helper function to filter missing data table

    +

    get_aux_table()

    +

    Return specified auxiliary data

    +

    get_aux_table_ui()

    +

    Return specified auxiliary data in wide format +Helper function to the UI

    +

    get_caller_names()

    +

    Get functions names in call stack

    +

    get_ctr_alt_agg()

    +

    Helper function to retrieve the required countries +needed to compute alternative aggregates requested by user +Get countries that belong to aggregates requested by the user that are NOT +official but alternative aggregates. We need to find out missing data +estimates only for those countries. For instance, if the user requested LAC +and AFE, we don't care about the the countries with missing data in the LAC +because their estimates are done implicitly. We DO care about the estimates +of the missing countries in AFE because we need the explicit SSA estimates.

    +

    get_grp_to_compute()

    +

    Helper function to retrieve the country/year pairs to be computed

    +

    get_impl_ctrs()

    +

    Helper function to retrieve the implicit country surveys present in both +alternative and official aggregates

    +

    get_md_vars()

    +

    Helper function to retrieve variables needed to handle imputation of +missing data

    +

    get_param_values()

    +

    Get valid query parameter values +Get vector of accepted query parameter values for the API

    +

    get_pip_version()

    +

    Return the versions of the pip packages used for computations

    +

    get_user_alt_gt()

    +

    Helper function to define user_alt_gt

    +

    get_user_x_code()

    +

    Helper function to define user_var_code

    +

    get_valid_aux_long_format_tables()

    +

    Returns all auxiliary tables that support the long_format=TRUE parameter

    +

    ifel_isnull()

    +

    Efficient "if" "else" evaluation of null.

    +

    is_empty()

    +

    Test whether a vector is length zero and IS not NULL

    +

    is_forked()

    +

    Helper function to determine whether an API call is compute intensive +and should be forked to a parallel process to avoid blocking the main +R process

    +

    lkup

    +

    List of lookup values

    +

    pip()

    +

    Compute PIP statistics

    +

    pipgd_lorenz_curve()

    +

    Lorenz curve

    +

    pip_aggregate()

    +

    Calculate estimates for aggregates different to the official regional +aggregation

    +

    pip_grp()

    +

    Compute various aggregations of PIP statistics

    +

    pip_grp_logic()

    +

    Logic for computing new aggregate

    +

    reporting_level_list

    +

    List of valid coverage values

    +

    return_correct_version()

    +

    Return the version of the data

    +

    return_if_exists()

    +

    Return the rows of the table if they exist in master file

    +

    select_country()

    +

    select_country +Helper function for subset_lkup()

    +

    select_off_alt_agg()

    +

    Helper function to identify how Official and Alternative regions should be +handled

    +

    select_reporting_level()

    +

    helper function to correctly filter look up table according to requested +reporting level

    +

    select_user_aggs()

    +

    Helper function to select correct Official Regions

    +

    select_years()

    +

    select_years +Helper function for subset_lkup()

    +

    start_api()

    +

    Main function to launch the API

    +

    ui_cp_charts()

    +

    Country Profiles Charts

    +

    ui_cp_download()

    +

    Country Profiles Key Indicators download

    +

    ui_cp_key_indicators()

    +

    Country Profiles Key Indicators

    +

    ui_hp_countries()

    +

    Home Page Country Charts

    +

    ui_hp_stacked()

    +

    Home Page Main Chart

    +

    ui_pc_charts()

    +

    Poverty Calculator Main chart

    +

    ui_pc_regional()

    +

    Poverty Calculator regional aggregates

    +

    ui_svy_meta()

    +

    Data Sources Survey Metadata

    +

    update_master_file()

    +

    Update master file with the contents of the dataframe

    +

    validate_input_grouped_stats()

    +

    Validate grouped-stats endpoint input values

    +

    valid_years()

    +

    Return available valid years

    +

    version_dataframe()

    +

    Return versions of the data available.

    +

    wld_lineup_year()

    +

    lineup year for the world

    + + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/is_empty.html b/docs/reference/is_empty.html new file mode 100644 index 00000000..6a186153 --- /dev/null +++ b/docs/reference/is_empty.html @@ -0,0 +1,124 @@ + +Test whether a vector is length zero and IS not NULL — is_empty • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Test whether a vector is length zero and IS not NULL

    +
    + +
    +
    is_empty(x)
    +
    + +
    +

    Arguments

    +
    x
    +

    Value to be passed

    + +
    +
    +

    Value

    + + +

    logical. TRUE if x is empty but it is not NULL

    +
    + +
    +

    Examples

    +
    x <- vector()
    +is_empty(x)
    +#> [1] TRUE
    +
    +y <- NULL
    +length(y)
    +#> [1] 0
    +is_empty(y)
    +#> [1] FALSE
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/is_forked.html b/docs/reference/is_forked.html new file mode 100644 index 00000000..30616088 --- /dev/null +++ b/docs/reference/is_forked.html @@ -0,0 +1,135 @@ + +Helper function to determine whether an API call is compute intensive +and should be forked to a parallel process to avoid blocking the main +R process — is_forked • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to determine whether an API call is compute intensive +and should be forked to a parallel process to avoid blocking the main +R process

    +
    + +
    +
    is_forked(country, year, intensity_threshold = 40, include_year = TRUE)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: selected countries

    + + +
    year
    +

    character: selected years

    + + +
    intensity_threshold
    +

    numeric: Number of selected country/year above which +the request will be considered intensive

    + + +
    include_year
    +

    logical: Whether year selection should be included to determine +the intensity of the request

    + +
    +
    +

    Value

    + + +

    logical

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/lkup.html b/docs/reference/lkup.html new file mode 100644 index 00000000..08767213 --- /dev/null +++ b/docs/reference/lkup.html @@ -0,0 +1,103 @@ + +List of lookup values — lkup • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    List of lookup values

    +
    + +
    +
    data(lkup)
    +
    + +
    +

    Format

    +

    A list of lookup values

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/pip.html b/docs/reference/pip.html new file mode 100644 index 00000000..fa1cd8cf --- /dev/null +++ b/docs/reference/pip.html @@ -0,0 +1,211 @@ + +Compute PIP statistics — pip • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Compute the main PIP poverty and inequality statistics.

    +
    + +
    +
    pip(
    +  country = "ALL",
    +  year = "ALL",
    +  povline = 1.9,
    +  popshare = NULL,
    +  fill_gaps = FALSE,
    +  group_by = c("none", "wb"),
    +  welfare_type = c("all", "consumption", "income"),
    +  reporting_level = c("all", "national", "rural", "urban"),
    +  ppp = NULL,
    +  lkup,
    +  censor = TRUE,
    +  lkup_hash = lkup$cache_data_id$hash_pip,
    +  additional_ind = FALSE
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    popshare
    +

    numeric: Proportion of the population living below the +poverty line

    + + +
    fill_gaps
    +

    logical: If set to TRUE, will interpolate / extrapolate +values for missing years

    + + +
    group_by
    +

    character: Will return aggregated values for predefined +sub-groups

    + + +
    welfare_type
    +

    character: Welfare type

    + + +
    reporting_level
    +

    character: Geographical reporting level

    + + +
    ppp
    +

    numeric: Custom Purchase Power Parity value

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    censor
    +

    logical: Triggers censoring of country/year statistics

    + + +
    lkup_hash
    +

    character: hash of pip

    + + +
    additional_ind
    +

    logical: If TRUE add new set of indicators. Default if +FALSE

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    +

    Examples

    +
    if (FALSE) {
    +# Create lkups
    +lkups <- create_lkups("<data-folder>")
    +
    +# A single country and year
    +pip(country = "AGO",
    +    year = 2000,
    +    povline = 1.9,
    +    lkup = lkups)
    +
    +# All years for a single country
    +pip(country = "AGO",
    +    year = "all",
    +    povline = 1.9,
    +    lkup = lkups)
    +
    +# Fill gaps
    +pip(country = "AGO",
    +    year = "all",
    +    povline = 1.9,
    +    fill_gaps = TRUE,
    +    lkup = lkups)
    +
    +# Group by regions
    +pip(country = "all",
    +    year = "all",
    +    povline = 1.9,
    +    group_by = "wb",
    +    lkup = lkups)
    +}
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/pip_aggregate.html b/docs/reference/pip_aggregate.html new file mode 100644 index 00000000..b303f66e --- /dev/null +++ b/docs/reference/pip_aggregate.html @@ -0,0 +1,127 @@ + +Calculate estimates for aggregates different to the official regional +aggregation — pip_aggregate • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Calculate estimates for aggregates different to the official regional +aggregation

    +
    + +
    +
    pip_aggregate(df, by = NULL, return_cols)
    +
    + +
    +

    Arguments

    +
    df
    +

    data.table from pip_fg()

    + + +
    by
    +

    character: Additional variable to use in by when doing the +aggregations. Default is NULL, but it should be use to include +aggregations variables

    + + +
    return_cols
    +

    list: lkup$return_cols$pip_grp object. Controls returned +columns

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/pip_grp.html b/docs/reference/pip_grp.html new file mode 100644 index 00000000..aa0c7907 --- /dev/null +++ b/docs/reference/pip_grp.html @@ -0,0 +1,169 @@ + +Compute various aggregations of PIP statistics — pip_grp • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Compute various aggregations of PIP statistics

    +
    + +
    +
    pip_grp(
    +  country = "ALL",
    +  year = "ALL",
    +  povline = 1.9,
    +  group_by = c("wb", "none"),
    +  welfare_type = c("all", "consumption", "income"),
    +  reporting_level = c("all", "national"),
    +  lkup,
    +  censor = TRUE,
    +  lkup_hash = lkup$cache_data_id$hash_pip_grp
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    group_by
    +

    character: Will return aggregated values for predefined +sub-groups

    + + +
    welfare_type
    +

    character: Welfare type

    + + +
    reporting_level
    +

    character: Geographical reporting level

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    censor
    +

    logical: Triggers censoring of country/year statistics

    + + +
    lkup_hash
    +

    character: hash of pip

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    +

    Examples

    +
    if (FALSE) {
    +# Create lkups
    +lkups <- create_lkups("<data-folder>")
    +
    +# A single country and year
    +pip_grp(country = "all",
    +        year = 2000,
    +        povline = 1.9,
    +        group_by = "wb",
    +        lkup = lkups)
    +}
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/pip_grp_logic.html b/docs/reference/pip_grp_logic.html new file mode 100644 index 00000000..91fb1687 --- /dev/null +++ b/docs/reference/pip_grp_logic.html @@ -0,0 +1,167 @@ + +Logic for computing new aggregate — pip_grp_logic • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Logic for computing new aggregate

    +
    + +
    +
    pip_grp_logic(
    +  country = "ALL",
    +  year = "ALL",
    +  povline = 1.9,
    +  group_by = c("wb", "none"),
    +  welfare_type = c("all", "consumption", "income"),
    +  reporting_level = c("all", "national"),
    +  lkup,
    +  censor = TRUE,
    +  lkup_hash = lkup$cache_data_id$hash_pip_grp,
    +  additional_ind = FALSE
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    group_by
    +

    character: Will return aggregated values for predefined +sub-groups

    + + +
    welfare_type
    +

    character: Welfare type

    + + +
    reporting_level
    +

    character: Geographical reporting level

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    censor
    +

    logical: Triggers censoring of country/year statistics

    + + +
    lkup_hash
    +

    character: hash of pip

    + + +
    additional_ind
    +

    logical: If TRUE add new set of indicators. Default if +FALSE

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    +

    Examples

    +
    if (FALSE) {
    +# Create lkups
    +}
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/pipgd_lorenz_curve.html b/docs/reference/pipgd_lorenz_curve.html new file mode 100644 index 00000000..9aec89d1 --- /dev/null +++ b/docs/reference/pipgd_lorenz_curve.html @@ -0,0 +1,162 @@ + +Lorenz curve — pipgd_lorenz_curve • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Returns the Lorenz curve. User provides the cumulative welfare and +cumulative weight, as well as the number of points on the lorenz curve required. +By default, the best fitting Lorenz parameterization (quadratic or beta) is +selected.

    +
    + +
    +
    pipgd_lorenz_curve(welfare = NULL, weight = NULL, lorenz = NULL, n_bins = 100)
    +
    + +
    +

    Arguments

    +
    welfare
    +

    numeric vector of cumulative share of welfare (income/consumption)

    + + +
    weight
    +

    numeric vector of cumulative share of the population

    + + +
    lorenz
    +

    either "lb" or "lq"

    + + +
    n_bins
    +

    atomic double vector of length 1: number of points on the +lorenz curve

    + + +
    params
    +

    list of parameters

    + +
    +
    +

    Value

    + + +

    Returns a list which contains:

    • numeric lorenz curve,

    • +
    • corresponding points on x-axis,

    • +
    • whether lq or lb parameterization, and

    • +
    • if complete=TRUE, also returns all params.

    • +
    + +
    +

    Examples

    +
    if (FALSE) {
    +# Example 1: Generating a Lorenz Curve with default settings
    +pipgd_lorenz_curve(welfare = pip_gd$L,
    +                   weight = pip_gd$P)
    +
    +# Example 2: Specifying the number of bins for the Lorenz Curve
    +pipgd_lorenz_curve(welfare = pip_gd$L,
    +                   weight = pip_gd$P,
    +                   n_bins = 50)
    +
    +# Example 3: Using pre-calculated parameters
    +use_params <- pipgd_params(welfare = pip_gd$L,
    +                           weight = pip_gd$P)
    +pipgd_lorenz_curve(params = use_params)
    +
    +
    +# Example 4: Generating Lorenz Curve with a specific Lorenz model(e.g. Lorenz beta)
    +pipgd_lorenz_curve(params = use_params,
    +                   lorenz = "lb")
    +}
    +
    +
    +
    +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/reporting_level_list.html b/docs/reference/reporting_level_list.html new file mode 100644 index 00000000..5f5104ee --- /dev/null +++ b/docs/reference/reporting_level_list.html @@ -0,0 +1,103 @@ + +List of valid coverage values — reporting_level_list • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    List of valid coverage values

    +
    + +
    +
    reporting_level_list
    +
    + +
    +

    Format

    +

    An object of class character of length 3.

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/return_correct_version.html b/docs/reference/return_correct_version.html new file mode 100644 index 00000000..3ace44eb --- /dev/null +++ b/docs/reference/return_correct_version.html @@ -0,0 +1,133 @@ + +Return the version of the data — return_correct_version • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return the version of the data

    +
    + +
    +
    return_correct_version(
    +  version = NULL,
    +  release_version = NULL,
    +  ppp_version = NULL,
    +  identity = "PROD",
    +  versions_available
    +)
    +
    + +
    +

    Arguments

    +
    version
    +

    Data version. Defaults to most recent version. See api/v1/versions

    + + +
    release_version
    +

    date when the data was published in YYYYMMDD format

    + + +
    ppp_version
    +

    ppp year to be used

    + + +
    identity
    +

    One of "PROD" (production), "INT" (internal) and "TEST"

    + + +
    versions_available
    +

    character vector of all the versions available

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/return_if_exists.html b/docs/reference/return_if_exists.html new file mode 100644 index 00000000..4c205d97 --- /dev/null +++ b/docs/reference/return_if_exists.html @@ -0,0 +1,123 @@ + +Return the rows of the table if they exist in master file — return_if_exists • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return the rows of the table if they exist in master file

    +
    + +
    +
    return_if_exists(lkup, povline, con)
    +
    + +
    +

    Arguments

    +
    lkup
    +

    list: A list of lkup tables

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    con
    +

    Connection object

    + + +
    country_code
    +

    Country Code

    + +
    +
    +

    Value

    + + +

    Dataframe

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/rg_pip.html b/docs/reference/rg_pip.html new file mode 100644 index 00000000..9278a0d0 --- /dev/null +++ b/docs/reference/rg_pip.html @@ -0,0 +1,154 @@ + +Compute survey year stats — rg_pip • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Compute the main PIP poverty and inequality statistics for survey years.

    +
    + +
    +
    rg_pip(
    +  country,
    +  year,
    +  povline,
    +  popshare,
    +  welfare_type,
    +  reporting_level,
    +  ppp,
    +  lkup,
    +  con
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    popshare
    +

    numeric: Proportion of the population living below the +poverty line

    + + +
    welfare_type
    +

    character: Welfare type

    + + +
    reporting_level
    +

    character: Geographical reporting level

    + + +
    ppp
    +

    numeric: Custom Purchase Power Parity value

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    con
    +

    duckdb connection object

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/select_country.html b/docs/reference/select_country.html new file mode 100644 index 00000000..4352c51b --- /dev/null +++ b/docs/reference/select_country.html @@ -0,0 +1,129 @@ + +select_country +Helper function for subset_lkup() — select_country • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    select_country +Helper function for subset_lkup()

    +
    + +
    +
    select_country(lkup, keep, country, valid_regions)
    +
    + +
    +

    Arguments

    +
    lkup
    +

    list: A list of lkup tables

    + + +
    keep
    +

    logical vector

    + + +
    country
    +

    character: Country ISO 3 codes

    + + +
    valid_regions
    +

    character: List of valid region codes that can be used +for region selection

    + +
    +
    +

    Value

    + + +

    logical vector

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/select_off_alt_agg.html b/docs/reference/select_off_alt_agg.html new file mode 100644 index 00000000..2e4f542c --- /dev/null +++ b/docs/reference/select_off_alt_agg.html @@ -0,0 +1,120 @@ + +Helper function to identify how Official and Alternative regions should be +handled — select_off_alt_agg • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to identify how Official and Alternative regions should be +handled

    +
    + +
    +
    select_off_alt_agg(user_gt, off_gt)
    +
    + +
    +

    Arguments

    +
    user_gt
    +

    character: Grouping type implicitly selected by user

    + + +
    off_gt
    +

    character: Grouping type associated with Offical Regions

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/select_reporting_level.html b/docs/reference/select_reporting_level.html new file mode 100644 index 00000000..622ee904 --- /dev/null +++ b/docs/reference/select_reporting_level.html @@ -0,0 +1,124 @@ + +helper function to correctly filter look up table according to requested +reporting level — select_reporting_level • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    helper function to correctly filter look up table according to requested +reporting level

    +
    + +
    +
    select_reporting_level(lkup, keep, reporting_level)
    +
    + +
    +

    Arguments

    +
    lkup
    +

    data.table: Main lookup table

    + + +
    keep
    +

    logical: Logical vector of rows to be kept

    + + +
    reporting_level
    +

    character: Requested reporting level

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/select_user_aggs.html b/docs/reference/select_user_aggs.html new file mode 100644 index 00000000..1003d8f9 --- /dev/null +++ b/docs/reference/select_user_aggs.html @@ -0,0 +1,123 @@ + +Helper function to select correct Official Regions — select_user_aggs • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to select correct Official Regions

    +
    + +
    +
    select_user_aggs(country, all_agg, off_reg_ext, aggs)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: User selected countries

    + + +
    all_agg
    +

    character: all country aggregates

    + + +
    off_reg_ext
    +

    character: Official region codes

    + + +
    aggs
    +

    data.frame: Regions lookup table

    + +
    +
    +

    Value

    + + +

    character

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/select_years.html b/docs/reference/select_years.html new file mode 100644 index 00000000..08e03da0 --- /dev/null +++ b/docs/reference/select_years.html @@ -0,0 +1,137 @@ + +select_years +Helper function for subset_lkup() — select_years • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    select_years +Helper function for subset_lkup()

    +
    + +
    +
    select_years(lkup, keep, year, country, data_dir, valid_regions = NULL)
    +
    + +
    +

    Arguments

    +
    lkup
    +

    list: A list of lkup tables

    + + +
    keep
    +

    logical vector

    + + +
    year
    +

    integer: Reporting year

    + + +
    country
    +

    character: Country ISO 3 codes

    + + +
    data_dir
    +

    character: directory path from lkup$data_root

    + + +
    valid_regions
    +

    character: List of valid region codes that can be used +for region selection

    + +
    +
    +

    Value

    + + +

    logical vector

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/start_api.html b/docs/reference/start_api.html new file mode 100644 index 00000000..9a28ba94 --- /dev/null +++ b/docs/reference/start_api.html @@ -0,0 +1,119 @@ + +Main function to launch the API — start_api • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Main function to launch the API

    +
    + +
    +
    start_api(api_version = "v1", port = 80, host = "0.0.0.0")
    +
    + +
    +

    Arguments

    +
    api_version
    +

    character: API version to launch

    + + +
    port
    +

    integer: Port

    + + +
    host
    +

    character: Host

    + +
    +
    +

    Value

    + + +

    plumber API

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/subset_ctry_years.html b/docs/reference/subset_ctry_years.html new file mode 100644 index 00000000..5a3d02ed --- /dev/null +++ b/docs/reference/subset_ctry_years.html @@ -0,0 +1,137 @@ + +Subset country-years table +This is a table created at start time to facilitate imputations +It part of the interpolated_list object — subset_ctry_years • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Subset country-years table +This is a table created at start time to facilitate imputations +It part of the interpolated_list object

    +
    + +
    +
    subset_ctry_years(country, year, lkup, valid_regions, data_dir)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    valid_regions
    +

    character: List of valid region codes that can be used

    + + +
    data_dir
    +

    character: directory path from lkup$data_root

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/subset_lkup.html b/docs/reference/subset_lkup.html new file mode 100644 index 00000000..d34af8dd --- /dev/null +++ b/docs/reference/subset_lkup.html @@ -0,0 +1,154 @@ + +Subset look-up data — subset_lkup • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Subset look-up data

    +
    + +
    +
    subset_lkup(
    +  country,
    +  year,
    +  welfare_type,
    +  reporting_level,
    +  lkup,
    +  valid_regions,
    +  data_dir = NULL,
    +  povline,
    +  con
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    welfare_type
    +

    character: Welfare type

    + + +
    reporting_level
    +

    character: Geographical reporting level

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    valid_regions
    +

    character: List of valid region codes that can be used +for region selection

    + + +
    data_dir
    +

    character: directory path from lkup$data_root

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    con
    +

    duckdb connection object

    + +
    +
    +

    Value

    + + +

    data.frame

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_cp_charts.html b/docs/reference/ui_cp_charts.html new file mode 100644 index 00000000..46332301 --- /dev/null +++ b/docs/reference/ui_cp_charts.html @@ -0,0 +1,134 @@ + +Country Profiles Charts — ui_cp_charts • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides numbers that will populate the country profile charts.

    +
    + +
    +
    ui_cp_charts(
    +  country = "AGO",
    +  povline = 1.9,
    +  pop_units = 1e+06,
    +  lkup,
    +  lkup_hash = lkup$cache_data_id$hash_ui_cp
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    pop_units
    +

    numeric: Units used to express population numbers (default +to million)

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    lkup_hash
    +

    character: hash of pip

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_cp_download.html b/docs/reference/ui_cp_download.html new file mode 100644 index 00000000..85f31cf0 --- /dev/null +++ b/docs/reference/ui_cp_download.html @@ -0,0 +1,133 @@ + +Country Profiles Key Indicators download — ui_cp_download • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Helper function to download Country Profile data

    +
    + +
    +
    ui_cp_download(
    +  country = "AGO",
    +  year = "ALL",
    +  povline = 1.9,
    +  lkup,
    +  lkup_hash = lkup$cache_data_id$hash_ui_cp
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    lkup_hash
    +

    character: hash of pip

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_cp_key_indicators.html b/docs/reference/ui_cp_key_indicators.html new file mode 100644 index 00000000..9977114f --- /dev/null +++ b/docs/reference/ui_cp_key_indicators.html @@ -0,0 +1,128 @@ + +Country Profiles Key Indicators — ui_cp_key_indicators • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides numbers that will population for country profiles key indicators.

    +
    + +
    +
    ui_cp_key_indicators(
    +  country = "AGO",
    +  povline = NULL,
    +  lkup,
    +  lkup_hash = lkup$cache_data_id$hash_ui_cp
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    lkup_hash
    +

    character: hash of pip

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_cp_poverty_charts.html b/docs/reference/ui_cp_poverty_charts.html new file mode 100644 index 00000000..035b36e6 --- /dev/null +++ b/docs/reference/ui_cp_poverty_charts.html @@ -0,0 +1,124 @@ + +CP Poverty Charts — ui_cp_poverty_charts • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides numbers that will populate the country profiles poverty charts

    +
    + +
    +
    ui_cp_poverty_charts(country, povline, pop_units, lkup)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    pop_units
    +

    numeric: Units used to express population numbers (default +to million)

    + + +
    lkup
    +

    list: A list of lkup tables

    + +
    +
    +

    Value

    + + +

    list

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_hp_countries.html b/docs/reference/ui_hp_countries.html new file mode 100644 index 00000000..5da2851d --- /dev/null +++ b/docs/reference/ui_hp_countries.html @@ -0,0 +1,129 @@ + +Home Page Country Charts — ui_hp_countries • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides numbers that will populate the home page country charts.

    +
    + +
    +
    ui_hp_countries(
    +  country = c("IDN", "CIV"),
    +  povline = 1.9,
    +  pop_units = 1e+06,
    +  lkup
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    pop_units
    +

    numeric: Units used to express population numbers (default +to million)

    + + +
    lkup
    +

    list: A list of lkup tables

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_hp_stacked.html b/docs/reference/ui_hp_stacked.html new file mode 100644 index 00000000..69c23a9f --- /dev/null +++ b/docs/reference/ui_hp_stacked.html @@ -0,0 +1,119 @@ + +Home Page Main Chart — ui_hp_stacked • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides numbers that will populate the home page main chart.

    +
    + +
    +
    ui_hp_stacked(povline = 1.9, lkup, lkup_hash = lkup$cache_data_id$hash_pip_grp)
    +
    + +
    +

    Arguments

    +
    povline
    +

    numeric: Poverty line

    + + +
    lkup
    +

    list: A list of lkup tables

    + + +
    lkup_hash
    +

    character: hash of pip

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_pc_charts.html b/docs/reference/ui_pc_charts.html new file mode 100644 index 00000000..504891e9 --- /dev/null +++ b/docs/reference/ui_pc_charts.html @@ -0,0 +1,156 @@ + +Poverty Calculator Main chart — ui_pc_charts • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides numbers that will populate the poverty calculator main chart.

    +
    + +
    +
    ui_pc_charts(
    +  country = c("AGO"),
    +  year = "all",
    +  povline = 1.9,
    +  fill_gaps = FALSE,
    +  group_by = "none",
    +  welfare_type = c("all", "consumption", "income"),
    +  reporting_level = c("all", "national", "rural", "urban"),
    +  pop_units = 1e+06,
    +  lkup
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    fill_gaps
    +

    logical: If set to TRUE, will interpolate / extrapolate +values for missing years

    + + +
    group_by
    +

    character: Will return aggregated values for predefined +sub-groups

    + + +
    welfare_type
    +

    character: Welfare type

    + + +
    reporting_level
    +

    character: Geographical reporting level

    + + +
    pop_units
    +

    numeric: Units used to express population numbers (default +to million)

    + + +
    lkup
    +

    list: A list of lkup tables

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_pc_regional.html b/docs/reference/ui_pc_regional.html new file mode 100644 index 00000000..b71de270 --- /dev/null +++ b/docs/reference/ui_pc_regional.html @@ -0,0 +1,136 @@ + +Poverty Calculator regional aggregates — ui_pc_regional • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides numbers that will populate poverty calculator regional aggregates +for all years.

    +
    + +
    +
    ui_pc_regional(
    +  country = "ALL",
    +  year = "ALL",
    +  povline = 1.9,
    +  pop_units = 1e+06,
    +  lkup
    +)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    year
    +

    integer: Reporting year

    + + +
    povline
    +

    numeric: Poverty line

    + + +
    pop_units
    +

    numeric: Units used to express population numbers (default +to million)

    + + +
    lkup
    +

    list: A list of lkup tables

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/ui_svy_meta.html b/docs/reference/ui_svy_meta.html new file mode 100644 index 00000000..bfa8b2b9 --- /dev/null +++ b/docs/reference/ui_svy_meta.html @@ -0,0 +1,115 @@ + +Data Sources Survey Metadata — ui_svy_meta • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Provides survey metadata that will populate the Data Sources page.

    +
    + +
    +
    ui_svy_meta(country = "all", lkup)
    +
    + +
    +

    Arguments

    +
    country
    +

    character: Country ISO 3 codes

    + + +
    lkup
    +

    list: A list of lkup tables

    + +
    +
    +

    Value

    + + +

    data.table

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/update_master_file.html b/docs/reference/update_master_file.html new file mode 100644 index 00000000..fe4ba563 --- /dev/null +++ b/docs/reference/update_master_file.html @@ -0,0 +1,115 @@ + +Update master file with the contents of the dataframe — update_master_file • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Update master file with the contents of the dataframe

    +
    + +
    +
    update_master_file(dat, con)
    +
    + +
    +

    Arguments

    +
    dat
    +

    Dataframe to be appended

    + + +
    con
    +

    DuckDB connection object

    + +
    +
    +

    Value

    + + +

    number of rows updated

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/valid_years.html b/docs/reference/valid_years.html new file mode 100644 index 00000000..67c1513e --- /dev/null +++ b/docs/reference/valid_years.html @@ -0,0 +1,111 @@ + +Return available valid years — valid_years • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return available valid years

    +
    + +
    +
    valid_years(data_dir)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Path to the root directory

    + +
    +
    +

    Value

    + + +

    numeric vector of valid years

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/validate_input_grouped_stats.html b/docs/reference/validate_input_grouped_stats.html new file mode 100644 index 00000000..fbc80a2f --- /dev/null +++ b/docs/reference/validate_input_grouped_stats.html @@ -0,0 +1,119 @@ + +Validate grouped-stats endpoint input values — validate_input_grouped_stats • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Validate grouped-stats endpoint input values

    +
    + +
    +
    validate_input_grouped_stats(welfare, population, max_length = 100)
    +
    + +
    +

    Arguments

    +
    welfare
    +

    character: query values

    + + +
    population
    +

    character: valid values

    + + +
    max_length
    +

    integer: Max length of welfare vector

    + +
    +
    +

    Value

    + + +

    list of two vectors welfare and population

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/version_dataframe.html b/docs/reference/version_dataframe.html new file mode 100644 index 00000000..c91b6831 --- /dev/null +++ b/docs/reference/version_dataframe.html @@ -0,0 +1,111 @@ + +Return versions of the data available. — version_dataframe • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    Return versions of the data available.

    +
    + +
    +
    version_dataframe(versions)
    +
    + +
    +

    Arguments

    +
    versions
    +

    character: All available versions

    + +
    +
    +

    Value

    + + +

    Dataframe with 4 columns, versions, release_version, ppp_version and identity

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/reference/wld_lineup_year.html b/docs/reference/wld_lineup_year.html new file mode 100644 index 00000000..7eebd627 --- /dev/null +++ b/docs/reference/wld_lineup_year.html @@ -0,0 +1,111 @@ + +lineup year for the world — wld_lineup_year • pipapi + + +
    +
    + + + +
    +
    + + +
    +

    lineup year for the world

    +
    + +
    +
    wld_lineup_year(data_dir)
    +
    + +
    +

    Arguments

    +
    data_dir
    +

    character: Path to the root directory

    + +
    +
    +

    Value

    + + +

    numeric vector of length one of lineup year for the world

    +
    + +
    + +
    + + +
    + +
    +

    Site built with pkgdown 2.0.7.

    +
    + +
    + + + + + + + + diff --git a/docs/sitemap.xml b/docs/sitemap.xml new file mode 100644 index 00000000..cdf78438 --- /dev/null +++ b/docs/sitemap.xml @@ -0,0 +1,300 @@ + + + + https://pip-technical-team.github.io/pipapi/404.html + + + https://pip-technical-team.github.io/pipapi/articles/debug-caching.html + + + https://pip-technical-team.github.io/pipapi/articles/duckdb-caching.html + + + https://pip-technical-team.github.io/pipapi/articles/index.html + + + https://pip-technical-team.github.io/pipapi/articles/new-endpoints.html + + + https://pip-technical-team.github.io/pipapi/authors.html + + + https://pip-technical-team.github.io/pipapi/CONTRIBUTING.html + + + https://pip-technical-team.github.io/pipapi/index.html + + + https://pip-technical-team.github.io/pipapi/LICENSE-text.html + + + https://pip-technical-team.github.io/pipapi/LICENSE.html + + + https://pip-technical-team.github.io/pipapi/news/index.html + + + https://pip-technical-team.github.io/pipapi/PULL_REQUEST_TEMPLATE.html + + + https://pip-technical-team.github.io/pipapi/reference/add_agg_medians.html + + + https://pip-technical-team.github.io/pipapi/reference/add_distribution_type.html + + + https://pip-technical-team.github.io/pipapi/reference/add_dist_stats.html + + + https://pip-technical-team.github.io/pipapi/reference/add_pg.html + + + https://pip-technical-team.github.io/pipapi/reference/add_spl.html + + + https://pip-technical-team.github.io/pipapi/reference/add_vars_out_of_pipeline.html + + + https://pip-technical-team.github.io/pipapi/reference/assign_serializer.html + + + https://pip-technical-team.github.io/pipapi/reference/available_versions.html + + + https://pip-technical-team.github.io/pipapi/reference/censor_stats.html + + + https://pip-technical-team.github.io/pipapi/reference/change_grouped_stats_to_csv.html + + + https://pip-technical-team.github.io/pipapi/reference/citation_from_version.html + + + https://pip-technical-team.github.io/pipapi/reference/clear_cache.html + + + https://pip-technical-team.github.io/pipapi/reference/create_countries_vctr.html + + + https://pip-technical-team.github.io/pipapi/reference/create_etag_header.html + + + https://pip-technical-team.github.io/pipapi/reference/create_lkups.html + + + https://pip-technical-team.github.io/pipapi/reference/create_return_cols.html + + + https://pip-technical-team.github.io/pipapi/reference/create_versioned_lkups.html + + + https://pip-technical-team.github.io/pipapi/reference/create_vintage_pattern_call.html + + + https://pip-technical-team.github.io/pipapi/reference/empty_response.html + + + https://pip-technical-team.github.io/pipapi/reference/empty_response_cp_poverty.html + + + https://pip-technical-team.github.io/pipapi/reference/empty_response_grp.html + + + https://pip-technical-team.github.io/pipapi/reference/estimate_type_ctr_lnp.html + + + https://pip-technical-team.github.io/pipapi/reference/estimate_type_var.html + + + https://pip-technical-team.github.io/pipapi/reference/extract_identity.html + + + https://pip-technical-team.github.io/pipapi/reference/extract_ppp_date.html + + + https://pip-technical-team.github.io/pipapi/reference/extract_release_date.html + + + https://pip-technical-team.github.io/pipapi/reference/fg_assign_nas_values_to_dup_cols.html + + + https://pip-technical-team.github.io/pipapi/reference/fg_pip.html + + + https://pip-technical-team.github.io/pipapi/reference/fg_remove_duplicates.html + + + https://pip-technical-team.github.io/pipapi/reference/fg_standardize_cache_id.html + + + https://pip-technical-team.github.io/pipapi/reference/fillin_list.html + + + https://pip-technical-team.github.io/pipapi/reference/filter_lkup.html + + + https://pip-technical-team.github.io/pipapi/reference/filter_md.html + + + https://pip-technical-team.github.io/pipapi/reference/get_additional_indicators.html + + + https://pip-technical-team.github.io/pipapi/reference/get_additional_indicators_grp.html + + + https://pip-technical-team.github.io/pipapi/reference/get_aux_table.html + + + https://pip-technical-team.github.io/pipapi/reference/get_aux_table_ui.html + + + https://pip-technical-team.github.io/pipapi/reference/get_caller_names.html + + + https://pip-technical-team.github.io/pipapi/reference/get_ctr_alt_agg.html + + + https://pip-technical-team.github.io/pipapi/reference/get_grp_to_compute.html + + + https://pip-technical-team.github.io/pipapi/reference/get_impl_ctrs.html + + + https://pip-technical-team.github.io/pipapi/reference/get_md_vars.html + + + https://pip-technical-team.github.io/pipapi/reference/get_metaregion_table.html + + + https://pip-technical-team.github.io/pipapi/reference/get_param_values.html + + + https://pip-technical-team.github.io/pipapi/reference/get_pg_table.html + + + https://pip-technical-team.github.io/pipapi/reference/get_pip_version.html + + + https://pip-technical-team.github.io/pipapi/reference/get_spr_table.html + + + https://pip-technical-team.github.io/pipapi/reference/get_svy_data.html + + + https://pip-technical-team.github.io/pipapi/reference/get_user_alt_gt.html + + + https://pip-technical-team.github.io/pipapi/reference/get_user_x_code.html + + + https://pip-technical-team.github.io/pipapi/reference/get_valid_aux_long_format_tables.html + + + https://pip-technical-team.github.io/pipapi/reference/ifel_isnull.html + + + https://pip-technical-team.github.io/pipapi/reference/index.html + + + https://pip-technical-team.github.io/pipapi/reference/is_empty.html + + + https://pip-technical-team.github.io/pipapi/reference/is_forked.html + + + https://pip-technical-team.github.io/pipapi/reference/lkup.html + + + https://pip-technical-team.github.io/pipapi/reference/pip.html + + + https://pip-technical-team.github.io/pipapi/reference/pipgd_lorenz_curve.html + + + https://pip-technical-team.github.io/pipapi/reference/pip_aggregate.html + + + https://pip-technical-team.github.io/pipapi/reference/pip_grp.html + + + https://pip-technical-team.github.io/pipapi/reference/pip_grp_logic.html + + + https://pip-technical-team.github.io/pipapi/reference/reporting_level_list.html + + + https://pip-technical-team.github.io/pipapi/reference/return_correct_version.html + + + https://pip-technical-team.github.io/pipapi/reference/return_if_exists.html + + + https://pip-technical-team.github.io/pipapi/reference/rg_pip.html + + + https://pip-technical-team.github.io/pipapi/reference/select_country.html + + + https://pip-technical-team.github.io/pipapi/reference/select_off_alt_agg.html + + + https://pip-technical-team.github.io/pipapi/reference/select_reporting_level.html + + + https://pip-technical-team.github.io/pipapi/reference/select_user_aggs.html + + + https://pip-technical-team.github.io/pipapi/reference/select_years.html + + + https://pip-technical-team.github.io/pipapi/reference/start_api.html + + + https://pip-technical-team.github.io/pipapi/reference/subset_ctry_years.html + + + https://pip-technical-team.github.io/pipapi/reference/subset_lkup.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_cp_charts.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_cp_download.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_cp_key_indicators.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_cp_poverty_charts.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_hp_countries.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_hp_stacked.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_pc_charts.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_pc_regional.html + + + https://pip-technical-team.github.io/pipapi/reference/ui_svy_meta.html + + + https://pip-technical-team.github.io/pipapi/reference/update_master_file.html + + + https://pip-technical-team.github.io/pipapi/reference/validate_input_grouped_stats.html + + + https://pip-technical-team.github.io/pipapi/reference/valid_years.html + + + https://pip-technical-team.github.io/pipapi/reference/version_dataframe.html + + + https://pip-technical-team.github.io/pipapi/reference/wld_lineup_year.html + + diff --git a/inst/TMP/TMP_duckdb_cache.R b/inst/TMP/TMP_duckdb_cache.R new file mode 100644 index 00000000..e37562d9 --- /dev/null +++ b/inst/TMP/TMP_duckdb_cache.R @@ -0,0 +1,38 @@ +devtools::load_all(".") +force <- FALSE +if (!"lkups" %in% ls() || isTRUE(force)) { + data_dir <- Sys.getenv("PIPAPI_DATA_ROOT_FOLDER_LOCAL") |> + fs::path() + fs::dir_ls(data_dir, recurse = FALSE) +} + + +latest_version <- + pipapi:::available_versions(data_dir) |> + max() + +latest_version <- NULL +latest_version <- "20240627_2017_01_02_PROD" +lkups <- create_versioned_lkups(data_dir, + vintage_pattern = latest_version) + +lkup <- lkups$versions_paths[[lkups$latest_release]] + + +reset_cache(lkup = lkup) + + + +# 1. +pip(country = "all", year = 2000, lkup = lkup) + +# 2. +pip(country = "AGO", year = 2000, lkup = lkup) + + +pip(country = "all", year = "all", lkup = lkup) + + +pip(country = "IND", year = 2018, lkup = lkup) + +pip(country = "IND", year = "all", lkup = lkup) diff --git a/inst/plumber/v1/endpoints.R b/inst/plumber/v1/endpoints.R index c88873e5..3a61a7a5 100644 --- a/inst/plumber/v1/endpoints.R +++ b/inst/plumber/v1/endpoints.R @@ -85,7 +85,7 @@ function(req, res) { # treated asynchronously. # 2) The introduction of PPP versioning implies having a dynamic default # poverty line - + browser() req <- pipapi:::assign_required_params(req, pl_lkup = lkups$pl_lkup) @@ -371,6 +371,18 @@ function() { } } +#* Reset DuckDB cache file +#* @get /api/v1/duckdb-reset +#* @param pass:[chr] Local password, this password is checked against the server password +#* @param type:[chr] Which table do you want to delete? Values accepted are "both", "rg" and "fg" +#* @serializer unboxedJSON +function(req, res) { + params <- req$argsQuery + params$lkup <- lkups$versions_paths[[params$version]] + params$version <- NULL + do.call(pipapi:::reset_cache, params) +} + # #* Return cache log # #* @get /api/v1/cache-log # #* @serializer print list(quote = FALSE) diff --git a/man/estimate_type_var.Rd b/man/estimate_type_var.Rd index 8ef32d77..e6e983cd 100644 --- a/man/estimate_type_var.Rd +++ b/man/estimate_type_var.Rd @@ -9,7 +9,7 @@ estimate_type_var(df, lkup) \arguments{ \item{df}{data.table: Table to censor.} -\item{censored_table}{data.table: Censor table} +\item{lkup}{lkup value} } \description{ It also censors specific stats diff --git a/man/fg_pip.Rd b/man/fg_pip.Rd index 9012b01b..3f671bdf 100644 --- a/man/fg_pip.Rd +++ b/man/fg_pip.Rd @@ -12,7 +12,8 @@ fg_pip( welfare_type, reporting_level, ppp, - lkup + lkup, + con ) } \arguments{ @@ -32,6 +33,8 @@ poverty line} \item{ppp}{numeric: Custom Purchase Power Parity value} \item{lkup}{list: A list of lkup tables} + +\item{con}{duckdb connection object} } \value{ data.frame diff --git a/man/get_user_x_code.Rd b/man/get_user_x_code.Rd index ad051135..fc1ba375 100644 --- a/man/get_user_x_code.Rd +++ b/man/get_user_x_code.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/create_countries_vctr.R \name{get_user_x_code} \alias{get_user_x_code} -\title{Helper function to define user_{var}_code} +\title{Helper function to define user_\{var\}_code} \usage{ get_user_x_code(x) } @@ -13,5 +13,5 @@ get_user_x_code(x) character } \description{ -Helper function to define user_{var}_code +Helper function to define user_\{var\}_code } diff --git a/man/pipgd_lorenz_curve.Rd b/man/pipgd_lorenz_curve.Rd index a5e40185..7547a5cd 100644 --- a/man/pipgd_lorenz_curve.Rd +++ b/man/pipgd_lorenz_curve.Rd @@ -15,8 +15,6 @@ pipgd_lorenz_curve(welfare = NULL, weight = NULL, lorenz = NULL, n_bins = 100) \item{n_bins}{atomic double vector of length 1: number of points on the lorenz curve} - -\item{params}{list of parameters} } \value{ Returns a list which contains: diff --git a/man/return_if_exists.Rd b/man/return_if_exists.Rd new file mode 100644 index 00000000..967f4689 --- /dev/null +++ b/man/return_if_exists.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/duckdb_func.R +\name{return_if_exists} +\alias{return_if_exists} +\title{Return the rows of the table if they exist in master file} +\usage{ +return_if_exists(lkup, povline, con, fill_gaps) +} +\arguments{ +\item{lkup}{list: A list of lkup tables} + +\item{povline}{numeric: Poverty line} + +\item{con}{Connection object to duckdb table} + +\item{fill_gaps}{logical: If set to TRUE, will interpolate / extrapolate +values for missing years} +} +\value{ +Dataframe +} +\description{ +Return the rows of the table if they exist in master file +} diff --git a/man/rg_pip.Rd b/man/rg_pip.Rd index 4a4f1881..5d107e95 100644 --- a/man/rg_pip.Rd +++ b/man/rg_pip.Rd @@ -12,7 +12,8 @@ rg_pip( welfare_type, reporting_level, ppp, - lkup + lkup, + con ) } \arguments{ @@ -32,6 +33,8 @@ poverty line} \item{ppp}{numeric: Custom Purchase Power Parity value} \item{lkup}{list: A list of lkup tables} + +\item{con}{duckdb connection object} } \value{ data.frame diff --git a/man/subset_lkup.Rd b/man/subset_lkup.Rd index 9278bf4b..48b7d162 100644 --- a/man/subset_lkup.Rd +++ b/man/subset_lkup.Rd @@ -11,7 +11,10 @@ subset_lkup( reporting_level, lkup, valid_regions, - data_dir = NULL + data_dir = NULL, + povline, + con, + fill_gaps ) } \arguments{ @@ -29,6 +32,13 @@ subset_lkup( for region selection} \item{data_dir}{character: directory path from lkup$data_root} + +\item{povline}{numeric: Poverty line} + +\item{con}{duckdb connection object} + +\item{fill_gaps}{logical: If set to TRUE, will interpolate / extrapolate +values for missing years} } \value{ data.frame diff --git a/man/update_master_file.Rd b/man/update_master_file.Rd new file mode 100644 index 00000000..f4e712a7 --- /dev/null +++ b/man/update_master_file.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/duckdb_func.R +\name{update_master_file} +\alias{update_master_file} +\title{Update master file with the contents of the dataframe} +\usage{ +update_master_file(dat, cache_file_path, fill_gaps) +} +\arguments{ +\item{dat}{Dataframe to be appended} + +\item{cache_file_path}{path where cache file is saved} + +\item{fill_gaps}{logical: If set to TRUE, will interpolate / extrapolate +values for missing years} +} +\value{ +number of rows updated +} +\description{ +Update master file with the contents of the dataframe +} diff --git a/pipapi.Rproj b/pipapi.Rproj index 7470a16d..7a441a72 100644 --- a/pipapi.Rproj +++ b/pipapi.Rproj @@ -1,5 +1,5 @@ Version: 1.0 -ProjectId: 73133a1c-39b9-4622-abdf-7862f43a14a1 +ProjectId: 3fab55c7-e5d2-495a-8d65-ef16b44733fe RestoreWorkspace: No SaveWorkspace: No diff --git a/tests/testthat/test-fg_pip-local.R b/tests/testthat/test-fg_pip-local.R index ee5523ed..c3c3ae97 100644 --- a/tests/testthat/test-fg_pip-local.R +++ b/tests/testthat/test-fg_pip-local.R @@ -13,6 +13,8 @@ lkups <- create_versioned_lkups(data_dir, vintage_pattern = latest_version) lkup <- lkups$versions_paths[[lkups$latest_release]] +con <- duckdb::dbConnect(duckdb::duckdb(), dbdir = fs::path(lkup$data_root, "cache", ext = "duckdb")) + local_mocked_bindings( get_caller_names = function() c("else") ) @@ -28,10 +30,11 @@ test_that("Imputation is working for extrapolated aggregated distribution", { welfare_type = "all", reporting_level = "all", ppp = NULL, - lkup = lkup + lkup = lkup, + con = con ) - expect_equal(nrow(tmp), 2) + expect_equal(nrow(tmp$main_data), 2) tmp <- fg_pip( country = "CHN", @@ -41,10 +44,11 @@ test_that("Imputation is working for extrapolated aggregated distribution", { welfare_type = "all", reporting_level = "national", ppp = NULL, - lkup = lkup + lkup = lkup, + con = con ) - expect_equal(nrow(tmp), 2) + expect_equal(nrow(tmp$main_data), 2) }) ## Interpolation ---- @@ -57,10 +61,11 @@ test_that("Imputation is working for interpolated mixed distribution", { welfare_type = "all", reporting_level = "all", ppp = NULL, - lkup = lkup + lkup = lkup, + con = con ) - expect_equal(nrow(tmp), 2) + expect_equal(nrow(tmp$main_data), 2) tmp <- fg_pip( country = "IND", @@ -70,10 +75,11 @@ test_that("Imputation is working for interpolated mixed distribution", { welfare_type = "all", reporting_level = "national", ppp = NULL, - lkup = lkup + lkup = lkup, + con = con ) - expect_equal(nrow(tmp), 2) + expect_equal(nrow(tmp$main_data), 2) }) test_that("Imputation is working for interpolated aggregate distribution", { @@ -85,10 +91,11 @@ test_that("Imputation is working for interpolated aggregate distribution", { welfare_type = "all", reporting_level = "all", ppp = NULL, - lkup = lkup + lkup = lkup, + con = con ) - expect_equal(nrow(tmp), 2) + expect_equal(nrow(tmp$main_data), 2) tmp <- fg_pip( country = "CHN", @@ -98,10 +105,11 @@ test_that("Imputation is working for interpolated aggregate distribution", { welfare_type = "all", reporting_level = "national", ppp = NULL, - lkup = lkup + lkup = lkup, + con = con ) - expect_equal(nrow(tmp), 2) + expect_equal(nrow(tmp$main_data), 2) }) @@ -150,9 +158,10 @@ tmp <- fg_pip( welfare_type = "all", reporting_level = "all", ppp = NULL, - lkup = lkup + lkup = lkup, + con = con ) - +tmp <- tmp$main_data # dt <- pip(country = "ALL", # lkup = lkup, # povline = 2.15, diff --git a/tests/testthat/test-ui_poverty_indicators.R b/tests/testthat/test-ui_poverty_indicators.R index b4422c97..d209887e 100644 --- a/tests/testthat/test-ui_poverty_indicators.R +++ b/tests/testthat/test-ui_poverty_indicators.R @@ -20,7 +20,7 @@ test_that("ui_pc_charts() works as expected", { povline = 1.9, lkup = lkups) expect_equal(class(res), c("data.table", "data.frame")) - expect_equal(names(res), lkups$return_cols$ui_pc_charts$cols) + expect_equal(names(res), setdiff(lkups$return_cols$ui_pc_charts$cols, "estimate_type")) expect_equal(nrow(res), nrow(lkups$svy_lkup[country_code == "AGO"])) }, get_caller_names = function() c("else") diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index da38fa01..5ec627d5 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -68,7 +68,7 @@ test_that("subset_lkup correctly selects all countries", { valid_regions = valid_regions, data_dir = data_dir) - expect_equal(nrow(tmp), nrow(ref_lkup)) + expect_equal(nrow(tmp$lkup), nrow(ref_lkup)) }) test_that("subset_lkup correctly selects countries", { @@ -81,7 +81,7 @@ test_that("subset_lkup correctly selects countries", { valid_regions = valid_regions, data_dir = data_dir) - expect_equal(sort(unique(tmp$country_code)), sort(selection)) + expect_equal(sort(unique(tmp$lkup$country_code)), sort(selection)) }) test_that("subset_lkup correctly selects single regions", { @@ -94,7 +94,7 @@ test_that("subset_lkup correctly selects single regions", { valid_regions = valid_regions, data_dir = data_dir) - expect_equal(sort(unique(tmp$region_code)), sort(selection)) + expect_equal(sort(unique(tmp$lkup$region_code)), sort(selection)) }) test_that("subset_lkup correctly selects multiple regions", { @@ -107,7 +107,7 @@ test_that("subset_lkup correctly selects multiple regions", { valid_regions = valid_regions, data_dir = data_dir) - expect_equal(sort(unique(tmp$region_code)), sort(selection)) + expect_equal(sort(unique(tmp$lkup$region_code)), sort(selection)) }) test_that("subset_lkup correctly selects countries and regions", { @@ -125,9 +125,9 @@ test_that("subset_lkup correctly selects countries and regions", { data_dir = data_dir) # Regions are selected - expect_true(all(region_selection %in% (unique(tmp$region_code)))) + expect_true(all(region_selection %in% (unique(tmp$lkup$region_code)))) # Countries are selected - expect_true(all(country_selection %in% (unique(tmp$country_code)))) + expect_true(all(country_selection %in% (unique(tmp$lkup$country_code)))) }) # select_country() test suite diff --git a/vignettes/debug-caching.Rmd b/vignettes/debug-caching.Rmd index ce110bfe..5b82048c 100644 --- a/vignettes/debug-caching.Rmd +++ b/vignettes/debug-caching.Rmd @@ -1,8 +1,12 @@ --- title: "Debug caching and API endpoints" -output: html_document date: "2024-10-02" author: "Ronak Shah" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{Debug caching and API endpoints} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} --- ## How caching works? diff --git a/vignettes/duckdb-caching.Rmd b/vignettes/duckdb-caching.Rmd new file mode 100644 index 00000000..fe5749c8 --- /dev/null +++ b/vignettes/duckdb-caching.Rmd @@ -0,0 +1,159 @@ +--- +title: "DuckDB Caching" +date: "2024-12-26" +author: "Ronak Shah" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{DuckDB Caching} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r setup, include=FALSE} +knitr::opts_chunk$set(eval = FALSE, echo = TRUE) +``` + +## Introduction + +Current caching mechanism for pip uses traditional caching where basically a hash is created based on the value of the arguments passed in the function and if someone calls the same function with the same arguments again the cached result is returned instead of doing the same calculation again. For `pip` we used the packages `cachem` and `memoise` to implement this system of caching. We will call this caching system as traditional caching strategy. This traditional caching strategy works well in general however, `pip` is a special case and it would benefit much more if it had a custom strategy for caching. + +## How caching currently works? + +Consider these pip functions + +```{r, eval=FALSE} +# 1. +pip(country = "all", year = 2000, lkup = lkup) + +# 2. +pip(country = "AGO", year = 2000, lkup = lkup) +``` + +Now since these are separate set of arguments 2 files of caching are created and saved on the disk. Now if a call to `pip` is made again `pip(country = "AGO", year = 2000, lkup = lkup)` which is same as 2) then it would return the result from the cached file stored on the disk without doing any calculation. Needless to say, this result is much faster. + +However, notice that the 2nd call is subset of the 1st one. What I mean by that is the result of 2) is already present in result of 1). We have done the calculations for all the countries for the year 2000 in 1) we just need output of `"AGO"` from it to get the result for 2). + +## Custom caching for pipapi. + +What if we could take subset of an existing cache like how we need it as above. However, this is not how traditional caching systems work so there is no ready-made solution available. We would need to implement this logic from scratch if we want to make this work. + +We came up with an idea to implement this custom caching using `duckdb` where we save the output in a table. Basically, all the queries that are called till now are saved in the table and whenever a new call is made it checks if the result already exists in the table, if yes then it returns the result immediately or else it will do the calculation and then save the result to the table for next use and return the result. There are various scenarios that we need to consider to understand this approach. Let's take help of an example to understand each one of them. + +Consider that we are just starting out and there is nothing saved in the table and it's empty. + +#### Scenario 1 - + +```{r} +pip(country = c("AGO", "USA"), year = 2000, lkup = lkup) +``` + +Since the table is empty, this call will do all the calculation and save the result in the table for future use and return the output. + +#### Scenario 2 - + +```{r} +pip(country = "USA", year = 2000, lkup = lkup) +``` + +Now this is something which we have already calculated in our previous call. In traditional caching this would be treated as a separate call and the calculation would have been performed again. However, in our custom caching it goes through the existing table and checks if we already have the result for this call. Since we do have it saved in our table we will just return the result in this case as it is from the table without doing any calculation. + +#### Scenario 3 - + +```{r} +pip(country = c("ARG", "USA"), year = 2000, lkup = lkup) +``` + +Notice this time it is combination of scenario 1 and 2 where one part of the calculation we already have ("USA") and another part we don't ("ARG"). In this case, we return the result for the country that we have in the table and send rest of the arguments for the calculation. We save the result from calculation in the table and return the output by combining both the result. + +#### Scenario 4 - + +```{r} +pip(country = "all", year = 2000, lkup = lkup) +``` + +In this scenario before we check in the table we need to decode this "all" argument to list of actual country names because in the table we save the data with actual country names. Once we have the list of country names we check which of those values are already available in the table. If we consider the 3 scenarios above then we already have result for `c("ARG", "AGO", "USA")` and we need to find result for the remaining countries. After saving the data for the remaining countries in the table, we return the result by combining the two. + +#### Scenario 5 - + +```{r} +pip(country = "AGO", year = "all", lkup = lkup) +``` + +This is similar to scenario 4 but instead of having `country = "all"` we have here `year = "all"` so in this case we need to decode the `year` parameter. However, the sequence of operation remains the same as above. + +#### Scenario 6 - + +```{r} +pip(country = "all", year = "all", lkup = lkup) +``` + +This is combination of scenario 4 and 5 where we need to decode both `country` and `year` parameter, check the values that are present in the table, query the data that does not exist, save it into the table, combine the result and return the output. + +These are 6 different scenarios that can occur. Note that I have not used all the arguments here in the `pip` call. We are using the default `povline` i.e 1.9 here but it can be something else. In which case, it will become scenario 1 where nothing is found in the table and the output is calculated and result is saved in the table. Similarly, we can also have situations where `fill_gaps` is set to `TRUE` which would also follow the same process. + +## Code overview + +We are creating a duckdb file to save our table. This file is specific to one release and is saved in the root of the release folder with name `cache.duckdb`. There are two tables created in the duckdb file called `rg_master_file` and `fg_master_file` based on the `fill_gaps` argument a table is selected to save and retrieve data. Based on `fill_gaps` parameter we call either the function `fg_pip` or `rg_pip`. Both the functions call the `subset_lkup` function to filter the data from `lkup` that is relevant to our call. In `subset_lkup` function we call the function `return_if_exists` which as the name suggests returns the data from cache if it exists. A new file called `duckdb_fun.R` has been added to manage all the functions related to duckdb. + +A named list is returned from `return_if_exists` function where it returns the final output (if it exists) from the master file and subsetted `lkup`. The partial (or full) final output is again returned as a named list from `subset_lkup` function which is used at the end to combine the two outputs. If `lkup` is non-empty then after all the calculation is done we use the function `update_master_file` to append the master file with new data. If we are running the function for the first time in the release the code also has a provision to create an empty `cache.duckdb` file with two tables. + +## Speed comparison + +For analysis purposes, we are comparing speed in different scenarios on `DEV` branch vs that in `implement-duckdb` branch. + +```{r} +microbenchmark::microbenchmark( + pip_DEV = pip(country = c("AGO", "USA"), year = 2000, lkup = lkup) +) + +#Unit: microseconds +# expr min lq mean median uq max neval +# duckdb_DEV 830.463 899.872 2241.876 918.446 954.1285 116429.3 100 + +microbenchmark::microbenchmark( + duckdb_caching = pip(country = c("AGO", "USA"), year = 2000, lkup = lkup) +) + +#Unit: milliseconds +# expr min lq mean median uq max neval +# duckdb_caching 161.6227 170.5818 185.5906 175.3116 184.9512 793.8183 100 +``` + +```{r} +country_list <- c("AGO", "ARG", "AUT", "BEL", "BGD", "BLR", "BOL", "CAN", "CHE", + "CHL", "COL", "CRI", "DEU", "DNK", "DOM", "ECU", "ESP", "EST", + "FIN", "FRA", "FSM", "GBR", "GEO", "GRC", "GTM", "HRV", "HUN", + "IDN", "IDN", "IDN", "IRL", "ITA", "KGZ", "LTU", "LUX", "MAR", + "MDA", "MEX", "MKD", "MRT", "NOR", "PAN", "PER", "PHL", "PHL", + "POL", "ROU", "RUS", "RWA", "SLV", "STP", "SWE", "SWZ", "THA", + "TON", "TUN", "TWN", "TZA", "URY", "USA", "UZB", "ZAF") + +tictoc::tic() + +for(i in seq_along(country_list)) { + out <- pip(country = country_list[seq_len(i)], year = 2000, lkup = lkup) +} + +tictoc::toc() + +## For DEV version +# 16.36 sec elapsed + +## For Duckdb +#18.17 sec elapsed +``` + +```{r} +tictoc::tic() + +for(i in seq_along(country_list)) { + out <- pip(country = country_list[seq_len(i)], year = "all", lkup = lkup) +} + +tictoc::toc() +## DEV +# 403.38 sec elapsed + +## Duckdb caching +# 33.53 sec elapsed +``` diff --git a/vignettes/new-endpoints.Rmd b/vignettes/new-endpoints.Rmd index df7f1fa6..e52a7e3b 100644 --- a/vignettes/new-endpoints.Rmd +++ b/vignettes/new-endpoints.Rmd @@ -18,3 +18,5 @@ The arguments are validated in function `validate_query_parameters` which has a **Values :** Validate your input values in `create_query_controls` function by adding range or list of accepted values. If the arguments is character then you need to give all possible values that it can take. If the argument is numeric, then you need to supply `min` and `max` values to ensure that the numeric values stays in range. Based on the type of argument, `check_param_chr`, `check_param_num` or `check_param_lgl` is called. This also ensures that the argument name should mean the same everywhere. So it is not possible that the same argument can have two different meaning. For example, it is not possible that the argument `requested_mean` accepts value 0 to 1 in one endpoint and `c("yes"/"no")` in another endpoint again ensuring consistency. Another thing to note is that the argument and values are available in both `req$args` as well as `req$argsQuery` however, all the validation is performed only on `argsQuery` and only `argsQuery` is used the entire API. So we suggest to continue using `argsQuery` for consistency purposes. + +Once you do these changes, don't forget to refresh the session before testing out your changes.