R/plot_ctr_processing_time.R

Defines functions plot_ctr_processing_time

Documented in plot_ctr_processing_time

# WARNING - Generated by {fusen} from /dev/dev_plot_Country.Rmd: do not edit by hand

#' Plot Average processing time from registration to first instance asylum decision
#' 
#' This indicator measures the average number of days from the date of completion of registration of the asylum application to the date of notification of first instance asylum decision for all persons who were notified of a first instance RSD/asylum decision during the reporting period. 
#' 
#' Status determination procedures are a core protection function and the principle mechanism through which international protection needs of Persons of Concern may be determined in accordance with the key provisions of the 1951 Convention and 1967 Protocol relating to the Status of Refugees, the 1954 Convention relating to the Status of Stateless Persons, or relevant regional refugee protection instruments. Status determination procedures are therefore central to the full and effective enjoyment of the universal right to seek and enjoy asylum and the specific rights guaranteed by the above instruments.
#' 
#' A prolonged waiting period during the status determination procedure is an important indicator of the state of efficiency, fairness, adaptability integrity and hence, overall quality of the national asylum or, depending on the context, UNHCR Mandate RSD procedure, including the timeliness and effectiveness of the overall protection response in the country.
#'  
#'  (RBM Outcome Indicator 2.1) - see [UNHCR Intranet](https://intranet.unhcr.org/content/dam/unhcr/intranet/protection-operations/compass/en/guidance/3/coreindicatorsmetadata/2.0%20Core%20Indicator%20Metadata%2004%2010%202021.pdf#page=67) - Credit to Hisham Galal for the chart initial idea and script
#' 
#' @param year Numeric value of the year (for instance 2020)
#' @param country_asylum_iso3c Character value with the ISO-3 character code of the Country of Asylum
#' 
#' @param country_origin_iso3c Character value with the ISO-3 character code of the Country of Asylum - if NUL then all countries are included
#' 
#' @param procedureType indicates whether "G" (Government) "J" (Joint) "U" (UNHCR)
#' @importFrom ggplot2  ggplot  aes  coord_flip   element_blank element_line
#'             element_text expansion geom_bar geom_col geom_hline unit stat_summary
#'             geom_label geom_text labs  position_stack  scale_color_manual scale_colour_manual guides guide_legend
#'             geom_text guide_axis facet_wrap vars geom_area annotate
#'             scale_fill_manual scale_x_continuous scale_x_discrete  scale_y_continuous   sym theme  scale_fill_manual
#' @importFrom utils  head
#' @importFrom tidyselect where
#' @importFrom stringr  str_replace 
#' @importFrom scales cut_short_scale label_percent label_number breaks_pretty
#' @importFrom tidyr pivot_longer 
#' @importFrom dplyr  desc select  case_when lag mutate group_by filter summarise ungroup
#'               pull distinct n arrange across slice left_join last transmute
#' @importFrom purrr detect_index
#' @importFrom lubridate date_decimal interval days make_date
#' @importFrom unhcrthemes theme_unhcr
#' 
#' @return a ggplot2 object
#' 
#' @export
#' @examples
#' plot_ctr_processing_time(year = 2022,
#'                          country_asylum_iso3c = "ARG")
#' 
#' 
#' plot_ctr_processing_time(year = 2022,
#'                          country_asylum_iso3c = "USA")
#' 
#' ## Display a filtered version of the chart for a specific country and procedure
#' plot_ctr_processing_time(year = 2022,
#'                          country_asylum_iso3c = "EGY",
#'                          country_origin_iso3c = "ERI",
#'                          procedureType = "U")
#' 
plot_ctr_processing_time <- function(year = 2022,
                              country_asylum_iso3c = country_asylum_iso3,
                              country_origin_iso3c = NULL,
                              procedureType = NULL){
    
  
#   library(tidyverse)
# library(lubridate)
# library(jsonlite)
#   country_asylum_iso3c <- "CHL" # iso3 code
  
  if( is.null(country_origin_iso3c)) {
        originfilter <-     c(ForcedDisplacementStat::asylum_applications |>
                                      dplyr::select(CountryOriginCode) |>
                                      unique() |>
                                    dplyr::pull() ) 
        originfilterlab <- ""
        } else { 
        originfilter <- c(country_origin_iso3c) 
        originfilterlab <- ForcedDisplacementStat::reference |>
                                   dplyr::filter( iso_3 == country_origin_iso3c) |>
                                   dplyr::pull(ctryname)}
  if( is.null(procedureType)) {
          procedurefilter <-     c(ForcedDisplacementStat::asylum_applications |>
                                      dplyr::select(ProcedureType) |>
                                      unique() |>
                                    dplyr::pull() )
          procedurefilterlab <- ""
          } else { 
          procedurefilter <- c(procedureType)
          procedurefilterlab <- ForcedDisplacementStat::asylum_applications |>
                                      dplyr::filter(ProcedureType == procedureType ) |>
                                     dplyr::select(ProcedureName)|>
                                      unique() |>
                                    dplyr::pull()}
   filterlab <- paste0( dplyr::if_else( originfilterlab == "",
                                        "",
                                        paste0( ", filtered for nationals from ",
                                                originfilterlab)),
                        dplyr::if_else( originfilterlab == "",
                                        "",
                                        paste0( " processed by ", 
                                                procedurefilterlab, " ")))
                        
      
  
  
    apps <- ForcedDisplacementStat::asylum_applications |>
          filter(CountryAsylumCode == country_asylum_iso3c )|>
      
          ## add conditional filter  if setup
          filter(CountryOriginCode %in% c(originfilter)  ) |>
          filter(ProcedureType %in% c(procedurefilter)  ) |>
      
      
          mutate ( DecisionTypeCode  = dplyr::case_when (
            (ApplicationTypeCode %in% c("N", "NR", "NA", "FA", "SP") ) ~ "FI",
             # | 
             #  (ApplicationTypeCode == "V" & 
             #    DecisionType %in% c("FI", "FA", "NA", "TR", "CA")) ) ~ "FI",
            TRUE ~ "Other"   )) |>
          group_by(Year, CountryAsylumCode,
                   CountryAsylumName, 
                   #ProcedureType,  ProcedureName,  ApplicationTypeCode, ApplicationType
                   DecisionTypeCode ) |>
         summarize (NumberApplications = sum(NumberApplications , na.rm= TRUE) )  |>
          dplyr::ungroup()
#     
#   # coa <-   "CHL"
#     
#   ## Equivalent to this API - call 
# # apps1 <- jsonlite::fromJSON(glue::glue("https://api.unhcr.org/population/v1/asylum-applications/?limit=100&dataset=asylum-applications&displayType=totals&yearFrom=1951&yearTo=2022&coa={coa}&columns%5B%5D=procedure_type&columns%5B%5D=app_type&columns%5B%5D=app_pc&columns%5B%5D=app_size&columns%5B%5D=dec_level&columns%5B%5D=applied"))$items |>  as_tibble()
    
  if( is.null(country_origin_iso3c)) {
        originfilter <-     c(ForcedDisplacementStat::asylum_decisions |>
                                      dplyr::select(CountryOriginCode) |>
                                      unique() |>
                                    dplyr::pull() ) } else { 
        originfilter <- c(country_origin_iso3c) }
  if( is.null(procedureType)) {
          procedurefilter <-     c(ForcedDisplacementStat::asylum_decisions |>
                                      dplyr::select(ProcedureType) |>
                                      unique() |>
                                    dplyr::pull() ) } else { 
          procedurefilter <- c(procedureType) }
# 
  decs <- ForcedDisplacementStat::asylum_decisions |>
          filter(CountryAsylumCode == country_asylum_iso3c ) |>
          ## add conditional filter  if setup
          filter(CountryOriginCode %in% c(originfilter)  ) |>
          filter(ProcedureType %in% c(procedurefilter)  ) |>
    
          group_by(Year, CountryAsylumCode,
                   CountryAsylumName, 
                   #ProcedureType,  ProcedureName,, DecisionTypeName
                   DecisionTypeCode) |>
         summarize (Recognized = sum(Recognized , na.rm= TRUE),
                  ComplementaryProtection = sum( ComplementaryProtection , na.rm= TRUE),
                  OtherwiseClosed = sum(OtherwiseClosed , na.rm= TRUE),
                  Rejected = sum(Rejected , na.rm= TRUE),
                  TotalDecided = sum(TotalDecided , na.rm= TRUE)) |>
          dplyr::ungroup()
  
  ## Equivalent to this API - call 
 # decs1 <- jsonlite::fromJSON(glue::glue("https://api.unhcr.org/population/v1/asylum-decisions/?limit=100&dataset=asylum-decisions&displayType=totals&yearFrom=1951&yearTo=2022&coa={coa}&columns%5B%5D=procedure_type&columns%5B%5D=dec_level&columns%5B%5D=dec_pc&columns%5B%5D=dec_recognized&columns%5B%5D=dec_other&columns%5B%5D=dec_rejected&columns%5B%5D=dec_closed&columns%5B%5D=dec_total"))$items |> as_tibble() 

data <-
  left_join(apps |> filter(DecisionTypeCode  == "FI") |> select(Year, CountryAsylumCode, NumberApplications),
            decs |> filter(DecisionTypeCode == "FI") |> select(Year, CountryAsylumCode, TotalDecided) ) |>
  arrange(Year) |>
  mutate(across(c(NumberApplications,
                  TotalDecided),
                replace_na, 0)) |>
  dplyr::transmute(Year = if_else(Year == last(Year),
                           Year+.5,
                           Year+1), # MYSR correction
            apps = cumsum(NumberApplications),
            decs = cumsum(TotalDecided))  
  
  idx <- purrr::detect_index(data$apps, ~.< dplyr::last(data$decs),
                                           .dir = "backward")
  
  t <- lubridate::date_decimal(data$Year[idx] + 
                                 (dplyr::last(data$decs) - data$apps[idx]) / 
                                 (data$apps[idx+1] - data$apps[idx]))
  
  stat <- lubridate::interval(t, lubridate::make_date(2022, 6, 30)) / lubridate::days()
  
  data2 <- data |>
      tidyr::pivot_longer(- Year, 
                          names_to = "flow",
                          values_to = "n")
  
  
  
  p <- data2 |>
    ggplot(aes(Year,
               n, 
               fill = flow)) +
    geom_area(position = "identity") +
    ## highlight the main indicator!
    annotate("segment",
             x = lubridate::decimal_date(t),
             y = dplyr::last(data$decs),
             xend = dplyr::last(data$Year),
             yend = dplyr::last(data$decs)) +
    annotate("text",
             x = 2020,
             y = last(data$decs),
             vjust = -.5,
             label = glue::glue("{round(stat)} days")) +
    scale_y_continuous(labels = scales::label_comma()) +
    scale_fill_manual(labels = c(decs = "Decisions",
                                 apps = "Applications"),
                      values = c(decs = "#0072BC",
                                 apps = "#FAEB00"),
                      name = NULL) +
    labs(title = stringr::str_wrap("Average Processing Time from Asylum Registration to First Instance Decision", 100),
         subtitle = glue::glue("In {ForcedDisplacementStat::reference |>
                                   dplyr::filter( iso_3 == country_asylum_iso3c) |>
                                   dplyr::pull(ctryname)}, comparative cumulative applications and decisions with gap measured in days as of {year} {filterlab}"),
         x = NULL,
         y = "Cumulative total",
         caption = "Source: UNHCR.org/refugee-statistics") +
    guides(fill = guide_legend(reverse = TRUE)) +
    theme_unhcr(font_size = 14, 
                grid = "Y")  + ## Insert UNHCR Style
    theme(legend.position = "top")
  
  return(p)
  
}
Edouard-Legoupil/unhcrdatapackage documentation built on Nov. 6, 2023, 6:10 p.m.