---
title: "HIV self-testing positivity rate and linkage to confirmatory testing and care: a telephone survey in Côte d’Ivoire, Mali and Senegal"
author: "Arsène Kra Kouassi et al."
date: today
toc: true
format:
  html:
    html-math-method: katex
    code-tools: true
    code-fold: true
    self-contained: true
execute:
  warning: false
---

\newpage

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r}
library(tidyverse)
library(gtsummary)
library(labelled)
library(scales)
library(utils)
data <- readr::read_csv("data.csv", show_col_types = FALSE) |> 
  set_variable_labels(
    country = "Country",
    sex = "Sex",
    age_group = "Age group",
    marital_status = "Marital status",
    educational_level = "Educational level",
    distribution_channel = "HIVST distribution channel",
    first_time_tester = "Firt-time tester",
    HIVST_reported_lines = "Reported number of visibles lines on the HIVST kit",
    HIVST_reported_result = "Reported self-interpreted result of the HIVST",
    date_phase1 = "Date when phase 1 questionnaire was completed",
    recontact_phase2 = "Accpeted to be recontacted for phase 2 survey?",
    status_phase2 = "Final status for participation in phase 2 survey",
    date_phase2 = "Date when phase 2 questionnaire was completed",
    status_phase_1and2 = "Final participation status for phase 1 and phase 2",
    confirmatory_test = "Did participant link to confirmatory testing?",
    reason_non_confirmatory_test = "If did not link to confirmatory testing, main reported reason",
    time_to_confirmation = "Reported time between HIVST and confirmatory testing",
    place_confirmatory_test = "Place of confirmatory testing",
    confirmatory_test_result = "Result of confirmatory testing",
    consulted_health_prof = "If diagnosed HIV positive, consulted a professionnal healthcare?",
    iniated_ART = "If diagnosed HIV positive, initiated antiretroviral treatment"
  )
```

## Table 1. Self-reported test result and the reported number of lines among participants of phase 1, and positivity rates according to different hypotheses

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
data <- data |>
  mutate(
    HIVST_detailed_result =
      case_when(
        (HIVST_reported_lines == "2 lines" & HIVST_reported_result == "reactive") ~ "2 lines / reactive",
        (HIVST_reported_lines == "2 lines" & HIVST_reported_result == "non reactive") ~ "2 lines / non-reactive",
        (HIVST_reported_lines == "2 lines" & (HIVST_reported_result == "DK" | HIVST_reported_result == "R")) ~ "2 lines / DK-R",
        (HIVST_reported_lines == "1 line" & HIVST_reported_result == "reactive") ~ "1 line / reactive",
        (HIVST_reported_lines == "1 line" & HIVST_reported_result == "non reactive") ~ "1 line / non-reactive",
        (HIVST_reported_lines == "1 line" & (HIVST_reported_result == "DK" | HIVST_reported_result == "R")) ~ "1 line / DK-R",
        (HIVST_reported_lines == "0 line" & HIVST_reported_result == "non reactive") ~ "0 line / non-reactive",
        (HIVST_reported_lines == "0 line" & HIVST_reported_result == "reactive") ~ "0 line / reactive",
        (HIVST_reported_lines == "0 line" & (HIVST_reported_result == "DK" | HIVST_reported_result == "R")) ~ "0 line / DK-R",
        ((HIVST_reported_lines == "0 line" | HIVST_reported_lines == "1 line") & HIVST_reported_result == "invalid") ~ "0-1 line / invalid",
        (HIVST_reported_lines == "2 lines" & HIVST_reported_result == "invalid") ~ "2 lines / invalid",
        ((HIVST_reported_lines == "DK" | HIVST_reported_lines == "R") & HIVST_reported_result == "invalid") ~ "DK-R / invalid",
        ((HIVST_reported_lines == "DK" | HIVST_reported_lines == "R") & HIVST_reported_result == "reactive") ~ "DK-R / reactive",
        ((HIVST_reported_lines == "DK" | HIVST_reported_lines == "R") & HIVST_reported_result == "non reactive") ~ "DK-R / non-reactive",
        ((HIVST_reported_lines == "DK" | HIVST_reported_lines == "R") & (HIVST_reported_result == "DK" | HIVST_reported_result == "R")) ~ "DK-R / DK-R"
      ),
     HIVST_detailed_result = HIVST_detailed_result |> 
      fct_relevel(
        "2 lines / reactive", "1 line / non-reactive", "0-1 line / invalid",
        "1 line / reactive", "2 lines / non-reactive", "0 line / non-reactive",
        "0 line / DK-R", "1 line / DK-R", "2 lines / DK-R", "DK-R / reactive",
        "DK-R / DK-R", "DK-R / non-reactive"
      )
  ) |>
  set_variable_labels(HIVST_detailed_result = "Reported number of lines / self-interpreted HIVST result")

tbl1 <-
  data |>
  tbl_summary(
    include = HIVST_detailed_result,
    label = HIVST_detailed_result ~ ""
  ) |>
  modify_header(label = "**Phase 1 participants**") |>
  as_gt() |>
  gt::tab_row_group(
    label = gt::md("Partial reponse (P)*"),
    rows = 8:13
  ) |>
  gt::tab_row_group(
    label = gt::md("*Inconsistant reponse (I)*"),
    rows = 5:7
  ) |>
  gt::tab_row_group(
    label = gt::md("*Consistant reponse (C)*"),
    rows = 2:4
  )

tbl1
```

## Table 2.a: Positivity rates based on self-interpreted HIVST result, by distribution channel, gender and country, among phase 1 participants

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
data <- data |>
  mutate(
    channel_by_sex = interaction(sex, distribution_channel) |>
      fct_recode() |>
      fct_relevel(
        "man.MSM-based channels", "woman.MSM-based channels", "man.FSW-based channels",
        "woman.FSW-based channels", "man.Other delivery channels", "woman.Other delivery channels"
      )
  ) |> 
  set_variable_labels(channel_by_sex = "Distribution channel by sex")

tbl2a_low <- data |>
  to_factor() |>
  tbl_custom_summary(
    include = c(country),
    by = channel_by_sex,
    stat_fns = ~ proportion_summary(variable = "HIVST_reported_result", value = c("reactive")),
    statistic = ~"{prop}% ({n}/{N})",
    digits = ~ list(
      function(x) {
        style_percent(x, digits = 0)
      }, 0, 0
    ),
    overall_row = TRUE
  ) |>
  add_overall(last = FALSE)

tbl2a_central <- data |>
  filter(HIVST_reported_result != "DK", HIVST_reported_result != "R") |>
  to_factor() |>
  tbl_custom_summary(
    include = c(country),
    by = channel_by_sex,
    stat_fns = ~ proportion_summary(variable = "HIVST_reported_result", value = c("reactive")),
    statistic = ~"{prop}% ({n}/{N})",
    digits = ~ list(
      function(x) {
        style_percent(x, digits = 0)
      }, 0, 0
    ),
    overall_row = TRUE
  ) |>
  add_overall(last = FALSE)

tbl2a_high <- data |>
  to_factor() |>
  tbl_custom_summary(
    include = c(country),
    by = channel_by_sex,
    stat_fns = ~ proportion_summary(variable = "HIVST_reported_result", value = c("reactive", "DK", "R")),
    statistic = ~"{prop}% ({n}/{N})",
    digits = ~ list(
      function(x) {
        style_percent(x, digits = 0)
      }, 0, 0
    ),
    overall_row = TRUE
  ) |>
  add_overall(last = FALSE)

tbl2a <- tbl_stack(
  list(tbl2a_low, tbl2a_central, tbl2a_high),
  group_header = c(
    "Low: positivity rate based on self reported test result and DK-R are considered not reactive",
    "Central: positivity rate based on self reported test result and DK-R are excluded",
    "High: positivity rate based on self reported test result and DK-R are considered reactive"
  )
)

tbl2a |>
  modify_header(label ~ "**Variable**") |>
  modify_spanning_header(
    c("stat_1", "stat_2") ~ "**MSM-based channels**",
    c("stat_3", "stat_4") ~ "**FSW-based channels**",
    c("stat_5", "stat_6") ~ "**Others delivery channels**",
    stat_0 ~ "**Total**"
  ) |>
  modify_header(
    stat_1 ~ "**Man**", stat_2 ~ "**Woman**",
    stat_3 ~ "**Man**", stat_4 ~ "**Woman**",
    stat_5 ~ "**Man**", stat_6 ~ "**Woman**",
    stat_0 ~ " "
  ) |>
  modify_footnote(update = everything() ~ NA)
```

## Table 2.b: Positivity rates based on the reported number of lines, by distribution channel, gender and country, among phase 1 participants

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
tbl2b_low <- data |>
  to_factor() |>
  tbl_custom_summary(
    include = c(country),
    by = channel_by_sex,
    stat_fns = ~ proportion_summary(variable = "HIVST_reported_lines", value = c("2 lines")),
    statistic = ~"{prop}% ({n}/{N})",
    digits = ~ list(
      function(x) {
        style_percent(x, digits = 0)
      }, 0, 0
    ),
    overall_row = TRUE
  ) |>
  add_overall(last = FALSE)


tbl2b_central <- data |>
  filter(HIVST_reported_lines != "DK", HIVST_reported_lines != "R") |>
  to_factor() |>
  tbl_custom_summary(
    include = c(country),
    by = channel_by_sex,
    stat_fns = ~ proportion_summary(variable = "HIVST_reported_lines", value = c("2 lines")),
    statistic = ~"{prop}% ({n}/{N})",
    digits = ~ list(
      function(x) {
        style_percent(x, digits = 0)
      }, 0, 0
    ),
    overall_row = TRUE
  ) |>
  add_overall(last = FALSE)


tbl2b_high <- data |>
  to_factor() |>
  tbl_custom_summary(
    include = c(country),
    by = channel_by_sex,
    stat_fns = ~ proportion_summary(variable = "HIVST_reported_lines", value = c("2 lines", "DK", "R")),
    statistic = ~"{prop}% ({n}/{N})",
    digits = ~ list(
      function(x) {
        style_percent(x, digits = 0)
      }, 0, 0
    ),
    overall_row = TRUE
  ) |>
  add_overall(last = FALSE)



tbl2b <- tbl_stack(list(tbl2b_low, tbl2b_central, tbl2b_high),
  group_header = c(
    "Low: positivity rate based on self reported number of lines and DK-R are considered not 2 lines",
    "Central: positivity rate based on self reported number of lines and DK-R are excluded",
    "High: positivity rate based on self reported number of lines and DK-R are considered 2 lines"
  )
)

tbl2b |>
  modify_header(label ~ "**Variable**") |>
  modify_spanning_header(
    c("stat_1", "stat_2") ~ "**MSM-based channels**",
    c("stat_3", "stat_4") ~ "**FSW-based channels**",
    c("stat_5", "stat_6") ~ "**Others delivery channels**",
    stat_0 ~ "**Total**"
  ) |>
  modify_header(
    stat_1 ~ "**Man**", stat_2 ~ "**Woman**",
    stat_3 ~ "**Man**", stat_4 ~ "**Woman**",
    stat_5 ~ "**Man**", stat_6 ~ "**Woman**",
    stat_0 ~ " "
  ) |>
  modify_footnote(update = everything() ~ NA)
```

## Table 3. Linkage to confirmatory testing, proportion being confirmed HIV positive and treatment initiation, by reported number of lines and self-interpreted HIVST result among phase 2 eligible participants who completed their questionnaire

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
dat <- data |>
  filter(
    status_phase2 == "questionnaires completed",
    HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines",
    recontact_phase2 == "yes"
  ) |>
  mutate(all = "ALL")
dat$HIVST_detailed_result <- droplevels(dat$HIVST_detailed_result)

tbl_completed <-
  dat |>
  tbl_summary(
    include = c(all, HIVST_detailed_result),
    statistic = ~"{n}"
  ) |>
  modify_header(stat_0 = "**n**") |>
  modify_footnote(update = everything() ~ NA)

tbl_linked <-
  dat |>
  tbl_summary(
    by = confirmatory_test,
    include = c(all, HIVST_detailed_result),
    percent = "row",
    digits = ~0
  ) |>
  add_ci(style_fun = ~ label_percent(accuracy = 1, suffix = "")) |>
  modify_column_hide(c(stat_1, ci_stat_1)) |>
  modify_header(stat_2 ~ "**n (%)**") |>
  modify_footnote(update = everything() ~ NA)

tbl_confirmed <-
  dat |>
  filter(confirmatory_test == "yes") |>
  mutate(confirmed = confirmatory_test_result == "positive") |>
  tbl_summary(
    by = confirmed,
    include = c(all, HIVST_detailed_result),
    percent = "row",
    digits = ~0
  ) |>
  add_ci(style_fun = ~ label_percent(accuracy = 1, suffix = "")) |>
  modify_column_hide(c(stat_1, ci_stat_1)) |>
  modify_header(stat_2 ~ "**n (%)**") |>
  modify_footnote(update = everything() ~ NA)

tbl_initiated <-
  dat |>
  filter(confirmatory_test_result == "positive") |>
  mutate(initiated = consulted_health_prof == "yes") |>
  mutate(HIVST_detailed_result = fct_drop(HIVST_detailed_result)) |>
  tbl_summary(
    by = initiated,
    include = c(all, HIVST_detailed_result),
    percent = "row",
    digits = ~0
  ) |>
  add_ci(style_fun = ~ label_percent(accuracy = 1, suffix = "")) |>
  modify_column_hide(c(stat_1, ci_stat_1)) |>
  modify_header(stat_2 ~ "**n (%)**") |>
  modify_footnote(update = everything() ~ NA)


tbl_merge(
  list(tbl_completed, tbl_linked, tbl_confirmed, tbl_initiated),
  tab_spanner = c(
    "**Completed phase 2**",
    "**Linked to confirmatory testing**",
    "**Confirmed HIV positive**",
    "**Initiated ART**"
  )
)
```

## Figure 3: Flow chart of the participant selection process for Phase 2 of the survey

```{r}
n_eligible_for_phase_2 <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines")) |>
  nrow()

n_eligible_agreed_recontacted <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes")) |>
  nrow()

n_eligible_refusal_recontacted <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "no")) |>
  nrow()

n_unreachable_time_phase2 <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes") & (status_phase2 == "unavaible" | is.na(status_phase2))) |>
  nrow()

n_successfully_recontacted <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes") & (status_phase2 != "unavaible" & !is.na(status_phase2))) |>
  nrow()

n_refused_partcipate <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes") & (status_phase2 != "unavaible" & !is.na(status_phase2)) & status_phase2 == "refusal") |>
  nrow()

n_accepted_partcipate <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes") & (status_phase2 != "unavaible" & !is.na(status_phase2)) & status_phase2 != "refusal") |>
  nrow()

n_disconneted <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes") & (status_phase2 != "unavaible" & !is.na(status_phase2)) & (status_phase2 != "refusal" & status_phase2 == "disconnected")) |>
  nrow()

n_dropped <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes") & (status_phase2 != "unavaible" & !is.na(status_phase2)) & status_phase2 != "refusal" & status_phase2 == "dropped out before the end") |>
  nrow()

n_completed_quest_phase2 <- data |>
  filter((HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines") & (recontact_phase2 == "yes") & status_phase2 == "questionnaires completed") |>
  nrow()
```

-   `r n_eligible_for_phase_2` participants who reported a reactive test and/or two lines in phase 1

-   `r n_eligible_agreed_recontacted` participants who agreed to be recalled several months later

-   `r n_eligible_refusal_recontacted` participants refusal to be recalled several months later

-   `r n_unreachable_time_phase2` unreachable at the time of phase 2

-   `r n_successfully_recontacted` successfully recontacted for phase 2

-   `r n_refused_partcipate` refused to participate

-   `r n_accepted_partcipate` accepted to participate in phase 2 survey

-   `r n_disconneted` disconnected and unreachable

-   `r n_dropped` dropped out before the end

-   `r n_completed_quest_phase2` completed questionnaire phase 2

## Table S1. Eligibility and participation in phase 2 survey by sociodemographic characteristics, distribution channel, HIV testing history, the reported number of lines and the self-interpreted HIVST result

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
data <- data |>
  mutate(
    marital_status = marital_status |>
      fct_relevel(
        "single", "divorced / separated / widowed", "living with partner / married"
      ),
    educational_level = educational_level |>
      fct_relevel(
        "none / primary", "secondary", "higher"
      )
  )

data |>
  tbl_summary(
    include =
      c(
        country, distribution_channel, age_group,
        marital_status, educational_level, first_time_tester, HIVST_detailed_result
      ),
    by = status_phase_1and2,
    type = list(c(first_time_tester) ~ "categorical")
  ) |>
  add_overall() |>
  add_p(
    test = list(
      HIVST_detailed_result ~ "chisq.test",
      distribution_channel ~ "chisq.test"
    )
  )
```

## Table S2: Main reason for not linking to confirmatory testing among phase 2 participants who did not link to confirmatory testing, by reported number of lines and self-interpreted HIVST result

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
data <- data |>
  set_variable_labels(
    reason_non_confirmatory_test = "Main reason for not  \n linking to confirmatory testing among phase 2  \n  participants who did not link to confirmatory testing"
  )

data |>
  filter(
    status_phase2 == "questionnaires completed",
    HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines",
    recontact_phase2 == "yes", confirmatory_test == "no"
  ) |>
  mutate(
    HIVST_detailed_result = droplevels(HIVST_detailed_result)
  ) |>
  tbl_summary(
    include = c(reason_non_confirmatory_test),
    by = HIVST_detailed_result, sort = reason_non_confirmatory_test ~ "frequency"
  ) |>
  add_overall()
```

## Table S3: Time between HIVST and confirmatory testing among phase 2 participants who did link to confirmatory testing, by reported number of lines and self-interpreted HIVST result

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
data <- data |>
  mutate(
    time_to_confirmation = time_to_confirmation |>
      fct_relevel(
        "last than a week after the HIVST", "between 1 and 2 weeks",
        "between 3 and 4 weeks", "between 1 and 2 months after", "3 months later or more"
      )
  )

data <- data |>
  set_variable_labels(
    time_to_confirmation = "Time between HIVST and confirmatory testing \n among phase 2 participants who did link to confirmatory testing"
  )

data |>
  filter(
    recontact_phase2 == "yes",
    HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines",
    confirmatory_test == "yes",
    status_phase2 == "questionnaires completed"
  ) |>
  mutate(
    HIVST_detailed_result = droplevels(HIVST_detailed_result)
  ) |>
  tbl_summary(
    include = c(time_to_confirmation),
    by = HIVST_detailed_result
  ) |>
  add_overall()
```

## Table S4: Place of confirmatory testing among phase 2 participants who did link to confirmatory testing, by reported number of lines and self-interpreted HIVST result

```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}
data |>
  filter(
    recontact_phase2 == "yes",
    HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines",
    status_phase2 == "questionnaires completed",
    confirmatory_test == "yes"
  ) |>
  mutate(
    HIVST_detailed_result = droplevels(HIVST_detailed_result)
  ) |>
  tbl_summary(
    include = c(place_confirmatory_test),
    by = HIVST_detailed_result
  ) |>
  add_overall()
```

## Table S5. Time between phase 1 and phase 2 interviews among phase 2 participants who did link to confirmatory testing, by reported number of lines and self-interpreted HIVST result

```{r fig.height=6, fig.width=12,message=FALSE,warning=FALSE}
data$date_phase1 <- ymd_hms(data$date_phase1)
data$date_phase2 <- ymd_hms(data$date_phase2)
data <-
  data |>
  mutate(
    time_between_phase1_2 = time_length(date_phase2 - date_phase1, "month")
  )
data$time_between_phase1_2 <- cut(data$time_between_phase1_2,
  include.lowest = TRUE,
  right = TRUE,
  dig.lab = 4,
  breaks = c(3, 4, 6, 9),
  labels = c("less than 4 months", "between 4 and 6 months", "more than 6 months")
)



data <- data |>
  set_variable_labels(
    time_between_phase1_2 = "Time between phase 1 and phase 2 interviews among phase 2 participants who did link to confirmatory testing"
  )

data |>
  filter(
    recontact_phase2 == "yes",
    HIVST_reported_result == "reactive" | HIVST_reported_lines == "2 lines",
    status_phase2 == "questionnaires completed"
  ) |>
  mutate(
    HIVST_detailed_result = droplevels(HIVST_detailed_result)
  ) |>
  tbl_summary(
    include = c(time_between_phase1_2),
    by = HIVST_detailed_result
  ) |>
  add_overall()
```
