msberends / AMR

Functions to simplify and standardise antimicrobial resistance (AMR) data analysis and to work with microbial and antimicrobial properties by using evidence-based methods, as described in https://doi.org/10.18637/jss.v104.i03.

Home Page:https://msberends.github.io/AMR/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add confidence intervals for AMR calculation

msberends opened this issue · comments

Add confidence intervals for proportions of resistance (i.e. Clopper Pearson method).

From email:

I think it is most suitable to use for resistance(). For me a typical use case would be either creating tables with stratified AMR (i.e. by comorbidities like Diabetes) or creating figures with AMR over time and having 95% CI’s. Right now I frequently use two approaches with I can show below. Sadly most of the standard frequency tools don’t support creating CI’s.

1st approach (using the ci_proportion function) (very bulky):

N <- dat_E_Coli %>%
  filter(!Trimethoprim == "",!Trimethoprim == " ",!Trimethoprim == "-") %>%
  filter(Trimethoprim == "R") %>% 
  filter(JAHR == 2015) %>%
  nrow()
 
Total <- dat_E_Coli %>%
  filter(!Trimethoprim == "",!Trimethoprim == " ",!Trimethoprim == "-") %>%
  filter(JAHR == 2015) %>%
  nrow()
 
table_Res_E_coli <- ci_proportion(N, n = Total, type = "Clopper-Pearson")
 
Estimate <- c(table_Res_E_coli$estimate)
            
CI_Lower <- c(table_Res_E_coli$interval)[1]
 
CI_Upper <- c(table_Res_E_coli$interval)[2]
 
df1 <- data.frame(Estimate, CI_Lower, CI_Upper, N, Total) %>%
  mutate(Year = "2015") %>%
  relocate(Year, .before = Estimate)

(Nice thing here ist, that you can chose the type of method i.e. like here Clopper Pearson

2nd approach (different DATASET with stratification by year and age) using free_table:

 dat_2_AST_CIP_Age1 <- dat_2 %>%
  filter(ERREGER == "Enterococcus_Faecalis") %>%
  filter(!Fluoroquinolones == "",!Fluoroquinolones == " ",!Fluoroquinolones == "-") %>%
  mutate(Fluoroquinolones = if_else((Fluoroquinolones == "I" | Fluoroquinolones == "M"), "S", Fluoroquinolones)) %>%
  filter(ALTERSGRP3 == 1) %>%
  freq_table (JAHR, Fluoroquinolones) %>%
  filter(!col_cat == "S") %>%
  select(row_cat, n_row, percent_row, lcl_row, ucl_row) %>%
  mutate(across(where(is.numeric), round, digits = 1)) %>%
  mutate(row_cat = as.numeric(row_cat)) %>%
  add_column(Age = "Group1", .before = "row_cat")

So this is how I currently use it. Great and more reliable would be an implementation in the resistance() function maybe even with a tool to set the method.


I came with something different in the meantime.

dat_Res <- dat %>%
  group_by(JAHR) %>%
  filter(ERREGER == "B_PSDMN_AERG") %>%
  summarise(
      R1 = resistance(ciprofloxacin, as_percent = F),
      n1 = n_rsi(ciprofloxacin), 
      N = count_resistant(ciprofloxacin), 
      total1 = n()) %>%
  mutate(n1 = as.numeric(n1)) %>%
  rowwise() %>%
  mutate(CI_low = if_else(n1 == 0, 0, ((ci_proportion(N, n = n1, type = "Clopper-Pearson"))$interval[1]))) %>%
  mutate(CI_high = if_else(n1 == 0, 0, ((ci_proportion(N, n = n1, type = "Clopper-Pearson"))$interval[2]))) %>%
  mutate(CI_low = CI_low*100) %>%
  mutate(CI_high = CI_high*100) %>%
  mutate(R1 = R1*100) %>%
  relocate(CI_low, .after = R1) %>%
  relocate(CI_high,.after = CI_low) %>%
  mutate(across(where(is.numeric), round, digits = 1))

Now available in main:

resistance(example_isolates$AMX)
#> [1] 0.5955556
rsi_confidence_interval(example_isolates$AMX)
#> [1] 0.5688204 0.6218738

Added as ci_min and ci_max in functions rsi_df() and proportion_df():

library(dplyr)

example_isolates %>% rsi_df()
#> # A tibble: 80 × 6
#>    antibiotic                 interpretation value ci_min ci_max isolates
#>  * <chr>                      <ord>          <dbl>  <dbl>  <dbl>    <int>
#>  1 Amikacine                  SI             0.363  0.327  0.400      251
#>  2 Amikacine                  R              0.637  0.600  0.673      441
#>  3 Amoxicilline               SI             0.404  0.378  0.431      546
#>  4 Amoxicilline               R              0.596  0.569  0.622      804
#>  5 Amoxicilline/clavulaanzuur SI             0.763  0.743  0.782     1433
#>  6 Amoxicilline/clavulaanzuur R              0.237  0.218  0.257      446
#>  7 Ampicilline                SI             0.404  0.378  0.431      546
#>  8 Ampicilline                R              0.596  0.569  0.622      804
#>  9 Azitromycine               SI             0.428  0.405  0.450      810
#> 10 Azitromycine               R              0.572  0.550  0.595     1084
#> # … with 70 more rows
#> # ℹ Use `print(n = ...)` to see more rows