HIV neuropathy: down, but not out
Peter Kamerman
22 February 2016It has been a while since my last post (I’ve been migrating the site from Wordpress to GitHub Pages), and I thought I would get back into the swing of things with a post on a topic close to my heart, HIV-associated sensory neuropathy (HIV-SN). The neuropathy (damaged nerves) affects the long sensory nerves from the hands and feet, producing reduced sensation. Somewhat counter-intuitively, this loss of sensation is often accompanied by chronic pain in the affected areas. The neuropathy is not fatal, but the loss of sensation, and particularly the pain, causes significant psychological, social, and economic problems for the person affected, their family/friends, and places a large burden on the healthcare system.
The mechanisms underlying the development of the neuropathy have not been clearly described, but one of the major risk factors for the neuropathy is exposure to older generation antiretroviral drugs (ddX: stavudine, didanosine, zalcitabine), which are toxic to neurones. Imagine starting a treatment that saves your life, but potentially leaves you with chronic, intractable pain.
Because of their toxicity (not just neuropathy, but a suite of other complications too), these older drugs were phased out of routine use in developed countries some time ago. More recently, there has been a steady shift away from using these drugs first-line in resource-poor countries too. With the global phasing out of neurotoxic ddX drugs, there is hope that the number of new cases of the neuropathy, and ultimately the total burden of the neuropathy, will fall. However, the epidemiological data to support this claim are scant. Head-to-head longitudinal efficacy and toxicological studies of old versus new antiretroviral treatments reported lower rates of the neuropathy in those people being treated with newer drugs, but these studies were poorly designed for detecting neuropathy in the first place. So where does that leave us in answering the question of whether we are witnessing the beginning of the end of HIV neuropathy?
Enter the CHARTER study
One source of data that may shed light on problem is the National Institutes of Health (NIH)-funded CNS HIV Anti-Retroviral Therapy Effects Research (CHARTER) study. The study is a prospective, multi-centre study in the US reporting on central (brain and spinal cord) and peripheral nervous system complications of HIV infections in cross-sectional (~1600 participants) and longitudinal (~650 participants) cohorts; all participants undergo comprehensive neurological and neurobehavioural assessment. In 2010, Ronald Ellis and colleagues published a fascinating paper describing the prevalence of HIV neuropathy in 1539 HIV-infected individuals enrolled between 2003 and 2007 (Ellis et al., Arch Neurol 67: 552-558, 2010. DOI: 10.1001/archneurol.2010.76). They reported that 57% (881/1539) of participants had HIV neuropathy (defined as the presence of at least 1 abnormal clinical sign of neuropathy - reduced/absent vibration or pin-prick sensation in the feet and toes, or reduced ankle reflexes). But, despite providing the data (see Table 1 below) they did not report whether the prevalence of HIV neuropathy differed between patients depending on their exposure to neurotoxic antiretroviral drugs.
Since the data are available, I saw an opportunity to look at whether the prevalence of HIV neuropathy did indeed differ between HIV-positive patients from the CHARTER study who were on combination antiretroviral therapy (cART), but who had never been exposed (ddX-naive) to neurotoxic ddX drugs, and those who had been exposed (ddX-exposed) at some time-point in their treatment.
The analysis
Prevalence of HIV-SN
The first step in the analysis involved extracting the relevant data from Table 1 of Ellis et al. (2010). Because the extraction only included a small number of data points I performed the extraction manually.
############################################################
# #
# Extract data from Ellis et al (2010) table 1 #
# #
############################################################
# sn_ddX_exposed: Sensory neuropathy (sn), and have been exposed to ddX
# Data extracted: Currently using ddX + used ddX in the past
<- 138 + 413
sn_ddX_exposed
# sn_free_ddX_exposed: No sensory neuropathy (sn), and have been exposed to ddX
# Data extracted: Currently using ddX + used ddX in the past
<- 72 + 175
sn_free_ddX_exposed
# sn_ddX_naive: Sensory neuropathy (sn), and never been exposed to ddX
# Data extracted: ddX-naive - cART-naive
<- 330 - 71
sn_ddX_naive
# sn_free_ddX_naive: No sensory neuropathy (sn), and never been exposed to ddX
# Data extracted: ddX-naive - cART-naive
<- 441 - 163
sn_free_ddX_naive
############################################################
# #
# Tabulate extracted data #
# #
############################################################
# Put into dataframe
<- tibble(Neuropathy = c('Yes', 'Yes', 'No', 'No'),
extr ddX_exposure = c('Yes', 'No', 'Yes', 'No'),
N = c(sn_ddX_exposed, sn_ddX_naive, sn_free_ddX_exposed, sn_free_ddX_naive))
# Tabulate
kable(extr,
caption = 'Summary of data extracted from Table 1 of Ellis et al. (2010)',
align = 'lll')
Neuropathy | ddX_exposure | N |
---|---|---|
Yes | Yes | 551 |
Yes | No | 259 |
No | Yes | 247 |
No | No | 278 |
Once I had extracted the data, I used the data to construct simulated datasets of the number of participants with (sn) and without (sn_free) sensory neuropathy in the ddX-naive and ddX-exposed groups.
############################################################
# #
# Simulate datasets #
# #
############################################################
# ddX-naive data
<- c(rep('sn', sn_ddX_naive),
ddX_naive rep('sn_free', sn_free_ddX_naive)) %>% # generate the data
sample(.,
size = length(.),
replace = FALSE) # shuffle the pack (for no good reason)
# ddX-exposed data
<- c(rep('sn', sn_ddX_exposed),
ddX_exposed rep('sn_free', sn_free_ddX_exposed)) %>% # generate the data
sample(.,
size = length(.),
replace = FALSE) # shuffle the pack (for no good reason)
############################################################
# #
# Tabulate simulated data #
# #
############################################################
# Put into dataframe
<- tibble(Group = c('ddX_exposure', 'ddX_naive'),
sim `Neuropathy (n)` = c(length(ddX_exposed[ddX_exposed == 'sn']),
length(ddX_naive[ddX_naive == 'sn'])),
`No neuropathy (n)` = c(length(ddX_exposed[ddX_exposed == 'sn_free']),
length(ddX_naive[ddX_naive == 'sn_free'])),
`Total (n)` = c(length(ddX_exposed),
length(ddX_naive))) %>%
mutate(`Prevalence (%)` = round(100 * (`Neuropathy (n)` / `Total (n)`)))
# Tabulate
kable(sim,
caption = 'Summary of neuropathy prevalence in simulated datasets',
align = 'lrrrr')
Group | Neuropathy (n) | No neuropathy (n) | Total (n) | Prevalence (%) |
---|---|---|---|---|
ddX_exposure | 551 | 247 | 798 | 69 |
ddX_naive | 259 | 278 | 537 | 48 |
With only a glance at the table above you can see that the prevalence of neuropathy in patients exposed to ddX at some time-point in their HIV treatment was greater than that in patients never exposed to any of the ddX drugs (69% vs 48%). But, these are point estimates of disease prevalence, based on the group of people who volunteered to take part in the study. It would be nice to get an estimate of the range of values within which the prevalence is estimated to lie by constructing 95% confidence intervals of the prevalence. A handy approach to generating these confidence intervals is bootstrapping; a resampling method that allows the generation of an estimate of a population parameter (e.g., disease prevalence) from sample data by resampling (with replacement) the sample data. It boils down to using the sample cohort as the population. There are several very good R packages that can be used to calculate bootstrap confidence intervals (the ‘boot’ package by Brain Ripley and Angelo Canty springs to mind), but I chose to use perform the bootstrap use base R functions.
############################################################
# #
# Bootstrap SN prevalence (resampling = 999) #
# #
############################################################
# Step 1: Define function 'bootstrp' to generate the 95% confidence
# interval of the prevalence.
# Generate a list ('boot_resample') containing 'B' bootstrap samples
# of 'data' (default = 999 samples)
<- function(data, B = 999){
bootstrp <- list() # Create empty list
boot_resample for(i in 1:B){
<- sample(x = data,
boot_resample[[i]] size = length(data),
replace = TRUE)
}
boot_resample
}
# Step 2: Run the function
<- bootstrp(ddX_exposed)
ddX_exposed_2 <- bootstrp(ddX_naive)
ddX_naive_2
# The next two steps could have been included in the 'boostrp' function,
# but I decided to seperate them from the function to keep the
# function simple, and make the process clearer.
# Step 3: Create a vector of neuropathy prevalence data for each item
# in the output of 'bootstrp'
<- sapply(ddX_exposed_2,
ddX_exposed_3 function(y) round(100 * (length(y[y == 'sn']) / length(y))))
<- sapply(ddX_naive_2,
ddX_naive_3 function(y) round(100 * (length(y[y == 'sn']) / length(y))))
# Step 4: Get the lower (0.025) and upper (0.975) limits of the
# vector of prevalence data
<- quantile(ddX_exposed_3,
ddX_exposed_4 probs = c(0.025, 0.975))
<- quantile(ddX_naive_3,
ddX_naive_4 probs = c(0.025, 0.975))
############################################################
# #
# Tabulate bootstrap outputs #
# #
############################################################
# Step 1: Prepare dataframe of simulated datasets (bootstrap sample)
<- right_join(tibble(N = 1:length(ddX_naive),
df ddX_naive = factor(ddX_naive)),
tibble(N = 1:length(ddX_exposed),
ddX_exposed = factor(ddX_exposed))) %>% # make a dataframe
gather(Group, Neuropathy, ddX_naive, ddX_exposed) %>% # gather columns
select(Group, Neuropathy) %>% # select required columns
filter(!is.na(Neuropathy)) %>% # remove NA from join
group_by(Group, Neuropathy) %>%
summarise(Count = n()) %>% # get counts from group_by
spread(Neuropathy, Count) %>% # spread the Neuropathy column
mutate(`Total (n)` = sn + sn_free,
`Prevalence (%)` = round(100 * (sn / `Total (n)`))) %>%
rename(`Neuropathy (n)`= sn,
`No neuropathy (n)` = sn_free) # rename columns
# Step 2: Add the bootstrap CI data to 'df'
<- df %>%
df2 bind_cols(data.frame(Lower_95CI = c(ddX_exposed_4[1], ddX_naive_4[1]),
data.frame(Upper_95CI = c(ddX_exposed_4[2], ddX_naive_4[2])))) %>%
rename(`Lower 95% CI` = Lower_95CI,
`Upper 95% CI` = Upper_95CI)
# Step 3: Print table
kable(df2,
caption = 'Neuropathy prevalence (95% bootstrap confidence interval) in simulated datasets',
align = 'lrrrrrr')
Group | Neuropathy (n) | No neuropathy (n) | Total (n) | Prevalence (%) | Lower 95% CI | Upper 95% CI |
---|---|---|---|---|---|---|
ddX_exposed | 551 | 247 | 798 | 69 | 65 | 72 |
ddX_naive | 259 | 278 | 537 | 48 | 44 | 53 |
############################################################
# #
# Plot bootstrap data #
# #
############################################################
# Step 1: Format 'df2' for plotting, including tooltip columns for
# interactive graph labelling
<- tibble(Max = c(max(ddX_exposed_3), max(ddX_naive_3)))
Max <- tibble(Min = c(min(ddX_exposed_3), min(ddX_naive_3)))
Min <- tibble(tooltip_prev = c(paste0('Point prevalence: ',
tooltip_prev $`Prevalence (%)`[1], '%'),
df2paste0('Point prevalence: ',
$`Prevalence (%)`[2], '%')))
df2<- tibble(tooltip_95CI = c(paste0('Bootstrap 95% CI: ', df2$`Lower 95% CI`[1],
tooltip_95CI ' to ', df2$`Upper 95% CI`[1], '%'),
paste0('Bootstrap 95% CI: ', df2$`Lower 95% CI`[2],
' to ', df2$`Upper 95% CI`[2], '%')))
<- df2 %>%
df2_plot select(c(1,5:7)) %>%
rename(Prevalence = `Prevalence (%)`,
Lower_95CI = `Lower 95% CI`,
Upper_95CI = `Upper 95% CI`) %>%
bind_cols(Max, Min, tooltip_prev, tooltip_95CI)
# Step 2: Set palette
<- c('#2a7eac', '#ac582a')
palette_dark <- c('#61add8', '#d88c61')
palette_light
# Step 3: Plot using interactive geoms from 'ggiraph' package
<- ggplot(data = df2_plot,
sn_plot aes(x = Group,
y = Prevalence,
fill = Group,
color = Group)) +
geom_rect_interactive(aes(ymin = Min,
ymax = Max,
tooltip = tooltip_95CI),
xmin = c(0.75, 1.75),
xmax = c(1.25, 2.25)) +
geom_segment_interactive(aes(y = Prevalence,
yend = Prevalence,
x = c(0.75, 1.75),
xend = c(1.25, 2.25),
tooltip = tooltip_prev),
size = 3) +
labs(y = 'Neuropathy prevalence (%)\n') +
scale_x_discrete(labels = c('Exposed\nto ddX', 'Never exposed\nto ddx')) +
scale_y_continuous(limits = c(0, 100)) +
scale_fill_manual(values = palette_light) +
scale_colour_manual(values = palette_dark) +
theme(legend.position = 'none',
panel.background = element_blank(),
panel.grid.major = element_line(colour = "#dddddd"),
plot.title = element_blank(),
axis.ticks = element_line(colour = "#dddddd"),
axis.title.x = element_blank(),
axis.title = element_text(size = 18),
axis.text = element_text(size = 18))
# Plot interactive graph
<- "background-color:#000000;color:#FFFFFF;font-family:helvetica;padding:10px;border-radius:10px 20px 10px 20px;"
extra_css ggiraph(code = print(sn_plot),
tooltip_extra_css = extra_css)
Figure 1. Point prevalence (with 95% bootstrap confidence intervals) of HIV neuropathy in simulated datasets based on neuropathy prevalence reported by Ellis et al. (2010). Data are shown for patients were/had been on combination antiretroviral therapy (cART), but who have never been exposed to the neurotoxic antiretroviral drugs (Never exposed to ddX; Orange), and patients who were/had been on cART, and who had been exposed to ddX (Exposed to ddX; Blue).
From the plot, you can clearly see that there was a much (~30%) lower prevalence of HIV neuropathy in those patients never exposed to neurotoxic ddX drugs compared to those who had been exposed (if seeing isn’t believing and you like to see a p-value, then see the table below). But, while the neuropathy was less common in patients treated with the newer drugs, almost half of the patient still had evidence of peripheral nerve damage; a substantial burden.
Significance testing
Estimate | 95% CI | P value |
---|---|---|
2.393 | 1.897 to 3.022 | < 0.001 |
Is the neuropathy still painful?
As I mentioned earlier, pain is a common symptom of the neuropathy, and this pain causes significant dysfuction and distress. Consequently, having shown that exposure to newer, less neurotoxic treatments is associated with reduced prevalence of HIV neuropathy compared with older drugs, it stands to reason that when neuropathy is present, the severity of the neuropathy associated with these newer drugs may be less than that induced by the older drugs. Therefore, I also looked at the frequency of painful symptoms in ddX-exposed and ddX-naive patients reported on by Ellis and colleagues (2010) that had at least one clinical sign of peripheral nerve damage (i.e., only patients who had a neuropathy). This new analysis followed exactly the same procedures as those described above, except that I took the data from Table 2 of Ellis et al. (2010) (see below). So, other than showing which data I extracted from Table 2, I have not shown the R scripts for this section (your can find the full .Rmd file on GitHub)
Here are the data I extracted from Table 2 of Ellis et al. (2010).
############################################################
# #
# Extract data from Ellis et al (2010) table 1 #
# #
############################################################
# Extract data
# pain_ddX_exposed: painful sensory neuropathy (pain), and have been exposed to ddX
# Data extracted: Currently using ddX + used ddX in the past
<- 38 + 184
pain_ddX_exposed
# pain_free_ddX_exposed: Nonpainful sensory neuropathy (pain_free), and have
# been exposed to ddX
# Data extracted: Currently using ddX + used ddX in the past
<- 100 + 229
pain_free_ddX_exposed
# pain_ddX_naive: Painful sensory neuropathy (pain), and never been exposed to ddX
# Data extracted: ddX-naive - cART-naive
<- 113 - 29
pain_ddX_naive
# pain_free_ddX_naive: Nonpainful sensory neuropathy (pain_free), and never
# been exposed to ddX
# Data extracted: ddX-naive - cART-naive
<- 217 - 42
pain_free_ddX_naive
############################################################
# #
# Tabulate extracted data #
# #
############################################################
# Put into dataframe
<- tibble(Pain = c('Yes', 'Yes', 'No', 'No'),
extr_pain ddX_exposure = c('Yes', 'No', 'Yes', 'No'),
N = c(pain_ddX_exposed, pain_ddX_naive,
pain_free_ddX_exposed, pain_free_ddX_naive))
# Tabulate
kable(extr_pain,
caption = 'Summary of data extracted from Table 2 of Ellis et al. (2010)',
align = 'l')
Pain | ddX_exposure | N |
---|---|---|
Yes | Yes | 222 |
Yes | No | 84 |
No | Yes | 329 |
No | No | 175 |
Following data extraction, I simulated datasets of the number of participants with (pain) and without (pain_free) painful sensory neuropathy in the ddX-naive and ddX-exposed groups, and then calculated and plotted bootstrap 95% confidence intervals.
############################################################
# #
# Simulate datasets #
# #
############################################################
# ddX-naive data
<- c(rep('pain', pain_ddX_naive),
ddX_naive_pain rep('pain_free', pain_free_ddX_naive)) %>% # generate the data
sample(.,
size = length(.),
replace = FALSE) # shuffle the pack (for no good reason)
# ddX-exposed data
<- c(rep('pain', pain_ddX_exposed),
ddX_exposed_pain rep('pain_free', pain_free_ddX_exposed)) %>% # generate the data
sample(.,
size = length(.),
replace = FALSE) # shuffle the pack (for no good reason)
############################################################
# #
# Tabulate simulated data #
# #
############################################################
# Put into dataframe
<- tibble(Group = c('ddX_exposure', 'ddX_naive'),
sim `Pain (n)` = c(length(ddX_exposed_pain[ddX_exposed_pain == 'pain']),
length(ddX_naive_pain[ddX_naive_pain == 'pain'])),
`No pain (n)` = c(length(ddX_exposed_pain[ddX_exposed_pain == 'pain_free']),
length(ddX_naive_pain[ddX_naive_pain == 'pain_free'])),
`Total (n)` = c(length(ddX_exposed_pain),
length(ddX_naive_pain))) %>%
mutate(`Prevalence (%)` = round(100 * (`Pain (n)` / `Total (n)`)))
# Tabulate
kable(sim,
caption = 'Summary of pain prevalence in simulated datasets',
justify = 'l')
Group | Pain (n) | No pain (n) | Total (n) | Prevalence (%) |
---|---|---|---|---|
ddX_exposure | 222 | 329 | 551 | 40 |
ddX_naive | 84 | 175 | 259 | 32 |
############################################################
# #
# Bootstrap SN prevalence (resampling = 999) #
# #
############################################################
# Step 1: Define function 'bootstrp' (already done)
# Step 2: Run the function
<- bootstrp(ddX_exposed_pain)
ddX_exposed_pain_2 <- bootstrp(ddX_naive_pain)
ddX_naive_pain_2
# Step 3: Create a vector of neuropathy prevalence data for each item
# in the output of 'bootstrp'
<- sapply(ddX_exposed_pain_2,
ddX_exposed_pain_3 function(y) round(100 * (length(y[y == 'pain']) / length(y))))
<- sapply(ddX_naive_pain_2,
ddX_naive_pain_3 function(y) round(100 * (length(y[y == 'pain']) / length(y))))
# Step 4: Get the lower (0.025) and upper (0.975) limits of the
# vector of prevalence data
<- quantile(ddX_exposed_pain_3,
ddX_exposed_pain_4 probs = c(0.025, 0.975))
<- quantile(ddX_naive_pain_3,
ddX_naive_pain_4 probs = c(0.025, 0.975))
############################################################
# #
# Tabulate bootstrap outputs #
# #
############################################################
# Step 1: Prepare dataframe of simulated datasets (bootstrap sample)
<- right_join(tibble(N = 1:length(ddX_naive_pain),
df_pain ddX_naive = factor(ddX_naive_pain)),
tibble(N = 1:length(ddX_exposed_pain),
ddX_exposed = factor(ddX_exposed_pain))) %>% # make a dataframe
gather(Group, Pain, ddX_naive, ddX_exposed) %>% # gather columns
select(Group, Pain) %>% # select required columns
filter(!is.na(Pain)) %>% # remove NA from join
group_by(Group, Pain) %>%
summarise(Count = n()) %>% # get counts from group_by
spread(Pain, Count) %>% # spread the Neuropathy column
mutate(`Total (n)` = pain + pain_free,
`Prevalence (%)` = round(100 * (pain / `Total (n)`))) %>%
rename(`Pain (n)`= pain,
`No pain (n)` = pain_free) # rename columns
# Step 2: Add the bootstrap CI data to 'df_pain'
<- df_pain %>%
df2_pain bind_cols(data.frame(Lower_95CI = c(ddX_exposed_pain_4[1], ddX_naive_pain_4[1]),
data.frame(Upper_95CI = c(ddX_exposed_pain_4[2], ddX_naive_pain_4[2])))) %>%
rename(`Lower 95% CI` = Lower_95CI,
`Upper 95% CI` = Upper_95CI)
# Step 3: Print table
kable(df2_pain,
caption = 'Painful neuropathy prevalence (95% bootstrap confidence interval) in simulated datasets',
align = 'lrrrrrr')
Group | Pain (n) | No pain (n) | Total (n) | Prevalence (%) | Lower 95% CI | Upper 95% CI |
---|---|---|---|---|---|---|
ddX_exposed | 222 | 329 | 551 | 40 | 36 | 45 |
ddX_naive | 84 | 175 | 259 | 32 | 27 | 38 |
############################################################
# #
# Plot bootstrap data #
# #
############################################################
# Step 1: Format df2_pain for plotting, including tooltip columns
# for interactive graph labelling
<- tibble(Max = c(max(ddX_exposed_pain_3), max(ddX_naive_pain_3)))
Max <- tibble(Min = c(min(ddX_exposed_pain_3), min(ddX_naive_pain_3)))
Min <- tibble(tooltip_prev = c(paste0('Point prevalence: ',
tooltip_prev $`Prevalence (%)`[1], '%'),
df2_painpaste0('Point prevalence: ',
$`Prevalence (%)`[2], '%')))
df2_pain<- tibble(tooltip_95CI = c(paste0('Bootstrap 95% CI: ',
tooltip_95CI $`Lower 95% CI`[1],
df2_pain' to ',
$`Upper 95% CI`[1], '%'),
df2_painpaste0('Bootstrap 95% CI: ',
$`Lower 95% CI`[2],
df2_pain' to ',
$`Upper 95% CI`[2], '%')))
df2_pain
<- df2_pain %>%
df2_pain_plot select(c(1,5:7)) %>%
rename(Prevalence = `Prevalence (%)`,
Lower_95CI = `Lower 95% CI`,
Upper_95CI = `Upper 95% CI`) %>%
bind_cols(Max, Min, tooltip_prev, tooltip_95CI)
# Step 2: Set palette
<- c('#2a7eac', '#ac582a')
palette_dark <- c('#61add8', '#d88c61')
palette_light
# Step 3: Plot using interactive geoms from 'ggiraph' package
<- ggplot(data = df2_pain_plot,
sn_pain aes(x = Group,
y = Prevalence,
fill = Group,
color = Group)) +
geom_rect_interactive(aes(ymin = Min,
ymax = Max,
tooltip = tooltip_95CI),
xmin = c(0.75, 1.75),
xmax = c(1.25, 2.25)) +
geom_segment_interactive(aes(y = Prevalence,
yend = Prevalence,
x = c(0.75, 1.75),
xend = c(1.25, 2.25),
tooltip = tooltip_prev),
size = 3) +
labs(y = 'Painful neuropathy prevalence (%)\n') +
scale_x_discrete(labels = c('Exposed\nto ddX', 'Never exposed\nto ddx')) +
scale_y_continuous(limits = c(0, 100)) +
scale_fill_manual(values = palette_light) +
scale_colour_manual(values = palette_dark) +
theme(legend.position = 'none',
panel.background = element_blank(),
panel.grid.major = element_line(colour = "#dddddd"),
plot.title = element_blank(),
axis.ticks = element_line(colour = "#dddddd"),
axis.title.x = element_blank(),
axis.title = element_text(size = 18),
axis.text = element_text(size = 18))
# Step 4: Plot interactive graph
<- "background-color:#000000;color:#FFFFFF;font-family:helvetica;padding:10px;border-radius:10px 20px 10px 20px;"
extra_css ggiraph(code = print(sn_pain),
tooltip_extra_css = extra_css)
Figure 1. Point prevalence (with 95% bootstrap confidence intervals) of painful HIV neuropathy in simulated datasets based on the prevalence of painfulperipheral neuropathy reported by Ellis et al. (2010). Data are shown for patients with a clinically diagnosed neuropathy, and were/had been on combination antiretroviral therapy (cART), but who have never been exposed to the neurotoxic antiretroviral drugs (Never exposed to ddX; Orange), and patients who were/had been on cART, and who had been exposed to ddX (Exposed to ddX; Blue).
From the plot, you can see that there was a slightly lower prevalence of painful HIV neuropathy in those patients never exposed to neurotoxic ddX drugs compared to those who had been exposed (there is overlap of the lower limit of the ddX-exposed group and the upper limit of the ddX-naive group). Like before, if seeing isn’t believing and you like to see a p-value, then see the table below. So, the newer drugs do appear to reduce the severity of the painful symptoms of the neuropathy compared with older ddX drugs, but like the findings for neuropathy per se, there still was a high burden of pain in those with neuropathy and who had only ever been exposed to newer treatments.
############################################################
# #
# Significance testing #
# #
############################################################
# Organise data for chi-square test
<- right_join(tibble(N = 1:length(ddX_naive_pain),
df_pain_chi ddX_naive = factor(ddX_naive_pain)),
tibble(N = 1:length(ddX_exposed_pain),
ddX_exposed = factor(ddX_exposed_pain))) %>%
gather(Group, Pain, ddX_naive, ddX_exposed) %>%
mutate(Group = factor(Group),
Pain = factor(Pain)) %>%
select(Group, Pain)
<- df_pain_chi[[1]]
ddX_exposure <- df_pain_chi[[2]]
pain_status
# Perform chi-square with simulated p-value, and tabulate output
.1 <- fisher.test(x = ddX_exposure,
fishy = pain_status,
simulate.p.value = TRUE,
B = 2000)
.2 <- tibble(Estimate = fish.1$estimate,
fish`95% CI` = paste0(round(fish.1$conf.int[1], 3), ' to ',
round(fish.1$conf.int[2], 3)),
`P value` = ifelse(fish.1$p.value < 0.001,
yes = '< 0.001',
no = fish.1$p.value))
kable(fish.2,
caption = paste0(fish.1$method, ': ', fish.1$data.name),
digits = 3,
align = 'r')
Estimate | 95% CI | P value |
---|---|---|
1.405 | 1.019 to 1.945 | 0.036 |
Take-home message
HIV neuropathy is not going to disappear anytime soon.
While the frequency of HIV neuropathy, and the painful symptoms of the neuropathy, was markedly reduced in patients on modern treatment regimens compared to those exposed to older, neurotoxic treatments, the burden of neuropathy (and pain) was still unacceptably high. These data indicate that the burden of this chronic complication of HIV infection may well decrease over time, but healthcare professionals still need to be cognisant that many of their patients, even if never exposed to ddX drugs, are still at risk of neuropathy, and its painful sequela.
Analysis script
The analysis script for this blog post can be found under the ellis-2010 subdirectory of the second-look-PAIN GitHub repository.
Citation
Peter Kamerman. (2016). HIV neuropathy: Going, going…but not gone. Figshare DOI: 10.6084/m9.figshare.2656255
Session information
## R version 4.0.4 (2021-02-15)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Catalina 10.15.7
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
##
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] gdtools_0.2.3 ggiraph_0.7.8 svglite_2.0.0 pander_0.6.3
## [5] knitr_1.31 forcats_0.5.1 stringr_1.4.0 dplyr_1.0.5
## [9] purrr_0.3.4 readr_1.4.0 tidyr_1.1.3 tibble_3.1.0
## [13] ggplot2_3.3.3 tidyverse_1.3.0
##
## loaded via a namespace (and not attached):
## [1] Rcpp_1.0.6 lubridate_1.7.10 assertthat_0.2.1 digest_0.6.27
## [5] utf8_1.2.1 R6_2.5.0 cellranger_1.1.0 backports_1.2.1
## [9] reprex_1.0.0 evaluate_0.14 httr_1.4.2 highr_0.8
## [13] pillar_1.5.1 rlang_0.4.10 readxl_1.3.1 uuid_0.1-4
## [17] rstudioapi_0.13 jquerylib_0.1.3 rmarkdown_2.7 labeling_0.4.2
## [21] htmlwidgets_1.5.3 munsell_0.5.0 broom_0.7.5 compiler_4.0.4
## [25] modelr_0.1.8 xfun_0.22 pkgconfig_2.0.3 systemfonts_1.0.1
## [29] htmltools_0.5.1.1 tidyselect_1.1.0 fansi_0.4.2 crayon_1.4.1
## [33] dbplyr_2.1.0 withr_2.4.1 grid_4.0.4 jsonlite_1.7.2
## [37] gtable_0.3.0 lifecycle_1.0.0 DBI_1.1.1 magrittr_2.0.1
## [41] scales_1.1.1 cli_2.3.1 stringi_1.5.3 farver_2.1.0
## [45] fs_1.5.0 xml2_1.3.2 bslib_0.2.4 ellipsis_0.3.1
## [49] generics_0.1.0 vctrs_0.3.6 tools_4.0.4 glue_1.4.2
## [53] hms_1.0.0 yaml_2.2.1 colorspace_2.0-0 rvest_1.0.0
## [57] haven_2.3.1 sass_0.3.1