# Loading packageslibrary(tidyverse)library(gtsummary)library(labelled)library(scales)library(ggrepel)library(RColorBrewer)library(utils)library(patchwork)# Data importdata <- readr::read_csv("data.csv", show_col_types =FALSE)
Table 1. Self-reported test result and the reported number of lines among participants of phase 1, and positivity rates according to different hypotheses
Figure 3. Positivity rates based on self-interpreted HIVST results or the reported number of visible lines, by distribution channel, gender and country, among participants of the first survey phase in Côte d’Ivoire, Mali, and Senegal (2021).
Code
## Fig 3.a BASED ON SELF-REPORTED RESULTS# Creating "delivery_channel_by_sex" variabledata <- data |>mutate(delivery_channel_by_sex =interaction(sex, delivery_channel_grouped) |>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" ) )# Recoding variable "delivery_channel_by_sex"d <- data |>mutate(delivery_channel_by_sex = delivery_channel_by_sex |>fct_recode("man\nMSM-\nbased\nchannels"="man.MSM-based channels","woman\nMSM-\nbased\nchannels"="woman.MSM-based channels","man\nFSW-\n based\nchannels"="man.FSW-based channels","woman\nFSW-\nbased\nchannels"="woman.FSW-based channels","man\nother\nchannels"="man.Other delivery channels","woman\nother\nchannels"="woman.Other delivery channels" ) )# Computing numerators and denominators for the 3 hypothesisdh1 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Low",n =sum(HIVST_reported_result %in%c("reactive")),N =n() )dh2 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Central",n =sum(HIVST_reported_result %in%c("reactive")),N =sum(!HIVST_reported_result %in%c("DK", "R")) )dh3 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="High",n =sum(HIVST_reported_result %in%c("reactive", "DK", "R")),N =n() )# Computing positivity rates based on self interpreted resultsd_self_interpreted <-bind_rows(dh1, dh2, dh3) |>mutate(hypothesis =factor(hypothesis, levels =c("Low", "Central", "High")),positivity_rate = n / N,label = scales::percent(positivity_rate, suffix ="", accuracy = .1) ) |>rowwise() |>mutate(ci_low =prop.test(n, N)$conf.int[1],ci_high =prop.test(n, N)$conf.int[2] ) |>mutate(ylabel = ci_high + .01 )# Dropping cells with denominator below 25to_drop <- d_self_interpreted$N <25d_self_interpreted$positivity_rate[to_drop] <-NAd_self_interpreted$ci_low[to_drop] <-NAd_self_interpreted$ci_high[to_drop] <-NAd_self_interpreted$label[to_drop] <-""d_self_interpreted$label[to_drop & d_self_interpreted$hypothesis =="Central"] <-"*"d_self_interpreted$ylabel[to_drop] <-0# Generating Figure 3.a.g_self_interpreted <- d_self_interpreted |>ggplot() +aes(x = delivery_channel_by_sex,y = positivity_rate,ymin = ci_low,ymax = ci_high,color = hypothesis,shape = hypothesis, ) +geom_errorbar(position =position_dodge(width =0.9),color ="#555555",width = .2 ) +geom_point(stat ="identity",position =position_dodge(width =0.9),size =2 ) +geom_text(mapping =aes(label = label, y = ylabel),position =position_dodge(width =0.9),color ="black",size =2.5,vjust =0,face ="bold" ) +facet_grid(cols =vars(country)) +labs(title ="", x ="", y ="") +ggtitle("a. Positivity rates based on self-interpreted HIVST result") +scale_y_continuous(labels = scales::percent, limits =c(0, .5)) +scale_colour_manual(values =c("#ACD39E", "#5AAE61", "#1B7837")) +theme_classic() +theme(panel.grid.major.y =element_line(colour ="#DDDDDD", linetype ="dotted"),legend.title =element_blank(),legend.position ="bottom" )## Fig 3.b BASED ON THE NUMBER OF LINES# Computing numerators and denominators for the 3 hypothesisdh1 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Low",n =sum(HIVST_reported_lines %in%c("2 lines")),N =n() )dh2 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Central",n =sum(HIVST_reported_lines %in%c("2 lines")),N =sum(!HIVST_reported_result %in%c("DK", "R")) )dh3 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="High",n =sum(HIVST_reported_lines %in%c("2 lines", "DK", "R")),N =n() )# Computing positivity rates based on the number of reported linesd_reported_lines <-bind_rows(dh1, dh2, dh3) |>mutate(hypothesis =factor(hypothesis, levels =c("Low", "Central", "High")),positivity_rate = n / N,label = scales::percent(positivity_rate, suffix ="", accuracy = .1) ) |>rowwise() |>mutate(ci_low =prop.test(n, N)$conf.int[1],ci_high =prop.test(n, N)$conf.int[2] ) |>mutate(ylabel = ci_high + .01 )# Dropping cells with denominator below 25to_drop <- d_reported_lines$N <25d_reported_lines$positivity_rate[to_drop] <-NAd_reported_lines$ci_low[to_drop] <-NAd_reported_lines$ci_high[to_drop] <-NAd_reported_lines$label[to_drop] <-""d_reported_lines$label[to_drop & d_reported_lines$hypothesis =="Central"] <-"*"d_reported_lines$ylabel[to_drop] <-0# Generating Figure 3.b.g_reported_lines <- d_reported_lines |>ggplot() +aes(x = delivery_channel_by_sex,y = positivity_rate,ymin = ci_low,ymax = ci_high,color = hypothesis,shape = hypothesis, ) +geom_errorbar(position =position_dodge(width =0.9),color ="#555555",width = .2 ) +geom_point(stat ="identity",position =position_dodge(width =0.9),size =2 ) +geom_text(mapping =aes(label = label, y = ylabel),position =position_dodge(width =0.9),color ="black",size =2.5,vjust =0,face ="bold" ) +facet_grid(cols =vars(country)) +labs(title ="", x ="", y ="") +ggtitle("b. Positivity rates based on the reported number of lines") +scale_y_continuous(labels = scales::percent, limits =c(0, .5)) +scale_colour_manual(values =c("#F67E4B", "#DD3D2D", "#A50026")) +theme_classic() +theme(panel.grid.major.y =element_line(colour ="#DDDDDD", linetype ="dotted"),legend.title =element_blank(),legend.position ="bottom" )# Combining fig 3.a and fig 3.bwrap_plots( g_self_interpreted, g_reported_lines,nrow =2) &theme(axis.text =element_text(size =8.5),legend.text =element_text(size =9),panel.spacing =unit(0.5, "lines"),strip.text =element_text(size =9, face ="bold"),plot.title =element_text(size =10, face ="bold") )
Figure 4: Elements for the flow chart of the participant selection process for Phase 2 of the survey
126 participants who reported a reactive test and/or two lines in phase 1
120 participants who agreed to be recalled several months later
6 participants refusal to be recalled several months later
24 unreachable at the time of phase 2
96 successfully recontacted for phase 2
7 refused to participate
89 accepted to participate in phase 2 survey
1 disconnected and unreachable
10 dropped out before the end
78 completed questionnaire phase 2
Table 2. 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
Code
# Selection of individuals eligible for phase 2 who completed their phase 2 questionnairephase2 <- data |>filter( HIVST_reported_result =="reactive"| HIVST_reported_lines =="2 lines", recontact_phase2 =="yes", status_phase2 =="questionnaires completed" ) |>mutate(all ="ALL")phase2$test_result_number_lines_reported <-droplevels(phase2$test_result_number_lines_reported)# Computing the numbers of individuals who completed phase 2 questionnairetbl_completed <- phase2 |>tbl_summary(include =c(all, test_result_number_lines_reported),statistic =~"{n}" ) |>modify_header(stat_0 ="**n**") |>modify_footnote(update =everything() ~NA)# Computing the proportion who linked to confirmatory testingtbl_linked <- phase2 |>tbl_summary(by = confirmatory_test,include =c(all, test_result_number_lines_reported),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)# Computing the proportion who were confirmed HIV-positivetbl_confirmed <- phase2 |>filter(confirmatory_test =="yes") |>mutate(confirmed = confirmatory_test_result =="positive") |>tbl_summary(by = confirmed,include =c(all, test_result_number_lines_reported),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)# Computing the proportion who initiated ARTtbl_initiated <- phase2 |>filter(confirmatory_test_result =="positive") |>mutate(initiated = consulted_health_prof =="yes") |>mutate(test_result_number_lines_reported =fct_drop(test_result_number_lines_reported)) |>tbl_summary(by = initiated,include =c(all, test_result_number_lines_reported),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)# Merging tablestbl_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**" ))
Characteristic
Completed phase 2
Linked to confirmatory testing
Confirmed HIV positive
Initiated ART
n
n (%)
95% CI1
n (%)
95% CI1
n (%)
95% CI1
all
ALL
78
34 (44%)
33%, 55%
19 (56%)
38%, 72%
18 (95%)
72%, 100%
test_result_number_lines_reported
2 lines / reactive
27
15 (56%)
36%, 74%
12 (80%)
51%, 95%
12 (100%)
70%, 100%
1 line / reactive
7
1 (14%)
1%, 58%
0 (0%)
0%, 95%
2 lines / non-reactive
25
9 (36%)
19%, 57%
3 (33%)
9%, 69%
3 (100%)
31%, 100%
2 lines / DK-R
18
8 (44%)
22%, 69%
4 (50%)
22%, 78%
3 (75%)
22%, 99%
DK-R / reactive
1
1 (100%)
5%, 100%
0 (0%)
0%, 95%
1 CI = Confidence Interval
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
eligible for phase 2 but did not complete the questionnaire, N = 421
phase 1 participants not eligible for phase 2, N = 2,4951
Overall, N = 2,6151
p-value2
Country
0.9
Côte d'Ivoire
39 (50%)
20 (48%)
1,331 (53%)
1,390 (53%)
Mali
31 (40%)
18 (43%)
935 (37%)
984 (38%)
Senegal
8 (10%)
4 (9.5%)
229 (9.2%)
241 (9.2%)
Sex and distribution channel
0.3
man.MSM-based channels
35 (45%)
14 (33%)
948 (38%)
997 (38%)
woman.MSM-based channels
5 (6.4%)
0 (0%)
98 (3.9%)
103 (3.9%)
man.FSW-based channels
22 (28%)
10 (24%)
588 (24%)
620 (24%)
woman.FSW-based channels
14 (18%)
15 (36%)
656 (26%)
685 (26%)
man.Other delivery channels
1 (1.3%)
2 (4.8%)
134 (5.4%)
137 (5.2%)
woman.Other delivery channels
1 (1.3%)
1 (2.4%)
71 (2.8%)
73 (2.8%)
Age group
0.5
24 years or less
27 (35%)
20 (48%)
1,117 (45%)
1,164 (45%)
25-34 years
38 (49%)
16 (38%)
1,009 (40%)
1,063 (41%)
35 years or more
13 (17%)
6 (14%)
369 (15%)
388 (15%)
Marital status
0.3
single
54 (69%)
28 (67%)
1,679 (67%)
1,761 (67%)
divorced / separated / widowed
6 (7.7%)
2 (4.8%)
89 (3.6%)
97 (3.7%)
living with partner / married
18 (23%)
12 (29%)
727 (29%)
757 (29%)
Educational level
0.057
none / primary
13 (17%)
10 (24%)
480 (19%)
503 (19%)
secondary
50 (64%)
28 (67%)
1,354 (54%)
1,432 (55%)
higher
15 (19%)
4 (9.5%)
661 (26%)
680 (26%)
Firt-time tester
0.3
no
40 (51%)
22 (52%)
1,475 (59%)
1,537 (59%)
yes
38 (49%)
20 (48%)
1,020 (41%)
1,078 (41%)
Reported number of lines & self-interpreted HIVST result
<0.001
2 lines / reactive
27 (35%)
20 (48%)
3 (0.1%)
50 (1.9%)
1 line / non-reactive
0 (0%)
0 (0%)
2,292 (92%)
2,292 (88%)
0-1 line / invalid
0 (0%)
0 (0%)
4 (0.2%)
4 (0.2%)
1 line / reactive
7 (9.0%)
3 (7.1%)
0 (0%)
10 (0.4%)
2 lines / non-reactive
25 (32%)
9 (21%)
1 (<0.1%)
35 (1.3%)
0 line / non-reactive
0 (0%)
0 (0%)
3 (0.1%)
3 (0.1%)
0 line / DK-R
0 (0%)
0 (0%)
1 (<0.1%)
1 (<0.1%)
1 line / DK-R
0 (0%)
0 (0%)
117 (4.7%)
117 (4.5%)
2 lines / DK-R
18 (23%)
9 (21%)
2 (<0.1%)
29 (1.1%)
DK-R / reactive
1 (1.3%)
1 (2.4%)
0 (0%)
2 (<0.1%)
DK-R / DK-R
0 (0%)
0 (0%)
28 (1.1%)
28 (1.1%)
DK-R / non-reactive
0 (0%)
0 (0%)
44 (1.8%)
44 (1.7%)
1 n (%)
2 Fisher’s exact test; Pearson’s Chi-squared test
Table S2.a: Positivity rates based on self-interpreted HIVST result, by distribution channel, gender and country, among phase 1 participants
Code
# Creation of a positivity rate table according to the low hypothesistblS2a_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the central hypothesistblS2a_central <- data |>filter(HIVST_reported_result !="DK", HIVST_reported_result !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the high hypothesistblS2a_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Merging the different tablestblS2a <-tbl_stack(list(tblS2a_low, tblS2a_central, tblS2a_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" ))tblS2a |>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)
Variable
Total
MSM-based channels
FSW-based channels
Others delivery channels
Man
Woman
Man
Woman
Man
Woman
Low: positivity rate based on self reported test result and DK-R are considered not reactive
Overall
2.4% (62/2,615)
3.2% (32/997)
1.0% (1/103)
1.6% (10/620)
2.5% (17/685)
0.7% (1/137)
1.4% (1/73)
Country
Côte d'Ivoire
1.8% (25/1,390)
2.5% (16/650)
1.4% (1/73)
1.5% (5/339)
1.2% (3/245)
0% (0/60)
0% (0/23)
Mali
3.5% (34/984)
4.6% (14/306)
0% (0/29)
1.9% (5/269)
3.9% (14/360)
9.1% (1/11)
0% (0/9)
Senegal
1.2% (3/241)
4.9% (2/41)
0% (0/1)
0% (0/12)
0% (0/80)
0% (0/66)
2.4% (1/41)
Central: positivity rate based on self reported test result and DK-R are excluded
Overall
2.5% (62/2,440)
3.4% (32/931)
1.0% (1/101)
1.7% (10/579)
2.7% (17/631)
0.8% (1/130)
1.5% (1/68)
Country
Côte d'Ivoire
2.0% (25/1,279)
2.7% (16/597)
1.4% (1/71)
1.6% (5/311)
1.4% (3/221)
0% (0/58)
0% (0/21)
Mali
3.6% (34/952)
4.7% (14/301)
0% (0/29)
1.9% (5/257)
4.1% (14/345)
9.1% (1/11)
0% (0/9)
Senegal
1.4% (3/209)
6.1% (2/33)
0% (0/1)
0% (0/11)
0% (0/65)
0% (0/61)
2.6% (1/38)
High: positivity rate based on self reported test result and DK-R are considered reactive
Overall
9.1% (237/2,615)
9.8% (98/997)
2.9% (3/103)
8.2% (51/620)
10% (71/685)
5.8% (8/137)
8.2% (6/73)
Country
Côte d'Ivoire
9.8% (136/1,390)
11% (69/650)
4.1% (3/73)
9.7% (33/339)
11% (27/245)
3.3% (2/60)
8.7% (2/23)
Mali
6.7% (66/984)
6.2% (19/306)
0% (0/29)
6.3% (17/269)
8.1% (29/360)
9.1% (1/11)
0% (0/9)
Senegal
15% (35/241)
24% (10/41)
0% (0/1)
8.3% (1/12)
19% (15/80)
7.6% (5/66)
9.8% (4/41)
Table S2.b: Positivity rates based on the reported number of lines, by distribution channel, gender and country, among phase 1 participants
Code
# Creation of a positivity rate table according to the low hypothesistblS2b_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the central hypothesistblS2b_central <- data |>filter(HIVST_reported_lines !="DK", HIVST_reported_lines !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the high hypothesistblS2b_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Merging of the different tablestblS2b <-tbl_stack(list(tblS2b_low, tblS2b_central, tblS2b_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" ))tblS2b |>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)
Variable
Total
MSM-based channels
FSW-based channels
Others delivery channels
Man
Woman
Man
Woman
Man
Woman
Low: positivity rate based on self reported number of lines and DK-R are considered not 2 lines
Overall
4.4% (114/2,615)
4.7% (47/997)
4.9% (5/103)
4.5% (28/620)
4.1% (28/685)
2.9% (4/137)
2.7% (2/73)
Country
Côte d'Ivoire
3.8% (53/1,390)
4.2% (27/650)
5.5% (4/73)
4.7% (16/339)
2.0% (5/245)
0% (0/60)
4.3% (1/23)
Mali
4.9% (48/984)
4.9% (15/306)
3.4% (1/29)
4.5% (12/269)
5.3% (19/360)
9.1% (1/11)
0% (0/9)
Senegal
5.4% (13/241)
12% (5/41)
0% (0/1)
0% (0/12)
5.0% (4/80)
4.5% (3/66)
2.4% (1/41)
Central: positivity rate based on self reported number of lines and DK-R are excluded
Overall
4.5% (114/2,541)
4.8% (47/977)
4.9% (5/103)
4.6% (28/605)
4.2% (28/660)
3.1% (4/128)
2.9% (2/68)
Country
Côte d'Ivoire
3.9% (53/1,368)
4.2% (27/641)
5.5% (4/73)
4.8% (16/331)
2.1% (5/241)
0% (0/60)
4.5% (1/22)
Mali
5.0% (48/955)
5.0% (15/298)
3.4% (1/29)
4.5% (12/264)
5.5% (19/344)
9.1% (1/11)
0% (0/9)
Senegal
6.0% (13/218)
13% (5/38)
0% (0/1)
0% (0/10)
5.3% (4/75)
5.3% (3/57)
2.7% (1/37)
High: positivity rate based on self reported number of lines and DK-R are considered 2 lines
Overall
7.2% (188/2,615)
6.7% (67/997)
4.9% (5/103)
6.9% (43/620)
7.7% (53/685)
9.5% (13/137)
9.6% (7/73)
Country
Côte d'Ivoire
5.4% (75/1,390)
5.5% (36/650)
5.5% (4/73)
7.1% (24/339)
3.7% (9/245)
0% (0/60)
8.7% (2/23)
Mali
7.8% (77/984)
7.5% (23/306)
3.4% (1/29)
6.3% (17/269)
9.7% (35/360)
9.1% (1/11)
0% (0/9)
Senegal
15% (36/241)
20% (8/41)
0% (0/1)
17% (2/12)
11% (9/80)
18% (12/66)
12% (5/41)
Table S3.a: Positivity rates based on self-interpreted HIVST result, by age group and country, among phase 1 participants
Code
# Creation of a positivity rate table according to the low hypothesistblS3a_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the central hypothesistblS3a_central <- data |>filter(HIVST_reported_result !="DK", HIVST_reported_result !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the high hypothesistblS3a_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Merging of the different tablestblS3a <-tbl_stack(list(tblS3a_low, tblS3a_central, tblS3a_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" ))tblS3a
Characteristic
Overall, N = 2,6151
24 years or less, N = 1,1641
25-34 years, N = 1,0631
35 years or more, N = 3881
Low: positivity rate based on self reported test result and DK-R are considered not reactive
Overall
2.4% (62/2,615)
2.2% (26/1,164)
2.7% (29/1,063)
1.8% (7/388)
Country
Côte d'Ivoire
1.8% (25/1,390)
1.7% (11/645)
2.0% (11/553)
1.6% (3/192)
Mali
3.5% (34/984)
3.3% (15/455)
3.9% (16/415)
2.6% (3/114)
Senegal
1.2% (3/241)
0% (0/64)
2.1% (2/95)
1.2% (1/82)
Central: positivity rate based on self reported test result and DK-R are excluded
Overall
2.5% (62/2,440)
2.4% (26/1,099)
2.9% (29/991)
2.0% (7/350)
Country
Côte d'Ivoire
2.0% (25/1,279)
1.8% (11/604)
2.2% (11/506)
1.8% (3/169)
Mali
3.6% (34/952)
3.4% (15/439)
4.0% (16/403)
2.7% (3/110)
Senegal
1.4% (3/209)
0% (0/56)
2.4% (2/82)
1.4% (1/71)
High: positivity rate based on self reported test result and DK-R are considered reactive
Overall
9.1% (237/2,615)
7.8% (91/1,164)
9.5% (101/1,063)
12% (45/388)
Country
Côte d'Ivoire
9.8% (136/1,390)
8.1% (52/645)
10% (58/553)
14% (26/192)
Mali
6.7% (66/984)
6.8% (31/455)
6.7% (28/415)
6.1% (7/114)
Senegal
15% (35/241)
13% (8/64)
16% (15/95)
15% (12/82)
1 prop% (n/N)
Table S3.b: Positivity rates based on the reported number of lines, by age group and country, among phase 1 participants
Code
# Creation of a positivity rate table according to the low hypothesistblS3b_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the central hypothesistblS3b_central <- data |>filter(HIVST_reported_lines !="DK", HIVST_reported_lines !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the high hypothesistblS3b_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Merging of the different tablestblS3b <-tbl_stack(list(tblS3b_low, tblS3b_central, tblS3b_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" ))tblS3b
Characteristic
Overall, N = 2,6151
24 years or less, N = 1,1641
25-34 years, N = 1,0631
35 years or more, N = 3881
Low: positivity rate based on self reported number of lines and DK-R are considered not 2 lines
Overall
4.4% (114/2,615)
3.7% (43/1,164)
4.9% (52/1,063)
4.9% (19/388)
Country
Côte d'Ivoire
3.8% (53/1,390)
3.1% (20/645)
4.5% (25/553)
4.2% (8/192)
Mali
4.9% (48/984)
4.8% (22/455)
4.8% (20/415)
5.3% (6/114)
Senegal
5.4% (13/241)
1.6% (1/64)
7.4% (7/95)
6.1% (5/82)
Central: positivity rate based on self reported number of lines and DK-R are excluded
Overall
4.5% (114/2,541)
3.8% (43/1,138)
5.0% (52/1,032)
5.1% (19/371)
Country
Côte d'Ivoire
3.9% (53/1,368)
3.1% (20/637)
4.6% (25/546)
4.3% (8/185)
Mali
5.0% (48/955)
4.9% (22/447)
5.0% (20/401)
5.6% (6/107)
Senegal
6.0% (13/218)
1.9% (1/54)
8.2% (7/85)
6.3% (5/79)
High: positivity rate based on self reported number of lines and DK-R are considered 2 lines
Overall
7.2% (188/2,615)
5.9% (69/1,164)
7.8% (83/1,063)
9.3% (36/388)
Country
Côte d'Ivoire
5.4% (75/1,390)
4.3% (28/645)
5.8% (32/553)
7.8% (15/192)
Mali
7.8% (77/984)
6.6% (30/455)
8.2% (34/415)
11% (13/114)
Senegal
15% (36/241)
17% (11/64)
18% (17/95)
9.8% (8/82)
1 prop% (n/N)
Table S4: 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
Code
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(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(reason_non_confirmatory_test),by = test_result_number_lines_reported, sort = reason_non_confirmatory_test ~"frequency" ) |>add_overall()
Characteristic
Overall, N = 441
2 lines / reactive, N = 121
1 line / reactive, N = 61
2 lines / non-reactive, N = 161
2 lines / DK-R, N = 101
Main reason for not `
` linking to confirmatory testing among phase 2 `
` participants who did not link to confirmatory testing
my test was non-reactive
20 (45%)
7 (58%)
3 (50%)
5 (31%)
5 (50%)
Didn't know he should get a confirmatory test
10 (23%)
2 (17%)
2 (33%)
5 (31%)
1 (10%)
Didn't have time
8 (18%)
3 (25%)
0 (0%)
3 (19%)
2 (20%)
Fear that the result will be known by others
2 (4.5%)
0 (0%)
0 (0%)
1 (6.3%)
1 (10%)
No reason
2 (4.5%)
0 (0%)
1 (17%)
1 (6.3%)
0 (0%)
Did not know where to take the test
1 (2.3%)
0 (0%)
0 (0%)
1 (6.3%)
0 (0%)
The testing site was too for away
1 (2.3%)
0 (0%)
0 (0%)
0 (0%)
1 (10%)
1 n (%)
Table S5: 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
Code
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_result =="positive", confirmatory_test =="yes", status_phase2 =="questionnaires completed", consulted_health_prof =="yes", ) |>mutate(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(time_to_confirmation),by = test_result_number_lines_reported ) |>add_overall()
Characteristic
Overall, N = 181
2 lines / reactive, N = 121
2 lines / non-reactive, N = 31
2 lines / DK-R, N = 31
Time between HIVST and confirmatory testing `
` among phase 2 participants who did link to confirmatory testing
last than a week after the HIVST
13 (72%)
10 (83%)
0 (0%)
3 (100%)
between 1 and 2 weeks
2 (11%)
0 (0%)
2 (67%)
0 (0%)
between 3 and 4 weeks
1 (5.6%)
1 (8.3%)
0 (0%)
0 (0%)
between 1 and 2 months after
1 (5.6%)
1 (8.3%)
0 (0%)
0 (0%)
3 months later or more
1 (5.6%)
0 (0%)
1 (33%)
0 (0%)
1 n (%)
Table S6: Place of confirmatory testing among phase 2 participants who did link to confirmatory testing, by reported number of lines and self-interpreted HIVST result
Code
data <- data |>set_variable_labels(place_confirmatory_test ="Place of confirmatory testing 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", confirmatory_test =="yes" ) |>mutate(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(place_confirmatory_test),by = test_result_number_lines_reported ) |>add_overall()
Characteristic
Overall, N = 341
2 lines / reactive, N = 151
1 line / reactive, N = 11
2 lines / non-reactive, N = 91
2 lines / DK-R, N = 81
DK-R / reactive, N = 11
Place of confirmatory testing among phase 2 participants who did link to confirmatory testing
Community Clinic/Dedicated Health Center
12 (35%)
3 (20%)
0 (0%)
6 (67%)
3 (38%)
0 (0%)
Health Center/ Hospital /Clinic/ Maternity
22 (65%)
12 (80%)
1 (100%)
3 (33%)
5 (63%)
1 (100%)
1 n (%)
Table S7. 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
Code
# Computing time between phase 1 and phase 2data$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"))# labeling the "place_confirmatory_test" variabledata <- 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" )# Generating the S7 tabledata |>filter( recontact_phase2 =="yes", HIVST_reported_result =="reactive"| HIVST_reported_lines =="2 lines", status_phase2 =="questionnaires completed" ) |>mutate(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(time_between_phase1_2),by = test_result_number_lines_reported ) |>add_overall()
Characteristic
Overall, N = 781
2 lines / reactive, N = 271
1 line / reactive, N = 71
2 lines / non-reactive, N = 251
2 lines / DK-R, N = 181
DK-R / reactive, N = 11
Time between phase 1 and phase 2 interviews among phase 2 participants who did link to confirmatory testing
less than 4 months
8 (10%)
3 (11%)
0 (0%)
4 (16%)
1 (5.6%)
0 (0%)
Between 4 and 6 months
67 (86%)
24 (89%)
5 (71%)
21 (84%)
17 (94%)
0 (0%)
More than 6 months
3 (3.8%)
0 (0%)
2 (29%)
0 (0%)
0 (0%)
1 (100%)
1 n (%)
Source Code
---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 Kouassi Kra et al"date: todaytoc: trueformat: html: code-tools: true code-fold: true self-contained: true toc: false dpi: 300 fig-responsive: trueexecute: warning: false---```{r setup, include=FALSE}knitr::opts_chunk$set(echo =TRUE)``````{r, message=FALSE}# Loading packageslibrary(tidyverse)library(gtsummary)library(labelled)library(scales)library(ggrepel)library(RColorBrewer)library(utils)library(patchwork)# Data importdata <- readr::read_csv("data.csv", show_col_types =FALSE)```## 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}# Creating "test_result_number_lines_reported" variabledata <- data |>mutate(test_result_number_lines_reported =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" ) ) |>set_variable_labels(test_result_number_lines_reported ="Reported number of lines / self-interpreted HIVST result")# Reorganizing the labels of the variable "test_result_number_lines_reported"data$test_result_number_lines_reported <- data$test_result_number_lines_reported |>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" )# Generating Table 1tbl1 <- data |>tbl_summary(include = test_result_number_lines_reported,label = test_result_number_lines_reported ~"" ) |>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```## Figure 3. Positivity rates based on self-interpreted HIVST results or the reported number of visible lines, by distribution channel, gender and country, among participants of the first survey phase in Côte d'Ivoire, Mali, and Senegal (2021).```{r}#| fig-width: 12#| fig-height: 8#| column: page## Fig 3.a BASED ON SELF-REPORTED RESULTS# Creating "delivery_channel_by_sex" variabledata <- data |>mutate(delivery_channel_by_sex =interaction(sex, delivery_channel_grouped) |>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" ) )# Recoding variable "delivery_channel_by_sex"d <- data |>mutate(delivery_channel_by_sex = delivery_channel_by_sex |>fct_recode("man\nMSM-\nbased\nchannels"="man.MSM-based channels","woman\nMSM-\nbased\nchannels"="woman.MSM-based channels","man\nFSW-\n based\nchannels"="man.FSW-based channels","woman\nFSW-\nbased\nchannels"="woman.FSW-based channels","man\nother\nchannels"="man.Other delivery channels","woman\nother\nchannels"="woman.Other delivery channels" ) )# Computing numerators and denominators for the 3 hypothesisdh1 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Low",n =sum(HIVST_reported_result %in%c("reactive")),N =n() )dh2 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Central",n =sum(HIVST_reported_result %in%c("reactive")),N =sum(!HIVST_reported_result %in%c("DK", "R")) )dh3 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="High",n =sum(HIVST_reported_result %in%c("reactive", "DK", "R")),N =n() )# Computing positivity rates based on self interpreted resultsd_self_interpreted <-bind_rows(dh1, dh2, dh3) |>mutate(hypothesis =factor(hypothesis, levels =c("Low", "Central", "High")),positivity_rate = n / N,label = scales::percent(positivity_rate, suffix ="", accuracy = .1) ) |>rowwise() |>mutate(ci_low =prop.test(n, N)$conf.int[1],ci_high =prop.test(n, N)$conf.int[2] ) |>mutate(ylabel = ci_high + .01 )# Dropping cells with denominator below 25to_drop <- d_self_interpreted$N <25d_self_interpreted$positivity_rate[to_drop] <-NAd_self_interpreted$ci_low[to_drop] <-NAd_self_interpreted$ci_high[to_drop] <-NAd_self_interpreted$label[to_drop] <-""d_self_interpreted$label[to_drop & d_self_interpreted$hypothesis =="Central"] <-"*"d_self_interpreted$ylabel[to_drop] <-0# Generating Figure 3.a.g_self_interpreted <- d_self_interpreted |>ggplot() +aes(x = delivery_channel_by_sex,y = positivity_rate,ymin = ci_low,ymax = ci_high,color = hypothesis,shape = hypothesis, ) +geom_errorbar(position =position_dodge(width =0.9),color ="#555555",width = .2 ) +geom_point(stat ="identity",position =position_dodge(width =0.9),size =2 ) +geom_text(mapping =aes(label = label, y = ylabel),position =position_dodge(width =0.9),color ="black",size =2.5,vjust =0,face ="bold" ) +facet_grid(cols =vars(country)) +labs(title ="", x ="", y ="") +ggtitle("a. Positivity rates based on self-interpreted HIVST result") +scale_y_continuous(labels = scales::percent, limits =c(0, .5)) +scale_colour_manual(values =c("#ACD39E", "#5AAE61", "#1B7837")) +theme_classic() +theme(panel.grid.major.y =element_line(colour ="#DDDDDD", linetype ="dotted"),legend.title =element_blank(),legend.position ="bottom" )## Fig 3.b BASED ON THE NUMBER OF LINES# Computing numerators and denominators for the 3 hypothesisdh1 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Low",n =sum(HIVST_reported_lines %in%c("2 lines")),N =n() )dh2 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="Central",n =sum(HIVST_reported_lines %in%c("2 lines")),N =sum(!HIVST_reported_result %in%c("DK", "R")) )dh3 <- d |>group_by(delivery_channel_by_sex, country) |>summarise(hypothesis ="High",n =sum(HIVST_reported_lines %in%c("2 lines", "DK", "R")),N =n() )# Computing positivity rates based on the number of reported linesd_reported_lines <-bind_rows(dh1, dh2, dh3) |>mutate(hypothesis =factor(hypothesis, levels =c("Low", "Central", "High")),positivity_rate = n / N,label = scales::percent(positivity_rate, suffix ="", accuracy = .1) ) |>rowwise() |>mutate(ci_low =prop.test(n, N)$conf.int[1],ci_high =prop.test(n, N)$conf.int[2] ) |>mutate(ylabel = ci_high + .01 )# Dropping cells with denominator below 25to_drop <- d_reported_lines$N <25d_reported_lines$positivity_rate[to_drop] <-NAd_reported_lines$ci_low[to_drop] <-NAd_reported_lines$ci_high[to_drop] <-NAd_reported_lines$label[to_drop] <-""d_reported_lines$label[to_drop & d_reported_lines$hypothesis =="Central"] <-"*"d_reported_lines$ylabel[to_drop] <-0# Generating Figure 3.b.g_reported_lines <- d_reported_lines |>ggplot() +aes(x = delivery_channel_by_sex,y = positivity_rate,ymin = ci_low,ymax = ci_high,color = hypothesis,shape = hypothesis, ) +geom_errorbar(position =position_dodge(width =0.9),color ="#555555",width = .2 ) +geom_point(stat ="identity",position =position_dodge(width =0.9),size =2 ) +geom_text(mapping =aes(label = label, y = ylabel),position =position_dodge(width =0.9),color ="black",size =2.5,vjust =0,face ="bold" ) +facet_grid(cols =vars(country)) +labs(title ="", x ="", y ="") +ggtitle("b. Positivity rates based on the reported number of lines") +scale_y_continuous(labels = scales::percent, limits =c(0, .5)) +scale_colour_manual(values =c("#F67E4B", "#DD3D2D", "#A50026")) +theme_classic() +theme(panel.grid.major.y =element_line(colour ="#DDDDDD", linetype ="dotted"),legend.title =element_blank(),legend.position ="bottom" )# Combining fig 3.a and fig 3.bwrap_plots( g_self_interpreted, g_reported_lines,nrow =2) &theme(axis.text =element_text(size =8.5),legend.text =element_text(size =9),panel.spacing =unit(0.5, "lines"),strip.text =element_text(size =9, face ="bold"),plot.title =element_text(size =10, face ="bold") )```## Figure 4: Elements for the 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 2. 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}# Selection of individuals eligible for phase 2 who completed their phase 2 questionnairephase2 <- data |>filter( HIVST_reported_result =="reactive"| HIVST_reported_lines =="2 lines", recontact_phase2 =="yes", status_phase2 =="questionnaires completed" ) |>mutate(all ="ALL")phase2$test_result_number_lines_reported <-droplevels(phase2$test_result_number_lines_reported)# Computing the numbers of individuals who completed phase 2 questionnairetbl_completed <- phase2 |>tbl_summary(include =c(all, test_result_number_lines_reported),statistic =~"{n}" ) |>modify_header(stat_0 ="**n**") |>modify_footnote(update =everything() ~NA)# Computing the proportion who linked to confirmatory testingtbl_linked <- phase2 |>tbl_summary(by = confirmatory_test,include =c(all, test_result_number_lines_reported),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)# Computing the proportion who were confirmed HIV-positivetbl_confirmed <- phase2 |>filter(confirmatory_test =="yes") |>mutate(confirmed = confirmatory_test_result =="positive") |>tbl_summary(by = confirmed,include =c(all, test_result_number_lines_reported),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)# Computing the proportion who initiated ARTtbl_initiated <- phase2 |>filter(confirmatory_test_result =="positive") |>mutate(initiated = consulted_health_prof =="yes") |>mutate(test_result_number_lines_reported =fct_drop(test_result_number_lines_reported)) |>tbl_summary(by = initiated,include =c(all, test_result_number_lines_reported),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)# Merging tablestbl_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**" ))```## 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}# Reordoring value labelsdata <- 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" ) )# Improving variable labelsdata <- data |>set_variable_labels(country ="Country",delivery_channel_by_sex ="Sex and distribution channel",age_group ="Age group",marital_status ="Marital status",educational_level ="Educational level",first_time_tester ="Firt-time tester",test_result_number_lines_reported ="Reported number of lines & self-interpreted HIVST result" )# Computing Table S1.data |>tbl_summary(include =c( country, delivery_channel_by_sex, age_group, marital_status, educational_level, first_time_tester, test_result_number_lines_reported ),by = final_status_phas,type =list(c(first_time_tester) ~"categorical") ) |>add_overall(TRUE) |>add_p(test =list( test_result_number_lines_reported ~"chisq.test", delivery_channel_by_sex ~"chisq.test" ) )```## Table S2.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}# Creation of a positivity rate table according to the low hypothesistblS2a_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the central hypothesistblS2a_central <- data |>filter(HIVST_reported_result !="DK", HIVST_reported_result !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the high hypothesistblS2a_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Merging the different tablestblS2a <-tbl_stack(list(tblS2a_low, tblS2a_central, tblS2a_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" ))tblS2a |>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 S2.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}# Creation of a positivity rate table according to the low hypothesistblS2b_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the central hypothesistblS2b_central <- data |>filter(HIVST_reported_lines !="DK", HIVST_reported_lines !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Creation of a positivity rate table according to the high hypothesistblS2b_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = delivery_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)# Merging of the different tablestblS2b <-tbl_stack(list(tblS2b_low, tblS2b_central, tblS2b_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" ))tblS2b |>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 S3.a: Positivity rates based on self-interpreted HIVST result, by age group and country, among phase 1 participants```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}# Creation of a positivity rate table according to the low hypothesistblS3a_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the central hypothesistblS3a_central <- data |>filter(HIVST_reported_result !="DK", HIVST_reported_result !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the high hypothesistblS3a_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Merging of the different tablestblS3a <-tbl_stack(list(tblS3a_low, tblS3a_central, tblS3a_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" ))tblS3a```## Table S3.b: Positivity rates based on the reported number of lines, by age group and country, among phase 1 participants```{r fig.height=6, fig.width=12, message=FALSE,warning=FALSE}# Creation of a positivity rate table according to the low hypothesistblS3b_low <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the central hypothesistblS3b_central <- data |>filter(HIVST_reported_lines !="DK", HIVST_reported_lines !="R") |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Creation of a positivity rate table according to the high hypothesistblS3b_high <- data |>to_factor() |>tbl_custom_summary(include =c(country),by = age_group,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)# Merging of the different tablestblS3b <-tbl_stack(list(tblS3b_low, tblS3b_central, tblS3b_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" ))tblS3b```## Table S4: 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(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(reason_non_confirmatory_test),by = test_result_number_lines_reported, sort = reason_non_confirmatory_test ~"frequency" ) |>add_overall()```## Table S5: 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_result =="positive", confirmatory_test =="yes", status_phase2 =="questionnaires completed", consulted_health_prof =="yes", ) |>mutate(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(time_to_confirmation),by = test_result_number_lines_reported ) |>add_overall()```## Table S6: 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 <- data |>set_variable_labels(place_confirmatory_test ="Place of confirmatory testing 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", confirmatory_test =="yes" ) |>mutate(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(place_confirmatory_test),by = test_result_number_lines_reported ) |>add_overall()```## Table S7. 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}# Computing time between phase 1 and phase 2data$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"))# labeling the "place_confirmatory_test" variabledata <- 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" )# Generating the S7 tabledata |>filter( recontact_phase2 =="yes", HIVST_reported_result =="reactive"| HIVST_reported_lines =="2 lines", status_phase2 =="questionnaires completed" ) |>mutate(test_result_number_lines_reported =droplevels(test_result_number_lines_reported) ) |>tbl_summary(include =c(time_between_phase1_2),by = test_result_number_lines_reported ) |>add_overall()```