168 Commits
Author SHA1 Message Date
MS Berends eb4ecd9108 Update .zenodo.json 2018-08-20 20:50:56 +02:00
dr. M.S. (Matthijs) Berends 8bad33858e readme typo 2018-08-15 11:12:38 +02:00
dr. M.S. (Matthijs) Berends bc7e36b533 v0.3.0 2018-08-14 14:06:18 +02:00
dr. M.S. (Matthijs) Berends 6bab01948e v0.3.0 2018-08-14 13:25:24 +02:00
dr. M.S. (Matthijs) Berends 1699d7b8b3 better example of grouping variable in ggplot_rsi 2018-08-14 12:07:03 +02:00
dr. M.S. (Matthijs) Berends b0995362af testthat error 2018-08-14 12:00:01 +02:00
dr. M.S. (Matthijs) Berends 533342583a Travis checks 2018-08-14 11:37:40 +02:00
dr. M.S. (Matthijs) Berends 324d8b955e AppVeyor update 2018-08-14 11:25:36 +02:00
dr. M.S. (Matthijs) Berends 7584c929a5 new AppVeyor environment 2018-08-14 08:57:17 +02:00
dr. M.S. (Matthijs) Berends e5193c7749 AppVeyor 2018-08-13 23:05:53 +02:00
dr. M.S. (Matthijs) Berends 59ce1eb1b1 ggplot_rsi improvements 2018-08-13 16:42:37 +02:00
dr. M.S. (Matthijs) Berends dba06c3295 abname improvement, small fixes 2018-08-13 11:00:53 +02:00
dr. M.S. (Matthijs) Berends ce2cdb9309 support groups for portion_df, update README 2018-08-12 22:34:03 +02:00
dr. M.S. (Matthijs) Berends e5d32cafe0 new unit tests for ggplot, small fixes 2018-08-12 17:44:06 +02:00
dr. M.S. (Matthijs) Berends 1ba7d883fe new ggplot enhancement 2018-08-11 21:30:00 +02:00
dr. M.S. (Matthijs) Berends 4680df1e9c travis: no devel for osx 2018-08-10 15:06:09 +02:00
dr. M.S. (Matthijs) Berends 53fa198e35 new portion functions 2018-08-10 15:01:05 +02:00
dr. M.S. (Matthijs) Berends ae2433a020 rsi family for resistance analysis 2018-08-03 14:49:29 +02:00
dr. M.S. (Matthijs) Berends 227121af3d add Dialister to microorganisms 2018-08-03 11:46:06 +02:00
dr. M.S. (Matthijs) Berends db5a0d32a5 typos of Becker algorithm 2018-08-03 10:58:48 +02:00
dr. M.S. (Matthijs) Berends bd9bcfef78 thesis advisors 2018-08-03 09:59:39 +02:00
dr. M.S. (Matthijs) Berends 6262315527 Becker classification
Lancefield classification
Added Lancefield groups to `microorganisms` data set
2018-08-02 13:15:45 +02:00
dr. M.S. (Matthijs) Berends edd2dd09dc rsi for freq 2018-08-01 22:37:28 +02:00
dr. M.S. (Matthijs) Berends d8f70a74de clipboard error 2018-08-01 10:32:24 +02:00
dr. M.S. (Matthijs) Berends a59d0661f7 check CMD error 2018-08-01 09:45:11 +02:00
dr. M.S. (Matthijs) Berends 7c667eb732 emph guess_bactid 2018-08-01 08:03:31 +02:00
dr. M.S. (Matthijs) Berends 36a5493099 travis update again 2018-07-30 01:22:50 +02:00
dr. M.S. (Matthijs) Berends 837dae925d travis update 2018-07-30 01:21:37 +02:00
dr. M.S. (Matthijs) Berends 211e3bae14 remove reshape2 dependency 2018-07-30 01:18:40 +02:00
dr. M.S. (Matthijs) Berends 510e8f22aa more unit tests 2018-07-30 00:57:49 +02:00
dr. M.S. (Matthijs) Berends d0a115d995 bactid speed improvement 2018-07-30 00:14:06 +02:00
dr. M.S. (Matthijs) Berends 826694323b new functions R, RI, SI, S 2018-07-29 22:14:51 +02:00
dr. M.S. (Matthijs) Berends 8421e3f005 more mic classes 2018-07-28 10:48:27 +02:00
dr. M.S. (Matthijs) Berends feab1cad6b small fixes 2018-07-28 09:34:03 +02:00
dr. M.S. (Matthijs) Berends 498e88b5cf improvement for forecasting resistance 2018-07-26 16:30:42 +02:00
dr. M.S. (Matthijs) Berends d9e204031d update to septic_patients, speed improvements 2018-07-25 14:17:04 +02:00
dr. M.S. (Matthijs) Berends 03a3cb397b clipboard update 2018-07-23 15:09:19 +02:00
dr. M.S. (Matthijs) Berends 8421638b60 new class bactid 2018-07-23 14:14:03 +02:00
dr. M.S. (Matthijs) Berends 40de1b4ac2 man 2018-07-23 10:37:49 +02:00
dr. M.S. (Matthijs) Berends 9920ac8a5c fix for keyab, more examples 2018-07-23 10:35:39 +02:00
dr. M.S. (Matthijs) Berends ad662d7bab new col names for key_antibiotics 2018-07-19 15:11:23 +02:00
dr. M.S. (Matthijs) Berends 0d64c166f0 keyab fixes 2018-07-17 19:51:09 +02:00
dr. M.S. (Matthijs) Berends 2a4d759fbc check fails 2018-07-17 14:48:11 +02:00
dr. M.S. (Matthijs) Berends 5cb9c541f8 new algorithm key abs 2018-07-17 13:02:05 +02:00
dr. M.S. (Matthijs) Berends 967ee86757 add unit tests 2018-07-17 11:18:36 +02:00
dr. M.S. (Matthijs) Berends a5a4354651 speed improvements 2018-07-17 10:32:26 +02:00
dr. M.S. (Matthijs) Berends 715a7630ca support format.freq 2018-07-16 16:41:48 +02:00
dr. M.S. (Matthijs) Berends 6eaf33baf3 speed improvements 2018-07-15 22:56:41 +02:00
dr. M.S. (Matthijs) Berends 8240959f38 support older mac release 2018-07-13 19:40:50 +02:00
dr. M.S. (Matthijs) Berends b6655f6454 Welcome C++! 2018-07-13 17:23:46 +02:00
dr. M.S. (Matthijs) Berends a28289562a remove print function, out of scope 2018-07-11 20:12:19 +02:00
dr. M.S. (Matthijs) Berends e3e10c2e88 fix for macOS and older tidyr versions 2018-07-11 12:34:02 +02:00
dr. M.S. (Matthijs) Berends eca406b18b travis build fails for macos 2018-07-11 11:46:06 +02:00
dr. M.S. (Matthijs) Berends 673ea81c0a libgit2 for macOS 2018-07-11 11:04:54 +02:00
dr. M.S. (Matthijs) Berends 330558e0f1 travis update 2018-07-11 10:39:47 +02:00
dr. M.S. (Matthijs) Berends 9e40771a17 get travis working again 2018-07-10 16:36:30 +02:00
dr. M.S. (Matthijs) Berends 490990c8cb no errors on 3.1 and 3.2 2018-07-10 16:31:13 +02:00
dr. M.S. (Matthijs) Berends 0da1071cd8 latest R version on both linux and macOS 2018-07-10 16:17:09 +02:00
dr. M.S. (Matthijs) Berends f2684b29e7 test R 3.1 to latest 2018-07-10 16:05:11 +02:00
dr. M.S. (Matthijs) Berends cde1892e25 allow failure of covr 2018-07-10 15:56:00 +02:00
dr. M.S. (Matthijs) Berends f63414d519 new g.test, extra unit tests 2018-07-10 12:27:07 +02:00
dr. M.S. (Matthijs) Berends fc30d3fb13 freq: support for table 2018-07-09 14:02:58 +02:00
dr. M.S. (Matthijs) Berends 18c91786bf Merge branch 'master' of https://github.com/msberends/AMR 2018-07-08 22:15:31 +02:00
dr. M.S. (Matthijs) Berends 14b990d769 kurtosis, skewness, start with ML 2018-07-08 22:14:55 +02:00
MS Berends e4ca66e3ee support zenodo 2018-07-04 23:42:43 +02:00
dr. M.S. (Matthijs) Berends c768ba0d9c A. lwoffi to A. lwoffii 2018-07-04 17:34:23 +02:00
dr. M.S. (Matthijs) Berends 34ee0247ac addins and small improvements to microorganisms dataset 2018-07-04 17:20:03 +02:00
dr. M.S. (Matthijs) Berends 10fce8382c include IQR and MAD in freq 2018-07-03 11:30:40 +02:00
dr. M.S. (Matthijs) Berends 3d0d21f322 rename vector2ratio to ratio 2018-07-02 11:14:20 +02:00
dr. M.S. (Matthijs) Berends a1acb2f3ac extra unit tests 2018-07-02 09:34:20 +02:00
dr. M.S. (Matthijs) Berends 2c8d4cb8bf forgot namespace... 2018-07-01 22:37:47 +02:00
dr. M.S. (Matthijs) Berends 2ca01e2d8d remove rlang dependency 2018-07-01 22:23:34 +02:00
dr. M.S. (Matthijs) Berends 965fe8681b rlang dep for Travis/macOS 2018-07-01 21:50:34 +02:00
dr. M.S. (Matthijs) Berends 3527894b49 new g.test() and edited freq() 2018-07-01 21:40:37 +02:00
dr. M.S. (Matthijs) Berends f7af8a81da update man page 2018-06-29 09:06:47 +02:00
dr. M.S. (Matthijs) Berends 6ee713cec1 move tbl_parse_guess 2018-06-29 08:56:03 +02:00
MS Berends 4bdcde9a00 allow clipboard on travis 2018-06-27 15:56:59 +02:00
dr. M.S. (Matthijs) Berends 649a8025aa add clipboard functions again 2018-06-27 15:54:56 +02:00
MS Berends dab085d7ad Update README.md 2018-06-27 10:44:24 +02:00
dr. M.S. (Matthijs) Berends a9bd5472d0 top_freq 2018-06-20 14:47:37 +02:00
dr. M.S. (Matthijs) Berends 4a027f3c34 extra unit tests, add row.names to freq 2018-06-19 15:20:14 +02:00
dr. M.S. (Matthijs) Berends bdc860e29c atc_groups 2018-06-19 10:05:38 +02:00
dr. M.S. (Matthijs) Berends 0a5898b17d fix for printing tibbles, improve guess_bactid 2018-06-08 12:06:54 +02:00
dr. M.S. (Matthijs) Berends efdf5a3dc5 prevent dplyr:row_number warning 2018-05-31 14:19:25 +02:00
MS Berends 7a6d5fb6b7 rsi/mic fix 2018-05-31 09:02:49 +02:00
dr. M.S. (Matthijs) Berends 5593aee19e edit as.rsi algor. 2018-05-30 23:02:16 +02:00
uscloud dcc26dd942 Update freq function 2018-05-22 16:34:22 +02:00
MS Berends 0d80647d41 fix SI and IR 2018-05-16 11:19:45 +02:00
dr. M.S. (Matthijs) Berends af524626b6 Merge branch 'master' of https://github.com/msberends/AMR 2018-05-14 11:54:25 +02:00
dr. M.S. (Matthijs) Berends 95f7c78fd6 edit vignette title 2018-05-14 11:54:08 +02:00
MS Berends eecd7a11e8 Set theme jekyll-theme-cayman 2018-05-09 11:49:50 +02:00
MS Berends c690db145e Set theme jekyll-theme-slate 2018-05-09 11:48:10 +02:00
dr. M.S. (Matthijs) Berends f05e7178cb added vignette of freq 2018-05-09 11:44:46 +02:00
dr. M.S. (Matthijs) Berends 25b3346d9a edit methodology of rsi 2018-05-03 10:19:02 +02:00
dr. M.S. (Matthijs) Berends c0fc82c794 Added function n_rsi 2018-05-02 14:56:25 +02:00
dr. M.S. (Matthijs) Berends e5ae7b98ac update logo 2018-05-01 09:59:37 +02:00
dr. M.S. (Matthijs) Berends 6eaf594cb7 update data info 2018-05-01 09:57:50 +02:00
dr. M.S. (Matthijs) Berends be5d714639 update README 2018-05-01 09:43:47 +02:00
dr. M.S. (Matthijs) Berends 19ccc51f40 remove clipboard functions 2018-05-01 09:36:45 +02:00
dr. M.S. (Matthijs) Berends 6fa93fc286 fix clipboard check 2018-04-30 16:54:37 +02:00
dr. M.S. (Matthijs) Berends 8fe70d5652 Fix Latex PDF error 2018-04-30 16:24:11 +02:00
dr. M.S. (Matthijs) Berends 970e3ed7f1 EUCAST rules for MDRO 2018-04-25 15:33:58 +02:00
dr. M.S. (Matthijs) Berends 0b22ddef8e more unit tests 2018-04-20 13:45:34 +02:00
dr. M.S. (Matthijs) Berends 82fec5cc51 Try to support older R versions 2018-04-19 14:10:57 +02:00
dr. M.S. (Matthijs) Berends e7396b8f39 Try to support older R versions 2018-04-19 12:50:23 +02:00
dr. M.S. (Matthijs) Berends d79132b29f Try to support older R versions 2018-04-18 15:41:27 +02:00
dr. M.S. (Matthijs) Berends 4b5530ed64 Try to support older R versions 2018-04-18 15:19:00 +02:00
dr. M.S. (Matthijs) Berends a814d82b4b try to support older R versions 2018-04-18 14:50:16 +02:00
dr. M.S. (Matthijs) Berends 2509e2413d MDRO, freq tables, new print format for tibbles 2018-04-18 12:24:54 +02:00
dr. M.S. (Matthijs) Berends 3165c50d06 more MOs 2018-04-03 16:07:32 +02:00
dr. M.S. (Matthijs) Berends 4a47e59e6f fortify code with more tests 2018-04-03 11:08:31 +02:00
dr. M.S. (Matthijs) Berends 972e923484 testthat for macOS 2018-04-02 16:21:03 +02:00
dr. M.S. (Matthijs) Berends 07bdd61241 update dependencies 2018-04-02 16:05:09 +02:00
dr. M.S. (Matthijs) Berends cee64ef050 fix Travis 2018-04-02 15:03:22 +02:00
dr. M.S. (Matthijs) Berends c182a9673d fix clipboard on linux 2018-04-02 11:11:21 +02:00
MS Berends abcb4accbd Update .travis.yml 2018-03-29 15:17:48 +02:00
MS Berends b7f29aa748 Update first_isolates.R 2018-03-29 15:15:31 +02:00
MS Berends 2647dacc0a add clipbaord support for Linux and macOS 2018-03-29 15:07:36 +02:00
MS Berends f1dbed6fcc Update clipboard.R 2018-03-29 14:56:40 +02:00
MS Berends e2a5202b69 Update test-clipboard.R 2018-03-29 14:47:52 +02:00
MS Berends 258e080756 Update test-clipboard.R 2018-03-29 14:26:26 +02:00
MS Berends 136272cb71 Update clipboard.R 2018-03-29 14:16:42 +02:00
MS Berends 9f943708cc Update .travis.yml 2018-03-29 14:07:54 +02:00
MS Berends fd04df5f9d Update clipboard.R 2018-03-29 13:23:02 +02:00
MS Berends dbec56c68a Update .travis.yml 2018-03-29 13:16:08 +02:00
MS Berends 339b445a30 Update test-clipboard.R 2018-03-29 13:12:49 +02:00
MS Berends 2f4823f7a7 Update clipboard.R 2018-03-29 13:10:55 +02:00
MS Berends ff90188f41 Update .travis.yml 2018-03-29 12:56:03 +02:00
dr. M.S. (Matthijs) Berends 1b3cc41c08 fix tests 2018-03-27 17:58:46 +02:00
dr. M.S. (Matthijs) Berends 6f7730dcaa add tests using testthat 2018-03-27 17:43:42 +02:00
MS Berends c26839b08e Test on Linux and Mac 2018-03-23 14:59:50 +01:00
MS Berends 9637b43357 Remove Windows only function 2018-03-23 14:59:02 +01:00
MS Berends 39eb307968 Remove Windows only function 2018-03-23 14:58:46 +01:00
MS Berends 1b3daebc84 Remove Windows only function 2018-03-23 14:52:56 +01:00
dr. M.S. (Matthijs) Berends 53464ff1c8 - For functions first_isolate, EUCAST_rules the antibiotic column names are case-insensitive
- Functions `first_isolate`, `EUCAST_rules` and `rsi_predict` supports tidyverse-like evaluation of parameters (no need to quote columns them anymore)
- Functions `clipboard_import` and `clipboard_export` as helper functions to quickly copy and paste from/to software like Excel and SPSS
- Renamed dataset `bactlist` to `microorganisms`
2018-03-23 14:46:02 +01:00
dr. M.S. (Matthijs) Berends e1e19af625 README update 2018-03-22 13:45:04 +01:00
dr. M.S. (Matthijs) Berends fe803f7279 use guess_bactid for GLIMS codes 2018-03-19 21:23:21 +01:00
dr. M.S. (Matthijs) Berends c765f424ab typo 2018-03-19 21:03:23 +01:00
dr. M.S. (Matthijs) Berends dd2517ecb7 - Added new algorithm to determine weighted isolates, can now be points or keyantibiotics, see ?first_isolate`
- Function `first_isolate` supports tidyverse-like evaluation of parameters (no need to quote them anymore)
- Functions `as.rsi` and `as.mic` now add the package name and version as attribute
2018-03-19 20:39:23 +01:00
MS Berends 2db25b3b38 Use R 3.2 to make covr work 2018-03-19 12:49:22 +01:00
dr. M.S. (Matthijs) Berends 502a44eb25 - Added new function guess_bactid to determine the ID of a microorganism based on genus/species
- Renamed `ablist` to `antibiotics`
- Added support for character vector in join functions
- Altered `%like%` to make it case insensitive
2018-03-19 12:43:22 +01:00
ceefluz 0fec64a240 Add ORCID identifier 2018-03-19 10:28:35 +01:00
dr. M.S. (Matthijs) Berends 6c67c8f6c1 examples edit 2018-03-14 09:58:58 +01:00
dr. M.S. (Matthijs) Berends 46db3f7b13 import from graphics 2018-03-13 15:40:10 +01:00
dr. M.S. (Matthijs) Berends 53959d40c7 typo in examples 2018-03-13 14:40:52 +01:00
dr. M.S. (Matthijs) Berends 04fc3573ec add barplots 2018-03-13 14:34:10 +01:00
dr. M.S. (Matthijs) Berends e4b371d30a add MIC values
add badges to readme
2018-03-13 11:57:30 +01:00
ceefluz 4ea0333349 Minor text changes for DDD definition 2018-03-13 11:48:30 +01:00
MS Berends aae393f2a9 Update .Rbuildignore 2018-03-11 21:20:28 +01:00
MS Berends 692116b4dc Create .travis.yml 2018-03-11 21:00:11 +01:00
dr. M.S. (Matthijs) Berends 34e70a65ed added septic_patients 2018-02-27 20:01:02 +01:00
dr. M.S. (Matthijs) Berends 98b2b99913 new atc codes 2018-02-26 16:06:49 +01:00
dr. M.S. (Matthijs) Berends 8a603876d2 misc 2018-02-26 15:53:09 +01:00
dr. M.S. (Matthijs) Berends 915d4db23b add rows to summary 2018-02-26 14:37:40 +01:00
dr. M.S. (Matthijs) Berends 6fa05fe33b first isolates 2018-02-26 14:06:31 +01:00
dr. M.S. (Matthijs) Berends d36a391747 export first_isolate 2018-02-26 12:15:52 +01:00
dr. M.S. (Matthijs) Berends be51a95448 rename columns 2018-02-26 10:53:54 +01:00
dr. M.S. (Matthijs) Berends 3f859210d5 new date for push test 2018-02-22 22:04:22 +01:00
dr. M.S. (Matthijs) Berends 11683b082e EUCAST man pages 2018-02-22 21:42:01 +01:00
dr. M.S. (Matthijs) Berends 10380bcfae add NEWS 2018-02-22 21:37:10 +01:00
dr. M.S. (Matthijs) Berends d8da8daf9a First CRAN submission edits 2018-02-22 20:48:48 +01:00
dr. M.S. (Matthijs) Berends 77194527b5 readme 2018-02-21 12:21:34 +01:00
MS Berends 942c41ae9c Update README.md 2018-02-21 12:19:42 +01:00
MS Berends 3cccf9df3f Update README.md 2018-02-21 12:15:04 +01:00
MS Berends 57d0314780 Update README.md 2018-02-21 12:14:17 +01:00
MS Berends 86c9f2913d Update README.md 2018-02-21 12:11:07 +01:00
dr. M.S. (Matthijs) Berends ab0503f8b8 abname, logo 2018-02-21 12:10:00 +01:00
dr. M.S. (Matthijs) Berends 62304dc23f first commit 2018-02-21 11:52:31 +01:00
846 changed files with 10528 additions and 77410 deletions
Executable
+6
View File
@@ -0,0 +1,6 @@
^.*\.Rproj$
^\.Rproj\.user$
.travis.yml
.zenodo.json
^cran-comments\.md$
^appveyor\.yml$
Executable
+15
View File
@@ -0,0 +1,15 @@
.Rproj.user
.Rhistory
.RData
.Ruserdata
AMR.Rproj
tests/testthat/Rplots.pdf
inst/doc
/src/*.o
/src/*.o-*
/src/*.d
/src/*.so
*.dll
vignettes/*.R
.DS_Store
^cran-comments\.md$
-1
View File
@@ -1 +0,0 @@
Executable
+51
View File
@@ -0,0 +1,51 @@
# Setting up R deps
language: r
jobs:
include:
- r: 3.1
os: linux
warnings_are_errors: false
- r: 3.2
os: linux
- r: 3.2
os: osx
- r: 3.3
os: linux
- r: 3.3
os: osx
- r: 3.4
os: linux
- r: 3.4
os: osx
- r: release
os: linux
- r: release
os: osx
- r: devel
os: linux
warnings_are_errors: false
# matrix:
# allow_failures:
# - r: 3.1
# - r: devel
r_packages: covr
cache: packages
cran: https://cran.rstudio.com
before_install:
# needed for clipboard function:
# - if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get -qq update; fi
# - if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get install -y xclip; fi
- if [ $TRAVIS_OS_NAME = osx ]; then brew install xclip; fi
- if [ $TRAVIS_OS_NAME = osx ]; then brew install libgit2; fi
# postrun
after_success:
# only run on osx, so clipboard functions can be checked
- if [ $TRAVIS_OS_NAME = osx ]; then Rscript -e 'covr::codecov()'; fi
notifications:
email:
recipients:
- m.s.berends@umcg.nl
# - c.f.luz@umcg.nl
on_success: change
on_failure: change
+33
View File
@@ -0,0 +1,33 @@
{
"description": "<p>This R package contains functions to make <strong>microbiological, epidemiological data analysis easier</strong>. It allows the use of some new classes to work with MIC values and antimicrobial interpretations (i.e. values S, I and R).</p>\n\n<p>With <code>AMR</code> you can also:</p>\n\n<ul>\n\t<li>Conduct AMR analysis with the <code>rsi</code> function, that can also be used with the <code>dplyr</code> package (e.g. in conjunction with <code>summarise</code>) to calculate the resistance percentages (and even co-resistance) of different antibiotic columns of a table</li>\n\t<li>Predict antimicrobial resistance for the nextcoming years with the <code>rsi_predict</code> function</li>\n\t<li>Apply <a href="http://www.eucast.org/expert_rules_and_intrinsic_resistance/">EUCAST rules to isolates</a> with the <code>EUCAST_rules</code> function</li>\n\t<li>Identify first isolates of every patient <a href="https://clsi.org/standards/products/microbiology/documents/m39/">using guidelines from the CLSI</a> (Clinical and Laboratory Standards Institute) with the <code>first_isolate</code> function</li>\n\t<li>Get antimicrobial ATC properties from the WHO Collaborating Centre for Drug Statistics Methodology (<a href="https://www.whocc.no/atc_ddd_methodology/who_collaborating_centre/">WHOCC</a>), to be able to:\n\t<ul>\n\t\t<li>Translate antibiotic codes (like <em>AMOX</em>), official names (like <em>amoxicillin</em>) and even trade names (like <em>Amoxil</em> or <em>Trimox</em>) to an <a href="https://www.whocc.no/atc_ddd_index/?code=J01CA04&amp;showdescription=no">ATC code</a> (like <em>J01CA04</em>) and vice versa with the <code>abname</code> function</li>\n\t\t<li>Get the latest antibiotic properties like hierarchic groups and <a href="https://en.wikipedia.org/wiki/Defined_daily_dose">defined daily dose</a> (DDD) with units and administration form from the WHOCC website with the <code>atc_property</code> function</li>\n\t</ul>\n\t</li>\n\t<li>Create frequency tables with the <code>freq</code> function</li>\n</ul>\n\n<p>And it contains:</p>\n\n<ul>\n\t<li>A recent data set with ~2500 human pathogenic microorganisms, including family, genus, species, gram stain and aerobic/anaerobic</li>\n\t<li>A recent data set with all antibiotics as defined by the <a href="https://www.whocc.no/atc_ddd_methodology/who_collaborating_centre/">WHOCC</a>, including ATC code, official name and DDD&#39;s</li>\n\t<li>An example data set <code>septic_patients</code>, consisting of 2000 blood culture isolates from anonymised septic patients between 2001 and 2017.</li>\n</ul>\n\n<p>With the <code>MDRO</code> function (abbreviation of Multi Drug Resistant Organisms), you can check your isolates for exceptional resistance with country-specific guidelines or EUCAST rules. Currently guidelines for Germany and the Netherlands are supported. Please suggest addition of your own country here: <a href="https://github.com/msberends/AMR/issues/new?title=New%20guideline%20for%20MDRO&amp;body=%3C--%20Please%20add%20your%20country%20code,%20guideline%20name,%20version%20and%20source%20below%20and%20remove%20this%20line--%3E">https://github.com/msberends/AMR/issues/new</a>.</p>\n",
"license": "GPL-2.0",
"title": "AMR: An R package to simplify the analysis and prediction of Antimicrobial Resistance and work with antibiotic properties by using evidence-based methods.",
"version": "0.3.0",
"upload_type": "software",
"publication_date": "2018-08-18",
"creators": [
{
"orcid": "0000-0001-7620-1800",
"affiliation": "University of Groningen, University Medical Center Groningen, Department of Medical Microbiology, Groningen, The Netherlands",
"name": "Matthijs S. Berends"
},
{
"orcid": "0000-0001-5809-5995",
"affiliation": "University of Groningen, University Medical Center Groningen, Department of Medical Microbiology, Groningen, The Netherlands",
"name": "Christian F. Luz"
}
],
"access_right": "open",
"related_identifiers": [
{
"scheme": "url",
"identifier": "https://github.com/msberends/AMR",
"relation": "isSupplementTo"
},
{
"scheme": "doi",
"identifier": "10.5281/zenodo.1305355",
"relation": "isVersionOf"
}
]
}
-104
View File
@@ -1,104 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Page not found (404) • AMR (for R)</title>
<!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="https://amr-for-r.org/favicon-96x96.png">
<link rel="icon" type="”image/svg+xml”" href="https://amr-for-r.org/favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="https://amr-for-r.org/apple-touch-icon.png">
<link rel="icon" sizes="any" href="https://amr-for-r.org/favicon.ico">
<link rel="manifest" href="https://amr-for-r.org/site.webmanifest">
<script src="https://amr-for-r.org/deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="https://amr-for-r.org/deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet">
<script src="https://amr-for-r.org/deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="https://amr-for-r.org/deps/Lato-0.4.10/font.css" rel="stylesheet">
<link href="https://amr-for-r.org/deps/Fira_Code-0.4.10/font.css" rel="stylesheet">
<link href="https://amr-for-r.org/deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet">
<link href="https://amr-for-r.org/deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet">
<script src="https://amr-for-r.org/deps/headroom-0.11.0/headroom.min.js"></script><script src="https://amr-for-r.org/deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="https://amr-for-r.org/deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="https://amr-for-r.org/deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="https://amr-for-r.org/deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="https://amr-for-r.org/deps/search-1.0.0/fuse.min.js"></script><script src="https://amr-for-r.org/deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="https://amr-for-r.org/pkgdown.js"></script><link href="https://amr-for-r.org/extra.css" rel="stylesheet">
<script src="https://amr-for-r.org/extra.js"></script><meta property="og:title" content="Page not found (404)">
<meta property="og:image" content="https://amr-for-r.org/logo.svg">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
</head>
<body>
<a href="https://amr-for-r.org/#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="https://amr-for-r.org/index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto">
<li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to">
<li><a class="dropdown-item" href="https://amr-for-r.org/articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="https://amr-for-r.org/reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="https://amr-for-r.org/articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="https://amr-for-r.org/reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="https://amr-for-r.org/authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul>
<ul class="navbar-nav">
<li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="search.json">
</form></li>
<li class="nav-item"><a class="nav-link" href="https://amr-for-r.org/news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul>
</div>
</div>
</nav><div class="container template-title-body">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="https://amr-for-r.org/logo.svg" class="logo" alt=""><h1>Page not found (404)</h1>
</div>
Content not found. Please use links in the navbar.
</main>
</div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer>
</div>
</body>
</html>
-3
View File
@@ -1,3 +0,0 @@
Content not found. Please use links in the navbar.
# Page not found (404)
-443
View File
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 296 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 296 KiB

-280
View File
@@ -1,280 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>CLAUDE.md — AMR R Package • AMR (for R)</title><!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="favicon-96x96.png"><link rel="icon" type="”image/svg+xml”" href="favicon.svg"><link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png"><link rel="icon" sizes="any" href="favicon.ico"><link rel="manifest" href="site.webmanifest"><script src="deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link href="deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet"><script src="deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="deps/Lato-0.4.10/font.css" rel="stylesheet"><link href="deps/Fira_Code-0.4.10/font.css" rel="stylesheet"><link href="deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet"><link href="deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet"><script src="deps/headroom-0.11.0/headroom.min.js"></script><script src="deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="deps/search-1.0.0/fuse.min.js"></script><script src="deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="pkgdown.js"></script><link href="extra.css" rel="stylesheet"><script src="extra.js"></script><meta property="og:title" content="CLAUDE.md — AMR R Package"><meta property="og:image" content="https://amr-for-r.org/logo.svg"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous"><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script></head><body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto"><li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to"><li><a class="dropdown-item" href="articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul></li>
<li class="nav-item"><a class="nav-link" href="articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul><ul class="navbar-nav"><li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="search.json"></form></li>
<li class="nav-item"><a class="nav-link" href="news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul></div>
</div>
</nav><div class="container template-title-body">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="logo.svg" class="logo" alt=""><h1>CLAUDE.md — AMR R Package</h1>
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/main/CLAUDE.md" class="external-link"><code>CLAUDE.md</code></a></small>
</div>
<div id="claudemd--amr-r-package" class="section level1">
<p>This file provides context for Claude Code when working in this repository.</p>
<div class="section level2">
<h2 id="project-overview">Project Overview<a class="anchor" aria-label="anchor" href="#project-overview"></a></h2>
<p><strong>AMR</strong> is a zero-dependency R package for antimicrobial resistance (AMR) data analysis using a One Health approach. It is peer-reviewed, used in 175+ countries, and supports 28 languages.</p>
<p>Key capabilities: - SIR (Susceptible/Intermediate/Resistant) classification using EUCAST 20112025 and CLSI 20112025 breakpoints - Antibiogram generation: traditional, combined, syndromic, and WISCA - Microorganism taxonomy database (~79,000 species) - Antimicrobial drug database (~620 drugs) - Multi-drug resistant organism (MDRO) classification - First-isolate identification - Minimum Inhibitory Concentration (MIC) and disk diffusion handling - Multilingual output (28 languages)</p>
</div>
<div class="section level2">
<h2 id="common-commands">Common Commands<a class="anchor" aria-label="anchor" href="#common-commands"></a></h2>
<p>All commands run inside an R session:</p>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># Rebuild documentation (roxygen2 → .Rd files + NAMESPACE)</span></span>
<span><span class="fu">devtools</span><span class="fu">::</span><span class="fu">document</span><span class="op">(</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Run all tests</span></span>
<span><span class="fu">devtools</span><span class="fu">::</span><span class="fu">test</span><span class="op">(</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Full package check (CRAN-level: docs + tests + checks)</span></span>
<span><span class="fu">devtools</span><span class="fu">::</span><span class="fu">check</span><span class="op">(</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Build pkgdown website locally</span></span>
<span><span class="fu">pkgdown</span><span class="fu">::</span><span class="fu"><a href="https://pkgdown.r-lib.org/reference/build_site.html" class="external-link">build_site</a></span><span class="op">(</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Code coverage report</span></span>
<span><span class="fu">covr</span><span class="fu">::</span><span class="fu"><a href="http://covr.r-lib.org/reference/package_coverage.html" class="external-link">package_coverage</a></span><span class="op">(</span><span class="op">)</span></span></code></pre></div>
<p>From the shell:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" tabindex="-1"></a><span class="co"># CRAN check from parent directory</span></span>
<span id="cb2-2"><a href="#cb2-2" tabindex="-1"></a><span class="ex">R</span> CMD check AMR</span></code></pre></div>
</div>
<div class="section level2">
<h2 id="repository-structure">Repository Structure<a class="anchor" aria-label="anchor" href="#repository-structure"></a></h2>
<pre><code>R/ # All R source files (62 files, ~28,000 lines)
man/ # Auto-generated .Rd documentation (do not edit manually)
tests/testthat/ # testthat test files (test-*.R) and helper-functions.R
data/ # Pre-compiled .rda datasets
data-raw/ # Scripts used to generate data/ files
vignettes/ # Rmd vignette articles
inst/ # Installed files (translations, etc.)
_pkgdown.yml # pkgdown website configuration</code></pre>
</div>
<div class="section level2">
<h2 id="r-source-file-conventions">R Source File Conventions<a class="anchor" aria-label="anchor" href="#r-source-file-conventions"></a></h2>
<p><strong>Naming conventions in <code>R/</code>:</strong></p>
<table class="table"><thead><tr><th>Prefix/Name</th>
<th>Purpose</th>
</tr></thead><tbody><tr><td><code>aa_*.R</code></td>
<td>Loaded first (helpers, globals, options, package docs)</td>
</tr><tr><td><code>zz_deprecated.R</code></td>
<td>Deprecated function wrappers</td>
</tr><tr><td><code>zzz.R</code></td>
<td>
<code>.onLoad</code> / <code>.onAttach</code> initialization</td>
</tr></tbody></table><p><strong>Key source files:</strong></p>
<ul><li>
<code>aa_helper_functions.R</code> / <code>aa_helper_pm_functions.R</code> — internal utility functions (large; ~63 KB and ~37 KB)</li>
<li>
<code>aa_globals.R</code> — global constants and breakpoint lookup structures</li>
<li>
<code>aa_options.R</code><code>amr_options()</code> / <code>get_AMR_option()</code> system</li>
<li>
<code>mo.R</code> / <code>mo_property.R</code> — microorganism lookup and properties</li>
<li>
<code>ab.R</code> / <code>ab_property.R</code> — antimicrobial drug functions</li>
<li>
<code>av.R</code> / <code>av_property.R</code> — antiviral drug functions</li>
<li>
<code>sir.R</code> / <code>sir_calc.R</code> / <code>sir_df.R</code> — SIR classification engine</li>
<li>
<code>mic.R</code> / <code>disk.R</code> — MIC and disk diffusion classes</li>
<li>
<code>antibiogram.R</code> — antibiogram generation (traditional, combined, syndromic, WISCA)</li>
<li>
<code>first_isolate.R</code> — first-isolate identification algorithms</li>
<li>
<code>mdro.R</code> — MDRO classification (EUCAST, CLSI, CDC, custom guidelines)</li>
<li>
<code>amr_selectors.R</code> — tidyselect helpers for selecting AMR columns</li>
<li>
<code>interpretive_rules.R</code> / <code>custom_eucast_rules.R</code> — clinical interpretation rules</li>
<li>
<code>translate.R</code> — 28-language translation system</li>
<li>
<code>ggplot_sir.R</code> / <code>ggplot_pca.R</code> / <code>plotting.R</code> — visualisation functions</li>
</ul></div>
<div class="section level2">
<h2 id="custom-s3-classes">Custom S3 Classes<a class="anchor" aria-label="anchor" href="#custom-s3-classes"></a></h2>
<p>The package defines five S3 classes with full print/format/plot/vctrs support:</p>
<table class="table"><thead><tr><th>Class</th>
<th>Created by</th>
<th>Represents</th>
</tr></thead><tbody><tr><td><code>&lt;mo&gt;</code></td>
<td><code><a href="reference/as.mo.html">as.mo()</a></code></td>
<td>Microorganism code</td>
</tr><tr><td><code>&lt;ab&gt;</code></td>
<td><code><a href="reference/as.ab.html">as.ab()</a></code></td>
<td>Antimicrobial drug code</td>
</tr><tr><td><code>&lt;av&gt;</code></td>
<td><code><a href="reference/as.av.html">as.av()</a></code></td>
<td>Antiviral drug code</td>
</tr><tr><td><code>&lt;sir&gt;</code></td>
<td><code><a href="reference/as.sir.html">as.sir()</a></code></td>
<td>SIR value (S/I/R/SDD)</td>
</tr><tr><td><code>&lt;mic&gt;</code></td>
<td><code><a href="reference/as.mic.html">as.mic()</a></code></td>
<td>Minimum inhibitory concentration</td>
</tr><tr><td><code>&lt;disk&gt;</code></td>
<td><code><a href="reference/as.disk.html">as.disk()</a></code></td>
<td>Disk diffusion diameter</td>
</tr></tbody></table></div>
<div class="section level2">
<h2 id="data-files">Data Files<a class="anchor" aria-label="anchor" href="#data-files"></a></h2>
<p>Pre-compiled in <code>data/</code> (do not edit directly; regenerate via <code>data-raw/</code> scripts):</p>
<table class="table"><colgroup><col width="50%"><col width="50%"></colgroup><thead><tr><th>File</th>
<th>Contents</th>
</tr></thead><tbody><tr><td><code>microorganisms.rda</code></td>
<td>~79,000 microbial species with full taxonomy</td>
</tr><tr><td><code>antimicrobials.rda</code></td>
<td>~620 antimicrobial drugs with ATC codes</td>
</tr><tr><td><code>antivirals.rda</code></td>
<td>Antiviral drugs</td>
</tr><tr><td><code>clinical_breakpoints.rda</code></td>
<td>EUCAST + CLSI breakpoints (20112025)</td>
</tr><tr><td><code>intrinsic_resistant.rda</code></td>
<td>Intrinsic resistance patterns</td>
</tr><tr><td><code>example_isolates.rda</code></td>
<td>Example AMR dataset for documentation/testing</td>
</tr><tr><td><code>WHONET.rda</code></td>
<td>Example WHONET-format dataset</td>
</tr></tbody></table></div>
<div class="section level2">
<h2 id="zero-dependency-design">Zero-Dependency Design<a class="anchor" aria-label="anchor" href="#zero-dependency-design"></a></h2>
<p>The package has <strong>no <code>Imports</code></strong> in <code>DESCRIPTION</code>. All optional integrations (ggplot2, dplyr, data.table, tidymodels, cli, crayon, etc.) are listed in <code>Suggests</code> and guarded with:</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="kw">if</span> <span class="op">(</span><span class="fu"><a href="https://rdrr.io/r/base/ns-load.html" class="external-link">requireNamespace</a></span><span class="op">(</span><span class="st">"pkg"</span>, quietly <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span><span class="op">)</span> <span class="op">{</span> <span class="va">...</span> <span class="op">}</span></span></code></pre></div>
<p>Never add packages to <code>Imports</code>. If new functionality requires an external package, add it to <code>Suggests</code> and guard usage appropriately.</p>
</div>
<div class="section level2">
<h2 id="testing">Testing<a class="anchor" aria-label="anchor" href="#testing"></a></h2>
<ul><li>
<strong>Framework:</strong> <code>testthat</code> (R ≥ 3.1); legacy <code>tinytest</code> used for R 3.03.6 CI</li>
<li>
<strong>Test files:</strong> <code>tests/testthat/test-*.R</code>
</li>
<li>
<strong>Helpers:</strong> <code>tests/testthat/helper-functions.R</code>
</li>
<li>
<strong>CI matrix:</strong> GitHub Actions across Windows / macOS / Linux × R devel / release / oldrel-1 through oldrel-4</li>
<li>
<strong>Coverage:</strong> <code>covr</code> (some files excluded: <code>atc_online.R</code>, <code>mo_source.R</code>, <code>translate.R</code>, <code>resistance_predict.R</code>, <code>zz_deprecated.R</code>, helper files, <code>zzz.R</code>)</li>
</ul></div>
<div class="section level2">
<h2 id="documentation">Documentation<a class="anchor" aria-label="anchor" href="#documentation"></a></h2>
<ul><li>All exported functions use <strong>roxygen2</strong> blocks (<code>RoxygenNote: 7.3.3</code>, markdown enabled)</li>
<li>Run <code>devtools::document()</code> after any change to roxygen comments</li>
<li>Never edit files in <code>man/</code> directly — they are auto-generated</li>
<li>Vignettes live in <code>vignettes/</code> as <code>.Rmd</code> files</li>
<li>The pkgdown website is configured in <code>_pkgdown.yml</code>
</li>
</ul></div>
<div class="section level2">
<h2 id="versioning">Versioning<a class="anchor" aria-label="anchor" href="#versioning"></a></h2>
<p>Version format: <code>major.minor.patch.dev</code> (e.g., <code>3.0.1.9021</code>)</p>
<ul><li>Development versions use a <code>.9xxx</code> suffix</li>
<li>Stable CRAN releases drop the dev suffix (e.g., <code>3.0.1</code>)</li>
<li>
<code>NEWS.md</code> uses sections <strong>New</strong>, <strong>Fixes</strong>, <strong>Updates</strong> with GitHub issue references (<code>#NNN</code>)</li>
</ul><div class="section level3">
<h3 id="version-and-date-bump-required-for-every-pr">Version and date bump required for every PR<a class="anchor" aria-label="anchor" href="#version-and-date-bump-required-for-every-pr"></a></h3>
<p>All PRs are <strong>squash-merged</strong>, so each PR lands as exactly <strong>one commit</strong> on the default branch. Version numbers are kept in sync with the cumulative commit count since the last released tag. Therefore <strong>exactly one version bump is allowed per PR</strong>, regardless of how many intermediate commits are made on the branch.</p>
<div class="section level4">
<h4 id="computing-the-correct-version-number">Computing the correct version number<a class="anchor" aria-label="anchor" href="#computing-the-correct-version-number"></a></h4>
<p><strong>First, ensure <code>git</code> and <code>gh</code> are installed</strong> — both are required for the version computation and for pushing changes. Install them if missing before doing anything else:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" tabindex="-1"></a><span class="fu">which</span> git <span class="kw">||</span> <span class="ex">apt-get</span> install <span class="at">-y</span> git</span>
<span id="cb5-2"><a href="#cb5-2" tabindex="-1"></a><span class="fu">which</span> gh <span class="kw">||</span> <span class="ex">apt-get</span> install <span class="at">-y</span> gh</span>
<span id="cb5-3"><a href="#cb5-3" tabindex="-1"></a><span class="co"># Also ensure all tags are fetched so git describe works</span></span>
<span id="cb5-4"><a href="#cb5-4" tabindex="-1"></a><span class="fu">git</span> fetch <span class="at">--tags</span></span></code></pre></div>
<p>Then run the following from the repo root to determine the version string to use:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" tabindex="-1"></a><span class="va">currenttag</span><span class="op">=</span><span class="va">$(</span><span class="fu">git</span> describe <span class="at">--tags</span> <span class="at">--abbrev</span><span class="op">=</span>0 <span class="kw">|</span> <span class="fu">sed</span> <span class="st">'s/v//'</span><span class="va">)</span></span>
<span id="cb6-2"><a href="#cb6-2" tabindex="-1"></a><span class="va">currenttagfull</span><span class="op">=</span><span class="va">$(</span><span class="fu">git</span> describe <span class="at">--tags</span> <span class="at">--abbrev</span><span class="op">=</span>0<span class="va">)</span></span>
<span id="cb6-3"><a href="#cb6-3" tabindex="-1"></a><span class="va">defaultbranch</span><span class="op">=</span><span class="va">$(</span><span class="fu">git</span> branch <span class="kw">|</span> <span class="fu">cut</span> <span class="at">-c</span> 3- <span class="kw">|</span> <span class="fu">grep</span> <span class="at">-E</span> <span class="st">'^master$|^main$'</span><span class="va">)</span></span>
<span id="cb6-4"><a href="#cb6-4" tabindex="-1"></a><span class="fu">git</span> fetch origin <span class="va">${defaultbranch}</span> <span class="at">--quiet</span></span>
<span id="cb6-5"><a href="#cb6-5" tabindex="-1"></a><span class="va">currentcommit</span><span class="op">=</span><span class="va">$(</span><span class="fu">git</span> rev-list <span class="at">--count</span> <span class="va">${currenttagfull}</span>..origin/<span class="va">${defaultbranch})</span></span>
<span id="cb6-6"><a href="#cb6-6" tabindex="-1"></a><span class="va">currentversion</span><span class="op">=</span><span class="st">"</span><span class="va">${currenttag}</span><span class="st">.</span><span class="va">$((currentcommit</span> <span class="op">+</span> <span class="dv">9001</span> <span class="op">+</span> <span class="dv">1</span><span class="va">))</span><span class="st">"</span></span>
<span id="cb6-7"><a href="#cb6-7" tabindex="-1"></a><span class="bu">echo</span> <span class="st">"</span><span class="va">$currentversion</span><span class="st">"</span></span></code></pre></div>
<p>The <code>+ 1</code> accounts for the fact that this PRs squash commit is not yet on the default branch. Set <strong>both</strong> of these files to the resulting version string (and only once per PR, even across multiple commits):</p>
<ol style="list-style-type: decimal"><li><p><strong><code>DESCRIPTION</code></strong> — the <code>Version:</code> field</p></li>
<li>
<p><strong><code>NEWS.md</code></strong><strong>only replace line 1</strong> (the <code># AMR &lt;version&gt;</code> heading) with the new version number; do <strong>not</strong> create a new section. <code>NEWS.md</code> is a <strong>continuous log</strong> for the entire current <code>x.y.z.9nnn</code> development series: all changes since the last stable release accumulate under that single heading. After updating line 1, append the new change as a bullet under the appropriate sub-heading (<code>### New</code>, <code>### Fixes</code>, or <code>### Updates</code>).</p>
<p>Style rules for <code>NEWS.md</code> entries:</p>
<ul><li>Be <strong>extremely concise</strong> — one short line per item</li>
<li>Do <strong>not</strong> end with a full stop (period)</li>
<li>No verbose explanations; just the essential fact</li>
</ul></li>
</ol><p>If <code>git describe</code> fails (e.g. no tags exist in the environment), fall back to reading the current version from <code>DESCRIPTION</code> and adding 1 to the last numeric component — but only if no bump has already been made in this PR.</p>
</div>
<div class="section level4">
<h4 id="date-field">Date field<a class="anchor" aria-label="anchor" href="#date-field"></a></h4>
<p>The <code>Date:</code> field in <code>DESCRIPTION</code> must reflect the date of the <strong>last commit to the PR</strong> (not the first), in ISO format. Update it with every commit so it is always current:</p>
<pre><code><span><span class="va">Date</span><span class="op">:</span> <span class="fl">2026</span><span class="op">-</span><span class="fl">03</span><span class="op">-</span><span class="fl">07</span></span></code></pre>
</div>
</div>
</div>
<div class="section level2">
<h2 id="internal-state">Internal State<a class="anchor" aria-label="anchor" href="#internal-state"></a></h2>
<p>The package uses a private <code>AMR_env</code> environment (created in <code>aa_globals.R</code>) for caching expensive lookups (e.g., microorganism matching scores, breakpoint tables). This avoids re-computation within a session.</p>
</div>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside></div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer></div>
</body></html>
-238
View File
@@ -1,238 +0,0 @@
# CLAUDE.md — AMR R Package
This file provides context for Claude Code when working in this
repository.
## Project Overview
**AMR** is a zero-dependency R package for antimicrobial resistance
(AMR) data analysis using a One Health approach. It is peer-reviewed,
used in 175+ countries, and supports 28 languages.
Key capabilities: - SIR (Susceptible/Intermediate/Resistant)
classification using EUCAST 20112025 and CLSI 20112025 breakpoints -
Antibiogram generation: traditional, combined, syndromic, and WISCA -
Microorganism taxonomy database (~79,000 species) - Antimicrobial drug
database (~620 drugs) - Multi-drug resistant organism (MDRO)
classification - First-isolate identification - Minimum Inhibitory
Concentration (MIC) and disk diffusion handling - Multilingual output
(28 languages)
## Common Commands
All commands run inside an R session:
``` r
# Rebuild documentation (roxygen2 → .Rd files + NAMESPACE)
devtools::document()
# Run all tests
devtools::test()
# Full package check (CRAN-level: docs + tests + checks)
devtools::check()
# Build pkgdown website locally
pkgdown::build_site()
# Code coverage report
covr::package_coverage()
```
From the shell:
``` bash
# CRAN check from parent directory
R CMD check AMR
```
## Repository Structure
R/ # All R source files (62 files, ~28,000 lines)
man/ # Auto-generated .Rd documentation (do not edit manually)
tests/testthat/ # testthat test files (test-*.R) and helper-functions.R
data/ # Pre-compiled .rda datasets
data-raw/ # Scripts used to generate data/ files
vignettes/ # Rmd vignette articles
inst/ # Installed files (translations, etc.)
_pkgdown.yml # pkgdown website configuration
## R Source File Conventions
**Naming conventions in `R/`:**
| Prefix/Name | Purpose |
|-------------------|--------------------------------------------------------|
| `aa_*.R` | Loaded first (helpers, globals, options, package docs) |
| `zz_deprecated.R` | Deprecated function wrappers |
| `zzz.R` | `.onLoad` / `.onAttach` initialization |
**Key source files:**
- `aa_helper_functions.R` / `aa_helper_pm_functions.R` — internal
utility functions (large; ~63 KB and ~37 KB)
- `aa_globals.R` — global constants and breakpoint lookup structures
- `aa_options.R` — `amr_options()` / `get_AMR_option()` system
- `mo.R` / `mo_property.R` — microorganism lookup and properties
- `ab.R` / `ab_property.R` — antimicrobial drug functions
- `av.R` / `av_property.R` — antiviral drug functions
- `sir.R` / `sir_calc.R` / `sir_df.R` — SIR classification engine
- `mic.R` / `disk.R` — MIC and disk diffusion classes
- `antibiogram.R` — antibiogram generation (traditional, combined,
syndromic, WISCA)
- `first_isolate.R` — first-isolate identification algorithms
- `mdro.R` — MDRO classification (EUCAST, CLSI, CDC, custom guidelines)
- `amr_selectors.R` — tidyselect helpers for selecting AMR columns
- `interpretive_rules.R` / `custom_eucast_rules.R` — clinical
interpretation rules
- `translate.R` — 28-language translation system
- `ggplot_sir.R` / `ggplot_pca.R` / `plotting.R` — visualisation
functions
## Custom S3 Classes
The package defines five S3 classes with full print/format/plot/vctrs
support:
| Class | Created by | Represents |
|----|----|----|
| `<mo>` | [`as.mo()`](https://amr-for-r.org/reference/as.mo.md) | Microorganism code |
| `<ab>` | [`as.ab()`](https://amr-for-r.org/reference/as.ab.md) | Antimicrobial drug code |
| `<av>` | [`as.av()`](https://amr-for-r.org/reference/as.av.md) | Antiviral drug code |
| `<sir>` | [`as.sir()`](https://amr-for-r.org/reference/as.sir.md) | SIR value (S/I/R/SDD) |
| `<mic>` | [`as.mic()`](https://amr-for-r.org/reference/as.mic.md) | Minimum inhibitory concentration |
| `<disk>` | [`as.disk()`](https://amr-for-r.org/reference/as.disk.md) | Disk diffusion diameter |
## Data Files
Pre-compiled in `data/` (do not edit directly; regenerate via
`data-raw/` scripts):
| File | Contents |
|----------------------------|-----------------------------------------------|
| `microorganisms.rda` | ~79,000 microbial species with full taxonomy |
| `antimicrobials.rda` | ~620 antimicrobial drugs with ATC codes |
| `antivirals.rda` | Antiviral drugs |
| `clinical_breakpoints.rda` | EUCAST + CLSI breakpoints (20112025) |
| `intrinsic_resistant.rda` | Intrinsic resistance patterns |
| `example_isolates.rda` | Example AMR dataset for documentation/testing |
| `WHONET.rda` | Example WHONET-format dataset |
## Zero-Dependency Design
The package has **no `Imports`** in `DESCRIPTION`. All optional
integrations (ggplot2, dplyr, data.table, tidymodels, cli, crayon, etc.)
are listed in `Suggests` and guarded with:
``` r
if (requireNamespace("pkg", quietly = TRUE)) { ... }
```
Never add packages to `Imports`. If new functionality requires an
external package, add it to `Suggests` and guard usage appropriately.
## Testing
- **Framework:** `testthat` (R ≥ 3.1); legacy `tinytest` used for R
3.03.6 CI
- **Test files:** `tests/testthat/test-*.R`
- **Helpers:** `tests/testthat/helper-functions.R`
- **CI matrix:** GitHub Actions across Windows / macOS / Linux × R devel
/ release / oldrel-1 through oldrel-4
- **Coverage:** `covr` (some files excluded: `atc_online.R`,
`mo_source.R`, `translate.R`, `resistance_predict.R`,
`zz_deprecated.R`, helper files, `zzz.R`)
## Documentation
- All exported functions use **roxygen2** blocks (`RoxygenNote: 7.3.3`,
markdown enabled)
- Run `devtools::document()` after any change to roxygen comments
- Never edit files in `man/` directly — they are auto-generated
- Vignettes live in `vignettes/` as `.Rmd` files
- The pkgdown website is configured in `_pkgdown.yml`
## Versioning
Version format: `major.minor.patch.dev` (e.g., `3.0.1.9021`)
- Development versions use a `.9xxx` suffix
- Stable CRAN releases drop the dev suffix (e.g., `3.0.1`)
- `NEWS.md` uses sections **New**, **Fixes**, **Updates** with GitHub
issue references (`#NNN`)
### Version and date bump required for every PR
All PRs are **squash-merged**, so each PR lands as exactly **one
commit** on the default branch. Version numbers are kept in sync with
the cumulative commit count since the last released tag. Therefore
**exactly one version bump is allowed per PR**, regardless of how many
intermediate commits are made on the branch.
#### Computing the correct version number
**First, ensure `git` and `gh` are installed** — both are required for
the version computation and for pushing changes. Install them if missing
before doing anything else:
``` bash
which git || apt-get install -y git
which gh || apt-get install -y gh
# Also ensure all tags are fetched so git describe works
git fetch --tags
```
Then run the following from the repo root to determine the version
string to use:
``` bash
currenttag=$(git describe --tags --abbrev=0 | sed 's/v//')
currenttagfull=$(git describe --tags --abbrev=0)
defaultbranch=$(git branch | cut -c 3- | grep -E '^master$|^main$')
git fetch origin ${defaultbranch} --quiet
currentcommit=$(git rev-list --count ${currenttagfull}..origin/${defaultbranch})
currentversion="${currenttag}.$((currentcommit + 9001 + 1))"
echo "$currentversion"
```
The `+ 1` accounts for the fact that this PRs squash commit is not yet
on the default branch. Set **both** of these files to the resulting
version string (and only once per PR, even across multiple commits):
1. **`DESCRIPTION`** — the `Version:` field
2. **`NEWS.md`** — **only replace line 1** (the `# AMR <version>`
heading) with the new version number; do **not** create a new
section. `NEWS.md` is a **continuous log** for the entire current
`x.y.z.9nnn` development series: all changes since the last stable
release accumulate under that single heading. After updating line 1,
append the new change as a bullet under the appropriate sub-heading
(`### New`, `### Fixes`, or `### Updates`).
Style rules for `NEWS.md` entries:
- Be **extremely concise** — one short line per item
- Do **not** end with a full stop (period)
- No verbose explanations; just the essential fact
If `git describe` fails (e.g. no tags exist in the environment), fall
back to reading the current version from `DESCRIPTION` and adding 1 to
the last numeric component — but only if no bump has already been made
in this PR.
#### Date field
The `Date:` field in `DESCRIPTION` must reflect the date of the **last
commit to the PR** (not the first), in ISO format. Update it with every
commit so it is always current:
Date: 2026-03-07
## Internal State
The package uses a private `AMR_env` environment (created in
`aa_globals.R`) for caching expensive lookups (e.g., microorganism
matching scores, breakpoint tables). This avoids re-computation within a
session.
-1
View File
@@ -1 +0,0 @@
amr-for-r.org
Executable
+70
View File
@@ -0,0 +1,70 @@
Package: AMR
Version: 0.3.0
Date: 2018-08-14
Title: Antimicrobial Resistance Analysis
Authors@R: c(
person(
given = c("Matthijs", "S."),
family = "Berends",
email = "m.s.berends@umcg.nl",
role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-7620-1800")),
person(
given = c("Christian", "F."),
family = "Luz",
email = "c.f.luz@umcg.nl",
role = c("aut", "rev"),
comment = c(ORCID = "0000-0001-5809-5995")),
person(
given = c("Erwin", "E.A."),
family = "Hassing",
email = "e.hassing@certe.nl",
role = "ctb"),
person(
given = "Corinna",
family = "Glasner",
email = "c.glasner@umcg.nl",
role = "ths",
comment = c(ORCID = "0000-0003-1241-1328")),
person(
given = c("Alex", "W."),
family = "Friedrich",
email = "alex.friedrich@umcg.nl",
role = "ths",
comment = c(ORCID = "0000-0003-4881-038X")),
person(
given = "Bhanu",
family = "Sinha",
email = "b.sinha@umcg.nl",
role = "ths",
comment = c(ORCID = "0000-0003-1634-0010")))
Description: Functions to simplify the analysis of Antimicrobial Resistance (AMR)
of microbial isolates, by using new S3 classes and applying EUCAST expert rules
on antibiograms according to Leclercq (2013)
<doi:10.1111/j.1469-0691.2011.03703.x>.
Depends:
R (>= 3.1.0)
Imports:
backports,
clipr,
curl,
dplyr (>= 0.7.0),
xml2 (>= 1.0.0),
knitr (>= 1.0.0),
readr,
rvest (>= 0.3.2),
tibble
Suggests:
testthat (>= 1.0.2),
covr (>= 3.0.1),
rmarkdown,
rstudioapi,
tidyr,
ggplot2
VignetteBuilder: knitr
URL: https://github.com/msberends/AMR
BugReports: https://github.com/msberends/AMR/issues
License: GPL-2 | file LICENSE
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.1.0
Executable
+339
View File
@@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{description}
Copyright (C) {year} {fullname}
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
-319
View File
@@ -1,319 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>License • AMR (for R)</title><!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="favicon-96x96.png"><link rel="icon" type="”image/svg+xml”" href="favicon.svg"><link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png"><link rel="icon" sizes="any" href="favicon.ico"><link rel="manifest" href="site.webmanifest"><script src="deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link href="deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet"><script src="deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="deps/Lato-0.4.10/font.css" rel="stylesheet"><link href="deps/Fira_Code-0.4.10/font.css" rel="stylesheet"><link href="deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet"><link href="deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet"><script src="deps/headroom-0.11.0/headroom.min.js"></script><script src="deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="deps/search-1.0.0/fuse.min.js"></script><script src="deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="pkgdown.js"></script><link href="extra.css" rel="stylesheet"><script src="extra.js"></script><meta property="og:title" content="License"><meta property="og:image" content="https://amr-for-r.org/logo.svg"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous"><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script></head><body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto"><li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to"><li><a class="dropdown-item" href="articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul></li>
<li class="nav-item"><a class="nav-link" href="articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul><ul class="navbar-nav"><li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="search.json"></form></li>
<li class="nav-item"><a class="nav-link" href="news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul></div>
</div>
</nav><div class="container template-title-body">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="logo.svg" class="logo" alt=""><h1>License</h1>
</div>
<pre>GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., &lt;http://fsf.org/&gt;
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
A SUMMARY OF THIS LICENSE BY THE ORIGINAL AUTHORS OF THE AMR R PACKAGE
This R package, with package name 'AMR':
- May be used for commercial purposes
- May be used for private purposes
- May NOT be used for patent purposes
- May be modified, although:
- Modifications MUST be released under the same license when distributing the package
- Changes made to the code MUST be documented
- May be distributed, although:
- Source code MUST be made available when the package is distributed
- A copy of the license and copyright notice MUST be included with the package.
- Comes with a LIMITATION of liability
- Comes with NO warranty
END OF THE SUMMARY
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
</pre>
</main></div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer></div>
</body></html>
-250
View File
@@ -1,250 +0,0 @@
# License
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
A SUMMARY OF THIS LICENSE BY THE ORIGINAL AUTHORS OF THE AMR R PACKAGE
This R package, with package name 'AMR':
- May be used for commercial purposes
- May be used for private purposes
- May NOT be used for patent purposes
- May be modified, although:
- Modifications MUST be released under the same license when distributing the package
- Changes made to the code MUST be documented
- May be distributed, although:
- Source code MUST be made available when the package is distributed
- A copy of the license and copyright notice MUST be included with the package.
- Comes with a LIMITATION of liability
- Comes with NO warranty
END OF THE SUMMARY
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Executable
+173
View File
@@ -0,0 +1,173 @@
# Generated by roxygen2: do not edit by hand
S3method(as.data.frame,bactid)
S3method(as.data.frame,frequency_tbl)
S3method(as.double,mic)
S3method(as.integer,mic)
S3method(as.numeric,mic)
S3method(as.vector,frequency_tbl)
S3method(as_tibble,frequency_tbl)
S3method(barplot,mic)
S3method(barplot,rsi)
S3method(format,frequency_tbl)
S3method(hist,frequency_tbl)
S3method(kurtosis,data.frame)
S3method(kurtosis,default)
S3method(kurtosis,matrix)
S3method(plot,frequency_tbl)
S3method(plot,mic)
S3method(plot,rsi)
S3method(print,bactid)
S3method(print,frequency_tbl)
S3method(print,mic)
S3method(print,rsi)
S3method(pull,bactid)
S3method(skewness,data.frame)
S3method(skewness,default)
S3method(skewness,matrix)
S3method(summary,mic)
S3method(summary,rsi)
export("%like%")
export(BRMO)
export(EUCAST_exceptional_phenotypes)
export(EUCAST_rules)
export(MDRO)
export(MRGN)
export(abname)
export(anti_join_microorganisms)
export(as.bactid)
export(as.mic)
export(as.rsi)
export(atc_ddd)
export(atc_groups)
export(atc_property)
export(clipboard_export)
export(clipboard_import)
export(facet_rsi)
export(first_isolate)
export(freq)
export(frequency_tbl)
export(full_join_microorganisms)
export(g.test)
export(geom_rsi)
export(ggplot_rsi)
export(guess_atc)
export(guess_bactid)
export(inner_join_microorganisms)
export(interpretive_reading)
export(is.bactid)
export(is.mic)
export(is.rsi)
export(key_antibiotics)
export(key_antibiotics_equal)
export(kurtosis)
export(left_join_microorganisms)
export(like)
export(mo_property)
export(n_rsi)
export(p.symbol)
export(portion_I)
export(portion_IR)
export(portion_R)
export(portion_S)
export(portion_SI)
export(portion_df)
export(ratio)
export(resistance_predict)
export(right_join_microorganisms)
export(rsi)
export(rsi_predict)
export(scale_rsi_colours)
export(scale_y_percent)
export(semi_join_microorganisms)
export(skewness)
export(theme_rsi)
export(top_freq)
exportMethods(as.data.frame.bactid)
exportMethods(as.data.frame.frequency_tbl)
exportMethods(as.double.mic)
exportMethods(as.integer.mic)
exportMethods(as.numeric.mic)
exportMethods(as.vector.frequency_tbl)
exportMethods(as_tibble.frequency_tbl)
exportMethods(barplot.mic)
exportMethods(barplot.rsi)
exportMethods(format.frequency_tbl)
exportMethods(hist.frequency_tbl)
exportMethods(kurtosis)
exportMethods(kurtosis.data.frame)
exportMethods(kurtosis.default)
exportMethods(kurtosis.matrix)
exportMethods(plot.frequency_tbl)
exportMethods(plot.mic)
exportMethods(plot.rsi)
exportMethods(print.bactid)
exportMethods(print.frequency_tbl)
exportMethods(print.mic)
exportMethods(print.rsi)
exportMethods(pull.bactid)
exportMethods(skewness)
exportMethods(skewness.data.frame)
exportMethods(skewness.default)
exportMethods(skewness.matrix)
exportMethods(summary.mic)
exportMethods(summary.rsi)
importFrom(clipr,read_clip_tbl)
importFrom(clipr,write_clip)
importFrom(curl,nslookup)
importFrom(dplyr,"%>%")
importFrom(dplyr,arrange)
importFrom(dplyr,arrange_at)
importFrom(dplyr,as_tibble)
importFrom(dplyr,between)
importFrom(dplyr,bind_rows)
importFrom(dplyr,case_when)
importFrom(dplyr,desc)
importFrom(dplyr,everything)
importFrom(dplyr,filter)
importFrom(dplyr,group_by)
importFrom(dplyr,group_by_at)
importFrom(dplyr,group_vars)
importFrom(dplyr,if_else)
importFrom(dplyr,lag)
importFrom(dplyr,left_join)
importFrom(dplyr,mutate)
importFrom(dplyr,n_distinct)
importFrom(dplyr,progress_estimated)
importFrom(dplyr,pull)
importFrom(dplyr,row_number)
importFrom(dplyr,select)
importFrom(dplyr,slice)
importFrom(dplyr,summarise)
importFrom(dplyr,summarise_if)
importFrom(dplyr,tibble)
importFrom(dplyr,top_n)
importFrom(grDevices,boxplot.stats)
importFrom(graphics,axis)
importFrom(graphics,barplot)
importFrom(graphics,hist)
importFrom(graphics,plot)
importFrom(graphics,text)
importFrom(knitr,kable)
importFrom(readr,locale)
importFrom(readr,parse_guess)
importFrom(rvest,html_children)
importFrom(rvest,html_node)
importFrom(rvest,html_nodes)
importFrom(rvest,html_table)
importFrom(stats,complete.cases)
importFrom(stats,fivenum)
importFrom(stats,glm)
importFrom(stats,lm)
importFrom(stats,mad)
importFrom(stats,pchisq)
importFrom(stats,predict)
importFrom(stats,sd)
importFrom(tibble,tibble)
importFrom(utils,View)
importFrom(utils,browseVignettes)
importFrom(utils,installed.packages)
importFrom(utils,object.size)
importFrom(utils,read.delim)
importFrom(utils,write.table)
importFrom(xml2,read_html)
Executable
+121
View File
@@ -0,0 +1,121 @@
# 0.3.0
**Published on CRAN: 2018-08-14**
#### New
* **BREAKING**: `rsi_df` was removed in favour of new functions `portion_R`, `portion_IR`, `portion_I`, `portion_SI` and `portion_S` to selectively calculate resistance or susceptibility. These functions are 20 to 30 times faster than the old `rsi` function. The old function still works, but is deprecated.
* New function `portion_df` to get all portions of S, I and R of a data set with antibiotic columns, with support for grouped variables
* **BREAKING**: the methodology for determining first weighted isolates was changed. The antibiotics that are compared between isolates (call *key antibiotics*) to include more first isolates (afterwards called first *weighted* isolates) are now as follows:
* Universal: amoxicillin, amoxicillin/clavlanic acid, cefuroxime, piperacillin/tazobactam, ciprofloxacin, trimethoprim/sulfamethoxazole
* Gram-positive: vancomycin, teicoplanin, tetracycline, erythromycin, oxacillin, rifampicin
* Gram-negative: gentamicin, tobramycin, colistin, cefotaxime, ceftazidime, meropenem
* Support for `ggplot2`
* New functions `geom_rsi`, `facet_rsi`, `scale_y_percent`, `scale_rsi_colours` and `theme_rsi`
* New wrapper function `ggplot_rsi` to apply all above functions on a data set:
* `septic_patients %>% select(tobr, gent) %>% ggplot_rsi` will show portions of S, I and R immediately in a pretty plot
* Support for grouped variables, see `?ggplot_rsi`
* Determining bacterial ID:
* New functions `as.bactid` and `is.bactid` to transform/ look up microbial ID's.
* The existing function `guess_bactid` is now an alias of `as.bactid`
* New Becker classification for *Staphylococcus* to categorise them into Coagulase Negative *Staphylococci* (CoNS) and Coagulase Positve *Staphylococci* (CoPS)
* New Lancefield classification for *Streptococcus* to categorise them into Lancefield groups
* For convience, new descriptive statistical functions `kurtosis` and `skewness` that are lacking in base R - they are generic functions and have support for vectors, data.frames and matrices
* Function `g.test` to perform the Χ<sup>2</sup> distributed [*G*-test](https://en.wikipedia.org/wiki/G-test), which use is the same as `chisq.test`
* Function `ratio` to transform a vector of values to a preset ratio
* For example: `ratio(c(10, 500, 10), ratio = "1:2:1")` would return `130, 260, 130`
* Support for Addins menu in RStudio to quickly insert `%in%` or `%like%` (and give them keyboard shortcuts), or to view the datasets that come with this package
* Function `p.symbol` to transform p values to their related symbols: `0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1`
* Functions `clipboard_import` and `clipboard_export` as helper functions to quickly copy and paste from/to software like Excel and SPSS. These functions use the `clipr` package, but are a little altered to also support headless Linux servers (so you can use it in RStudio Server)
* New for frequency tables (function `freq`):
* A vignette to explain its usage
* Support for `rsi` (antimicrobial resistance) to use as input
* Support for `table` to use as input: `freq(table(x, y))`
* Support for existing functions `hist` and `plot` to use a frequency table as input: `hist(freq(df$age))`
* Support for `as.vector`, `as.data.frame`, `as_tibble` and `format`
* Support for quasiquotation: `freq(mydata, mycolumn)` is the same as `mydata %>% freq(mycolumn)`
* Function `top_freq` function to return the top/below *n* items as vector
* Header of frequency tables now also show Mean Absolute Deviaton (MAD) and Interquartile Range (IQR)
* Possibility to globally set the default for the amount of items to print, with `options(max.print.freq = n)` where *n* is your preset value
#### Changed
* Improvements for forecasting with `resistance_predict` and added more examples
* More antibiotics added as parameters for EUCAST rules
* Updated version of the `septic_patients` data set to better reflect the reality
* Pretty printing for tibbles removed as it is not really the scope of this package
* Printing of `mic` and `rsi` classes now returns all values - use `freq` to check distributions
* Improved speed of key antibiotics comparison for determining first isolates
* Column names for the `key_antibiotics` function are now generic: 6 for broadspectrum ABs, 6 for Gram-positive specific and 6 for Gram-negative specific ABs
* Speed improvement for the `abname` function
* `%like%` now supports multiple patterns
* Frequency tables are now actual `data.frame`s with altered console printing to make it look like a frequency table. Because of this, the parameter `toConsole` is not longer needed.
* Fix for `freq` where the class of an item would be lost
* Small translational improvements to the `septic_patients` dataset and the column `bactid` now has the new class `"bactid"`
* Small improvements to the `microorganisms` dataset (especially for *Salmonella*) and the column `bactid` now has the new class `"bactid"`
* Combined MIC/RSI values will now be coerced by the `rsi` and `mic` functions:
* `as.rsi("<=0.002; S")` will return `S`
* `as.mic("<=0.002; S")` will return `<=0.002`
* Now possible to coerce MIC values with a space between operator and value, i.e. `as.mic("<= 0.002")` now works
* Classes `rsi` and `mic` do not add the attribute `package.version` anymore
* Added `"groups"` option for `atc_property(..., property)`. It will return a vector of the ATC hierarchy as defined by the [WHO](https://www.whocc.no/atc/structure_and_principles/). The new function `atc_groups` is a convenient wrapper around this.
* Build-in host check for `atc_property` as it requires the host set by `url` to be responsive
* Improved `first_isolate` algorithm to exclude isolates where bacteria ID or genus is unavailable
* Fix for warning *hybrid evaluation forced for row_number* ([`924b62`](https://github.com/tidyverse/dplyr/commit/924b62)) from the `dplyr` package v0.7.5 and above
* Support for empty values and for 1 or 2 columns as input for `guess_bactid` (now called `as.bactid`)
* So `yourdata %>% select(genus, species) %>% as.bactid()` now also works
* Other small fixes
#### Other
* Added integration tests (check if everything works as expected) for all releases of R 3.1 and higher
* Linux and macOS: https://travis-ci.org/msberends/AMR
* Windows: https://ci.appveyor.com/project/msberends/amr
* Added thesis advisors to DESCRIPTION file
# 0.2.0
**Published on CRAN: 2018-05-03**
#### New
* Full support for Windows, Linux and macOS
* Full support for old R versions, only R-3.0.0 (April 2013) or later is needed (needed packages may have other dependencies)
* Function `n_rsi` to count cases where antibiotic test results were available, to be used in conjunction with `dplyr::summarise`, see ?rsi
* Function `guess_bactid` to **determine the ID** of a microorganism based on genus/species or known abbreviations like MRSA
* Function `guess_atc` to **determine the ATC** of an antibiotic based on name, trade name, or known abbreviations
* Function `freq` to create **frequency tables**, with additional info in a header
* Function `MDRO` to **determine Multi Drug Resistant Organisms (MDRO)** with support for country-specific guidelines.
* Suggest your own via [https://github.com/msberends/AMR/issues/new](https://github.com/msberends/AMR/issues/new?title=New%20guideline%20for%20MDRO&body=%3C--%20Please%20add%20your%20country%20code,%20guideline%20name,%20version%20and%20source%20below%20and%20remove%20this%20line--%3E)
* [Exceptional resistances defined by EUCAST](http://www.eucast.org/expert_rules_and_intrinsic_resistance) are also supported instead of countries alone
* Functions `BRMO` and `MRGN` are wrappers for Dutch and German guidelines, respectively
* New algorithm to determine weighted isolates, can now be `"points"` or `"keyantibiotics"`, see `?first_isolate`
* New print format for `tibble`s and `data.table`s
#### Changed
* Fixed `rsi` class for vectors that contain only invalid antimicrobial interpretations
* Renamed dataset `ablist` to `antibiotics`
* Renamed dataset `bactlist` to `microorganisms`
* Added common abbreviations and trade names to the `antibiotics` dataset
* Added more microorganisms to the `microorganisms` dataset
* Added analysis examples on help page of dataset `septic_patients`
* Added support for character vector in `join` functions
* Added warnings when a join results in more rows after than before the join
* Altered `%like%` to make it case insensitive
* For parameters of functions `first_isolate` and `EUCAST_rules` column names are now case-insensitive
* Functions `as.rsi` and `as.mic` now add the package name and version as attributes
#### Other
* Expanded `README.md` with more examples
* Added [ORCID](https://orcid.org) of authors to DESCRIPTION file
* Added unit testing with the `testthat` package
* Added build tests for Linux and macOS using Travis CI (https://travis-ci.org/msberends/AMR)
* Added line coverage checking using CodeCov (https://codecov.io/gh/msberends/AMR/tree/master/R)
# 0.1.1
**Published on CRAN: 2018-03-14**
* `EUCAST_rules` applies for amoxicillin even if ampicillin is missing
* Edited column names to comply with GLIMS, the laboratory information system
* Added more valid MIC values
* Renamed 'Daily Defined Dose' to 'Defined Daily Dose'
* Added barplots for `rsi` and `mic` classes
# 0.1.0
**Published on CRAN: 2018-02-22**
* First submission to CRAN.
+163
View File
@@ -0,0 +1,163 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Name of an antibiotic
#'
#' Convert antibiotic codes (from a laboratory information system like MOLIS or GLIMS) to a (trivial) antibiotic name or ATC code, or vice versa. This uses the data from \code{\link{antibiotics}}.
#' @param abcode a code or name, like \code{"AMOX"}, \code{"AMCL"} or \code{"J01CA04"}
#' @param from,to type to transform from and to. See \code{\link{antibiotics}} for its column names. WIth \code{from = "guess"} the from will be guessed from \code{"atc"}, \code{"molis"} and \code{"umcg"}. When using \code{to = "atc"}, the ATC code will be searched using \code{\link{guess_atc}}.
#' @param textbetween text to put between multiple returned texts
#' @param tolower return output as lower case with function \code{\link{tolower}}.
#' @keywords ab antibiotics
#' @source \code{\link{antibiotics}}
#' @export
#' @importFrom dplyr %>% pull
#' @examples
#' abname("AMCL")
#' # "amoxicillin and enzyme inhibitor"
#'
#' # It is quite flexible at default (having `from = "guess"`)
#' abname(c("amox", "J01CA04", "Trimox", "dispermox", "Amoxil"))
#' # "Amoxicillin" "Amoxicillin" "Amoxicillin" "Amoxicillin" "Amoxicillin"
#'
#' # Multiple antibiotics can be combined with "+".
#' # The second antibiotic will be set to lower case when `tolower` was not set:
#' abname("AMCL+GENT", textbetween = "/")
#' # "amoxicillin and enzyme inhibitor/gentamicin"
#'
#' abname(c("AMCL", "GENT"))
#' # "Amoxicillin and beta-lactamase inhibitor" "Gentamicin"
#'
#' abname("AMCL", to = "trivial_nl")
#' # "Amoxicilline/clavulaanzuur"
#'
#' abname("AMCL", to = "atc")
#' # "J01CR02"
#'
#' # specific codes for University Medical Center Groningen (UMCG):
#' abname("J01CR02", from = "atc", to = "umcg")
#' # "AMCL"
abname <- function(abcode,
from = c("guess", "atc", "molis", "umcg"),
to = 'official',
textbetween = ' + ',
tolower = FALSE) {
if (length(to) != 1L) {
stop('`to` must be of length 1', call. = FALSE)
}
if (to == "atc") {
return(guess_atc(abcode))
}
#antibiotics <- AMR::antibiotics
abx <- AMR::antibiotics
from <- from[1]
# if (from == "guess") {
# for (i in 1:3) {
# if (abcode[1] %in% (antibiotics %>% pull(i))) {
# from <- colnames(antibiotics)[i]
# }
# }
# if (from == "guess") {
# from <- "umcg"
# }
# }
colnames(abx) <- colnames(abx) %>% tolower()
from <- from %>% tolower()
to <- to %>% tolower()
if (!(from %in% colnames(abx) | from == "guess") |
!to %in% colnames(abx)) {
stop(paste0('Invalid `from` or `to`. Choose one of ',
colnames(abx) %>% paste(collapse = ", "), '.'), call. = FALSE)
}
abcode <- as.character(abcode)
abcode.bak <- abcode
for (i in 1:length(abcode)) {
if (abcode[i] %like% "[+]") {
# support for multiple ab's with +
parts <- trimws(strsplit(abcode[i], split = "+", fixed = TRUE)[[1]])
ab1 <- abname(parts[1], from = from, to = to)
ab2 <- abname(parts[2], from = from, to = to)
if (missing(tolower)) {
ab2 <- tolower(ab2)
}
abcode[i] <- paste0(ab1, textbetween, ab2)
next
}
if (from %in% c("atc", "guess")) {
if (abcode[i] %in% abx$atc) {
abcode[i] <- abx[which(abx$atc == abcode[i]),] %>% pull(to)
next
}
}
if (from %in% c("molis", "guess")) {
if (abcode[i] %in% abx$molis) {
abcode[i] <- abx[which(abx$molis == abcode[i]),] %>% pull(to)
next
}
}
if (from %in% c("umcg", "guess")) {
if (abcode[i] %in% abx$umcg) {
abcode[i] <- abx[which(abx$umcg == abcode[i]),] %>% pull(to)
next
}
}
if (from %in% c("trade_name", "guess")) {
if (abcode[i] %in% abx$trade_name) {
abcode[i] <- abx[which(abx$trade_name == abcode[i]),] %>% pull(to)
next
}
if (sum(abx$trade_name %like% abcode[i]) > 0) {
abcode[i] <- abx[which(abx$trade_name %like% abcode[i]),] %>% pull(to)
next
}
}
if (from != "guess") {
# when not found, try any `from`
abcode[i] <- abx[which(abx[,from] == abcode[i]),] %>% pull(to) %>% .[1]
}
# when nothing found, try first chars of official name
# if (is.na(abcode[i])) {
# abcode[i] <- antibiotics %>%
# filter(official %like% paste0('^', abcode.bak[i])) %>%
# pull(to) %>%
# .[1]
# next
# }
if (is.na(abcode[i]) | length(abcode[i] == 0)) {
abcode[i] <- abcode.bak[i]
warning('Code "', abcode.bak[i], '" not found in antibiotics list.', call. = FALSE)
}
}
if (tolower == TRUE) {
abcode <- abcode %>% tolower()
}
abcode
}
Executable
+289
View File
@@ -0,0 +1,289 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Properties of an ATC code
#'
#' Gets data from the WHO to determine properties of an ATC (e.g. an antibiotic) like name, defined daily dose (DDD) or standard unit. \cr \strong{This function requires an internet connection.}
#' @param atc_code a character or character vector with ATC code(s) of antibiotic(s)
#' @param property property of an ATC code. Valid values are \code{"ATC"}, \code{"Name"}, \code{"DDD"}, \code{"U"} (\code{"unit"}), \code{"Adm.R"}, \code{"Note"} and \code{groups}. For this last option, all hierarchical groups of an ATC code will be returned, see Examples.
#' @param administration type of administration when using \code{property = "Adm.R"}, see Details
#' @param url url of website of the WHO. The sign \code{\%s} can be used as a placeholder for ATC codes.
#' @param ... parameters to pass on to \code{atc_property}
#' @details
#' Options for parameter \code{administration}:
#' \itemize{
#' \item{\code{"Implant"}}{ = Implant}
#' \item{\code{"Inhal"}}{ = Inhalation}
#' \item{\code{"Instill"}}{ = Instillation}
#' \item{\code{"N"}}{ = nasal}
#' \item{\code{"O"}}{ = oral}
#' \item{\code{"P"}}{ = parenteral}
#' \item{\code{"R"}}{ = rectal}
#' \item{\code{"SL"}}{ = sublingual/buccal}
#' \item{\code{"TD"}}{ = transdermal}
#' \item{\code{"V"}}{ = vaginal}
#' }
#'
#' Abbreviations of return values when using \code{property = "U"} (unit):
#' \itemize{
#' \item{\code{"g"}}{ = gram}
#' \item{\code{"mg"}}{ = milligram}
#' \item{\code{"mcg"}}{ = microgram}
#' \item{\code{"U"}}{ = unit}
#' \item{\code{"TU"}}{ = thousand units}
#' \item{\code{"MU"}}{ = million units}
#' \item{\code{"mmol"}}{ = millimole}
#' \item{\code{"ml"}}{ = milliliter (e.g. eyedrops)}
#' }
#' @export
#' @rdname atc_property
#' @importFrom dplyr %>% progress_estimated
#' @importFrom xml2 read_html
#' @importFrom rvest html_children html_node html_nodes html_table
#' @importFrom curl nslookup
#' @source \url{https://www.whocc.no/atc_ddd_alterations__cumulative/ddd_alterations/abbrevations/}
#' @examples
#' \donttest{
#' # What's the ATC of amoxicillin?
#' guess_atc("Amoxicillin")
#' # [1] "J01CA04"
#'
#' # oral DDD (Defined Daily Dose) of amoxicillin
#' atc_property("J01CA04", "DDD", "O")
#' # parenteral DDD (Defined Daily Dose) of amoxicillin
#' atc_property("J01CA04", "DDD", "P")
#'
#' atc_property("J01CA04", property = "groups") # search hierarchical groups of amoxicillin
#' # [1] "ANTIINFECTIVES FOR SYSTEMIC USE"
#' # [2] "ANTIBACTERIALS FOR SYSTEMIC USE"
#' # [3] "BETA-LACTAM ANTIBACTERIALS, PENICILLINS"
#' # [4] "Penicillins with extended spectrum"
#' }
atc_property <- function(atc_code,
property,
administration = 'O',
url = 'https://www.whocc.no/atc_ddd_index/?code=%s&showdescription=no') {
# check active network interface, from https://stackoverflow.com/a/5078002/4575331
has_internet <- function(url) {
# extract host from given url
# https://www.whocc.no/atc_ddd_index/ -> www.whocc.no
url <- url %>%
gsub("^(http://|https://)", "", .) %>%
strsplit('/', fixed = TRUE) %>%
unlist() %>%
.[1]
!is.null(curl::nslookup(url, error = FALSE))
}
# check for connection using the ATC of amoxicillin
if (!has_internet(url = url)) {
message("The URL could not be reached.")
return(rep(NA, length(atc_code)))
}
if (length(property) != 1L) {
stop('`property` must be of length 1', call. = FALSE)
}
if (length(administration) != 1L) {
stop('`administration` must be of length 1', call. = FALSE)
}
# also allow unit as property
if (property %like% 'unit') {
property <- 'U'
}
# validation of properties
valid_properties <- c("ATC", "Name", "DDD", "U", "Adm.R", "Note", "groups")
valid_properties.bak <- valid_properties
property <- tolower(property)
valid_properties <- tolower(valid_properties)
if (!property %in% valid_properties) {
stop('Invalid `property`, use one of ', paste(valid_properties.bak, collapse = ", "), '.')
}
if (property == 'ddd') {
returnvalue <- rep(NA_real_, length(atc_code))
} else if (property == 'groups') {
returnvalue <- list()
} else {
returnvalue <- rep(NA_character_, length(atc_code))
}
progress <- progress_estimated(n = length(atc_code))
for (i in 1:length(atc_code)) {
progress$tick()$print()
atc_url <- sub('%s', atc_code[i], url, fixed = TRUE)
if (property == "groups") {
tbl <- xml2::read_html(atc_url) %>%
rvest::html_node("#content") %>%
rvest::html_children() %>%
rvest::html_node("a")
# get URLS of items
hrefs <- tbl %>% rvest::html_attr("href")
# get text of items
texts <- tbl %>% rvest::html_text()
# select only text items where URL like "code="
texts <- texts[grepl("?code=", tolower(hrefs), fixed = TRUE)]
# last one is antibiotics, skip it
texts <- texts[1:length(texts) - 1]
returnvalue <- c(list(texts), returnvalue)
} else {
tbl <- xml2::read_html(atc_url) %>%
rvest::html_nodes('table') %>%
rvest::html_table(header = TRUE) %>%
as.data.frame(stringsAsFactors = FALSE)
# case insensitive column names
colnames(tbl) <- tolower(colnames(tbl)) %>% gsub('^atc.*', 'atc', .)
if (length(tbl) == 0) {
warning('ATC not found: ', atc_code[i], '. Please check ', atc_url, '.', call. = FALSE)
returnvalue[i] <- NA
next
}
if (property %in% c('atc', 'name')) {
# ATC and name are only in first row
returnvalue[i] <- tbl[1, property]
} else {
if (!'adm.r' %in% colnames(tbl) | is.na(tbl[1, 'adm.r'])) {
returnvalue[i] <- NA
next
} else {
for (j in 1:nrow(tbl)) {
if (tbl[j, 'adm.r'] == administration) {
returnvalue[i] <- tbl[j, property]
}
}
}
}
}
}
if (property == "groups" & length(returnvalue) == 1) {
returnvalue <- returnvalue[[1]]
}
returnvalue
}
#' @rdname atc_property
#' @export
atc_groups <- function(atc_code, ...) {
atc_property(atc_code = atc_code, property = "groups", ...)
}
#' @rdname atc_property
#' @export
atc_ddd <- function(atc_code, ...) {
atc_property(atc_code = atc_code, property = "ddd", ...)
}
#' Find ATC code based on antibiotic property
#'
#' Use this function to determine the ATC code of one or more antibiotics. The dataset \code{\link{antibiotics}} will be searched for abbreviations, official names and trade names.
#' @param x character vector to determine \code{ATC} code
#' @export
#' @importFrom dplyr %>% filter slice pull
#' @details In the ATC classification system, the active substances are classified in a hierarchy with five different levels. The system has fourteen main anatomical/pharmacological groups or 1st levels. Each ATC main group is divided into 2nd levels which could be either pharmacological or therapeutic groups. The 3rd and 4th levels are chemical, pharmacological or therapeutic subgroups and the 5th level is the chemical substance. The 2nd, 3rd and 4th levels are often used to identify pharmacological subgroups when that is considered more appropriate than therapeutic or chemical subgroups.
#' Source: \url{https://www.whocc.no/atc/structure_and_principles/}
#' @return Character (vector).
#' @seealso \code{\link{antibiotics}} for the dataframe that is being used to determine ATC's.
#' @examples
#' # These examples all return "J01FA01", the ATC code of Erythromycin:
#' guess_atc("J01FA01")
#' guess_atc("Erythromycin")
#' guess_atc("eryt")
#' guess_atc("ERYT")
#' guess_atc("ERY")
#' guess_atc("Erythrocin") # Trade name
#' guess_atc("Eryzole") # Trade name
#' guess_atc("Pediamycin") # Trade name
guess_atc <- function(x) {
# use this later to further fill AMR::antibiotics
# drug <- "Ciprofloxacin"
# url <- xml2::read_html(paste0("https://www.ncbi.nlm.nih.gov/pccompound?term=", drug)) %>%
# html_nodes(".rslt") %>%
# .[[1]] %>%
# html_nodes(".title a") %>%
# html_attr("href") %>%
# gsub("/compound/", "/rest/pug_view/data/compound/", ., fixed = TRUE) %>%
# paste0("/XML/?response_type=display")
# synonyms <- url %>%
# read_xml() %>%
# xml_contents() %>% .[[6]] %>%
# xml_contents() %>% .[[8]] %>%
# xml_contents() %>% .[[3]] %>%
# xml_contents() %>% .[[3]] %>%
# xml_contents() %>%
# paste() %>%
# .[. %like% "StringValueList"] %>%
# gsub("[</]+StringValueList[>]", "", .)
for (i in 1:length(x)) {
# first try atc
found <- AMR::antibiotics %>% filter(atc == x[i])
if (nrow(found) == 0) {
# try abbreviation of molis and glims
found <- AMR::antibiotics %>% filter(tolower(molis) == tolower(x[i]) | tolower(umcg) == tolower(x[i]))
}
if (nrow(found) == 0) {
# try exact official name
found <- AMR::antibiotics[which(tolower(AMR::antibiotics$official) == tolower(x[i])),]
}
if (nrow(found) == 0) {
# try trade name
found <- AMR::antibiotics[which(paste0("(", AMR::antibiotics$trade_name, ")") %like% x[i]),]
}
if (nrow(found) == 0) {
# try abbreviation
found <- AMR::antibiotics[which(paste0("(", AMR::antibiotics$abbr, ")") %like% x[i]),]
}
# if (nrow(found) == 0) {
# # loosely try official name
# found <- AMR::antibiotics[which(AMR::antibiotics$official %like% x[i]),]
# }
if (nrow(found) != 0) {
x[i] <- found %>%
slice(1) %>%
pull(atc)
} else {
x[i] <- NA
}
}
x
}
+396
View File
@@ -0,0 +1,396 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Transform to bacteria ID
#'
#' Use this function to determine a valid ID based on a genus (and species). This input can be a full name (like \code{"Staphylococcus aureus"}), an abbreviated name (like \code{"S. aureus"}), or just a genus. You could also \code{\link{select}} a genus and species column, zie Examples.
#' @param x a character vector or a dataframe with one or two columns
#' @param Becker a logical to indicate whether \emph{Staphylococci} should be categorised into Coagulase Negative \emph{Staphylococci} ("CoNS") and Coagulase Positive \emph{Staphylococci} ("CoPS") instead of their own species, according to Karsten Becker \emph{et al.} [1]. This excludes \emph{Staphylococcus aureus} at default, use \code{Becker = "all"} to also categorise \emph{S. aureus} as "CoPS".
#' @param Lancefield a logical to indicate whether beta-haemolytic \emph{Streptococci} should be categorised into Lancefield groups instead of their own species, according to Rebecca C. Lancefield [2]. These \emph{Streptococci} will be categorised in their first group, i.e. \emph{Streptococcus dysgalactiae} will be group C, although officially it was also categorised into groups G and L. Groups D and E will be ignored, since they are \emph{Enterococci}.
#' @rdname as.bactid
#' @keywords bactid Becker becker Lancefield lancefield guess
#' @details \code{guess_bactid} is an alias of \code{as.bactid}.
#'
#' Some exceptions have been built in to get more logical results, based on prevalence of human pathogens. These are:
#' \itemize{
#' \item{\code{"E. coli"} will return the ID of \emph{Escherichia coli} and not \emph{Entamoeba coli}, although the latter would alphabetically come first}
#' \item{\code{"H. influenzae"} will return the ID of \emph{Haemophilus influenzae} and not \emph{Haematobacter influenzae}}
#' \item{Something like \code{"p aer"} will return the ID of \emph{Pseudomonas aeruginosa} and not \emph{Pasteurella aerogenes}}
#' \item{Something like \code{"stau"} or \code{"staaur"} will return the ID of \emph{Staphylococcus aureus} and not \emph{Staphylococcus auricularis}}
#' }
#' Moreover, this function also supports ID's based on only Gram stain, when the species is not known. \cr
#' For example, \code{"Gram negative rods"} and \code{"GNR"} will both return the ID of a Gram negative rod: \code{GNR}.
#' @source
#' [1] Becker K \emph{et al.} \strong{Coagulase-Negative Staphylococci}. 2014. Clin Microbiol Rev. 27(4): 870926. \cr
#' \url{https://dx.doi.org/10.1128/CMR.00109-13} \cr
#' [2] Lancefield RC \strong{A serological differentiation of human and other groups of hemolytic streptococci}. 1933. J Exp Med. 57(4): 57195. \cr
#' \url{https://dx.doi.org/10.1084/jem.57.4.571}
#' @export
#' @importFrom dplyr %>% filter pull
#' @return Character (vector) with class \code{"bactid"}. Unknown values will return \code{NA}.
#' @seealso \code{\link{microorganisms}} for the dataframe that is being used to determine ID's.
#' @examples
#' # These examples all return "STAAUR", the ID of S. aureus:
#' as.bactid("stau")
#' as.bactid("STAU")
#' as.bactid("staaur")
#' as.bactid("S. aureus")
#' as.bactid("S aureus")
#' as.bactid("Staphylococcus aureus")
#' as.bactid("MRSA") # Methicillin Resistant S. aureus
#' as.bactid("VISA") # Vancomycin Intermediate S. aureus
#' as.bactid("VRSA") # Vancomycin Resistant S. aureus
#'
#' guess_bactid("S. epidermidis") # will remain species: STAEPI
#' guess_bactid("S. epidermidis", Becker = TRUE) # will not remain species: STACNS
#'
#' guess_bactid("S. pyogenes") # will remain species: STCAGA
#' guess_bactid("S. pyogenes", Lancefield = TRUE) # will not remain species: STCGRA
#'
#' \dontrun{
#' df$bactid <- as.bactid(df$microorganism_name)
#'
#' # the select function of tidyverse is also supported:
#' library(dplyr)
#' df$bactid <- df %>%
#' select(microorganism_name) %>%
#' guess_bactid()
#'
#' # and can even contain 2 columns, which is convenient for genus/species combinations:
#' df$bactid <- df %>%
#' select(genus, species) %>%
#' guess_bactid()
#'
#' # same result:
#' df <- df %>%
#' mutate(bactid = guess_bactid(paste(genus, species)))
#' }
as.bactid <- function(x, Becker = FALSE, Lancefield = FALSE) {
failures <- character(0)
if (NCOL(x) == 2) {
# support tidyverse selection like: df %>% select(colA, colB)
# paste these columns together
x_vector <- vector("character", NROW(x))
for (i in 1:NROW(x)) {
x_vector[i] <- paste(pull(x[i,], 1), pull(x[i,], 2), sep = " ")
}
x <- x_vector
} else {
if (NCOL(x) > 2) {
stop('`x` can be 2 columns at most', call. = FALSE)
}
# support tidyverse selection like: df %>% select(colA)
if (!is.vector(x)) {
x <- pull(x, 1)
}
}
x.fullbackup <- x
# remove dots and other non-text in case of "E. coli" except spaces
x <- gsub("[^a-zA-Z0-9 ]+", "", x)
# but spaces before and after should be omitted
x <- trimws(x, which = "both")
x.backup <- x
# replace space by regex sign
x_withspaces <- gsub(" ", ".* ", x, fixed = TRUE)
x <- gsub(" ", ".*", x, fixed = TRUE)
# for species
x_species <- paste(x, 'species')
# add start en stop regex
x <- paste0('^', x, '$')
x_withspaces <- paste0('^', x_withspaces, '$')
for (i in 1:length(x)) {
if (Becker == TRUE | Becker == "all") {
mo <- suppressWarnings(guess_bactid(x.fullbackup[i]))
if (mo %like% '^STA') {
# See Source. It's this figure:
# https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4187637/figure/F3/
species <- left_join_microorganisms(mo)$species
if (species %in% c("arlettae", "auricularis", "capitis",
"caprae", "carnosus", "cohnii", "condimenti",
"devriesei", "epidermidis", "equorum",
"fleurettii", "gallinarum", "haemolyticus",
"hominis", "jettensis", "kloosii", "lentus",
"lugdunensis", "massiliensis", "microti",
"muscae", "nepalensis", "pasteuri", "petrasii",
"pettenkoferi", "piscifermentans", "rostri",
"saccharolyticus", "saprophyticus", "sciuri",
"stepanovicii", "simulans", "succinus",
"vitulinus", "warneri", "xylosus")) {
x[i] <- "STACNS"
next
} else if ((Becker == "all" & species == "aureus")
| species %in% c("simiae", "agnetis", "chromogenes",
"delphini", "felis", "lutrae",
"hyicus", "intermedius",
"pseudintermedius", "pseudointermedius",
"schleiferi")) {
x[i] <- "STACPS"
next
}
}
}
if (Lancefield == TRUE) {
mo <- suppressWarnings(guess_bactid(x.fullbackup[i]))
if (mo %like% '^STC') {
# See Source
species <- left_join_microorganisms(mo)$species
if (species == "pyogenes") {
x[i] <- "STCGRA"
next
}
if (species == "agalactiae") {
x[i] <- "STCGRB"
next
}
if (species %in% c("equisimilis", "equi",
"zooepidemicus", "dysgalactiae")) {
x[i] <- "STCGRC"
next
}
if (species == "anginosus") {
x[i] <- "STCGRF"
next
}
if (species == "sanguis") {
x[i] <- "STCGRH"
next
}
if (species == "salivarius") {
x[i] <- "STCGRK"
next
}
}
}
if (identical(x.backup[i], "")) {
# empty values
x[i] <- NA
failures <- c(failures, x.fullbackup[i])
next
}
if (x.fullbackup[i] %in% AMR::microorganisms$bactid) {
# is already a valid bactid
x[i] <- x.fullbackup[i]
next
}
if (x.backup[i] %in% AMR::microorganisms$bactid) {
# is already a valid bactid
x[i] <- x.backup[i]
next
}
if (tolower(x[i]) == '^e.*coli$') {
# avoid detection of Entamoeba coli in case of E. coli
x[i] <- 'ESCCOL'
next
}
if (tolower(x[i]) == '^h.*influenzae$') {
# avoid detection of Haematobacter influenzae in case of H. influenzae
x[i] <- 'HAEINF'
next
}
if (tolower(x[i]) == '^st.*au$'
| tolower(x[i]) == '^stau$'
| tolower(x[i]) == '^staaur$') {
# avoid detection of Staphylococcus auricularis in case of S. aureus
x[i] <- 'STAAUR'
next
}
if (tolower(x[i]) == '^p.*aer$') {
# avoid detection of Pasteurella aerogenes in case of Pseudomonas aeruginosa
x[i] <- 'PSEAER'
next
}
if (tolower(x[i]) %like% 'coagulase negative'
| tolower(x[i]) %like% 'cns'
| tolower(x[i]) %like% 'cons') {
# coerce S. coagulase negative, also as CNS and CoNS
x[i] <- 'STACNS'
next
}
# translate known trivial names to genus+species
if (!is.na(x.backup[i])) {
if (toupper(x.backup[i]) == 'MRSA'
| toupper(x.backup[i]) == 'VISA'
| toupper(x.backup[i]) == 'VRSA') {
x[i] <- 'STAAUR'
next
}
if (toupper(x.backup[i]) == 'MRSE') {
x[i] <- 'STAEPI'
next
}
if (toupper(x.backup[i]) == 'VRE') {
x[i] <- 'ENC'
next
}
if (toupper(x.backup[i]) == 'MRPA') {
# multi resistant P. aeruginosa
x[i] <- 'PSEAER'
next
}
if (toupper(x.backup[i]) %in% c('PISP', 'PRSP', 'VISP', 'VRSP')) {
# peni R, peni I, vanco I, vanco R: S. pneumoniae
x[i] <- 'STCPNE'
next
}
}
# let's try the ID's first
found <- AMR::microorganisms[which(AMR::microorganisms$bactid == x.backup[i]),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# now try exact match
found <- AMR::microorganisms[which(AMR::microorganisms$fullname == x[i]),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# try any match keeping spaces
found <- AMR::microorganisms[which(AMR::microorganisms$fullname %like% x_withspaces[i]),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# try any match diregarding spaces
found <- AMR::microorganisms[which(AMR::microorganisms$fullname %like% x[i]),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# try exact match of only genus, with 'species' attached
# (this prevents Streptococcus from becoming Peptostreptococcus, since "p" < "s")
found <- AMR::microorganisms[which(AMR::microorganisms$fullname == x_species[i]),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# try any match of only genus, with 'species' attached
found <- AMR::microorganisms[which(AMR::microorganisms$fullname %like% x_species[i]),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# search for GLIMS code
found <- AMR::microorganisms.umcg[which(toupper(AMR::microorganisms.umcg$mocode) == toupper(x.backup[i])),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# try splitting of characters and then find ID
# like esco = E. coli, klpn = K. pneumoniae, stau = S. aureus
x_split <- x
x_length <- nchar(x.backup[i])
x_split[i] <- paste0(x.backup[i] %>% substr(1, x_length / 2) %>% trimws(),
'.* ',
x.backup[i] %>% substr((x_length / 2) + 1, x_length) %>% trimws())
found <- AMR::microorganisms[which(AMR::microorganisms$fullname %like% paste0('^', x_split[i])),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
# try any match with text before and after original search string
# so "negative rods" will be "GNR"
if (x.backup[i] %like% "^Gram") {
x.backup[i] <- gsub("^Gram", "", x.backup[i], ignore.case = TRUE)
# remove leading and trailing spaces again
x.backup[i] <- trimws(x.backup[i], which = "both")
}
if (!is.na(x.backup[i])) {
found <- AMR::microorganisms[which(AMR::microorganisms$fullname %like% x.backup[i]),]$bactid
if (length(found) > 0) {
x[i] <- found[1L]
next
}
}
# not found
x[i] <- NA_character_
failures <- c(failures, x.fullbackup[i])
}
failures <- failures[!failures %in% c(NA, NULL, NaN)]
if (length(failures) > 0) {
warning("These values could not be coerced to a valid bactid: ",
paste('"', unique(failures), '"', sep = "", collapse = ', '),
".",
call. = FALSE)
}
class(x) <- "bactid"
attr(x, 'package') <- 'AMR'
x
}
#' @rdname as.bactid
#' @export
guess_bactid <- as.bactid
#' @rdname as.bactid
#' @export
is.bactid <- function(x) {
identical(class(x), "bactid")
}
#' @exportMethod print.bactid
#' @export
#' @noRd
print.bactid <- function(x, ...) {
cat("Class 'bactid'\n")
print.default(as.character(x), quote = FALSE)
}
#' @exportMethod as.data.frame.bactid
#' @export
#' @noRd
as.data.frame.bactid <- function (x, ...) {
# same as as.data.frame.character but with removed stringsAsFactors
nm <- paste(deparse(substitute(x), width.cutoff = 500L),
collapse = " ")
if (!"nm" %in% names(list(...))) {
as.data.frame.vector(x, ..., nm = nm)
} else {
as.data.frame.vector(x, ...)
}
}
#' @exportMethod pull.bactid
#' @export
#' @importFrom dplyr pull
#' @noRd
pull.bactid <- function(.data, ...) {
pull(as.data.frame(.data), ...)
}
Executable
+405
View File
@@ -0,0 +1,405 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Class 'rsi'
#'
#' This transforms a vector to a new class \code{rsi}, which is an ordered factor with levels \code{S < I < R}. Invalid antimicrobial interpretations will be translated as \code{NA} with a warning.
#' @rdname as.rsi
#' @param x vector
#' @return Ordered factor with new class \code{rsi} and new attribute \code{package}
#' @keywords rsi
#' @export
#' @importFrom dplyr %>%
#' @seealso \code{\link{as.mic}}
#' @examples
#' rsi_data <- as.rsi(c(rep("S", 474), rep("I", 36), rep("R", 370)))
#' rsi_data <- as.rsi(c(rep("S", 474), rep("I", 36), rep("R", 370), "A", "B", "C"))
#' is.rsi(rsi_data)
#'
#' # this can also coerce combined MIC/RSI values:
#' as.rsi("<= 0.002; S") # will return S
#'
#' plot(rsi_data) # for percentages
#' barplot(rsi_data) # for frequencies
#' freq(rsi_data) # frequency table with informative header
as.rsi <- function(x) {
if (is.rsi(x)) {
x
} else {
x <- x %>% unlist()
x.bak <- x
na_before <- x[is.na(x) | x == ''] %>% length()
# remove all spaces
x <- gsub(' +', '', x)
# remove all MIC-like values: numbers, operators and periods
x <- gsub('[0-9.,;:<=>]+', '', x)
# disallow more than 3 characters
x[nchar(x) > 3] <- NA
# set to capitals
x <- toupper(x)
# remove all invalid characters
x <- gsub('[^RSI]+', '', x)
# in cases of "S;S" keep S, but in case of "S;I" make it NA
x <- gsub('^S+$', 'S', x)
x <- gsub('^I+$', 'I', x)
x <- gsub('^R+$', 'R', x)
x[!x %in% c('S', 'I', 'R')] <- NA
na_after <- x[is.na(x) | x == ''] %>% length()
if (na_before != na_after) {
list_missing <- x.bak[is.na(x) & !is.na(x.bak) & x.bak != ''] %>%
unique() %>%
sort()
list_missing <- paste0('"', list_missing , '"', collapse = ", ")
warning(na_after - na_before, ' results truncated (',
round(((na_after - na_before) / length(x)) * 100),
'%) that were invalid antimicrobial interpretations: ',
list_missing, call. = FALSE)
}
x <- x %>% factor(levels = c("S", "I", "R"), ordered = TRUE)
class(x) <- c('rsi', 'ordered', 'factor')
attr(x, 'package') <- 'AMR'
x
}
}
#' @rdname as.rsi
#' @export
#' @importFrom dplyr %>%
is.rsi <- function(x) {
class(x) %>% identical(c('rsi', 'ordered', 'factor'))
}
#' @exportMethod print.rsi
#' @export
#' @importFrom dplyr %>%
#' @noRd
print.rsi <- function(x, ...) {
cat("Class 'rsi'\n")
print(as.character(x), quote = FALSE)
}
#' @exportMethod summary.rsi
#' @export
#' @noRd
summary.rsi <- function(object, ...) {
x <- object
c(
"Mode" = 'rsi',
"<NA>" = sum(is.na(x)),
"Sum S" = sum(x == "S", na.rm = TRUE),
"Sum IR" = sum(x %in% c("I", "R"), na.rm = TRUE),
"-Sum R" = sum(x == "R", na.rm = TRUE),
"-Sum I" = sum(x == "I", na.rm = TRUE)
)
}
#' @exportMethod plot.rsi
#' @export
#' @importFrom dplyr %>% group_by summarise filter mutate if_else n_distinct
#' @importFrom graphics plot text
#' @noRd
plot.rsi <- function(x, ...) {
x_name <- deparse(substitute(x))
data <- data.frame(x = x,
y = 1,
stringsAsFactors = TRUE) %>%
group_by(x) %>%
summarise(n = sum(y)) %>%
filter(!is.na(x)) %>%
mutate(s = round((n / sum(n)) * 100, 1))
data$x <- factor(data$x, levels = c('S', 'I', 'R'), ordered = TRUE)
ymax <- if_else(max(data$s) > 95, 105, 100)
plot(x = data$x,
y = data$s,
lwd = 2,
col = c('green', 'orange', 'red'),
ylim = c(0, ymax),
ylab = 'Percentage',
xlab = 'Antimicrobial Interpretation',
main = paste('Susceptibility Analysis of', x_name),
axes = FALSE,
...)
# x axis
axis(side = 1, at = 1:n_distinct(data$x), labels = levels(data$x), lwd = 0)
# y axis, 0-100%
axis(side = 2, at = seq(0, 100, 5))
text(x = data$x,
y = data$s + 4,
labels = paste0(data$s, '% (n = ', data$n, ')'))
}
#' @exportMethod barplot.rsi
#' @export
#' @importFrom dplyr %>% group_by summarise filter mutate if_else n_distinct
#' @importFrom graphics barplot axis
#' @noRd
barplot.rsi <- function(height, ...) {
x <- height
x_name <- deparse(substitute(height))
data <- data.frame(rsi = x, cnt = 1) %>%
group_by(rsi) %>%
summarise(cnt = sum(cnt)) %>%
droplevels()
barplot(table(x),
col = c('green3', 'orange2', 'red3'),
xlab = 'Antimicrobial Interpretation',
main = paste('Susceptibility Analysis of', x_name),
ylab = 'Frequency',
axes = FALSE,
...)
# y axis, 0-100%
axis(side = 2, at = seq(0, max(data$cnt) + max(data$cnt) * 1.1, by = 25))
}
#' Class 'mic'
#'
#' This transforms a vector to a new class \code{mic}, which is an ordered factor with valid MIC values as levels. Invalid MIC values will be translated as \code{NA} with a warning.
#' @rdname as.mic
#' @param x vector
#' @param na.rm a logical indicating whether missing values should be removed
#' @return Ordered factor with new class \code{mic} and new attribute \code{package}
#' @keywords mic
#' @export
#' @importFrom dplyr %>%
#' @seealso \code{\link{as.rsi}}
#' @examples
#' mic_data <- as.mic(c(">=32", "1.0", "1", "1.00", 8, "<=0.128", "8", "16", "16"))
#' is.mic(mic_data)
#'
#' # this can also coerce combined MIC/RSI values:
#' as.mic("<=0.002; S") # will return <=0.002
#'
#' plot(mic_data)
#' barplot(mic_data)
#' freq(mic_data)
as.mic <- function(x, na.rm = FALSE) {
if (is.mic(x)) {
x
} else {
x <- x %>% unlist()
if (na.rm == TRUE) {
x <- x[!is.na(x)]
}
x.bak <- x
# comma to period
x <- gsub(',', '.', x, fixed = TRUE)
# remove space between operator and number ("<= 0.002" -> "<=0.002")
x <- gsub('(<|=|>) +', '\\1', x)
# starting dots must start with 0
x <- gsub('^[.]+', '0.', x)
# <=0.2560.512 should be 0.512
x <- gsub('.*[.].*[.]', '0.', x)
# remove ending .0
x <- gsub('[.]+0$', '', x)
# remove all after last digit
x <- gsub('[^0-9]+$', '', x)
# remove last zeroes
x <- gsub('[.]?0+$', '', x)
# force to be character
x <- as.character(x)
# these are alllowed MIC values and will become factor levels
lvls <- c("<0.002", "<=0.002", "0.002", ">=0.002", ">0.002",
"<0.003", "<=0.003", "0.003", ">=0.003", ">0.003",
"<0.004", "<=0.004", "0.004", ">=0.004", ">0.004",
"<0.006", "<=0.006", "0.006", ">=0.006", ">0.006",
"<0.008", "<=0.008", "0.008", ">=0.008", ">0.008",
"<0.012", "<=0.012", "0.012", ">=0.012", ">0.012",
"<0.0125", "<=0.0125", "0.0125", ">=0.0125", ">0.0125",
"<0.016", "<=0.016", "0.016", ">=0.016", ">0.016",
"<0.023", "<=0.023", "0.023", ">=0.023", ">0.023",
"<0.025", "<=0.025", "0.025", ">=0.025", ">0.025",
"<0.03", "<=0.03", "0.03", ">=0.03", ">0.03",
"<0.032", "<=0.032", "0.032", ">=0.032", ">0.032",
"<0.047", "<=0.047", "0.047", ">=0.047", ">0.047",
"<0.05", "<=0.05", "0.05", ">=0.05", ">0.05",
"<0.054", "<=0.054", "0.054", ">=0.054", ">0.054",
"<0.06", "<=0.06", "0.06", ">=0.06", ">0.06",
"<0.0625", "<=0.0625", "0.0625", ">=0.0625", ">0.0625",
"<0.063", "<=0.063", "0.063", ">=0.063", ">0.063",
"<0.064", "<=0.064", "0.064", ">=0.064", ">0.064",
"<0.09", "<=0.09", "0.09", ">=0.09", ">0.09",
"<0.094", "<=0.094", "0.094", ">=0.094", ">0.094",
"<0.12", "<=0.12", "0.12", ">=0.12", ">0.12",
"<0.125", "<=0.125", "0.125", ">=0.125", ">0.125",
"<0.128", "<=0.128", "0.128", ">=0.128", ">0.128",
"<0.16", "<=0.16", "0.16", ">=0.16", ">0.16",
"<0.19", "<=0.19", "0.19", ">=0.19", ">0.19",
"<0.23", "<=0.23", "0.23", ">=0.23", ">0.23",
"<0.25", "<=0.25", "0.25", ">=0.25", ">0.25",
"<0.256", "<=0.256", "0.256", ">=0.256", ">0.256",
"<0.28", "<=0.28", "0.28", ">=0.28", ">0.28",
"<0.30", "<=0.30", "0.30", ">=0.30", ">0.30",
"<0.32", "<=0.32", "0.32", ">=0.32", ">0.32",
"<0.36", "<=0.36", "0.36", ">=0.36", ">0.36",
"<0.38", "<=0.38", "0.38", ">=0.38", ">0.38",
"<0.5", "<=0.5", "0.5", ">=0.5", ">0.5",
"<0.512", "<=0.512", "0.512", ">=0.512", ">0.512",
"<0.64", "<=0.64", "0.64", ">=0.64", ">0.64",
"<0.75", "<=0.75", "0.75", ">=0.75", ">0.75",
"<1", "<=1", "1", ">=1", ">1",
"<1.5", "<=1.5", "1.5", ">=1.5", ">1.5",
"<2", "<=2", "2", ">=2", ">2",
"<3", "<=3", "3", ">=3", ">3",
"<4", "<=4", "4", ">=4", ">4",
"<5", "<=5", "5", ">=5", ">5",
"<6", "<=6", "6", ">=6", ">6",
"<7", "<=7", "7", ">=7", ">7",
"<8", "<=8", "8", ">=8", ">8",
"<10", "<=10", "10", ">=10", ">10",
"<12", "<=12", "12", ">=12", ">12",
"<16", "<=16", "16", ">=16", ">16",
"<20", "<=20", "20", ">=20", ">20",
"<24", "<=24", "24", ">=24", ">24",
"<32", "<=32", "32", ">=32", ">32",
"<40", "<=40", "40", ">=40", ">40",
"<48", "<=48", "48", ">=48", ">48",
"<64", "<=64", "64", ">=64", ">64",
"<80", "<=80", "80", ">=80", ">80",
"<96", "<=96", "96", ">=96", ">96",
"<128", "<=128", "128", ">=128", ">128",
"<160", "<=160", "160", ">=160", ">160",
"<256", "<=256", "256", ">=256", ">256",
"<320", "<=320", "320", ">=320", ">320",
"<512", "<=512", "512", ">=512", ">512",
"<1024", "<=1024", "1024", ">=1024", ">1024")
na_before <- x[is.na(x) | x == ''] %>% length()
x[!x %in% lvls] <- NA
na_after <- x[is.na(x) | x == ''] %>% length()
if (na_before != na_after) {
list_missing <- x.bak[is.na(x) & !is.na(x.bak) & x.bak != ''] %>%
unique() %>%
sort()
list_missing <- paste0('"', list_missing , '"', collapse = ", ")
warning(na_after - na_before, ' results truncated (',
round(((na_after - na_before) / length(x)) * 100),
'%) that were invalid MICs: ',
list_missing, call. = FALSE)
}
x <- factor(x = x,
levels = lvls,
ordered = TRUE)
class(x) <- c('mic', 'ordered', 'factor')
attr(x, 'package') <- 'AMR'
x
}
}
#' @rdname as.mic
#' @export
#' @importFrom dplyr %>%
is.mic <- function(x) {
class(x) %>% identical(c('mic', 'ordered', 'factor'))
}
#' @exportMethod as.double.mic
#' @export
#' @noRd
as.double.mic <- function(x, ...) {
as.double(gsub('(<|=|>)+', '', as.character(x)))
}
#' @exportMethod as.integer.mic
#' @export
#' @noRd
as.integer.mic <- function(x, ...) {
as.integer(gsub('(<|=|>)+', '', as.character(x)))
}
#' @exportMethod as.numeric.mic
#' @export
#' @noRd
as.numeric.mic <- function(x, ...) {
as.numeric(gsub('(<|=|>)+', '', as.character(x)))
}
#' @exportMethod print.mic
#' @export
#' @importFrom dplyr %>% tibble group_by summarise pull
#' @noRd
print.mic <- function(x, ...) {
cat("Class 'mic'\n")
print(as.character(x), quote = FALSE)
}
#' @exportMethod summary.mic
#' @export
#' @importFrom dplyr %>%
#' @noRd
summary.mic <- function(object, ...) {
x <- object
n_total <- x %>% length()
x <- x[!is.na(x)]
n <- x %>% length()
lst <- c('mic',
n_total - n,
sort(x)[1] %>% as.character(),
sort(x)[n] %>% as.character())
names(lst) <- c("Mode", "<NA>", "Min.", "Max.")
lst
}
#' @exportMethod plot.mic
#' @export
#' @importFrom dplyr %>% group_by summarise
#' @importFrom graphics plot text
#' @noRd
plot.mic <- function(x, ...) {
x_name <- deparse(substitute(x))
create_barplot_mic(x, x_name, ...)
}
#' @exportMethod barplot.mic
#' @export
#' @importFrom graphics barplot axis
#' @noRd
barplot.mic <- function(height, ...) {
x_name <- deparse(substitute(height))
create_barplot_mic(height, x_name, ...)
}
#' @importFrom graphics barplot axis
#' @importFrom dplyr %>% group_by summarise
create_barplot_mic <- function(x, x_name, ...) {
data <- data.frame(mic = x, cnt = 1) %>%
group_by(mic) %>%
summarise(cnt = sum(cnt)) %>%
droplevels()
barplot(table(droplevels(x)),
ylab = 'Frequency',
xlab = 'MIC value',
main = paste('MIC values of', x_name),
axes = FALSE,
...)
axis(2, seq(0, max(data$cnt)))
}
+165
View File
@@ -0,0 +1,165 @@
#' Import/export from clipboard
#'
#' @description These are helper functions around \code{\link{read.table}} and \code{\link{write.table}} to import from and export to clipboard with support for Windows, Linux and macOS.
#'
#' The data will be read and written as tab-separated by default, which makes it possible to copy and paste from other software like Excel and SPSS without further transformation.
#'
#' This also supports automatic column type transformation, with AMR classes \code{\link{as.rsi}} and \code{\link{as.mic}}.
#' @rdname clipboard
#' @name clipboard
#' @inheritParams base::data.frame
#' @inheritParams utils::read.table
#' @inheritParams utils::write.table
#' @inheritParams readr::locale
#' @param startrow \emph{n}th row to start importing from. When \code{header = TRUE}, the import will start on row \code{startrow} \emph{below} the header.
#' @param as_vector a logical value indicating whether data consisting of only one column should be imported as vector using \code{\link[dplyr]{pull}}. This will strip off the header.
#' @param guess_col_types a logical value indicating whether column types should be guessed and transformed automatically with \code{\link[readr]{parse_guess}} from the \code{readr} package. Besides, the antimicrobial classes in this AMR package (\code{\link{as.rsi}} and \code{\link{as.mic}}) are also supported.
#' @param remove_ASCII_escape_char remove ASCII escape character
#' @param info print info to console
#' @keywords clipboard clipboard_import clipboard_export import export
#' @importFrom dplyr %>% pull as_tibble
#' @importFrom clipr read_clip_tbl write_clip
#' @importFrom utils read.delim write.table object.size
#' @importFrom readr parse_guess locale
#' @details
#' The parameter \code{stringsAsFactors} defaults to \code{FALSE}, as opposed to most base \R methods.
#'
#' The parameters \code{date_format} and \code{time_format} also support generic date and time formats like \code{"dd-mm-yyyy"} like Excel.
#'
#' \if{html}{
#' \strong{Example for copying from Excel:}
#' \out{<div style="text-align: left">}\figure{clipboard_copy.png}\out{</div>}
#' \cr
#' \strong{And pasting in R:} \cr
#' \cr
#' \code{> data <- clipboard_import()} \cr
#' \code{> data} \cr
#' \out{<div style="text-align: left">}\figure{clipboard_paste.png}\out{</div>}
#' \cr
#' \strong{The resulting data contains the right RSI-classes:} \cr
#' \cr
#' \code{> data$amox} \cr
#' \out{<div style="text-align: left">}\figure{clipboard_rsi.png}\out{</div>}
#' }
#' @export
#' @examples
#' \dontrun{
#'
#' df1 <- data.frame(a = letters[1:12],
#' b = runif(n = 12, min = 1000, max = 2000),
#' stringsAsFactors = FALSE)
#' clipboard_export(df1)
#' df2 <- clipboard_import()
#' identical(df1, df2)
#'
#' # send frequency table to clipboard (e.g. for pasting in Excel)
#' septic_patients %>%
#' freq(age) %>%
#' format() %>% # this will format the percentages
#' clipboard_export()
#' }
clipboard_import <- function(sep = '\t',
quote = "",
header = TRUE,
dec = ".",
na = c("", "NA", "NULL"),
stringsAsFactors = FALSE,
startrow = 1,
as_vector = TRUE,
guess_col_types = TRUE,
date_names = 'en',
date_format = '%Y-%m-%d',
time_format = '%H:%M',
remove_ASCII_escape_char = FALSE,
tz = "UTC",
encoding = "UTF-8",
info = TRUE) {
if (!clipr::clipr_available() & Sys.info()['sysname'] == "Linux") {
# try to support on X11, by setting the R variable DISPLAY
Sys.setenv(DISPLAY = "localhost:10.0")
}
# this will fail when clipr is (still) not available
import_tbl <- clipr::read_clip_tbl(file = file,
sep = sep,
quote = quote,
header = header,
strip.white = TRUE,
dec = dec,
na.strings = na,
encoding = 'UTF-8',
stringsAsFactors = stringsAsFactors)
# use tibble, so column types will be translated correctly
import_tbl <- as_tibble(import_tbl)
if (startrow > 1) {
# would else lose column headers
import_tbl <- import_tbl[startrow:NROW(import_tbl),]
}
colnames(import_tbl) <- gsub('[.]+', '_', colnames(import_tbl))
if (guess_col_types == TRUE) {
if (info == TRUE) {
cat('Transforming data by guessing column types...')
}
import_tbl <- tbl_parse_guess(tbl = import_tbl,
date_names = date_names,
date_format = date_format,
time_format = time_format,
decimal_mark = dec,
tz = tz,
encoding = encoding,
remove_ASCII_escape_char = remove_ASCII_escape_char,
na = na)
if (info == TRUE) {
cat('OK\n')
}
}
if (NCOL(import_tbl) == 1 & as_vector == TRUE) {
import_tbl <- import_tbl %>% pull(1)
}
# and transform back to data.frame
import_tbl <- as.data.frame(import_tbl, stringsAsFactors = stringsAsFactors)
if (info == TRUE) {
cat("Successfully imported from clipboard:", NROW(import_tbl), "obs. of", NCOL(import_tbl), "variables.\n")
}
import_tbl
}
#' @rdname clipboard
#' @importFrom dplyr %>% pull as_tibble
#' @export
clipboard_export <- function(x,
sep = '\t',
dec = ".",
na = "",
header = TRUE,
info = TRUE) {
if (!clipr::clipr_available() & Sys.info()['sysname'] == "Linux") {
# try to support on X11, by setting the R variable DISPLAY
Sys.setenv(DISPLAY = "localhost:10.0")
}
clipr::write_clip(content = x,
na = na,
sep = sep,
row.names = FALSE,
col.names = header,
dec = dec,
quote = FALSE)
if (info == TRUE) {
cat("Successfully exported to clipboard:", NROW(x), "obs. of", NCOL(x), "variables.\n")
}
}
Executable
+336
View File
@@ -0,0 +1,336 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Dataset with 420 antibiotics
#'
#' A dataset containing all antibiotics with a J0 code, with their DDD's. Properties were downloaded from the WHO, see Source.
#' @format A data.frame with 420 observations and 18 variables:
#' \describe{
#' \item{\code{atc}}{ATC code, like \code{J01CR02}}
#' \item{\code{molis}}{MOLIS code, like \code{amcl}}
#' \item{\code{umcg}}{UMCG code, like \code{AMCL}}
#' \item{\code{abbr}}{Abbreviation as used by many countries, to be used for \code{\link{guess_atc}}}
#' \item{\code{official}}{Official name by the WHO, like \code{"Amoxicillin and enzyme inhibitor"}}
#' \item{\code{official_nl}}{Official name in the Netherlands, like \code{"Amoxicilline met enzymremmer"}}
#' \item{\code{trivial_nl}}{Trivial name in Dutch, like \code{"Amoxicilline/clavulaanzuur"}}
#' \item{\code{trade_name}}{Trade name as used by many countries, to be used for \code{\link{guess_atc}}}
#' \item{\code{oral_ddd}}{Defined Daily Dose (DDD), oral treatment}
#' \item{\code{oral_units}}{Units of \code{ddd_units}}
#' \item{\code{iv_ddd}}{Defined Daily Dose (DDD), parenteral treatment}
#' \item{\code{iv_units}}{Units of \code{iv_ddd}}
#' \item{\code{atc_group1}}{ATC group, like \code{"Macrolides, lincosamides and streptogramins"}}
#' \item{\code{atc_group2}}{Subgroup of \code{atc_group1}, like \code{"Macrolides"}}
#' \item{\code{atc_group1_nl}}{ATC group in Dutch, like \code{"Macroliden, lincosamiden en streptograminen"}}
#' \item{\code{atc_group2_nl}}{Subgroup of \code{atc_group1} in Dutch, like \code{"Macroliden"}}
#' \item{\code{useful_gramnegative}}{\code{FALSE} if not useful according to EUCAST, \code{NA} otherwise (see Source)}
#' \item{\code{useful_grampositive}}{\code{FALSE} if not useful according to EUCAST, \code{NA} otherwise (see Source)}
#' }
#' @source - World Health Organization: \url{https://www.whocc.no/atc_ddd_index/} \cr - EUCAST - Expert rules intrinsic exceptional V3.1 \cr - MOLIS (LIS of Certe): \url{https://www.certe.nl} \cr - GLIMS (LIS of UMCG): \url{https://www.umcg.nl}
#' @seealso \code{\link{microorganisms}}
# abbr and trade_name created with:
# https://hs.unr.edu/Documents/dhs/chs/NVPHTC/antibiotic_refeference_guide.pdf
# antibiotics %>%
# mutate(abbr =
# case_when(
# official == 'Amikacin' ~ 'Ak|AN|AMI|AMK',
# official == 'Amoxicillin' ~ 'AMX|AMOX|AC',
# official == 'Amoxicillin and beta-lactamase inhibitor' ~ 'AUG|A/C|XL|AML',
# official == 'Ampicillin' ~ 'AM|AMP',
# official == 'Ampicillin and beta-lactamase inhibitor' ~ 'A/S|SAM|AMS|AB',
# official == 'Azithromycin' ~ 'Azi|AZM|AZ',
# official == 'Azlocillin' ~ 'AZ|AZL',
# official == 'Aztreonam' ~ 'Azt|ATM|AT|AZM',
# official == 'Carbenicillin' ~ 'Cb|BAR',
# official == 'Cefaclor' ~ 'Ccl|CEC|Cfr|FAC|CF',
# official == 'Cefadroxil' ~ 'CFR|FAD',
# official == 'Cefazolin' ~ 'Cfz|CZ|FAZ|KZ',
# official == 'Cefdinir' ~ 'Cdn|CDR|DIN|CD|CFD',
# official == 'Cefditoren' ~ 'CDN',
# official == 'Cefepime' ~ 'Cpe|FEP|PM|CPM',
# official == 'Cefixime' ~ 'Cfe|DCFM|FIX|IX',
# official == 'Cefoperazone' ~ 'Cfp|CPZ|PER|FOP|CP',
# official == 'Cefotaxime' ~ 'Cft|CTX|TAX|FOT|CT',
# official == 'Cefotetan' ~ 'Ctn|CTT|CTE|TANS|CN',
# official == 'Cefoxitin' ~ 'Cfx|FOX|CX|FX',
# official == 'Cefpodoxime' ~ 'Cpd|POD|PX',
# official == 'Cefprozil' ~ 'Cpz|CPR|FP',
# official == 'Ceftaroline' ~ 'CPT',
# official == 'Ceftazidime' ~ 'Caz|TAZ|TZ',
# official == 'Ceftibuten' ~ 'CTB|TIB|CB',
# official == 'Ceftizoxime' ~ 'Cz|ZOX|CZX|CZ|CTZ|TIZ',
# official == 'Ceftriaxone' ~ 'Cax|CRO|CTR|FRX|AXO|TX',
# official == 'Cefuroxime' ~ 'Crm|CXM|CFX|ROX|FUR|XM',
# official == 'Cephalexin' ~ 'CN|LX|CFL',
# official == 'Cephalothin' ~ 'Cf',
# official == 'Chloramphenicol' ~ 'C|CHL|CL',
# official == 'Ciprofloxacin' ~ 'Cp|CIP|CI',
# official == 'Clarithromycin' ~ 'Cla|CLR|CLM|CH',
# official == 'Clindamycin' ~ 'Cd|CC|CM|CLI|DA',
# official == 'Colistin' ~ 'CL|CS|CT',
# official == 'Daptomycin' ~ 'Dap',
# official == 'Doxycycline' ~ 'Dox',
# official == 'Doripenem' ~ 'DOR|Dor',
# official == 'Ertapenem' ~ 'Etp',
# official == 'Erythromycin' ~ 'E|ERY|EM',
# official == 'Fosfomycin' ~ 'FOS|FF|FO|FM',
# official == 'Flucloxacillin' ~ 'CLOX',
# official == 'Gentamicin' ~ 'Gm|CN|GEN',
# official == 'Imipenem' ~ 'Imp|IPM|IMI|IP',
# official == 'Kanamycin' ~ 'K|KAN|HLK|KM',
# official == 'Levofloxacin' ~ 'Lvx|LEV|LEVO|LE',
# official == 'Linezolid' ~ 'Lzd|LNZ|LZ',
# official == 'Lomefloxacin' ~ 'Lmf|LOM',
# official == 'Meropenem' ~ 'Mer|MEM|MERO|MRP|MP',
# official == 'Metronidazole' ~ 'MNZ',
# official == 'Mezlocillin' ~ 'Mz|MEZ',
# official == 'Minocycline' ~ 'Min|MI|MN|MNO|MC|MH',
# official == 'Moxifloxacin' ~ 'Mox|MXF',
# official == 'Mupirocin' ~ 'MUP',
# official == 'Nafcillin' ~ 'Naf|NF',
# official == 'Nalidixic acid' ~ 'NA|NAL',
# official == 'Nitrofurantoin' ~ 'Fd|F/M|FT|NIT|NI|F',
# official == 'Norfloxacin' ~ 'Nxn|NOR|NX',
# official == 'Ofloxacin' ~ 'Ofl|OFX|OF',
# official == 'Oxacillin' ~ 'Ox|OXS|OXA',
# official == 'Benzylpenicillin' ~ 'P|PEN|PV',
# official == 'Penicillins, combinations with other antibacterials' ~ 'P|PEN|PV',
# official == 'Piperacillin' ~ 'Pi|PIP|PP',
# official == 'Piperacillin and beta-lactamase inhibitor' ~ 'PT|TZP|PTZ|P/T|PTc',
# official == 'Polymyxin B' ~ 'PB',
# official == 'Quinupristin/dalfopristin' ~ 'Syn|Q/D|QDA|RP',
# official == 'Rifampin' ~ 'Rif|RA|RI|RD',
# official == 'Spectinomycin' ~ 'SPT|SPE|SC',
# official == 'Streptomycin' ~ 'S|STR',
# official == 'Teicoplanin' ~ 'Tei|TEC|TPN|TP|TPL',
# official == 'Telavancin' ~ 'TLV',
# official == 'Telithromcyin' ~ 'Tel',
# official == 'Tetracycline' ~ 'Te|TET|TC',
# official == 'Ticarcillin' ~ 'Ti|TIC|TC',
# official == 'Ticarcillin and beta-lactamase inhibitor' ~ 'Tim|T/C|TCC|TLc',
# official == 'Tigecycline' ~ 'TGC',
# official == 'Tobramycin' ~ 'To|NN|TM|TOB',
# official == 'Trimethoprim' ~ 'T|TMP|TR|W',
# official == 'Sulfamethoxazole and trimethoprim' ~ 'T/S|SXT|SxT|TS|COT',
# official == 'Vancomycin' ~ 'Va|VAN',
# TRUE ~ NA_character_),
#
# trade_name =
# case_when(
# official == 'Amikacin' ~ 'Amikin',
# official == 'Amoxicillin' ~ 'Amoxil|Dispermox|Larotid|Trimox',
# official == 'Amoxicillin and beta-lactamase inhibitor' ~ 'Augmentin',
# official == 'Ampicillin' ~ 'Pfizerpen-A|Principen',
# official == 'Ampicillin and beta-lactamase inhibitor' ~ 'Unasyn',
# official == 'Azithromycin' ~ 'Zithromax',
# official == 'Azlocillin' ~ 'Azlin',
# official == 'Aztreonam' ~ 'Azactam',
# official == 'Carbenicillin' ~ 'Geocillin',
# official == 'Cefaclor' ~ 'Ceclor',
# official == 'Cefadroxil' ~ 'Duricef',
# official == 'Cefazolin' ~ 'Ancef',
# official == 'Cefdinir' ~ 'Omnicef',
# official == 'Cefditoren' ~ 'Spectracef',
# official == 'Cefepime' ~ 'Maxipime',
# official == 'Cefixime' ~ 'Suprax',
# official == 'Cefoperazone' ~ 'Cefobid',
# official == 'Cefotaxime' ~ 'Claforan',
# official == 'Cefotetan' ~ 'Cefotan',
# official == 'Cefoxitin' ~ 'Mefoxin',
# official == 'Cefpodoxime' ~ 'Vantin',
# official == 'Cefprozil' ~ 'Cefzil',
# official == 'Ceftaroline' ~ 'Teflaro',
# official == 'Ceftazidime' ~ 'Fortaz|Tazicef|Tazidime',
# official == 'Ceftibuten' ~ 'Cedax',
# official == 'Ceftizoxime' ~ 'Cefizox',
# official == 'Ceftriaxone' ~ 'Rocephin',
# official == 'Cefuroxime' ~ 'Ceftin|Zinacef',
# official == 'Cephalexin' ~ 'Keflex|Panixine',
# official == 'Cephalothin' ~ 'Keflin',
# official == 'Chloramphenicol' ~ 'Chloromycetin',
# official == 'Ciprofloxacin' ~ 'Cipro|Ciloxan|Ciproxin',
# official == 'Clarithromycin' ~ 'Biaxin',
# official == 'Clindamycin' ~ 'Cleocin|Clinda-Derm|Clindagel|Clindesse|Clindets|Evoclin',
# official == 'Colistin' ~ 'Coly-Mycin',
# official == 'Daptomycin' ~ 'Cubicin',
# official == 'Doxycycline' ~ 'Doryx|Monodox|Vibramycin|Atridox|Oracea|Periostat|Vibra-Tabs',
# official == 'Doripenem' ~ 'Doribax',
# official == 'Ertapenem' ~ 'Invanz',
# official == 'Erythromycin' ~ 'Eryc|EryPed|Erythrocin|E-Base|E-Glades|E-Mycin|E.E.S.|Ery-Tab|Eryderm|Erygel|Erythra-derm|Eryzole|Pediamycin',
# official == 'Fosfomycin' ~ 'Monurol',
# official == 'Flucloxacillin' ~ 'Flopen|Floxapen|Fluclox|Sesamol|Softapen|Staphylex',
# official == 'Gentamicin' ~ 'Garamycin|Genoptic',
# official == 'Imipenem' ~ 'Primaxin',
# official == 'Kanamycin' ~ 'Kantrex',
# official == 'Levofloxacin' ~ 'Levaquin|Quixin',
# official == 'Linezolid' ~ 'Zyvox',
# official == 'Lomefloxacin' ~ 'Maxaquin',
# official == 'Meropenem' ~ 'Merrem',
# official == 'Metronidazole' ~ 'Flagyl|MetroGel|MetroCream|MetroLotion',
# official == 'Mezlocillin' ~ 'Mezlin',
# official == 'Minocycline' ~ 'Arestin|Solodyn',
# official == 'Moxifloxacin' ~ 'Avelox|Vigamox',
# official == 'Mupirocin' ~ 'Bactroban|Centany',
# official == 'Nafcillin' ~ 'Unipen',
# official == 'Nalidixic acid' ~ 'NegGram',
# official == 'Nitrofurantoin' ~ 'Furadantin|Macrobid|Macrodantin',
# official == 'Norfloxacin' ~ 'Noroxin',
# official == 'Ofloxacin' ~ 'Floxin|Ocuflox|Ophthalmic',
# official == 'Oxacillin' ~ 'Bactocill',
# official == 'Benzylpenicillin' ~ 'Permapen|Pfizerpen|Veetids',
# official == 'Penicillins, combinations with other antibacterials' ~ 'Permapen|Pfizerpen|Veetids',
# official == 'Piperacillin' ~ 'Pipracil',
# official == 'Piperacillin and beta-lactamase inhibitor' ~ 'Zosyn',
# official == 'Polymyxin B' ~ 'Poly-RX',
# official == 'Quinupristin/dalfopristin' ~ 'Synercid',
# official == 'Rifampin' ~ 'Rifadin|Rifamate|Rimactane',
# official == 'Spectinomycin' ~ 'Trobicin',
# official == 'Streptomycin' ~ 'Streptomycin Sulfate',
# official == 'Teicoplanin' ~ 'Targocid',
# official == 'Telavancin' ~ 'Vibativ',
# official == 'Telithromcyin' ~ 'Ketek',
# official == 'Tetracycline' ~ 'Sumycin|Bristacycline|Tetrex',
# official == 'Ticarcillin' ~ 'Ticar',
# official == 'Ticarcillin and beta-lactamase inhibitor' ~ 'Timentin',
# official == 'Tigecycline' ~ 'Tygacil',
# official == 'Tobramycin' ~ 'Tobi|Aktob|Tobre',
# official == 'Trimethoprim' ~ 'Primsol|Proloprim',
# official == 'Sulfamethoxazole and trimethoprim' ~ 'Bactrim|Septra|Sulfatrim',
# official == 'Vancomycin' ~ 'Vancocin|Vancomycin Hydrochloride',
# TRUE ~ NA_character_)
# )
# last two columns created with:
# antibiotics %>%
# mutate(useful_gramnegative =
# if_else(
# atc_group1 %like% '(fusidic|glycopeptide|macrolide|lincosamide|daptomycin|linezolid)' |
# atc_group2 %like% '(fusidic|glycopeptide|macrolide|lincosamide|daptomycin|linezolid)' |
# official %like% '(fusidic|glycopeptide|macrolide|lincosamide|daptomycin|linezolid)',
# FALSE,
# NA
# ),
# useful_grampositive =
# if_else(
# atc_group1 %like% '(aztreonam|temocillin|polymyxin|colistin|nalidixic)' |
# atc_group2 %like% '(aztreonam|temocillin|polymyxin|colistin|nalidixic)' |
# official %like% '(aztreonam|temocillin|polymyxin|colistin|nalidixic)',
# FALSE,
# NA
# )
# )
"antibiotics"
#' Dataset with ~2500 microorganisms
#'
#' A dataset containing 2464 microorganisms. MO codes of the UMCG can be looked up using \code{\link{microorganisms.umcg}}.
#' @format A data.frame with 2464 observations and 12 variables:
#' \describe{
#' \item{\code{bactid}}{ID of microorganism}
#' \item{\code{bactsys}}{Bactsyscode of microorganism}
#' \item{\code{family}}{Family name of microorganism}
#' \item{\code{genus}}{Genus name of microorganism, like \code{"Echerichia"}}
#' \item{\code{species}}{Species name of microorganism, like \code{"coli"}}
#' \item{\code{subspecies}}{Subspecies name of bio-/serovar of microorganism, like \code{"EHEC"}}
#' \item{\code{fullname}}{Full name, like \code{"Echerichia coli (EHEC)"}}
#' \item{\code{type}}{Type of microorganism, like \code{"Bacteria"} and \code{"Fungus/yeast"}}
#' \item{\code{gramstain}}{Gram of microorganism, like \code{"Negative rods"}}
#' \item{\code{aerobic}}{Logical whether bacteria is aerobic}
#' \item{\code{type_nl}}{Type of microorganism in Dutch, like \code{"Bacterie"} and \code{"Schimmel/gist"}}
#' \item{\code{gramstain_nl}}{Gram of microorganism in Dutch, like \code{"Negatieve staven"}}
#' }
# source MOLIS (LIS of Certe) - \url{https://www.certe.nl}
# new <- microorganisms %>% filter(genus == "Bacteroides") %>% .[1,]
# new[1, 'bactid'] <- "DIAPNU"
# new[1, 'bactsys'] <- "DIAPNU"
# new[1, 'family'] <- "Veillonellaceae"
# new[1, 'genus'] <- "Dialister"
# new[1, 'species'] <- "pneumosintes"
# new[1, 'subspecies'] <- NA
# new[1, 'fullname'] <- paste(new[1, 'genus'], new[1, 'species'])
# microorganisms <- microorganisms %>% bind_rows(new) %>% arrange(bactid)
#' @seealso \code{\link{guess_bactid}} \code{\link{antibiotics}} \code{\link{microorganisms.umcg}}
"microorganisms"
#' Translation table for UMCG with ~1100 microorganisms
#'
#' A dataset containing all bacteria codes of UMCG MMB. These codes can be joined to data with an ID from \code{\link{microorganisms}$bactid} (using \code{\link{left_join_microorganisms}}). GLIMS codes can also be translated to valid \code{bactid}'s with \code{\link{guess_bactid}}.
#' @format A data.frame with 1090 observations and 2 variables:
#' \describe{
#' \item{\code{mocode}}{Code of microorganism according to UMCG MMB}
#' \item{\code{bactid}}{Code of microorganism in \code{\link{microorganisms}}}
#' }
# source MOLIS (LIS of Certe) - \url{https://www.certe.nl} \cr \cr GLIMS (LIS of UMCG) - \url{https://www.umcg.nl}
#' @seealso \code{\link{guess_bactid}} \code{\link{microorganisms}}
"microorganisms.umcg"
#' Dataset with 2000 blood culture isolates of septic patients
#'
#' An anonymised dataset containing 2000 microbial blood culture isolates with their full antibiograms found in septic patients in 4 different hospitals in the Netherlands, between 2001 and 2017. It is true, genuine data. This \code{data.frame} can be used to practice AMR analysis. For examples, press F1.
#' @format A data.frame with 2000 observations and 49 variables:
#' \describe{
#' \item{\code{date}}{date of receipt at the laboratory}
#' \item{\code{hospital_id}}{ID of the hospital, from A to D}
#' \item{\code{ward_icu}}{logical to determine if ward is an intensive care unit}
#' \item{\code{ward_clinical}}{logical to determine if ward is a regular clinical ward}
#' \item{\code{ward_outpatient}}{logical to determine if ward is an outpatient clinic}
#' \item{\code{age}}{age of the patient}
#' \item{\code{sex}}{sex of the patient}
#' \item{\code{patient_id}}{ID of the patient, first 10 characters of an SHA hash containing irretrievable information}
#' \item{\code{bactid}}{ID of microorganism, see \code{\link{microorganisms}}}
#' \item{\code{peni:rifa}}{40 different antibiotics with class \code{rsi} (see \code{\link{as.rsi}}); these column names occur in \code{\link{antibiotics}} data set and can be translated with \code{\link{abname}}}
#' }
# source MOLIS (LIS of Certe) - \url{https://www.certe.nl}
#' @examples
#' # ----------- #
#' # PREPARATION #
#' # ----------- #
#'
#' # Save this example dataset to an object, so we can edit it:
#' my_data <- septic_patients
#'
#' # load the dplyr package to make data science A LOT easier
#' library(dplyr)
#'
#' # Add first isolates to our dataset:
#' my_data <- my_data %>%
#' mutate(first_isolates = first_isolate(my_data, "date", "patient_id", "bactid"))
#'
#' # -------- #
#' # ANALYSIS #
#' # -------- #
#'
#' # 1. Get the amoxicillin resistance percentages (p)
#' # and numbers (n) of E. coli, divided by hospital:
#'
#' my_data %>%
#' filter(bactid == guess_bactid("E. coli"),
#' first_isolates == TRUE) %>%
#' group_by(hospital_id) %>%
#' summarise(n = n_rsi(amox),
#' p = portion_IR(amox))
#'
#'
#' # 2. Get the amoxicillin/clavulanic acid resistance
#' # percentages of E. coli, trend over the years:
#'
#' my_data %>%
#' filter(bactid == guess_bactid("E. coli"),
#' first_isolates == TRUE) %>%
#' group_by(year = format(date, "%Y")) %>%
#' summarise(n = n_rsi(amcl),
#' p = portion_IR(amcl, minimum = 20))
"septic_patients"
Executable
+732
View File
@@ -0,0 +1,732 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' EUCAST expert rules
#'
#' Apply expert rules (like intrinsic resistance), as defined by the European Committee on Antimicrobial Susceptibility Testing (EUCAST, \url{http://eucast.org}), see \emph{Source}.
#' @param tbl table with antibiotic columns, like e.g. \code{amox} and \code{amcl}
#' @param col_bactid column name of the bacteria ID in \code{tbl} - values of this column should be present in \code{microorganisms$bactid}, see \code{\link{microorganisms}}
#' @param info print progress
#' @param amcl,amik,amox,ampi,azit,azlo,aztr,cefa,cfep,cfot,cfox,cfra,cfta,cftr,cfur,chlo,cipr,clar,clin,clox,coli,czol,dapt,doxy,erta,eryt,fosf,fusi,gent,imip,kana,levo,linc,line,mero,mezl,mino,moxi,nali,neom,neti,nitr,norf,novo,oflo,peni,pita,poly,pris,qida,rifa,roxi,siso,teic,tetr,tica,tige,tobr,trim,trsu,vanc column names of antibiotics. Use \code{NA} to skip a column, like \code{tica = NA}. Non-existing columns will anyway be skipped. See the Antibiotics section for an explanation of the abbreviations.
#' @param ... parameters that are passed on to \code{EUCAST_rules}
#' @section Abbrevations of antibiotics:
#' Abbrevations of the column containing antibiotics:
#'
#' \strong{amcl}: amoxicillin and beta-lactamase inhibitor (\emph{J01CR02}),
#' \strong{amik}: amikacin (\emph{J01GB06}),
#' \strong{amox}: amoxicillin (\emph{J01CA04}),
#' \strong{ampi}: ampicillin (\emph{J01CA01}),
#' \strong{azit}: azithromycin (\emph{J01FA10}),
#' \strong{azlo}: azlocillin (\emph{J01CA09}),
#' \strong{aztr}: aztreonam (\emph{J01DF01}),
#' \strong{cefa}: cefaloridine (\emph{J01DB02}),
#' \strong{cfep}: cefepime (\emph{J01DE01}),
#' \strong{cfot}: cefotaxime (\emph{J01DD01}),
#' \strong{cfox}: cefoxitin (\emph{J01DC01}),
#' \strong{cfra}: cefradine (\emph{J01DB09}),
#' \strong{cfta}: ceftazidime (\emph{J01DD02}),
#' \strong{cftr}: ceftriaxone (\emph{J01DD04}),
#' \strong{cfur}: cefuroxime (\emph{J01DC02}),
#' \strong{chlo}: chloramphenicol (\emph{J01BA01}),
#' \strong{cipr}: ciprofloxacin (\emph{J01MA02}),
#' \strong{clar}: clarithromycin (\emph{J01FA09}),
#' \strong{clin}: clindamycin (\emph{J01FF01}),
#' \strong{clox}: flucloxacillin (\emph{J01CF05}),
#' \strong{coli}: colistin (\emph{J01XB01}),
#' \strong{czol}: cefazolin (\emph{J01DB04}),
#' \strong{dapt}: daptomycin (\emph{J01XX09}),
#' \strong{doxy}: doxycycline (\emph{J01AA02}),
#' \strong{erta}: ertapenem (\emph{J01DH03}),
#' \strong{eryt}: erythromycin (\emph{J01FA01}),
#' \strong{fosf}: fosfomycin (\emph{J01XX01}),
#' \strong{fusi}: fusidic acid (\emph{J01XC01}),
#' \strong{gent}: gentamicin (\emph{J01GB03}),
#' \strong{imip}: imipenem and cilastatin (\emph{J01DH51}),
#' \strong{kana}: kanamycin (\emph{J01GB04}),
#' \strong{levo}: levofloxacin (\emph{J01MA12}),
#' \strong{linc}: lincomycin (\emph{J01FF02}),
#' \strong{line}: linezolid (\emph{J01XX08}),
#' \strong{mero}: meropenem (\emph{J01DH02}),
#' \strong{mezl}: mezlocillin (\emph{J01CA10}),
#' \strong{mino}: minocycline (\emph{J01AA08}),
#' \strong{moxi}: moxifloxacin (\emph{J01MA14}),
#' \strong{nali}: nalidixic acid (\emph{J01MB02}),
#' \strong{neom}: neomycin (\emph{J01GB05}),
#' \strong{neti}: netilmicin (\emph{J01GB07}),
#' \strong{nitr}: nitrofurantoin (\emph{J01XE01}),
#' \strong{norf}: norfloxacin (\emph{J01MA06}),
#' \strong{novo}: novobiocin (an ATCvet code: \emph{QJ01XX95}),
#' \strong{oflo}: ofloxacin (\emph{J01MA01}),
#' \strong{peni}: penicillins, combinations with other antibacterials (\emph{J01RA01}),
#' \strong{pita}: piperacillin and beta-lactamase inhibitor (\emph{J01CR05}),
#' \strong{poly}: polymyxin B (\emph{J01XB02}),
#' \strong{pris}: pristinamycin (\emph{J01FG01}),
#' \strong{qida}: quinupristin/dalfopristin (\emph{J01FG02}),
#' \strong{rifa}: rifampicin (\emph{J04AB02}),
#' \strong{roxi}: roxithromycin (\emph{J01FA06}),
#' \strong{siso}: sisomicin (\emph{J01GB08}),
#' \strong{teic}: teicoplanin (\emph{J01XA02}),
#' \strong{tetr}: tetracycline (\emph{J01AA07}),
#' \strong{tica}: ticarcillin (\emph{J01CA13}),
#' \strong{tige}: tigecycline (\emph{J01AA12}),
#' \strong{tobr}: tobramycin (\emph{J01GB01}),
#' \strong{trim}: trimethoprim (\emph{J01EA01}),
#' \strong{trsu}: sulfamethoxazole and trimethoprim (\emph{J01EE01}),
#' \strong{vanc}: vancomycin (\emph{J01XA01}).
#' @keywords interpretive eucast reading resistance
#' @rdname EUCAST
#' @export
#' @importFrom dplyr %>% left_join select
#' @return table with edited variables of antibiotics.
#' @source
#' EUCAST Expert Rules Version 2.0: \cr
#' Leclercq et al. \strong{EUCAST expert rules in antimicrobial susceptibility testing.} \emph{Clin Microbiol Infect.} 2013;19(2):141-60. \cr
#' \url{https://doi.org/10.1111/j.1469-0691.2011.03703.x} \cr
#' \cr
#' EUCAST Expert Rules Version 3.1 (Intrinsic Resistance and Exceptional Phenotypes Tables): \cr
#' \url{http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf}
#' @examples
#' a <- EUCAST_rules(septic_patients)
#' a <- data.frame(bactid = c("STAAUR", # Staphylococcus aureus
#' "ENCFAE", # Enterococcus faecalis
#' "ESCCOL", # Escherichia coli
#' "KLEPNE", # Klebsiella pneumoniae
#' "PSEAER"), # Pseudomonas aeruginosa
#' vanc = "-", # Vancomycin
#' amox = "-", # Amoxicillin
#' coli = "-", # Colistin
#' cfta = "-", # Ceftazidime
#' cfur = "-", # Cefuroxime
#' stringsAsFactors = FALSE)
#' a
#'
#' b <- EUCAST_rules(a)
#' b
EUCAST_rules <- function(tbl,
col_bactid = 'bactid',
info = TRUE,
amcl = 'amcl',
amik = 'amik',
amox = 'amox',
ampi = 'ampi',
azit = 'azit',
azlo = 'azlo',
aztr = 'aztr',
cefa = 'cefa',
cfep = 'cfep',
cfot = 'cfot',
cfox = 'cfox',
cfra = 'cfra',
cfta = 'cfta',
cftr = 'cftr',
cfur = 'cfur',
chlo = 'chlo',
cipr = 'cipr',
clar = 'clar',
clin = 'clin',
clox = 'clox',
coli = 'coli',
czol = 'czol',
dapt = 'dapt',
doxy = 'doxy',
erta = 'erta',
eryt = 'eryt',
fosf = 'fosf',
fusi = 'fusi',
gent = 'gent',
imip = 'imip',
kana = 'kana',
levo = 'levo',
linc = 'linc',
line = 'line',
mero = 'mero',
mezl = 'mezl',
mino = 'mino',
moxi = 'moxi',
nali = 'nali',
neom = 'neom',
neti = 'neti',
nitr = 'nitr',
norf = 'norf',
novo = 'novo',
oflo = 'oflo',
peni = 'peni',
pita = 'pita',
poly = 'poly',
pris = 'pris',
qida = 'qida',
rifa = 'rifa',
roxi = 'roxi',
siso = 'siso',
teic = 'teic',
tetr = 'tetr',
tica = 'tica',
tige = 'tige',
tobr = 'tobr',
trim = 'trim',
trsu = 'trsu',
vanc = 'vanc') {
EUCAST_VERSION <- "3.1"
if (!col_bactid %in% colnames(tbl)) {
stop('Column ', col_bactid, ' not found.', call. = FALSE)
}
# check columns
col.list <- c(amcl, amik, amox, ampi, azit, azlo, aztr, cefa, cfra, cfep, cfot,
cfox, cfta, cftr, cfur, chlo, cipr, clar, clin, clox, coli,
czol, dapt, doxy, erta, eryt, fosf, fusi, gent, imip, kana,
levo, linc, line, mero, mezl, mino, moxi, nali, neom, neti, nitr,
novo, norf, oflo, peni, pita, poly, pris, qida, rifa, roxi, siso,
teic, tetr, tica, tige, tobr, trim, trsu, vanc)
col.list <- check_available_columns(tbl = tbl, col.list = col.list, info = info)
amcl <- col.list[amcl]
amik <- col.list[amik]
amox <- col.list[amox]
ampi <- col.list[ampi]
azit <- col.list[azit]
azlo <- col.list[azlo]
aztr <- col.list[aztr]
cefa <- col.list[cefa]
cfep <- col.list[cfep]
cfot <- col.list[cfot]
cfox <- col.list[cfox]
cfra <- col.list[cfra]
cfta <- col.list[cfta]
cftr <- col.list[cftr]
cfur <- col.list[cfur]
chlo <- col.list[chlo]
cipr <- col.list[cipr]
clar <- col.list[clar]
clin <- col.list[clin]
clox <- col.list[clox]
coli <- col.list[coli]
czol <- col.list[czol]
dapt <- col.list[dapt]
doxy <- col.list[doxy]
erta <- col.list[erta]
eryt <- col.list[eryt]
fosf <- col.list[fosf]
fusi <- col.list[fusi]
gent <- col.list[gent]
imip <- col.list[imip]
kana <- col.list[kana]
levo <- col.list[levo]
linc <- col.list[linc]
line <- col.list[line]
mero <- col.list[mero]
mezl <- col.list[mezl]
mino <- col.list[mino]
moxi <- col.list[moxi]
nali <- col.list[nali]
neom <- col.list[neom]
neti <- col.list[neti]
nitr <- col.list[nitr]
norf <- col.list[norf]
novo <- col.list[novo]
oflo <- col.list[oflo]
peni <- col.list[peni]
pita <- col.list[pita]
poly <- col.list[poly]
pris <- col.list[pris]
qida <- col.list[qida]
rifa <- col.list[rifa]
roxi <- col.list[roxi]
siso <- col.list[siso]
teic <- col.list[teic]
tetr <- col.list[tetr]
tica <- col.list[tica]
tige <- col.list[tige]
tobr <- col.list[tobr]
trim <- col.list[trim]
trsu <- col.list[trsu]
vanc <- col.list[vanc]
total <- 0
total_rows <- integer(0)
# helper function for editing the table
edit_rsi <- function(to, rows, cols, EUCAST_rule = "") {
# later: use this as attribute for the edited observations
EUCAST_rule <- trimws(paste("EUCAST rule", EUCAST_rule))
cols <- cols[!is.na(cols)]
if (length(rows) > 0 & length(cols) > 0) {
tbl[rows, cols] <<- to
total <<- total + (length(rows) * length(cols))
total_rows <<- c(total_rows, rows)
}
}
# join to microorganisms data set
if (!tbl %>% pull(col_bactid) %>% is.bactid()) {
warning("Improve integrity of the `", col_bactid, "` column by transforming it with 'as.bactid'.")
}
tbl <- tbl %>% left_join_microorganisms(by = col_bactid, suffix = c("_tempmicroorganisms", ""))
# antibiotic classes
aminoglycosides <- c(tobr, gent, kana, neom, neti, siso)
tetracyclines <- c(doxy, mino, tetr) # since EUCAST v3.1 tige(cycline) is set apart
polymyxins <- c(poly, coli)
macrolides <- c(eryt, azit, roxi, clar) # since EUCAST v3.1 clinda is set apart
glycopeptides <- c(vanc, teic)
streptogramins <- c(qida, pris) # should officially also be quinupristin/dalfopristin
cephalosporins <- c(cfep, cfot, cfox, cfra, cfta, cftr, cfur, czol)
carbapenems <- c(erta, imip, mero)
aminopenicillins <- c(ampi, amox)
ureidopenicillins <- c(pita, azlo, mezl)
fluoroquinolones <- c(oflo, cipr, norf, levo, moxi)
if (info == TRUE) {
cat(
paste0(
'\nApplying rules to ',
tbl[!is.na(tbl$genus),] %>% nrow() %>% format(big.mark = ","),
' rows according to "EUCAST Expert Rules Version ', EUCAST_VERSION, '"\n')
)
}
# Table 1: Intrinsic resistance in Enterobacteriaceae ----
if (info == TRUE) {
cat('- Table 1: Intrinsic resistance in Enterobacteriaceae\n')
}
# Intrisiek R for this group
edit_rsi(to = 'R',
rows = which(tbl$family == 'Enterobacteriaceae'),
cols = c(peni, glycopeptides, fusi, macrolides, linc, streptogramins, rifa, dapt, line))
# Citrobacter
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Citrobacter (koseri|amalonaticus|sedlakii|farmeri|rodentium)'),
cols = c(aminopenicillins, tica))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Citrobacter (freundii|braakii|murliniae|werkmanii|youngae)'),
cols = c(aminopenicillins, amcl, czol, cfox))
# Enterobacter
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Enterobacter cloacae'),
cols = c(aminopenicillins, amcl, czol, cfox))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Enterobacter aerogenes'),
cols = c(aminopenicillins, amcl, czol, cfox))
# Escherichia
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Escherichia hermanni'),
cols = c(aminopenicillins, tica))
# Hafnia
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Hafnia alvei'),
cols = c(aminopenicillins, amcl, czol, cfox))
# Klebsiella
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Klebsiella'),
cols = c(aminopenicillins, tica))
# Morganella / Proteus
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Morganella morganii'),
cols = c(aminopenicillins, amcl, czol, tetracyclines, polymyxins, nitr))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Proteus mirabilis'),
cols = c(tetracyclines, tige, polymyxins, nitr))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Proteus penneri'),
cols = c(aminopenicillins, czol, cfur, tetracyclines, tige, polymyxins, nitr))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Proteus vulgaris'),
cols = c(aminopenicillins, czol, cfur, tetracyclines, tige, polymyxins, nitr))
# Providencia
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Providencia rettgeri'),
cols = c(aminopenicillins, amcl, czol, cfur, tetracyclines, tige, polymyxins, nitr))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Providencia stuartii'),
cols = c(aminopenicillins, amcl, czol, cfur, tetracyclines, tige, polymyxins, nitr))
# Raoultella
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Raoultella'),
cols = c(aminopenicillins, tica))
# Serratia
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Serratia marcescens'),
cols = c(aminopenicillins, amcl, czol, cfox, cfur, tetracyclines[tetracyclines != 'mino'], polymyxins, nitr))
# Yersinia
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Yersinia enterocolitica'),
cols = c(aminopenicillins, amcl, tica, czol, cfox))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Yersinia pseudotuberculosis'),
cols = c(poly, coli))
# Table 2: Intrinsic resistance in non-fermentative Gram-negative bacteria ----
if (info == TRUE) {
cat('- Table 2: Intrinsic resistance in non-fermentative Gram-negative bacteria\n')
}
# Intrisiek R for this group
edit_rsi(to = 'R',
rows = which(tbl$genus %in% c('Achromobacter',
'Acinetobacter',
'Alcaligenes',
'Bordatella',
'Burkholderia',
'Elizabethkingia',
'Flavobacterium',
'Ochrobactrum',
'Pseudomonas',
'Stenotrophomonas')),
cols = c(peni, cfox, cfur, glycopeptides, fusi, macrolides, linc, streptogramins, rifa, dapt, line))
# Acinetobacter
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Acinetobacter (baumannii|pittii|nosocomialis|calcoaceticus)'),
cols = c(aminopenicillins, amcl, czol, cfot, cftr, aztr, erta, trim, fosf, tetracyclines[tetracyclines != 'mino']))
# Achromobacter
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Achromobacter (xylosoxydans|xylosoxidans)'),
cols = c(aminopenicillins, czol, cfot, cftr, erta))
# Burkholderia
edit_rsi(to = 'R',
# onder 'Burkholderia cepacia complex' vallen deze species allemaal: PMID 16217180.
rows = which(tbl$fullname %like% '^Burkholderia (cepacia|multivorans|cenocepacia|stabilis|vietnamiensis|dolosa|ambifaria|anthina|pyrrocinia|ubonensis)'),
cols = c(aminopenicillins, amcl, tica, pita, czol, cfot, cftr, aztr, erta, cipr, chlo, aminoglycosides, trim, fosf, polymyxins))
# Elizabethkingia
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Elizabethkingia meningoseptic(a|um)'),
cols = c(aminopenicillins, amcl, tica, czol, cfot, cftr, cfta, cfep, aztr, erta, imip, mero, polymyxins))
# Ochrobactrum
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Ochrobactrum anthropi'),
cols = c(aminopenicillins, amcl, tica, pita, czol, cfot, cftr, cfta, cfep, aztr, erta))
# Pseudomonas
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Pseudomonas aeruginosa'),
cols = c(aminopenicillins, amcl, czol, cfot, cftr, erta, chlo, kana, neom, trim, trsu, tetracyclines, tige))
# Stenotrophomonas
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Stenotrophomonas maltophilia'),
cols = c(aminopenicillins, amcl, tica, pita, czol, cfot, cftr, cfta, aztr, erta, imip, mero, aminoglycosides, trim, fosf, tetr))
# Table 3: Intrinsic resistance in other Gram-negative bacteria ----
if (info == TRUE) {
cat('- Table 3: Intrinsic resistance in other Gram-negative bacteria\n')
}
# Intrisiek R for this group
edit_rsi(to = 'R',
rows = which(tbl$genus %in% c('Haemophilus',
'Moraxella',
'Neisseria',
'Campylobacter')),
cols = c(glycopeptides, linc, dapt, line))
# Haemophilus
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Haemophilus influenzae'),
cols = c(fusi, streptogramins))
# Moraxella
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Moraxella catarrhalis'),
cols = trim)
# Neisseria
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Neisseria'),
cols = trim)
# Campylobacter
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Campylobacter fetus'),
cols = c(fusi, streptogramins, trim, nali))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Campylobacter (jejuni|coli)'),
cols = c(fusi, streptogramins, trim))
# Table 4: Intrinsic resistance in Gram-positive bacteria ----
if (info == TRUE) {
cat('- Table 4: Intrinsic resistance in Gram-positive bacteria\n')
}
# Intrisiek R for this group
edit_rsi(to = 'R',
rows = which(tbl$gramstain %like% 'Positi(e|)(v|f)'),
cols = c(aztr, polymyxins, nali))
# Staphylococcus
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Staphylococcus saprophyticus'),
cols = c(fusi, cfta, fosf, novo))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Staphylococcus (cohnii|xylosus)'),
cols = c(cfta, novo))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Staphylococcus capitis'),
cols = c(cfta, fosf))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Staphylococcus (aureus|epidermidis|coagulase negatief|hominis|haemolyticus|intermedius|pseudointermedius)'),
cols = cfta)
# Streptococcus
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Streptococcus'),
cols = c(fusi, cfta, aminoglycosides))
# Enterococcus
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Enterococcus faecalis'),
cols = c(fusi, cfta, cephalosporins[cephalosporins != cfta], aminoglycosides, macrolides, clin, qida, trim, trsu))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Enterococcus (gallinarum|casseliflavus)'),
cols = c(fusi, cfta, cephalosporins[cephalosporins != cfta], aminoglycosides, macrolides, clin, qida, vanc, trim, trsu))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Enterococcus faecium'),
cols = c(fusi, cfta, cephalosporins[cephalosporins != cfta], aminoglycosides, macrolides, trim, trsu))
# Corynebacterium
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Corynebacterium'),
cols = fosf)
# Listeria
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Listeria monocytogenes'),
cols = c(cfta, cephalosporins[cephalosporins != cfta]))
# overig
edit_rsi(to = 'R',
rows = which(tbl$genus %in% c('Leuconostoc', 'Pediococcus')),
cols = c(vanc, teic))
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Lactobacillus'),
cols = c(vanc, teic))
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Clostridium (ramosum|innocuum)'),
cols = vanc)
# Table 8: Interpretive rules for B-lactam agents and Gram-positive cocci ----
if (info == TRUE) {
cat('- Table 8: Interpretive rules for B-lactam agents and Gram-positive cocci\n')
}
# rule 8.3
if (!is.na(peni)) {
edit_rsi(to = 'S',
rows = which(tbl$fullname %like% '^Streptococcus (pyogenes|agalactiae|dysgalactiae|groep A|groep B|groep C|groep G)'
& tbl[, peni] == 'S'),
cols = c(aminopenicillins, cephalosporins, carbapenems))
}
# rule 8.6
if (!is.na(ampi)) {
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Enterococcus'
& tbl[, ampi] == 'R'),
cols = c(ureidopenicillins, carbapenems))
}
if (!is.na(amox)) {
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Enterococcus'
& tbl[, amox] == 'R'),
cols = c(ureidopenicillins, carbapenems))
}
# Table 9: Interpretive rules for B-lactam agents and Gram-negative rods ----
if (info == TRUE) {
cat('- Table 9: Interpretive rules for B-lactam agents and Gram-negative rods\n')
}
# rule 9.3
if (!is.na(tica) & !is.na(pita)) {
edit_rsi(to = 'R',
rows = which(tbl$family == 'Enterobacteriaceae'
& tbl[, tica] == 'R'
& tbl[, pita] == 'S'),
cols = pita)
}
# Table 10: Interpretive rules for B-lactam agents and other Gram-negative bacteria ----
if (info == TRUE) {
cat('- Table 10: Interpretive rules for B-lactam agents and other Gram-negative bacteria\n')
}
# rule 10.2
if (!is.na(ampi)) {
# you should know first if the are B-lactamase positive, so do not run for now
# edit_rsi(to = 'R',
# rows = which(tbl$fullname %like% '^Haemophilus influenza'
# & tbl[, ampi] == 'R'),
# cols = c(ampi, amox, amcl, pita, cfur))
}
# Table 11: Interpretive rules for macrolides, lincosamides, and streptogramins ----
if (info == TRUE) {
cat('- Table 11: Interpretive rules for macrolides, lincosamides, and streptogramins\n')
}
# rule 11.1
if (!is.na(eryt)) {
if (!is.na(azit)) {
tbl[, azit] <- tbl[, eryt]
}
if (!is.na(clar)) {
tbl[, clar] <- tbl[, eryt]
}
}
# Table 12: Interpretive rules for aminoglycosides ----
if (info == TRUE) {
cat('- Table 12: Interpretive rules for aminoglycosides\n')
}
# rule 12.2
if (!is.na(tobr)) {
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Staphylococcus'
& tbl[, tobr] == 'R'),
cols = c(kana, amik))
}
# rule 12.3
if (!is.na(gent)) {
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Staphylococcus'
& tbl[, gent] == 'R'),
cols = aminoglycosides)
}
# rule 12.8
if (!is.na(gent) & !is.na(tobr)) {
edit_rsi(to = 'R',
rows = which(tbl$family == 'Enterobacteriaceae'
& tbl[, gent] == 'I'
& tbl[, tobr] == 'S'),
cols = gent)
}
# rule 12.9
if (!is.na(gent) & !is.na(tobr)) {
edit_rsi(to = 'R',
rows = which(tbl$family == 'Enterobacteriaceae'
& tbl[, tobr] == 'I'
& tbl[, gent] == 'R'),
cols = tobr)
}
# Table 13: Interpretive rules for quinolones ----
if (info == TRUE) {
cat('- Table 13: Interpretive rules for quinolones\n')
}
# rule 13.2
if (!is.na(moxi)) {
edit_rsi(to = 'R',
rows = which(tbl$genus == 'Staphylococcus'
& tbl[, moxi] == 'R'),
cols = fluoroquinolones)
}
# rule 13.4
if (!is.na(moxi)) {
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Streptococcus pneumoniae'
& tbl[, moxi] == 'R'),
cols = fluoroquinolones)
}
# rule 13.5
if (!is.na(cipr)) {
edit_rsi(to = 'R',
rows = which(tbl$family == 'Enterobacteriaceae'
& tbl[, cipr] == 'R'),
cols = fluoroquinolones)
}
# rule 13.8
if (!is.na(cipr)) {
edit_rsi(to = 'R',
rows = which(tbl$fullname %like% '^Neisseria gonorrhoeae'
& tbl[, cipr] == 'R'),
cols = fluoroquinolones)
}
# Other ----
if (info == TRUE) {
cat('- Non-EUCAST: trim = R where trsu = R and ampi = R where amcl = R\n')
}
if (!is.na(amcl)) {
edit_rsi(to = 'R',
rows = which(tbl[, amcl] == 'R'),
cols = ampi)
}
if (!is.na(trsu)) {
edit_rsi(to = 'R',
rows = which(tbl[, trsu] == 'R'),
cols = trim)
}
if (info == TRUE) {
cat('- Non-EUCAST: trsu = S where trim = S and amcl = S where ampi = S\n')
}
if (!is.na(amcl)) {
edit_rsi(to = 'S',
rows = which(tbl[, ampi] == 'S'),
cols = amcl)
}
if (!is.na(trsu)) {
edit_rsi(to = 'S',
rows = which(tbl[, trim] == 'S'),
cols = trsu)
}
# amox = ampi
if (!is.na(ampi) & !is.na(amox)) {
tbl[, amox] <- tbl %>% pull(ampi)
}
# Remove added columns again
microorganisms.ncol <- ncol(AMR::microorganisms) - 2
tbl.ncol <- ncol(tbl)
tbl <- tbl %>% select(-c((tbl.ncol - microorganisms.ncol):tbl.ncol))
# and remove added suffices
colnames(tbl) <- gsub("_tempmicroorganisms", "", colnames(tbl))
if (info == TRUE) {
cat('Done.\n\nEUCAST Expert rules applied to',
total_rows %>% unique() %>% length() %>% format(big.mark = ","),
'different rows; overwritten a total of',
total %>% format(big.mark = ","), 'test results.\n\n')
}
tbl
}
#' @rdname EUCAST
#' @export
interpretive_reading <- function(...) {
EUCAST_rules(...)
}
#' Poperties of a microorganism
#'
#' @param bactid ID of a microorganisme, like \code{"STAAUR} and \code{"ESCCOL}
#' @param property One of the values \code{bactid}, \code{bactsys}, \code{family}, \code{genus}, \code{species}, \code{subspecies}, \code{fullname}, \code{type}, \code{gramstain}, \code{aerobic}
#' @export
#' @importFrom dplyr %>% filter select
#' @seealso \code{\link{microorganisms}}
mo_property <- function(bactid, property = 'fullname') {
mocode <- as.character(bactid)
for (i in 1:length(mocode)) {
bug <- mocode[i]
if (!is.na(bug)) {
result = tryCatch({
mocode[i] <-
AMR::microorganisms %>%
filter(bactid == bug) %>%
select(property) %>%
unlist() %>%
as.character()
}, error = function(error_condition) {
warning('Code ', bug, ' not found in bacteria list.')
}, finally = {
if (mocode[i] == bug & !property %in% c('bactid', 'bactsys')) {
mocode[i] <- NA
}
})
}
}
mocode
}
+427
View File
@@ -0,0 +1,427 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Determine first (weighted) isolates
#'
#' Determine first (weighted) isolates of all microorganisms of every patient per episode and (if needed) per specimen type.
#' @param tbl a \code{data.frame} containing isolates.
#' @param col_date column name of the result date (or date that is was received on the lab)
#' @param col_patient_id column name of the unique IDs of the patients
#' @param col_bactid column name of the unique IDs of the microorganisms: \code{bactid}'s. If this column has another class than \code{"bactid"}, values will be coerced using \code{\link{as.bactid}}.
#' @param col_testcode column name of the test codes. Use \code{col_testcode = NA} to \strong{not} exclude certain test codes (like test codes for screening). In that case \code{testcodes_exclude} will be ignored. Supports tidyverse-like quotation.
#' @param col_specimen column name of the specimen type or group
#' @param col_icu column name of the logicals (\code{TRUE}/\code{FALSE}) whether a ward or department is an Intensive Care Unit (ICU)
#' @param col_keyantibiotics column name of the key antibiotics to determine first \emph{weighted} isolates, see \code{\link{key_antibiotics}}. Supports tidyverse-like quotation.
#' @param episode_days episode in days after which a genus/species combination will be determined as 'first isolate' again
#' @param testcodes_exclude character vector with test codes that should be excluded (case-insensitive)
#' @param icu_exclude logical whether ICU isolates should be excluded
#' @param filter_specimen specimen group or type that should be excluded
#' @param output_logical return output as \code{logical} (will else be the values \code{0} or \code{1})
#' @param type type to determine weighed isolates; can be \code{"keyantibiotics"} or \code{"points"}, see Details
#' @param ignore_I logical to determine whether antibiotic interpretations with \code{"I"} will be ignored when \code{type = "keyantibiotics"}, see Details
#' @param points_threshold points until the comparison of key antibiotics will lead to inclusion of an isolate when \code{type = "points"}, see Details
#' @param info print progress
#' @param col_genus (deprecated, use \code{col_bactid} instead) column name of the genus of the microorganisms
#' @param col_species (deprecated, use \code{col_bactid} instead) column name of the species of the microorganisms
#' @details \strong{WHY THIS IS SO IMPORTANT} \cr
#' To conduct an analysis of antimicrobial resistance, you should only include the first isolate of every patient per episode \href{https://www.ncbi.nlm.nih.gov/pubmed/17304462}{[1]}. If you would not do this, you could easily get an overestimate or underestimate of the resistance of an antibiotic. Imagine that a patient was admitted with an MRSA and that it was found in 5 different blood cultures the following week. The resistance percentage of oxacillin of all \emph{S. aureus} isolates would be overestimated, because you included this MRSA more than once. It would be \href{https://en.wikipedia.org/wiki/Selection_bias}{selection bias}.
#' @section Key antibiotics:
#' There are two ways to determine whether isolates can be included as first \emph{weighted} isolates which will give generally the same results: \cr
#'
#' \strong{1. Using} \code{type = "keyantibiotics"} \strong{and parameter} \code{ignore_I} \cr
#' Any difference from S to R (or vice versa) will (re)select an isolate as a first weighted isolate. With \code{ignore_I = FALSE}, also differences from I to S|R (or vice versa) will lead to this. This is a reliable method and 30-35 times faster than method 2. \cr
#'
#' \strong{2. Using} \code{type = "points"} \strong{and parameter} \code{points_threshold} \cr
#' A difference from I to S|R (or vice versa) means 0.5 points, a difference from S to R (or vice versa) means 1 point. When the sum of points exceeds \code{points_threshold}, an isolate will be (re)selected as a first weighted isolate.
#' @keywords isolate isolates first
#' @seealso \code{\link{key_antibiotics}}
#' @export
#' @importFrom dplyr arrange_at lag between row_number filter mutate arrange
#' @return A vector to add to table, see Examples.
#' @source Methodology of this function is based on: \strong{M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 4th Edition}, 2014, \emph{Clinical and Laboratory Standards Institute (CLSI)}. \url{https://clsi.org/standards/products/microbiology/documents/m39/}.
#' @examples
#' # septic_patients is a dataset available in the AMR package. It is true, genuine data.
#' ?septic_patients
#'
#' library(dplyr)
#' my_patients <- septic_patients %>%
#' mutate(first_isolate = first_isolate(.,
#' col_date = "date",
#' col_patient_id = "patient_id",
#' col_bactid = "bactid"))
#'
#' # Now let's see if first isolates matter:
#' A <- my_patients %>%
#' group_by(hospital_id) %>%
#' summarise(count = n_rsi(gent), # gentamicin availability
#' resistance = portion_IR(gent)) # gentamicin resistance
#'
#' B <- my_patients %>%
#' filter(first_isolate == TRUE) %>% # the 1st isolate filter
#' group_by(hospital_id) %>%
#' summarise(count = n_rsi(gent), # gentamicin availability
#' resistance = portion_IR(gent)) # gentamicin resistance
#'
#' # Have a look at A and B.
#' # B is more reliable because every isolate is only counted once.
#' # Gentamicin resitance in hospital D appears to be 5.4% higher than
#' # when you (erroneously) would have used all isolates!
#'
#' ## OTHER EXAMPLES:
#'
#' \dontrun{
#'
#' # set key antibiotics to a new variable
#' tbl$keyab <- key_antibiotics(tbl)
#'
#' tbl$first_isolate <-
#' first_isolate(tbl)
#'
#' tbl$first_isolate_weighed <-
#' first_isolate(tbl,
#' col_keyantibiotics = 'keyab')
#'
#' tbl$first_blood_isolate <-
#' first_isolate(tbl,
#' filter_specimen = 'Blood')
#'
#' tbl$first_blood_isolate_weighed <-
#' first_isolate(tbl,
#' filter_specimen = 'Blood',
#' col_keyantibiotics = 'keyab')
#'
#' tbl$first_urine_isolate <-
#' first_isolate(tbl,
#' filter_specimen = 'Urine')
#'
#' tbl$first_urine_isolate_weighed <-
#' first_isolate(tbl,
#' filter_specimen = 'Urine',
#' col_keyantibiotics = 'keyab')
#'
#' tbl$first_resp_isolate <-
#' first_isolate(tbl,
#' filter_specimen = 'Respiratory')
#'
#' tbl$first_resp_isolate_weighed <-
#' first_isolate(tbl,
#' filter_specimen = 'Respiratory',
#' col_keyantibiotics = 'keyab')
#' }
first_isolate <- function(tbl,
col_date,
col_patient_id,
col_bactid = NA,
col_testcode = NA,
col_specimen = NA,
col_icu = NA,
col_keyantibiotics = NA,
episode_days = 365,
testcodes_exclude = '',
icu_exclude = FALSE,
filter_specimen = NA,
output_logical = TRUE,
type = "keyantibiotics",
ignore_I = TRUE,
points_threshold = 2,
info = TRUE,
col_genus = NA,
col_species = NA) {
# bactid OR genus+species must be available
if (is.na(col_bactid) & (is.na(col_genus) | is.na(col_species))) {
stop('`col_bactid` or both `col_genus` and `col_species` must be available.')
}
# check if columns exist
check_columns_existance <- function(column, tblname = tbl) {
if (NROW(tblname) <= 1 | NCOL(tblname) <= 1) {
stop('Please check tbl for existance.')
}
if (!is.na(column)) {
if (!(column %in% colnames(tblname))) {
stop('Column `', column, '` not found.')
}
}
}
check_columns_existance(col_date)
check_columns_existance(col_patient_id)
check_columns_existance(col_bactid)
check_columns_existance(col_genus)
check_columns_existance(col_species)
check_columns_existance(col_testcode)
check_columns_existance(col_icu)
check_columns_existance(col_keyantibiotics)
if (!is.na(col_bactid)) {
if (!tbl %>% pull(col_bactid) %>% is.bactid()) {
warning("Improve integrity of the `", col_bactid, "` column by transforming it with 'as.bactid'.")
}
# join to microorganisms data set
tbl <- tbl %>% left_join_microorganisms(by = col_bactid)
col_genus <- "genus"
col_species <- "species"
}
if (is.na(col_testcode)) {
testcodes_exclude <- NA
}
# remove testcodes
if (!is.na(testcodes_exclude[1]) & testcodes_exclude[1] != '' & info == TRUE) {
cat('[Criteria] Excluded test codes:\n', toString(testcodes_exclude), '\n')
}
if (is.na(col_icu)) {
icu_exclude <- FALSE
} else {
tbl <- tbl %>%
mutate(col_icu = tbl %>% pull(col_icu) %>% as.logical())
}
if (is.na(col_specimen)) {
filter_specimen <- ''
}
# filter on specimen group and keyantibiotics when they are filled in
if (!is.na(filter_specimen) & filter_specimen != '') {
check_columns_existance(col_specimen, tbl)
if (info == TRUE) {
cat('[Criteria] Excluded other than specimen group \'', filter_specimen, '\'\n', sep = '')
}
} else {
filter_specimen <- ''
}
if (col_keyantibiotics %in% c(NA, '')) {
col_keyantibiotics <- ''
} else {
tbl <- tbl %>% mutate(key_ab = tbl %>% pull(col_keyantibiotics))
}
if (is.na(testcodes_exclude[1])) {
testcodes_exclude <- ''
}
# create new dataframe with original row index and right sorting
tbl <- tbl %>%
mutate(first_isolate_row_index = 1:nrow(tbl),
date_lab = tbl %>% pull(col_date),
patient_id = tbl %>% pull(col_patient_id),
species = tbl %>% pull(col_species),
genus = tbl %>% pull(col_genus)) %>%
mutate(species = if_else(is.na(species) | species == "(no MO)", "", species),
genus = if_else(is.na(genus) | genus == "(no MO)", "", genus))
if (filter_specimen == '') {
if (icu_exclude == FALSE) {
if (info == TRUE & !is.na(col_icu)) {
cat('[Criteria] Included isolates from ICU.\n')
}
tbl <- tbl %>%
arrange_at(c(col_patient_id,
col_genus,
col_species,
col_date))
row.start <- 1
row.end <- nrow(tbl)
} else {
if (info == TRUE) {
cat('[Criteria] Excluded isolates from ICU.\n')
}
tbl <- tbl %>%
arrange_at(c(col_icu,
col_patient_id,
col_genus,
col_species,
col_date))
suppressWarnings(
row.start <- which(tbl %>% pull(col_icu) == FALSE) %>% min(na.rm = TRUE)
)
suppressWarnings(
row.end <- which(tbl %>% pull(col_icu) == FALSE) %>% max(na.rm = TRUE)
)
}
} else {
# sort on specimen and only analyse these row to save time
if (icu_exclude == FALSE) {
if (info == TRUE & !is.na(col_icu)) {
cat('[Criteria] Included isolates from ICU.\n')
}
tbl <- tbl %>%
arrange_at(c(col_specimen,
col_patient_id,
col_genus,
col_species,
col_date))
suppressWarnings(
row.start <- which(tbl %>% pull(col_specimen) == filter_specimen) %>% min(na.rm = TRUE)
)
suppressWarnings(
row.end <- which(tbl %>% pull(col_specimen) == filter_specimen) %>% max(na.rm = TRUE)
)
} else {
if (info == TRUE) {
cat('[Criteria] Excluded isolates from ICU.\n')
}
tbl <- tbl %>%
arrange_at(c(col_icu,
col_specimen,
col_patient_id,
col_genus,
col_species,
col_date))
suppressWarnings(
row.start <- which(tbl %>% pull(col_specimen) == filter_specimen
& tbl %>% pull(col_icu) == FALSE) %>% min(na.rm = TRUE)
)
suppressWarnings(
row.end <- which(tbl %>% pull(col_specimen) == filter_specimen
& tbl %>% pull(col_icu) == FALSE) %>% max(na.rm = TRUE)
)
}
}
if (abs(row.start) == Inf | abs(row.end) == Inf) {
if (info == TRUE) {
message('No isolates found.')
}
# NA's where genus is unavailable
tbl <- tbl %>%
mutate(real_first_isolate = if_else(genus == '', NA, FALSE))
if (output_logical == FALSE) {
tbl$real_first_isolate <- tbl %>% pull(real_first_isolate) %>% as.integer()
}
return(tbl %>% pull(real_first_isolate))
}
# suppress warnings because dplyr want us to use library(dplyr) when using filter(row_number())
suppressWarnings(
scope.size <- tbl %>%
filter(
row_number() %>% between(row.start,
row.end),
genus != '') %>%
nrow()
)
# Analysis of first isolate ----
all_first <- tbl %>%
mutate(other_pat_or_mo = if_else(patient_id == lag(patient_id)
& genus == lag(genus)
& species == lag(species),
FALSE,
TRUE),
days_diff = 0) %>%
mutate(days_diff = if_else(other_pat_or_mo == FALSE,
(date_lab - lag(date_lab)) + lag(days_diff),
0))
weighted.notice <- ''
if (col_keyantibiotics != '') {
weighted.notice <- 'weighted '
if (info == TRUE) {
if (type == 'keyantibiotics') {
cat('[Criteria] Inclusion based on key antibiotics, ')
if (ignore_I == FALSE) {
cat('not ')
}
cat('ignoring I.\n')
}
if (type == 'points') {
cat(paste0('[Criteria] Inclusion based on key antibiotics, using points threshold of '
, points_threshold, '.\n'))
}
}
type_param <- type
# suppress warnings because dplyr want us to use library(dplyr) when using filter(row_number())
suppressWarnings(
all_first <- all_first %>%
mutate(key_ab_lag = lag(key_ab)) %>%
mutate(key_ab_other = !key_antibiotics_equal(x = key_ab,
y = key_ab_lag,
type = type_param,
ignore_I = ignore_I,
points_threshold = points_threshold,
info = info)) %>%
mutate(
real_first_isolate =
if_else(
between(row_number(), row.start, row.end)
& genus != ''
& (other_pat_or_mo
| days_diff >= episode_days
| key_ab_other),
TRUE,
FALSE))
)
} else {
# suppress warnings because dplyr want us to use library(dplyr) when using filter(row_number())
suppressWarnings(
all_first <- all_first %>%
mutate(
real_first_isolate =
if_else(
between(row_number(), row.start, row.end)
& genus != ''
& (other_pat_or_mo
| days_diff >= episode_days),
TRUE,
FALSE))
)
}
# first one as TRUE
all_first[row.start, 'real_first_isolate'] <- TRUE
# no tests that should be included, or ICU
if (!is.na(col_testcode)) {
all_first[which(all_first[, col_testcode] %in% tolower(testcodes_exclude)), 'real_first_isolate'] <- FALSE
}
if (icu_exclude == TRUE) {
all_first[which(all_first[, col_icu] == TRUE), 'real_first_isolate'] <- FALSE
}
# NA's where genus is unavailable
all_first <- all_first %>%
mutate(real_first_isolate = if_else(genus %in% c('', '(no MO)', NA), NA, real_first_isolate))
all_first <- all_first %>%
arrange(first_isolate_row_index) %>%
pull(real_first_isolate)
if (info == TRUE) {
message(paste0('Found ',
all_first %>% sum(na.rm = TRUE),
' first ', weighted.notice, 'isolates (',
(all_first %>% sum(na.rm = TRUE) / scope.size) %>% percent(),
' of isolates in scope [where genus was not empty] and ',
(all_first %>% sum(na.rm = TRUE) / tbl %>% nrow()) %>% percent(),
' of total)'))
}
if (output_logical == FALSE) {
all_first <- all_first %>% as.integer()
}
all_first
}
Executable
+643
View File
@@ -0,0 +1,643 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Frequency table
#'
#' Create a frequency table of a vector with items or a data frame. Supports quasiquotation and markdown for reports. \code{top_freq} can be used to get the top/bottom \emph{n} items of a frequency table, with counts as names.
#' @param x vector of any class or a \code{\link{data.frame}}, \code{\link{tibble}} or \code{\link{table}}
#' @param ... up to nine different columns of \code{x} when \code{x} is a \code{data.frame} or \code{tibble}, to calculate frequencies from - see Examples
#' @param sort.count sort on count, i.e. frequencies. This will be \code{TRUE} at default for everything except for factors.
#' @param nmax number of row to print. The default, \code{15}, uses \code{\link{getOption}("max.print.freq")}. Use \code{nmax = 0}, \code{nmax = Inf}, \code{nmax = NULL} or \code{nmax = NA} to print all rows.
#' @param na.rm a logical value indicating whether \code{NA} values should be removed from the frequency table. The header will always print the amount of \code{NA}s.
#' @param row.names a logical value indicating whether row indices should be printed as \code{1:nrow(x)}
#' @param markdown print table in markdown format (this forces \code{nmax = NA})
#' @param digits how many significant digits are to be used for numeric values in the header (not for the items themselves, that depends on \code{\link{getOption}("digits")})
#' @param sep a character string to separate the terms when selecting multiple columns
#' @param f a frequency table
#' @param n number of top \emph{n} items to return, use -n for the bottom \emph{n} items. It will include more than \code{n} rows if there are ties.
#' @details Frequency tables (or frequency distributions) are summaries of the distribution of values in a sample. With the `freq` function, you can create univariate frequency tables. Multiple variables will be pasted into one variable, so it forces a univariate distribution. This package also has a vignette available to explain the use of this function further, run \code{browseVignettes("AMR")} to read it.
#'
#' For numeric values of any class, these additional values will all be calculated with \code{na.rm = TRUE} and shown into the header:
#' \itemize{
#' \item{Mean, using \code{\link[base]{mean}}}
#' \item{Standard Deviation, using \code{\link[stats]{sd}}}
#' \item{Coefficient of Variation (CV), the standard deviation divided by the mean}
#' \item{Mean Absolute Deviation (MAD), using \code{\link[stats]{mad}}}
#' \item{Tukey Five-Number Summaries (minimum, Q1, median, Q3, maximum), using \code{\link[stats]{fivenum}}}
#' \item{Interquartile Range (IQR) calculated as \code{Q3 - Q1} using the Tukey Five-Number Summaries, i.e. \strong{not} using the \code{\link[stats]{quantile}} function}
#' \item{Coefficient of Quartile Variation (CQV, sometimes called coefficient of dispersion), calculated as \code{(Q3 - Q1) / (Q3 + Q1)} using the Tukey Five-Number Summaries}
#' \item{Outliers (total count and unique count), using \code{\link[grDevices]{boxplot.stats}}}
#' }
#'
#' For dates and times of any class, these additional values will be calculated with \code{na.rm = TRUE} and shown into the header:
#' \itemize{
#' \item{Oldest, using \code{\link{min}}}
#' \item{Newest, using \code{\link{max}}, with difference between newest and oldest}
#' \item{Median, using \code{\link[stats]{median}}, with percentage since oldest}
#' }
#'
#'
#' The function \code{top_freq} uses \code{\link[dplyr]{top_n}} internally and will include more than \code{n} rows if there are ties.
#' @importFrom stats fivenum sd mad
#' @importFrom grDevices boxplot.stats
#' @importFrom dplyr %>% select pull n_distinct group_by arrange desc mutate summarise n_distinct
#' @importFrom utils browseVignettes installed.packages
#' @importFrom tibble tibble
#' @keywords summary summarise frequency freq
#' @rdname freq
#' @name freq
#' @return A \code{data.frame} with an additional class \code{"frequency_tbl"}
#' @export
#' @examples
#' library(dplyr)
#'
#' # this all gives the same result:
#' freq(septic_patients$hospital_id)
#' freq(septic_patients[, "hospital_id"])
#' septic_patients$hospital_id %>% freq()
#' septic_patients[, "hospital_id"] %>% freq()
#' septic_patients %>% freq("hospital_id")
#' septic_patients %>% freq(hospital_id) #<- easiest to remember when you're used to tidyverse
#'
#' # you could also use `select` or `pull` to get your variables
#' septic_patients %>%
#' filter(hospital_id == "A") %>%
#' select(bactid) %>%
#' freq()
#'
#' # multiple selected variables will be pasted together
#' septic_patients %>%
#' left_join_microorganisms %>%
#' filter(hospital_id == "A") %>%
#' freq(genus, species)
#'
#' # get top 10 bugs of hospital A as a vector
#' septic_patients %>%
#' filter(hospital_id == "A") %>%
#' freq(bactid) %>%
#' top_freq(10)
#'
#' # save frequency table to an object
#' years <- septic_patients %>%
#' mutate(year = format(date, "%Y")) %>%
#' freq(year)
#'
#' # show only the top 5
#' years %>% print(nmax = 5)
#'
#' # save to an object with formatted percentages
#' years <- format(years)
#'
#' # print a histogram of numeric values
#' septic_patients %>%
#' freq(age) %>%
#' hist() # prettier: ggplot(septic_patients, aes(age)) + geom_histogram()
#'
#' # or print all points to a regular plot
#' septic_patients %>%
#' freq(age) %>%
#' plot()
#'
#' # transform to a data.frame or tibble
#' septic_patients %>%
#' freq(age) %>%
#' as.data.frame()
#'
#' # or transform (back) to a vector
#' septic_patients %>%
#' freq(age) %>%
#' as.vector()
#'
#' identical(septic_patients %>%
#' freq(age) %>%
#' as.vector() %>%
#' sort(),
#' sort(septic_patients$age)) # TRUE
#'
#' # it also supports `table` objects:
#' table(septic_patients$sex,
#' septic_patients$age) %>%
#' freq(sep = " **sep** ")
#'
#' \dontrun{
#' # send frequency table to clipboard (e.g. for pasting in Excel)
#' septic_patients %>%
#' freq(age) %>%
#' format() %>% # this will format the percentages
#' clipboard_export()
#' }
frequency_tbl <- function(x,
...,
sort.count = TRUE,
nmax = getOption("max.print.freq"),
na.rm = TRUE,
row.names = TRUE,
markdown = FALSE,
digits = 2,
sep = " ") {
mult.columns <- 0
if (any(class(x) == 'data.frame')) {
x.name <- deparse(substitute(x))
if (x.name == ".") {
x.name <- NULL
}
dots <- base::eval(base::substitute(base::alist(...)))
ndots <- length(dots)
if (NROW(x) == 0) {
x <- NA
} else if (ndots > 0 & ndots < 10) {
cols <- as.character(dots)
if (!all(cols %in% colnames(x))) {
stop("one or more columns not found: `", paste(cols, collapse = "`, `"), '`', call. = FALSE)
}
x <- x[, cols]
} else if (ndots >= 10) {
stop('A maximum of 9 columns can be analysed at the same time.', call. = FALSE)
} else {
cols <- NULL
}
} else if (any(class(x) == 'table')) {
if (!"tidyr" %in% rownames(installed.packages())) {
stop('transformation from `table` to frequency table requires the tidyr package.', call. = FALSE)
}
x <- x %>%
as.data.frame(stringsAsFactors = FALSE) %>%
# paste first two columns
tidyr::unite(col = "Pasted", 1:2, sep = sep, remove = TRUE)
x <- rep(x %>% pull(Pasted), x %>% pull(Freq))
x.name <- "a `table` object"
cols <- NULL
mult.columns <- 2
} else {
x.name <- NULL
cols <- NULL
}
if (!is.null(ncol(x))) {
if (ncol(x) == 1 & any(class(x) == 'data.frame')) {
x <- x %>% pull(1)
} else if (ncol(x) < 10) {
mult.columns <- ncol(x)
colnames(x) <- LETTERS[1:ncol(x)]
if (ncol(x) == 2) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
sep = sep)
} else if (ncol(x) == 3) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
x$C %>% as.character(),
sep = sep)
} else if (ncol(x) == 4) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
x$C %>% as.character(),
x$D %>% as.character(),
sep = sep)
} else if (ncol(x) == 5) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
x$C %>% as.character(),
x$D %>% as.character(),
x$E %>% as.character(),
sep = sep)
} else if (ncol(x) == 6) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
x$C %>% as.character(),
x$D %>% as.character(),
x$E %>% as.character(),
x$F %>% as.character(),
sep = sep)
} else if (ncol(x) == 7) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
x$C %>% as.character(),
x$D %>% as.character(),
x$E %>% as.character(),
x$F %>% as.character(),
x$G %>% as.character(),
sep = sep)
} else if (ncol(x) == 8) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
x$C %>% as.character(),
x$D %>% as.character(),
x$E %>% as.character(),
x$F %>% as.character(),
x$G %>% as.character(),
x$H %>% as.character(),
sep = sep)
} else if (ncol(x) == 9) {
x$total <- paste(x$A %>% as.character(),
x$B %>% as.character(),
x$C %>% as.character(),
x$D %>% as.character(),
x$E %>% as.character(),
x$F %>% as.character(),
x$G %>% as.character(),
x$H %>% as.character(),
x$I %>% as.character(),
sep = sep)
}
x <- x$total
} else {
stop('A maximum of 9 columns can be analysed at the same time.', call. = FALSE)
}
}
if (mult.columns > 1) {
NAs <- x[is.na(x) | x == trimws(strrep('NA ', mult.columns))]
} else {
NAs <- x[is.na(x)]
}
if (na.rm == TRUE) {
x_class <- class(x)
x <- x[!x %in% NAs]
class(x) <- x_class
}
if (missing(sort.count) & 'factor' %in% class(x)) {
# sort on factor level at default when x is a factor and sort.count is not set
sort.count <- FALSE
}
header <- character(0)
markdown_line <- ''
if (markdown == TRUE) {
markdown_line <- '\n'
}
x_align <- 'l'
if (mult.columns > 0) {
header <- header %>% paste0(markdown_line, 'Columns: ', mult.columns)
} else {
header <- header %>% paste0(markdown_line, 'Class: ', class(x) %>% rev() %>% paste(collapse = " > "))
}
if (is.list(x) | is.matrix(x) | is.environment(x) | is.function(x)) {
stop('frequency tables do not support lists, matrices, environments and functions.', call. = FALSE)
}
header <- header %>% paste0(markdown_line, '\nLength: ', (NAs %>% length() + x %>% length()) %>% format(),
' (of which NA: ', NAs %>% length() %>% format(),
' = ', (NAs %>% length() / (NAs %>% length() + x %>% length())) %>% percent(force_zero = TRUE, round = digits) %>% sub('NaN', '0', ., fixed = TRUE), ')')
header <- header %>% paste0(markdown_line, '\nUnique: ', x %>% n_distinct() %>% format())
if (NROW(x) > 0 & any(class(x) %in% c('double', 'integer', 'numeric', 'raw', 'single'))) {
# right align number
Tukey_five <- stats::fivenum(x, na.rm = TRUE)
x_align <- 'r'
header <- header %>% paste0('\n')
header <- header %>% paste(markdown_line, '\nMean: ', x %>% base::mean(na.rm = TRUE) %>% format(digits = digits))
header <- header %>% paste0(markdown_line, '\nStd. dev.: ', x %>% stats::sd(na.rm = TRUE) %>% format(digits = digits),
' (CV: ', x %>% cv(na.rm = TRUE) %>% format(digits = digits),
', MAD: ', x %>% stats::mad(na.rm = TRUE) %>% format(digits = digits), ')')
header <- header %>% paste0(markdown_line, '\nFive-Num: ', Tukey_five %>% format(digits = digits) %>% trimws() %>% paste(collapse = ' | '),
' (IQR: ', (Tukey_five[4] - Tukey_five[2]) %>% format(digits = digits),
', CQV: ', x %>% cqv(na.rm = TRUE) %>% format(digits = digits), ')')
outlier_length <- length(boxplot.stats(x)$out)
header <- header %>% paste0(markdown_line, '\nOutliers: ', outlier_length)
if (outlier_length > 0) {
header <- header %>% paste0(' (unique: ', boxplot.stats(x)$out %>% n_distinct(), ')')
}
}
if (NROW(x) > 0 & any(class(x) == "rsi")) {
header <- header %>% paste0('\n')
cnt_S <- sum(x == "S")
cnt_I <- sum(x == "I")
cnt_R <- sum(x == "R")
header <- header %>% paste(markdown_line, '\n%IR: ',
((cnt_I + cnt_R) / sum(!is.na(x))) %>% percent(force_zero = TRUE, round = digits))
header <- header %>% paste0(markdown_line, '\nRatio SIR: 1.0 : ',
(cnt_I / cnt_S) %>% format(digits = 1, nsmall = 1), " : ",
(cnt_R / cnt_S) %>% format(digits = 1, nsmall = 1))
}
formatdates <- "%e %B %Y" # = d mmmm yyyy
if (any(class(x) == 'hms')) {
x <- x %>% as.POSIXlt()
formatdates <- "%H:%M:%S"
}
if (NROW(x) > 0 & any(class(x) %in% c('Date', 'POSIXct', 'POSIXlt'))) {
header <- header %>% paste0('\n')
mindate <- x %>% min(na.rm = TRUE)
maxdate <- x %>% max(na.rm = TRUE)
maxdate_days <- difftime(maxdate, mindate, units = 'auto') %>% as.double()
mediandate <- x %>% median(na.rm = TRUE)
median_days <- difftime(mediandate, mindate, units = 'auto') %>% as.double()
header <- header %>% paste0(markdown_line, '\nOldest: ', mindate %>% format(formatdates) %>% trimws())
header <- header %>% paste0(markdown_line, '\nNewest: ', maxdate %>% format(formatdates) %>% trimws(),
' (+', difftime(maxdate, mindate, units = 'auto') %>% as.double() %>% format(), ')')
header <- header %>% paste0(markdown_line, '\nMedian: ', mediandate %>% format(formatdates) %>% trimws(),
' (~', percent(median_days / maxdate_days, round = 0), ')')
}
if (any(class(x) == 'POSIXlt')) {
x <- x %>% format(formatdates)
}
nmax.set <- !missing(nmax)
if (!nmax.set & is.null(nmax) & is.null(base::getOption("max.print.freq", default = NULL))) {
# default for max print setting
nmax <- 15
} else if (is.null(nmax)) {
nmax <- length(x)
}
if (nmax %in% c(0, Inf, NA, NULL)) {
nmax <- length(x)
}
# create table with counts and percentages
column_names <- c('Item', 'Count', 'Percent', 'Cum. Count', 'Cum. Percent', '(Factor Level)')
column_names_df <- c('item', 'count', 'percent', 'cum_count', 'cum_percent', 'factor_level')
if (any(class(x) == 'factor')) {
df <- tibble::tibble(item = x,
fctlvl = x %>% as.integer()) %>%
group_by(item, fctlvl)
column_align <- c('l', 'r', 'r', 'r', 'r', 'r')
} else {
df <- tibble::tibble(item = x) %>%
group_by(item)
# strip factor lvl from col names
column_names <- column_names[1:length(column_names) - 1]
column_names_df <- column_names_df[1:length(column_names_df) - 1]
column_align <- c(x_align, 'r', 'r', 'r', 'r')
}
df <- df %>% summarise(count = n())
if (df$item %>% paste(collapse = ',') %like% '\033') {
df <- df %>%
mutate(item = item %>%
# remove escape char
# see https://en.wikipedia.org/wiki/Escape_character#ASCII_escape_character
gsub('\033', ' ', ., fixed = TRUE))
}
# sort according to setting
if (sort.count == TRUE) {
df <- df %>% arrange(desc(count), item)
} else {
if (any(class(x) == 'factor')) {
df <- df %>% arrange(fctlvl, item)
} else {
df <- df %>% arrange(item)
}
}
df <- as.data.frame(df, stringsAsFactors = FALSE)
df$percent <- df$count / base::sum(df$count, na.rm = TRUE)
df$cum_count <- base::cumsum(df$count)
df$cum_percent <- df$cum_count / base::sum(df$count, na.rm = TRUE)
if (any(class(x) == 'factor')) {
# put factor last
df <- df %>% select(item, count, percent, cum_count, cum_percent, fctlvl)
}
colnames(df) <- column_names_df
class(df) <- c('frequency_tbl', class(df))
attr(df, 'package') <- 'AMR'
if (markdown == TRUE) {
tbl_format <- 'markdown'
} else {
tbl_format <- 'pandoc'
}
attr(df, 'opt') <- list(data = x.name,
vars = cols,
header = header,
row_names = row.names,
column_names = column_names,
column_align = column_align,
tbl_format = tbl_format,
nmax = nmax,
nmax.set = nmax.set)
df
}
#' @rdname freq
#' @export
freq <- frequency_tbl
#' @rdname freq
#' @export
#' @importFrom dplyr top_n pull
top_freq <- function(f, n) {
if (!'frequency_tbl' %in% class(f)) {
stop('top_freq can only be applied to frequency tables', call. = FALSE)
}
if (!is.numeric(n) | length(n) != 1L) {
stop('For top_freq, `nmax` must be a number of length 1', call. = FALSE)
}
top <- f %>% top_n(n, count)
vect <- top %>% pull(item)
names(vect) <- top %>% pull(count)
if (length(vect) > abs(n)) {
message("top_freq: selecting ", length(vect), " items instead of ", abs(n), ", because of ties")
}
vect
}
#' @rdname freq
#' @exportMethod print.frequency_tbl
#' @importFrom knitr kable
#' @importFrom dplyr n_distinct
#' @export
print.frequency_tbl <- function(x, nmax = getOption("max.print.freq", default = 15), ...) {
opt <- attr(x, 'opt')
if (!is.null(opt$data) & !is.null(opt$vars)) {
title <- paste0("of `", paste0(opt$vars, collapse = "` and `"), "` from ", opt$data)
} else if (!is.null(opt$data) & is.null(opt$vars)) {
title <- paste("of", opt$data)
} else if (is.null(opt$data) & !is.null(opt$vars)) {
title <- paste0("of `", paste0(opt$vars, collapse = "` and `"), "`")
} else {
title <- ""
}
if (!missing(nmax)) {
opt$nmax <- nmax
opt$nmax.set <- TRUE
}
cat("Frequency table", title, "\n")
if (!is.null(opt$header)) {
cat(opt$header)
}
if (NROW(x) == 0) {
cat('\n\nNo observations.\n')
return(invisible())
}
if (all(x$count == 1)) {
warning('All observations are unique.', call. = FALSE)
}
# save old NA setting for kable
opt.old <- options()$knitr.kable.NA
options(knitr.kable.NA = "<NA>")
if (nrow(x) > opt$nmax & opt$tbl_format != "markdown") {
x.rows <- nrow(x)
x.unprinted <- base::sum(x[(opt$nmax + 1):nrow(x), 'count'], na.rm = TRUE)
x.printed <- base::sum(x$count) - x.unprinted
if (opt$nmax.set == TRUE) {
nmax <- opt$nmax
} else {
nmax <- getOption("max.print.freq", default = 15)
}
x <- x[1:nmax,]
if (opt$nmax.set == TRUE) {
footer <- paste('[ reached `nmax = ', opt$nmax, '`', sep = '')
} else {
footer <- '[ reached getOption("max.print.freq")'
}
footer <- paste(footer,
' -- omitted ',
format(x.rows - opt$nmax),
' entries, n = ',
format(x.unprinted),
' (',
(x.unprinted / (x.unprinted + x.printed)) %>% percent(force_zero = TRUE),
') ]\n', sep = '')
} else {
footer <- NULL
}
if (any(class(x$item) %in% c('double', 'integer', 'numeric', 'raw', 'single'))) {
x$item <- format(x$item)
}
x$count <- format(x$count)
x$percent <- percent(x$percent, force_zero = TRUE)
x$cum_count <- format(x$cum_count)
x$cum_percent <- percent(x$cum_percent, force_zero = TRUE)
print(
knitr::kable(x,
format = opt$tbl_format,
row.names = opt$row_names,
col.names = opt$column_names,
align = opt$column_align,
padding = 1)
)
if (!is.null(footer)) {
cat(footer)
}
cat('\n')
# reset old kable setting
options(knitr.kable.NA = opt.old)
return(invisible())
}
#' @noRd
#' @exportMethod as.data.frame.frequency_tbl
#' @export
as.data.frame.frequency_tbl <- function(x, ...) {
attr(x, 'package') <- NULL
attr(x, 'opt') <- NULL
as.data.frame.data.frame(x, ...)
}
#' @noRd
#' @exportMethod as_tibble.frequency_tbl
#' @export
#' @importFrom dplyr as_tibble
as_tibble.frequency_tbl <- function(x, validate = TRUE, ..., rownames = NA) {
attr(x, 'package') <- NULL
attr(x, 'opt') <- NULL
as_tibble(x = as.data.frame(x), validate = validate, ..., rownames = rownames)
}
#' @noRd
#' @exportMethod hist.frequency_tbl
#' @export
#' @importFrom graphics hist
hist.frequency_tbl <- function(x, ...) {
opt <- attr(x, 'opt')
if (!is.null(opt$vars)) {
title <- opt$vars
} else {
title <- ""
}
hist(as.vector(x), main = paste("Histogram of", title), xlab = title, ...)
}
#' @noRd
#' @exportMethod plot.frequency_tbl
#' @export
plot.frequency_tbl <- function(x, y, ...) {
opt <- attr(x, 'opt')
if (!is.null(opt$vars)) {
title <- opt$vars
} else {
title <- ""
}
plot(x = x$item, y = x$count, ylab = "Count", xlab = title, ...)
}
#' @noRd
#' @exportMethod as.vector.frequency_tbl
#' @export
as.vector.frequency_tbl <- function(x, mode = "any") {
as.vector(rep(x$item, x$count), mode = mode)
}
#' @noRd
#' @exportMethod format.frequency_tbl
#' @export
format.frequency_tbl <- function(x, digits = 1, ...) {
opt <- attr(x, 'opt')
if (opt$nmax.set == TRUE) {
nmax <- opt$nmax
} else {
nmax <- getOption("max.print.freq", default = 15)
}
x <- x[1:nmax,]
x$percent <- percent(x$percent, round = digits, force_zero = TRUE)
x$cum_percent <- percent(x$cum_percent, round = digits, force_zero = TRUE)
base::format.data.frame(x, ...)
}
+257
View File
@@ -0,0 +1,257 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' \emph{G}-test for Count Data
#'
#' \code{g.test} performs chi-squared contingency table tests and goodness-of-fit tests, just like \code{\link{chisq.test}} but is more reliable [1]. A \emph{G}-test can be used to see whether the number of observations in each category fits a theoretical expectation (called a \strong{\emph{G}-test of goodness-of-fit}), or to see whether the proportions of one variable are different for different values of the other variable (called a \strong{\emph{G}-test of independence}).
#' @inherit stats::chisq.test params return
#' @details If \code{x} is a matrix with one row or column, or if \code{x} is a vector and \code{y} is not given, then a \emph{goodness-of-fit test} is performed (\code{x} is treated as a one-dimensional contingency table). The entries of \code{x} must be non-negative integers. In this case, the hypothesis tested is whether the population probabilities equal those in \code{p}, or are all equal if \code{p} is not given.
#'
#' If \code{x} is a matrix with at least two rows and columns, it is taken as a two-dimensional contingency table: the entries of \code{x} must be non-negative integers. Otherwise, \code{x} and \code{y} must be vectors or factors of the same length; cases with missing values are removed, the objects are coerced to factors, and the contingency table is computed from these. Then Pearson's chi-squared test is performed of the null hypothesis that the joint distribution of the cell counts in a 2-dimensional contingency table is the product of the row and column marginals.
#'
#' The p-value is computed from the asymptotic chi-squared distribution of the test statistic.
#'
#' In the contingency table case simulation is done by random sampling from the set of all contingency tables with given marginals, and works only if the marginals are strictly positive. Note that this is not the usual sampling situation assumed for a chi-squared test (like the \emph{G}-test) but rather that for Fisher's exact test.
#'
#' In the goodness-of-fit case simulation is done by random sampling from the discrete distribution specified by \code{p}, each sample being of size \code{n = sum(x)}. This simulation is done in \R and may be slow.
#' @section \emph{G}-test of goodness-of-fit (likelihood ratio test):
#' Use the \emph{G}-test of goodness-of-fit when you have one nominal variable with two or more values (such as male and female, or red, pink and white flowers). You compare the observed counts of numbers of observations in each category with the expected counts, which you calculate using some kind of theoretical expectation (such as a 1:1 sex ratio or a 1:2:1 ratio in a genetic cross).
#'
#' If the expected number of observations in any category is too small, the \emph{G}-test may give inaccurate results, and you should use an exact test instead (\code{\link{fisher.test}}).
#'
#' The \emph{G}-test of goodness-of-fit is an alternative to the chi-square test of goodness-of-fit (\code{\link{chisq.test}}); each of these tests has some advantages and some disadvantages, and the results of the two tests are usually very similar.
#'
#' @section \emph{G}-test of independence:
#' Use the \emph{G}-test of independence when you have two nominal variables, each with two or more possible values. You want to know whether the proportions for one variable are different among values of the other variable.
#'
#' It is also possible to do a \emph{G}-test of independence with more than two nominal variables. For example, Jackson et al. (2013) also had data for children under 3, so you could do an analysis of old vs. young, thigh vs. arm, and reaction vs. no reaction, all analyzed together.
#'
#' Fisher's exact test (\code{\link{fisher.test}}) is more accurate than the \emph{G}-test of independence when the expected numbers are small, so it is recommend to only use the \emph{G}-test if your total sample size is greater than 1000.
#'
#' The \emph{G}-test of independence is an alternative to the chi-square test of independence (\code{\link{chisq.test}}), and they will give approximately the same results.
#' @section How the test works:
#' Unlike the exact test of goodness-of-fit (\code{\link{fisher.test}}), the \emph{G}-test does not directly calculate the probability of obtaining the observed results or something more extreme. Instead, like almost all statistical tests, the \emph{G}-test has an intermediate step; it uses the data to calculate a test statistic that measures how far the observed data are from the null expectation. You then use a mathematical relationship, in this case the chi-square distribution, to estimate the probability of obtaining that value of the test statistic.
#'
#' The \emph{G}-test uses the log of the ratio of two likelihoods as the test statistic, which is why it is also called a likelihood ratio test or log-likelihood ratio test. The formula to calculate a \emph{G}-statistic is:
#'
#' \code{G <- 2 * sum(x * log(x / E))}
#'
#' where \code{E} are the expected values. Since this is chi-square distributed, the p value can be calculated with:
#'
#' \code{p <- stats::pchisq(G, df, lower.tail = FALSE)}
#'
#' where \code{df} are the degrees of freedom.
#'
#' If there are more than two categories and you want to find out which ones are significantly different from their null expectation, you can use the same method of testing each category vs. the sum of all categories, with the Bonferroni correction. You use \emph{G}-tests for each category, of course.
#' @keywords chi
#' @seealso \code{\link{chisq.test}}
#' @references [1] McDonald, J.H. 2014. \strong{Handbook of Biological Statistics (3rd ed.)}. Sparky House Publishing, Baltimore, Maryland. \url{http://www.biostathandbook.com/gtestgof.html}.
#' @source This code is almost identical to \code{\link{chisq.test}}, except that:
#' \itemize{
#' \item{The calculation of the statistic was changed to \code{2 * sum(x * log(x / E))}}
#' \item{Yates' continuity correction was removed as it does not apply to a \emph{G}-test}
#' \item{The possibility to simulate p values with \code{simulate.p.value} was removed}
#' }
#' @export
#' @importFrom stats pchisq complete.cases
#' @examples
#' # = EXAMPLE 1 =
#' # Shivrain et al. (2006) crossed clearfield rice (which are resistant
#' # to the herbicide imazethapyr) with red rice (which are susceptible to
#' # imazethapyr). They then crossed the hybrid offspring and examined the
#' # F2 generation, where they found 772 resistant plants, 1611 moderately
#' # resistant plants, and 737 susceptible plants. If resistance is controlled
#' # by a single gene with two co-dominant alleles, you would expect a 1:2:1
#' # ratio.
#'
#' x <- c(772, 1611, 737)
#' E <- ratio(x, "1:2:1")
#' E
#' # 780 1560 780
#'
#' G <- g.test(x, p = c(1, 2, 1) / 4)
#' # G$p.value = 0.12574.
#'
#' # There is no significant difference from a 1:2:1 ratio.
#' # Meaning: resistance controlled by a single gene with two co-dominant
#' # alleles, is plausible.
#'
#'
#' # = EXAMPLE 2 =
#' # Red crossbills (Loxia curvirostra) have the tip of the upper bill either
#' # right or left of the lower bill, which helps them extract seeds from pine
#' # cones. Some have hypothesized that frequency-dependent selection would
#' # keep the number of right and left-billed birds at a 1:1 ratio. Groth (1992)
#' # observed 1752 right-billed and 1895 left-billed crossbills.
#'
#' x <- c(1752, 1895)
#' g.test(x)
#' # p = 0.01787343
#'
#' # There is a significant difference from a 1:1 ratio.
#' # Meaning: there are significantly more left-billed birds.
#'
g.test <- function(x,
y = NULL,
# correct = TRUE,
p = rep(1/length(x), length(x)),
rescale.p = FALSE) {
DNAME <- deparse(substitute(x))
if (is.data.frame(x))
x <- as.matrix(x)
if (is.matrix(x)) {
if (min(dim(x)) == 1L)
x <- as.vector(x)
}
if (!is.matrix(x) && !is.null(y)) {
if (length(x) != length(y))
stop("'x' and 'y' must have the same length")
DNAME2 <- deparse(substitute(y))
xname <- if (length(DNAME) > 1L || nchar(DNAME, "w") >
30)
""
else DNAME
yname <- if (length(DNAME2) > 1L || nchar(DNAME2, "w") >
30)
""
else DNAME2
OK <- complete.cases(x, y)
x <- factor(x[OK])
y <- factor(y[OK])
if ((nlevels(x) < 2L) || (nlevels(y) < 2L))
stop("'x' and 'y' must have at least 2 levels")
x <- table(x, y)
names(dimnames(x)) <- c(xname, yname)
DNAME <- paste(paste(DNAME, collapse = "\n"), "and",
paste(DNAME2, collapse = "\n"))
}
if (any(x < 0) || anyNA(x))
stop("all entries of 'x' must be nonnegative and finite")
if ((n <- sum(x)) == 0)
stop("at least one entry of 'x' must be positive")
# if (simulate.p.value) {
# setMETH <- function() METHOD <<- paste(METHOD, "with simulated p-value\n\t (based on",
# B, "replicates)")
# almost.1 <- 1 - 64 * .Machine$double.eps
# }
if (is.matrix(x)) {
METHOD <- "G-test of independence"
nr <- as.integer(nrow(x))
nc <- as.integer(ncol(x))
if (is.na(nr) || is.na(nc) || is.na(nr * nc))
stop("invalid nrow(x) or ncol(x)", domain = NA)
sr <- rowSums(x)
sc <- colSums(x)
E <- outer(sr, sc, "*")/n
v <- function(r, c, n) c * r * (n - r) * (n - c)/n^3
V <- outer(sr, sc, v, n)
dimnames(E) <- dimnames(x)
# if (simulate.p.value && all(sr > 0) && all(sc > 0)) {
# setMETH()
# tmp <- .Call(chisq_sim, sr, sc, B, E, PACKAGE = "stats")
# STATISTIC <- 2 * sum(x * log(x / E)) # sum(sort((x - E)^2/E, decreasing = TRUE)) for chisq.test
# PARAMETER <- NA
# PVAL <- (1 + sum(tmp >= almost.1 * STATISTIC))/(B +
# 1)
# }
# else {
# if (simulate.p.value)
# warning("cannot compute simulated p-value with zero marginals")
# if (correct && nrow(x) == 2L && ncol(x) == 2L) {
# YATES <- min(0.5, abs(x - E))
# if (YATES > 0)
# METHOD <- paste(METHOD, "with Yates' continuity correction")
# }
# else YATES <- 0
STATISTIC <- 2 * sum(x * log(x / E)) # sum((abs(x - E) - YATES)^2/E) for chisq.test
PARAMETER <- (nr - 1L) * (nc - 1L)
PVAL <- pchisq(STATISTIC, PARAMETER, lower.tail = FALSE)
# }
}
else {
if (length(dim(x)) > 2L)
stop("invalid 'x'")
if (length(x) == 1L)
stop("'x' must at least have 2 elements")
if (length(x) != length(p))
stop("'x' and 'p' must have the same number of elements")
if (any(p < 0))
stop("probabilities must be non-negative.")
if (abs(sum(p) - 1) > sqrt(.Machine$double.eps)) {
if (rescale.p)
p <- p/sum(p)
else stop("probabilities must sum to 1.")
}
METHOD <- "G-test of goodness-of-fit (likelihood ratio test)"
E <- n * p
V <- n * p * (1 - p)
STATISTIC <- 2 * sum(x * log(x / E)) # sum((x - E)^2/E) for chisq.test
names(E) <- names(x)
# if (simulate.p.value) {
# setMETH()
# nx <- length(x)
# sm <- matrix(sample.int(nx, B * n, TRUE, prob = p),
# nrow = n)
# ss <- apply(sm, 2L, function(x, E, k) {
# sum((table(factor(x, levels = 1L:k)) - E)^2/E)
# }, E = E, k = nx)
# PARAMETER <- NA
# PVAL <- (1 + sum(ss >= almost.1 * STATISTIC))/(B +
# 1)
# }
# else {
PARAMETER <- length(x) - 1
PVAL <- pchisq(STATISTIC, PARAMETER, lower.tail = FALSE)
# }
}
names(STATISTIC) <- "X-squared"
names(PARAMETER) <- "df"
if (any(E < 5) && is.finite(PARAMETER))
warning("G-statistic approximation may be incorrect")
structure(list(statistic = STATISTIC, parameter = PARAMETER,
p.value = PVAL, method = METHOD, data.name = DNAME,
observed = x, expected = E, residuals = (x - E)/sqrt(E),
stdres = (x - E)/sqrt(V)), class = "htest")
}
#' Transform vector to ratio
#' @param x vector of values
#' @param ratio vector with ratios of \code{x} and with same length (like \code{ratio = c(1, 2, 1)}) or a text with characters \code{":"}, \code{"-"} or \code{","} (like \code{ratio = "1:2:1"} or even \code{ratio = "1:2:1.25"})
#' @export
#' @seealso \code{\link{g.test}}
#' @references McDonald, J.H. 2014. \strong{Handbook of Biological Statistics (3rd ed.)}. Sparky House Publishing, Baltimore, Maryland.
#' @importFrom dplyr %>%
#' @inherit g.test examples
ratio <- function(x, ratio) {
if (!all(is.numeric(x))) {
stop('`x` must be a vector of numeric values.')
}
if (length(ratio) == 1) {
if (ratio %like% '^([0-9]+([.][0-9]+)?[-,:])+[0-9]+([.][0-9]+)?$') {
# support for "1:2:1", "1-2-1", "1,2,1" and even "1.75:2:1.5"
ratio <- ratio %>% base::strsplit("[-,:]") %>% base::unlist() %>% base::as.double()
} else {
stop('Invalid `ratio`: ', ratio, '.')
}
}
if (length(x) != length(ratio)) {
stop('`x` and `ratio` must be of same size.')
}
base::sum(x, na.rm = TRUE) * (ratio / base::sum(ratio, na.rm = TRUE))
}
+191
View File
@@ -0,0 +1,191 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' AMR bar plots with \code{ggplot}
#'
#' Use these functions to create bar plots for antimicrobial resistance analysis. All functions rely on internal \code{\link[ggplot2]{ggplot}} functions.
#' @param data a \code{data.frame} with column(s) of class \code{"rsi"} (see \code{\link{as.rsi}})
#' @param position position adjustment of bars, either \code{"stack"} (default) or \code{"dodge"}
#' @param x variable to show on x axis, either \code{"Antibiotic"} (default) or \code{"Interpretation"} or a grouping variable
#' @param fill variable to categorise using the plots legend, either \code{"Antibiotic"} (default) or \code{"Interpretation"} or a grouping variable
#' @param facet variable to split plots by, either \code{"Interpretation"} (default) or \code{"Antibiotic"} or a grouping variable
#' @param translate_ab a column name of the \code{\link{antibiotics}} data set to translate the antibiotic abbreviations into, using \code{\link{abname}}. Default behaviour is to translate to official names according to the WHO. Use \code{translate_ab = FALSE} to disable translation.
#' @param ... other parameters passed on to \code{\link[ggplot2]{facet_wrap}}
#' @details At default, the names of antibiotics will be shown on the plots using \code{\link{abname}}. This can be set with the option \code{get_antibiotic_names} (a logical value), so change it e.g. to \code{FALSE} with \code{options(get_antibiotic_names = FALSE)}.
#'
#' \strong{The functions}\cr
#' \code{geom_rsi} will take any variable from the data that has an \code{rsi} class (created with \code{\link{as.rsi}}) using \code{\link{portion_df}} and will plot bars with the percentage R, I and S. The default behaviour is to have the bars stacked and to have the different antibiotics on the x axis.
#'
#' \code{facet_rsi} creates 2d plots (at default based on S/I/R) using \code{\link[ggplot2]{facet_wrap}}.
#'
#' \code{scale_y_percent} transforms the y axis to a 0 to 100\% range.
#'
#' \code{scale_rsi_colours} sets colours to the bars: green for S, yellow for I and red for R.
#'
#' \code{theme_rsi} is a \code{\link[ggplot2]{theme}} with minimal distraction.
#'
#' \code{ggplot_rsi} is a wrapper around all above functions that uses data as first input. This makes it possible to use this function after a pipe (\code{\%>\%}). See Examples.
#' @rdname ggplot_rsi
#' @export
#' @examples
#' library(dplyr)
#' library(ggplot2)
#'
#' # get antimicrobial results for drugs against a UTI:
#' ggplot(septic_patients %>% select(amox, nitr, fosf, trim, cipr)) +
#' geom_rsi()
#'
#' # prettify the plot using some additional functions:
#' df <- septic_patients[, c("amox", "nitr", "fosf", "trim", "cipr")]
#' ggplot(df) +
#' geom_rsi() +
#' facet_rsi() +
#' scale_y_percent() +
#' scale_rsi_colours() +
#' theme_rsi()
#'
#' # or better yet, simplify this using the wrapper function - a single command:
#' septic_patients %>%
#' select(amox, nitr, fosf, trim, cipr) %>%
#' ggplot_rsi()
#' \donttest{
#' # it also supports groups (don't forget to use the group on `x` or `facet`):
#' septic_patients %>%
#' select(hospital_id, amox, nitr, fosf, trim, cipr) %>%
#' group_by(hospital_id) %>%
#' ggplot_rsi(x = "hospital_id",
#' facet = "Antibiotic",
#' nrow = 1) +
#' labs(title = "AMR of Anti-UTI Drugs Per Hospital",
#' x = "Hospital")
#'
#' # genuine analysis: check 2 most prevalent microorganisms
#' septic_patients %>%
#' # create new bacterial ID's, with all CoNS under the same group (Becker et al.)
#' mutate(bactid = as.bactid(bactid, Becker = TRUE)) %>%
#' # filter on top 2 bacterial ID's
#' filter(bactid %in% top_freq(freq(.$bactid), 2)) %>%
#' # determine first isolates
#' mutate(first_isolate = first_isolate(.,
#' col_date = "date",
#' col_patient_id = "patient_id",
#' col_bactid = "bactid")) %>%
#' # filter on first isolates
#' filter(first_isolate == TRUE) %>%
#' # join the `microorganisms` data set
#' left_join_microorganisms() %>%
#' # select full name and some antiseptic drugs
#' select(mo = fullname,
#' cfur, gent, cipr) %>%
#' # group by MO
#' group_by(mo) %>%
#' # plot the thing, putting MOs on the facet
#' ggplot_rsi(x = "Antibiotic",
#' facet = "mo") +
#' labs(title = "AMR of Top Two Microorganisms In Blood Culture Isolates",
#' subtitle = "Only First Isolates, CoNS grouped according to Becker et al.",
#' x = "Microorganisms")
#' }
ggplot_rsi <- function(data,
position = "stack",
x = "Antibiotic",
fill = "Interpretation",
facet = NULL,
translate_ab = "official",
...) {
if (!"ggplot2" %in% rownames(installed.packages())) {
stop('this function requires the ggplot2 package.', call. = FALSE)
}
p <- ggplot2::ggplot(data = data) +
geom_rsi(position = position, x = x, fill = fill, translate_ab = translate_ab) +
scale_y_percent() +
theme_rsi()
if (fill == "Interpretation") {
# set RSI colours
p <- p + scale_rsi_colours()
}
if (!is.null(facet)) {
p <- p + facet_rsi(facet = facet, ...)
}
p
}
#' @rdname ggplot_rsi
#' @export
geom_rsi <- function(position = "stack",
x = c("Antibiotic", "Interpretation"),
fill = "Interpretation",
translate_ab = "official") {
x <- x[1]
if (x %in% tolower(c('ab', 'antibiotic', 'abx', 'antibiotics'))) {
x <- "Antibiotic"
} else if (x %in% tolower(c('SIR', 'RSI', 'interpretation', 'interpretations', 'result'))) {
x <- "Interpretation"
}
options(get_antibiotic_names = translate_ab)
ggplot2::layer(geom = "bar", stat = "identity", position = position,
mapping = ggplot2::aes_string(x = x, y = "Percentage", fill = fill),
data = AMR::portion_df, params = list())
}
#' @rdname ggplot_rsi
#' @export
facet_rsi <- function(facet = c("Interpretation", "Antibiotic"), ...) {
facet <- facet[1]
if (facet %in% tolower(c('SIR', 'RSI', 'interpretation', 'interpretations', 'result'))) {
facet <- "Interpretation"
} else if (facet %in% tolower(c('ab', 'antibiotic', 'abx', 'antibiotics'))) {
facet <- "Antibiotic"
}
ggplot2::facet_wrap(facets = facet, scales = "free", ...)
}
#' @rdname ggplot_rsi
#' @export
scale_y_percent <- function() {
ggplot2::scale_y_continuous(name = "Percentage",
breaks = seq(0, 1, 0.1),
limits = c(0, 1),
labels = percent(seq(0, 1, 0.1)))
}
#' @rdname ggplot_rsi
#' @export
scale_rsi_colours <- function() {
ggplot2::scale_fill_brewer(palette = "RdYlGn")
}
#' @rdname ggplot_rsi
#' @export
theme_rsi <- function() {
theme_minimal() +
theme(panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank(),
panel.grid.major.y = element_line(colour = "grey75"))
}
Executable
+75
View File
@@ -0,0 +1,75 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
globalVariables(c('abname',
'Antibiotic',
'Interpretation',
'Percentage',
'bind_rows',
'element_blank',
'element_line',
'theme',
'theme_minimal',
'antibiotic',
'antibiotics',
'atc',
'bactid',
'C_chisq_sim',
'cnt',
'count',
'counts',
'cum_count',
'cum_percent',
'date_lab',
'days_diff',
'fctlvl',
'first_isolate_row_index',
'Freq',
'fullname',
'genus',
'gramstain',
'item',
'key_ab',
'key_ab_lag',
'key_ab_other',
'labs',
'median',
'mic',
'MIC',
'microorganisms',
'mocode',
'molis',
'n',
'na.omit',
'observations',
'official',
'other_pat_or_mo',
'Pasted',
'patient_id',
'quantile',
'R',
'real_first_isolate',
'S',
'septic_patients',
'species',
'umcg',
'value',
'values',
'View',
'y',
'.'))
+148
View File
@@ -0,0 +1,148 @@
#' Join a table with \code{microorganisms}
#'
#' Join the dataset \code{\link{microorganisms}} easily to an existing table or character vector.
#' @rdname join
#' @name join
#' @aliases join inner_join
#' @param x existing table to join, also supports character vectors
#' @param by a variable to join by - could be a column name of \code{x} with values that exist in \code{microorganisms$bactid} (like \code{by = "bacteria_id"}), or another column in \code{\link{microorganisms}} (but then it should be named, like \code{by = c("my_genus_species" = "fullname")})
#' @param suffix if there are non-joined duplicate variables in \code{x} and \code{y}, these suffixes will be added to the output to disambiguate them. Should be a character vector of length 2.
#' @param ... other parameters to pass on to \code{dplyr::\link[dplyr]{join}}.
#' @details As opposed to the \code{\link[dplyr]{join}} functions of \code{dplyr}, characters vectors are supported and at default existing columns will get a suffix \code{"2"} and the newly joined columns will not get a suffix. See \code{\link[dplyr]{join}} for more information.
#' @export
#' @examples
#' left_join_microorganisms("STAAUR")
#'
#' library(dplyr)
#' septic_patients %>% left_join_microorganisms()
#'
#' df <- data.frame(date = seq(from = as.Date("2018-01-01"),
#' to = as.Date("2018-01-07"),
#' by = 1),
#' bacteria_id = c("STAAUR", "STAAUR", "STAAUR", "STAAUR",
#' "ESCCOL", "ESCCOL", "ESCCOL"),
#' stringsAsFactors = FALSE)
#' colnames(df)
#' df2 <- left_join_microorganisms(df, "bacteria_id")
#' colnames(df2)
inner_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) {
if (!any(class(x) %in% c("data.frame", "matrix"))) {
x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE)
}
# no name set to `by` parameter
if (is.null(names(by))) {
joinby <- colnames(AMR::microorganisms)[1]
names(joinby) <- by
} else {
joinby <- by
}
join <- suppressWarnings(
dplyr::inner_join(x = x, y = AMR::microorganisms, by = joinby, suffix = c("2", ""), ...)
)
if (nrow(join) > nrow(x)) {
warning('the newly joined tbl contains ', nrow(join) - nrow(x), ' rows more that its original')
}
join
}
#' @rdname join
#' @export
left_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) {
if (!any(class(x) %in% c("data.frame", "matrix"))) {
x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE)
}
# no name set to `by` parameter
if (is.null(names(by))) {
joinby <- colnames(AMR::microorganisms)[1]
names(joinby) <- by
} else {
joinby <- by
}
join <- suppressWarnings(
dplyr::left_join(x = x, y = AMR::microorganisms, by = joinby, suffix = c("2", ""), ...)
)
if (nrow(join) > nrow(x)) {
warning('the newly joined tbl contains ', nrow(join) - nrow(x), ' rows more that its original')
}
join
}
#' @rdname join
#' @export
right_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) {
if (!any(class(x) %in% c("data.frame", "matrix"))) {
x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE)
}
# no name set to `by` parameter
if (is.null(names(by))) {
joinby <- colnames(AMR::microorganisms)[1]
names(joinby) <- by
} else {
joinby <- by
}
join <- suppressWarnings(
dplyr::right_join(x = x, y = AMR::microorganisms, by = joinby, suffix = c("2", ""), ...)
)
if (nrow(join) > nrow(x)) {
warning('the newly joined tbl contains ', nrow(join) - nrow(x), ' rows more that its original')
}
join
}
#' @rdname join
#' @export
full_join_microorganisms <- function(x, by = 'bactid', suffix = c("2", ""), ...) {
if (!any(class(x) %in% c("data.frame", "matrix"))) {
x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE)
}
# no name set to `by` parameter
if (is.null(names(by))) {
joinby <- colnames(AMR::microorganisms)[1]
names(joinby) <- by
} else {
joinby <- by
}
join <- suppressWarnings(
dplyr::full_join(x = x, y = AMR::microorganisms, by = joinby, suffix = c("2", ""), ...)
)
if (nrow(join) > nrow(x)) {
warning('the newly joined tbl contains ', nrow(join) - nrow(x), ' rows more that its original')
}
join
}
#' @rdname join
#' @export
semi_join_microorganisms <- function(x, by = 'bactid', ...) {
if (!any(class(x) %in% c("data.frame", "matrix"))) {
x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE)
}
# no name set to `by` parameter
if (is.null(names(by))) {
joinby <- colnames(AMR::microorganisms)[1]
names(joinby) <- by
} else {
joinby <- by
}
suppressWarnings(
dplyr::semi_join(x = x, y = AMR::microorganisms, by = joinby, ...)
)
}
#' @rdname join
#' @export
anti_join_microorganisms <- function(x, by = 'bactid', ...) {
if (!any(class(x) %in% c("data.frame", "matrix"))) {
x <- data.frame(bactid = as.character(x), stringsAsFactors = FALSE)
}
# no name set to `by` parameter
if (is.null(names(by))) {
joinby <- colnames(AMR::microorganisms)[1]
names(joinby) <- by
} else {
joinby <- by
}
suppressWarnings(
dplyr::anti_join(x = x, y = AMR::microorganisms, by = joinby, ...)
)
}
+255
View File
@@ -0,0 +1,255 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Key antibiotics for first \emph{weighted} isolates
#'
#' These function can be used to determine first isolates (see \code{\link{first_isolate}}). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates will then be called first \emph{weighted} isolates.
#' @param tbl table with antibiotics coloms, like \code{amox} and \code{amcl}.
#' @param x,y characters to compare
#' @inheritParams first_isolate
#' @param universal_1,universal_2,universal_3,universal_4,universal_5,universal_6 column names of \strong{broad-spectrum} antibiotics, case-insensitive
#' @param GramPos_1,GramPos_2,GramPos_3,GramPos_4,GramPos_5,GramPos_6 column names of antibiotics for \strong{Gram positives}, case-insensitive
#' @param GramNeg_1,GramNeg_2,GramNeg_3,GramNeg_4,GramNeg_5,GramNeg_6 column names of antibiotics for \strong{Gram negatives}, case-insensitive
#' @param warnings give warning about missing antibiotic columns, they will anyway be ignored
#' @details The function \code{key_antibiotics} returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using \code{key_antibiotics_equal}, to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (\code{"."}). The \code{\link{first_isolate}} function only uses this function on the same microbial species from the same patient. Using this, an MRSA will be included after a susceptible \emph{S. aureus} (MSSA) found within the same episode (see \code{episode} parameter of \code{\link{first_isolate}}). Without key antibiotic comparison it wouldn't.
#'
#' At default, the antibiotics that are used for \strong{Gram positive bacteria} are (colum names): \cr
#' \code{"amox"}, \code{"amcl"}, \code{"cfur"}, \code{"pita"}, \code{"cipr"}, \code{"trsu"} (until here is universal), \code{"vanc"}, \code{"teic"}, \code{"tetr"}, \code{"eryt"}, \code{"oxac"}, \code{"rifa"}.
#'
#' At default, the antibiotics that are used for \strong{Gram negative bacteria} are (colum names): \cr
#' \code{"amox"}, \code{"amcl"}, \code{"cfur"}, \code{"pita"}, \code{"cipr"}, \code{"trsu"} (until here is universal), \code{"gent"}, \code{"tobr"}, \code{"coli"}, \code{"cfot"}, \code{"cfta"}, \code{"mero"}.
#'
#'
#' The function \code{key_antibiotics_equal} checks the characters returned by \code{key_antibiotics} for equality, and returns a logical vector.
#' @inheritSection first_isolate Key antibiotics
#' @rdname key_antibiotics
#' @export
#' @importFrom dplyr %>% mutate if_else
#' @seealso \code{\link{first_isolate}}
#' @examples
#' # septic_patients is a dataset available in the AMR package
#' ?septic_patients
#' my_patients <- septic_patients
#'
#' library(dplyr)
#' # set key antibiotics to a new variable
#' my_patients <- my_patients %>%
#' mutate(keyab = key_antibiotics(.)) %>%
#' mutate(
#' # now calculate first isolates
#' first_regular = first_isolate(., "date", "patient_id", "bactid"),
#' # and first WEIGHTED isolates
#' first_weighted = first_isolate(., "date", "patient_id", "bactid",
#' col_keyantibiotics = "keyab")
#' )
#'
#' # Check the difference, in this data set it results in 7% more isolates:
#' sum(my_patients$first_regular, na.rm = TRUE)
#' sum(my_patients$first_weighted, na.rm = TRUE)
#'
#'
#' # output of the `key_antibiotics` function could be like this:
#' strainA <- "SSSRR.S.R..S"
#' strainB <- "SSSIRSSSRSSS"
#'
#' key_antibiotics_equal(strainA, strainB)
#' # TRUE, because I is ignored (as are missing values)
#'
#' key_antibiotics_equal(strainA, strainB, ignore_I = FALSE)
#' # FALSE, because I is not ignored and so the 4th value differs
key_antibiotics <- function(tbl,
col_bactid = "bactid",
universal_1 = "amox",
universal_2 = "amcl",
universal_3 = "cfur",
universal_4 = "pita",
universal_5 = "cipr",
universal_6 = "trsu",
GramPos_1 = "vanc",
GramPos_2 = "teic",
GramPos_3 = "tetr",
GramPos_4 = "eryt",
GramPos_5 = "oxac",
GramPos_6 = "rifa",
GramNeg_1 = "gent",
GramNeg_2 = "tobr",
GramNeg_3 = "coli",
GramNeg_4 = "cfot",
GramNeg_5 = "cfta",
GramNeg_6 = "mero",
warnings = TRUE) {
if (!col_bactid %in% colnames(tbl)) {
stop('Column ', col_bactid, ' not found.', call. = FALSE)
}
# check columns
col.list <- c(universal_1, universal_2, universal_3, universal_4, universal_5, universal_6,
GramPos_1, GramPos_2, GramPos_3, GramPos_4, GramPos_5, GramPos_6,
GramNeg_1, GramNeg_2, GramNeg_3, GramNeg_4, GramNeg_5, GramNeg_6)
col.list <- check_available_columns(tbl = tbl, col.list = col.list, info = warnings)
universal_1 <- col.list[universal_1]
universal_2 <- col.list[universal_2]
universal_3 <- col.list[universal_3]
universal_4 <- col.list[universal_4]
universal_5 <- col.list[universal_5]
universal_6 <- col.list[universal_6]
GramPos_1 <- col.list[GramPos_1]
GramPos_2 <- col.list[GramPos_2]
GramPos_3 <- col.list[GramPos_3]
GramPos_4 <- col.list[GramPos_4]
GramPos_5 <- col.list[GramPos_5]
GramPos_6 <- col.list[GramPos_6]
GramNeg_1 <- col.list[GramNeg_1]
GramNeg_2 <- col.list[GramNeg_2]
GramNeg_3 <- col.list[GramNeg_3]
GramNeg_4 <- col.list[GramNeg_4]
GramNeg_5 <- col.list[GramNeg_5]
GramNeg_6 <- col.list[GramNeg_6]
universal <- c(universal_1, universal_2, universal_3,
universal_4, universal_5, universal_6)
gram_positive = c(universal,
GramPos_1, GramPos_2, GramPos_3,
GramPos_4, GramPos_5, GramPos_6)
gram_positive <- gram_positive[!is.na(gram_positive)]
gram_negative = c(universal,
GramNeg_1, GramNeg_2, GramNeg_3,
GramNeg_4, GramNeg_5, GramNeg_6)
gram_negative <- gram_negative[!is.na(gram_negative)]
# join microorganisms
tbl <- tbl %>% left_join_microorganisms(col_bactid)
tbl$key_ab <- NA_character_
# Gram +
tbl <- tbl %>% mutate(key_ab =
if_else(gramstain %like% '^Positive ',
apply(X = tbl[, gram_positive],
MARGIN = 1,
FUN = function(x) paste(x, collapse = "")),
key_ab))
# Gram -
tbl <- tbl %>% mutate(key_ab =
if_else(gramstain %like% '^Negative ',
apply(X = tbl[, gram_negative],
MARGIN = 1,
FUN = function(x) paste(x, collapse = "")),
key_ab))
# format
key_abs <- tbl %>%
pull(key_ab) %>%
gsub('(NA|NULL)', '.', .) %>%
gsub('[^SIR]', '.', ., ignore.case = TRUE)
key_abs
}
#' @importFrom dplyr progress_estimated %>%
#' @rdname key_antibiotics
#' @export
key_antibiotics_equal <- function(x,
y,
type = c("keyantibiotics", "points"),
ignore_I = TRUE,
points_threshold = 2,
info = FALSE) {
# x is active row, y is lag
type <- type[1]
if (length(x) != length(y)) {
stop('Length of `x` and `y` must be equal.')
}
# only show progress bar on points or when at least 5000 isolates
info_needed <- info == TRUE & (type == "points" | length(x) > 5000)
result <- logical(length(x))
if (info_needed == TRUE) {
p <- dplyr::progress_estimated(length(x))
}
for (i in 1:length(x)) {
if (info_needed == TRUE) {
p$tick()$print()
}
if (is.na(x[i])) {
x[i] <- ''
}
if (is.na(y[i])) {
y[i] <- ''
}
if (x[i] == y[i]) {
result[i] <- TRUE
} else if (nchar(x[i]) != nchar(y[i])) {
result[i] <- FALSE
} else {
x_split <- strsplit(x[i], "")[[1]]
y_split <- strsplit(y[i], "")[[1]]
if (type == 'keyantibiotics') {
if (ignore_I == TRUE) {
x_split[x_split == "I"] <- "."
y_split[y_split == "I"] <- "."
}
y_split[x_split == "."] <- "."
x_split[y_split == "."] <- "."
result[i] <- all(x_split == y_split)
} else if (type == 'points') {
# count points for every single character:
# - no change is 0 points
# - I <-> S|R is 0.5 point
# - S|R <-> R|S is 1 point
# use the levels of as.rsi (S = 1, I = 2, R = 3)
suppressWarnings(x_split <- x_split %>% as.rsi() %>% as.double())
suppressWarnings(y_split <- y_split %>% as.rsi() %>% as.double())
points <- (x_split - y_split) %>% abs() %>% sum(na.rm = TRUE) / 2
result[i] <- points >= points_threshold
} else {
stop('`', type, '` is not a valid value for type, must be "points" or "keyantibiotics". See ?first_isolate.')
}
}
}
if (info_needed == TRUE) {
cat('\n')
}
result
}
+40
View File
@@ -0,0 +1,40 @@
#' Kurtosis of the sample
#'
#' @description Kurtosis is a measure of the "tailedness" of the probability distribution of a real-valued random variable.
#'
#' @param x a vector of values, a \code{matrix} or a \code{data frame}
#' @param na.rm a logical value indicating whether \code{NA} values should be stripped before the computation proceeds.
#' @exportMethod kurtosis
#' @seealso \code{\link{skewness}}
#' @rdname kurtosis
#' @export
kurtosis <- function(x, na.rm = FALSE) {
UseMethod("kurtosis")
}
#' @exportMethod kurtosis.default
#' @rdname kurtosis
#' @export
kurtosis.default <- function (x, na.rm = FALSE) {
x <- as.vector(x)
if (na.rm == TRUE) {
x <- x[!is.na(x)]
}
n <- length(x)
n * base::sum((x - base::mean(x, na.rm = na.rm))^4, na.rm = na.rm) /
(base::sum((x - base::mean(x, na.rm = na.rm))^2, na.rm = na.rm)^2)
}
#' @exportMethod kurtosis.matrix
#' @rdname kurtosis
#' @export
kurtosis.matrix <- function (x, na.rm = FALSE) {
base::apply(x, 2, kurtosis.default, na.rm = na.rm)
}
#' @exportMethod kurtosis.data.frame
#' @rdname kurtosis
#' @export
kurtosis.data.frame <- function (x, na.rm = FALSE) {
base::sapply(x, kurtosis.default, na.rm = na.rm)
}
+80
View File
@@ -0,0 +1,80 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Pattern Matching
#'
#' Convenient wrapper around \code{\link[base]{grep}} to match a pattern: \code{a \%like\% b}. It always returns a \code{logical} vector and is always case-insensitive. Also, \code{pattern} (\code{b}) can be as long as \code{x} (\code{a}) to compare items of each index in both vectors.
#' @inheritParams base::grepl
#' @return A \code{logical} vector
#' @name like
#' @rdname like
#' @export
#' @details Using RStudio? This function can also be inserted from the Addins menu and can have its own Keyboard Shortcut like Ctrl+Shift+L or Cmd+Shift+L (see Tools > Modify Keyboard Shortcuts...).
#' @source Idea from the \href{https://github.com/Rdatatable/data.table/blob/master/R/like.R}{\code{like} function from the \code{data.table} package}, but made it case insensitive at default and let it support multiple patterns.
#' @seealso \code{\link[base]{grep}}
#' @examples
#' # simple test
#' a <- "This is a test"
#' b <- "TEST"
#' a %like% b
#' #> TRUE
#' b %like% a
#' #> FALSE
#'
#' # also supports multiple patterns, length must be equal to x
#' a <- c("Test case", "Something different", "Yet another thing")
#' b <- c("case", "diff", "yet")
#' a %like% b
#' #> TRUE TRUE TRUE
#'
#' # get frequencies of bacteria whose name start with 'Ent' or 'ent'
#' library(dplyr)
#' septic_patients %>%
#' left_join_microorganisms() %>%
#' filter(genus %like% '^ent') %>%
#' freq(genus, species)
like <- function(x, pattern) {
if (length(pattern) > 1) {
if (length(x) != length(pattern)) {
pattern <- pattern[1]
warning('only the first element of argument `pattern` used for `%like%`', call. = FALSE)
} else {
# x and pattern are of same length, so items with each other
res <- vector(length = length(pattern))
for (i in 1:length(res)) {
if (is.factor(x[i])) {
res[i] <- as.integer(x[i]) %in% base::grep(pattern[i], levels(x[i]), ignore.case = TRUE)
} else {
res[i] <- base::grepl(pattern[i], x[i], ignore.case = TRUE)
}
}
return(res)
}
}
# the regular way how grepl works; just one pattern against one or more x
if (is.factor(x)) {
as.integer(x) %in% base::grep(pattern, levels(x), ignore.case = TRUE)
} else {
base::grepl(pattern, x, ignore.case = TRUE)
}
}
#' @rdname like
#' @export
"%like%" <- like
Executable
+422
View File
@@ -0,0 +1,422 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Determine multidrug-resistant organisms (MDRO)
#'
#' Determine which isolates are multidrug-resistant organisms (MDRO) according to country-specific guidelines.
#' @param tbl table with antibiotic columns, like e.g. \code{amox} and \code{amcl}
#' @param country country code to determine guidelines. EUCAST rules will be used when left empty, see Details. Should be or a code from the \href{https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements}{list of ISO 3166-1 alpha-2 country codes}. Case-insensitive. Currently supported are \code{de} (Germany) and \code{nl} (the Netherlands).
#' @param col_bactid column name of the bacteria ID in \code{tbl} - values of this column should be present in \code{microorganisms$bactid}, see \code{\link{microorganisms}}
#' @param info print progress
#' @param amcl,amik,amox,ampi,azit,aztr,cefa,cfra,cfep,cfot,cfox,cfta,cftr,cfur,chlo,cipr,clar,clin,clox,coli,czol,dapt,doxy,erta,eryt,fosf,fusi,gent,imip,kana,levo,linc,line,mero,metr,mino,moxi,nali,neom,neti,nitr,novo,norf,oflo,peni,pita,poly,qida,rifa,roxi,siso,teic,tetr,tica,tige,tobr,trim,trsu,vanc column names of antibiotics. column names of antibiotics
#' @param ... parameters that are passed on to methods
#' @details When \code{country} will be left blank, guidelines will be taken from EUCAST Expert Rules Version 3.1 "Intrinsic Resistance and Exceptional Phenotypes Tables" (\url{http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf}).
#' @return Ordered factor with levels \code{Unknown < Negative < Unconfirmed < Positive}.
#' @rdname MDRO
#' @export
#' @examples
#' library(dplyr)
#'
#' septic_patients %>%
#' mutate(EUCAST = MDRO(.),
#' BRMO = MDRO(., "nl"))
MDRO <- function(tbl,
country = NULL,
col_bactid = 'bactid',
info = TRUE,
amcl = 'amcl',
amik = 'amik',
amox = 'amox',
ampi = 'ampi',
azit = 'azit',
aztr = 'aztr',
cefa = 'cefa',
cfra = 'cfra',
cfep = 'cfep',
cfot = 'cfot',
cfox = 'cfox',
cfta = 'cfta',
cftr = 'cftr',
cfur = 'cfur',
chlo = 'chlo',
cipr = 'cipr',
clar = 'clar',
clin = 'clin',
clox = 'clox',
coli = 'coli',
czol = 'czol',
dapt = 'dapt',
doxy = 'doxy',
erta = 'erta',
eryt = 'eryt',
fosf = 'fosf',
fusi = 'fusi',
gent = 'gent',
imip = 'imip',
kana = 'kana',
levo = 'levo',
linc = 'linc',
line = 'line',
mero = 'mero',
metr = 'metr',
mino = 'mino',
moxi = 'moxi',
nali = 'nali',
neom = 'neom',
neti = 'neti',
nitr = 'nitr',
novo = 'novo',
norf = 'norf',
oflo = 'oflo',
peni = 'peni',
pita = 'pita',
poly = 'poly',
qida = 'qida',
rifa = 'rifa',
roxi = 'roxi',
siso = 'siso',
teic = 'teic',
tetr = 'tetr',
tica = 'tica',
tige = 'tige',
tobr = 'tobr',
trim = 'trim',
trsu = 'trsu',
vanc = 'vanc') {
if (!col_bactid %in% colnames(tbl)) {
stop('Column ', col_bactid, ' not found.', call. = FALSE)
}
# strip whitespaces
if (length(country) > 1) {
stop('`country` must be a length one character string.', call. = FALSE)
}
if (is.null(country)) {
country <- 'EUCAST'
}
country <- trimws(country)
if (country != 'EUCAST' & !country %like% '^[a-z]{2}$') {
stop('This is not a valid ISO 3166-1 alpha-2 country code: "', country, '". Please see ?MDRO.', call. = FALSE)
}
# create list and make country code case-independent
guideline <- list(country = list(code = tolower(country)))
if (guideline$country$code == 'eucast') {
guideline$country$name <- '(European guidelines)'
guideline$name <- 'EUCAST Expert Rules, "Intrinsic Resistance and Exceptional Phenotypes Tables"'
guideline$version <- 'Version 3.1'
guideline$source <- 'http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf'
# support per country:
} else if (guideline$country$code == 'de') {
guideline$country$name <- 'Germany'
guideline$name <- ''
guideline$version <- ''
guideline$source <- ''
} else if (guideline$country$code == 'nl') {
guideline$country$name <- 'The Netherlands'
guideline$name <- 'WIP-Richtlijn BRMO'
guideline$version <- 'Revision of December 2017'
guideline$source <- 'https://www.rivm.nl/Documenten_en_publicaties/Professioneel_Praktisch/Richtlijnen/Infectieziekten/WIP_Richtlijnen/WIP_Richtlijnen/Ziekenhuizen/WIP_richtlijn_BRMO_Bijzonder_Resistente_Micro_Organismen_ZKH'
# add here more countries like this:
# } else if (country$code == 'AA') {
# country$name <- 'country name'
} else {
stop('This country code is currently unsupported: ', guideline$country$code, call. = FALSE)
}
# Console colours
# source: http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
ANSI_red <- "\033[31m"
ANSI_blue <- "\033[34m"
ANSI_reset <- "\033[0m"
if (info == TRUE) {
cat("Determining multidrug-resistant organisms (MDRO), according to:\n",
"Guideline: ", ANSI_red, guideline$name, ", ", guideline$version, ANSI_reset, "\n",
"Country : ", ANSI_red, guideline$country$name, ANSI_reset, "\n",
"Source : ", ANSI_blue, guideline$source, ANSI_reset, "\n",
"\n", sep = "")
}
# check columns
col.list <- c(amcl, amik, amox, ampi, azit, aztr, cefa, cfra, cfep, cfot,
cfox, cfta, cftr, cfur, chlo, cipr, clar, clin, clox, coli,
czol, dapt, doxy, erta, eryt, fosf, fusi, gent, imip, kana,
levo, linc, line, mero, metr, mino, moxi, nali, neom, neti, nitr,
novo, norf, oflo, peni, pita, poly, qida, rifa, roxi, siso,
teic, tetr, tica, tige, tobr, trim, trsu, vanc)
col.list <- check_available_columns(tbl = tbl, col.list = col.list, info = info)
amcl <- col.list[amcl]
amik <- col.list[amik]
amox <- col.list[amox]
ampi <- col.list[ampi]
azit <- col.list[azit]
aztr <- col.list[aztr]
cefa <- col.list[cefa]
cfra <- col.list[cfra]
cfep <- col.list[cfep]
cfot <- col.list[cfot]
cfox <- col.list[cfox]
cfta <- col.list[cfta]
cftr <- col.list[cftr]
cfur <- col.list[cfur]
chlo <- col.list[chlo]
cipr <- col.list[cipr]
clar <- col.list[clar]
clin <- col.list[clin]
clox <- col.list[clox]
coli <- col.list[coli]
czol <- col.list[czol]
dapt <- col.list[dapt]
doxy <- col.list[doxy]
erta <- col.list[erta]
eryt <- col.list[eryt]
fosf <- col.list[fosf]
fusi <- col.list[fusi]
gent <- col.list[gent]
imip <- col.list[imip]
kana <- col.list[kana]
levo <- col.list[levo]
linc <- col.list[linc]
line <- col.list[line]
mero <- col.list[mero]
metr <- col.list[metr]
mino <- col.list[mino]
moxi <- col.list[moxi]
nali <- col.list[nali]
neom <- col.list[neom]
neti <- col.list[neti]
nitr <- col.list[nitr]
novo <- col.list[novo]
norf <- col.list[norf]
oflo <- col.list[oflo]
peni <- col.list[peni]
pita <- col.list[pita]
poly <- col.list[poly]
qida <- col.list[qida]
rifa <- col.list[rifa]
roxi <- col.list[roxi]
siso <- col.list[siso]
teic <- col.list[teic]
tetr <- col.list[tetr]
tica <- col.list[tica]
tige <- col.list[tige]
tobr <- col.list[tobr]
trim <- col.list[trim]
trsu <- col.list[trsu]
vanc <- col.list[vanc]
# antibiotic classes
aminoglycosides <- c(tobr, gent, kana, neom, neti, siso)
tetracyclines <- c(doxy, mino, tetr) # since EUCAST v3.1 tige(cycline) is set apart
polymyxins <- c(poly, coli)
macrolides <- c(eryt, azit, roxi, clar) # since EUCAST v3.1 clin(damycin) is set apart
glycopeptides <- c(vanc, teic)
streptogramins <- qida # should officially also be pristinamycin and quinupristin/dalfopristin
cephalosporins <- c(cfep, cfot, cfox, cfra, cfta, cftr, cfur, czol)
cephalosporins_3rd <- c(cfot, cftr, cfta)
carbapenems <- c(erta, imip, mero)
aminopenicillins <- c(ampi, amox)
ureidopenicillins <- pita # should officially also be azlo and mezlo
fluoroquinolones <- c(oflo, cipr, norf, levo, moxi)
# helper function for editing the table
trans_tbl <- function(to, rows, cols) {
cols <- cols[!is.na(cols)]
if (length(rows) > 0 & length(cols) > 0) {
col_filter <- which(tbl[, cols] == 'R')
rows <- rows[rows %in% col_filter]
tbl[rows, 'MDRO'] <<- to
}
}
# join microorganisms
tbl <- tbl %>% left_join_microorganisms(col_bactid)
tbl$MDRO <- NA_integer_
if (guideline$country$code == 'eucast') {
# EUCAST ------------------------------------------------------------------
# Table 5
trans_tbl(4,
which(tbl$family == 'Enterobacteriaceae'
| tbl$fullname %like% '^Pseudomonas aeruginosa'
| tbl$genus == 'Acinetobacter'),
coli)
trans_tbl(4,
which(tbl$fullname %like% '^Salmonella Typhi'),
c(carbapenems, fluoroquinolones))
trans_tbl(4,
which(tbl$fullname %like% '^Haemophilus influenzae'),
c(cephalosporins_3rd, carbapenems, fluoroquinolones))
trans_tbl(4,
which(tbl$fullname %like% '^Moraxella catarrhalis'),
c(cephalosporins_3rd, fluoroquinolones))
trans_tbl(4,
which(tbl$fullname %like% '^Neisseria meningitidis'),
c(cephalosporins_3rd, fluoroquinolones))
trans_tbl(4,
which(tbl$fullname %like% '^Neisseria gonorrhoeae'),
azit)
# Table 6
trans_tbl(4,
which(tbl$fullname %like% '^Staphylococcus (aureus|epidermidis|coagulase negatief|hominis|haemolyticus|intermedius|pseudointermedius)'),
c(vanc, teic, dapt, line, qida, tige))
trans_tbl(4,
which(tbl$genus == 'Corynebacterium'),
c(vanc, teic, dapt, line, qida, tige))
trans_tbl(4,
which(tbl$fullname %like% '^Streptococcus pneumoniae'),
c(carbapenems, vanc, teic, dapt, line, qida, tige, rifa))
trans_tbl(4, # Sr. groups A/B/C/G
which(tbl$fullname %like% '^Streptococcus (pyogenes|agalactiae|equisimilis|equi|zooepidemicus|dysgalactiae|anginosus)'),
c(peni, cephalosporins, vanc, teic, dapt, line, qida, tige))
trans_tbl(4,
which(tbl$genus == 'Enterococcus'),
c(dapt, line, tige, teic))
trans_tbl(4,
which(tbl$fullname %like% '^Enterococcus faecalis'),
c(ampi, amox))
# Table 7
trans_tbl(4,
which(tbl$genus == 'Bacteroides'),
metr)
trans_tbl(4,
which(tbl$fullname %like% '^Clostridium difficile'),
c(metr, vanc))
}
if (guideline$country$code == 'de') {
# Germany -----------------------------------------------------------------
stop("We are still working on German guidelines in this beta version.", call. = FALSE)
}
if (guideline$country$code == 'nl') {
# Netherlands -------------------------------------------------------------
aminoglycosides <- aminoglycosides[!is.na(aminoglycosides)]
fluoroquinolones <- fluoroquinolones[!is.na(fluoroquinolones)]
carbapenems <- carbapenems[!is.na(carbapenems)]
# Table 1
tbl[which(
tbl$family == 'Enterobacteriaceae'
& rowSums(tbl[, aminoglycosides] == 'R', na.rm = TRUE) >= 1
& rowSums(tbl[, fluoroquinolones] == 'R', na.rm = TRUE) >= 1
), 'MDRO'] <- 4
tbl[which(
tbl$family == 'Enterobacteriaceae'
& rowSums(tbl[, carbapenems] == 'R', na.rm = TRUE) >= 1
), 'MDRO'] <- 3
# rest is negative
tbl[which(
tbl$family == 'Enterobacteriaceae'
& tbl$MDRO == 1
), 'MDRO'] <- 2
# Table 2
tbl[which(
tbl$genus == 'Acinetobacter'
& rowSums(tbl[, carbapenems] == 'R', na.rm = TRUE) >= 1
), 'MDRO'] <- 3
tbl[which(
tbl$genus == 'Acinetobacter'
& rowSums(tbl[, aminoglycosides] == 'R', na.rm = TRUE) >= 1
& rowSums(tbl[, fluoroquinolones] == 'R', na.rm = TRUE) >= 1
), 'MDRO'] <- 4
# rest of Acinetobacter is negative
tbl[which(
tbl$genus == 'Acinetobacter'
& tbl$MDRO == 1
), 'MDRO'] <- 2
tbl[which(
tbl$fullname %like% 'Stenotrophomonas maltophilia'
& tbl[, trsu] == 'R'
), 'MDRO'] <- 4
# rest of Stenotrophomonas is negative
tbl[which(
tbl$fullname %like% 'Stenotrophomonas maltophilia'
& tbl$MDRO == 1
), 'MDRO'] <- 2
tbl[which(
tbl$fullname %like% 'Pseudomonas aeruginosa'
& sum(rowSums(tbl[, carbapenems] == 'R', na.rm = TRUE) >= 1,
rowSums(tbl[, aminoglycosides] == 'R', na.rm = TRUE) >= 1,
rowSums(tbl[, fluoroquinolones] == 'R', na.rm = TRUE) >= 1,
tbl[, cfta] == 'R',
tbl[, pita] == 'R') >= 3
), 'MDRO'] <- 4
# rest of Pseudomonas is negative
tbl[which(
tbl$fullname %like% 'Pseudomonas aeruginosa'
& tbl$MDRO == 1
), 'MDRO'] <- 2
# Table 3
tbl[which(
tbl$fullname %like% 'Streptococcus pneumoniae'
& tbl[, peni] == 'R'
), 'MDRO'] <- 4
tbl[which(
tbl$fullname %like% 'Streptococcus pneumoniae'
& tbl[, vanc] == 'R'
), 'MDRO'] <- 4
# rest of Streptococcus pneumoniae is negative
tbl[which(
tbl$fullname %like% 'Streptococcus pneumoniae'
& tbl$MDRO == 1
), 'MDRO'] <- 2
tbl[which(
tbl$fullname %like% 'Enterococcus faecium'
& rowSums(tbl[, c(peni, vanc)] == 'R', na.rm = TRUE) >= 1
), 'MDRO'] <- 4
# rest of Enterococcus faecium is negative
tbl[which(
tbl$fullname %like% 'Enterococcus faecium'
& tbl$MDRO == 1
), 'MDRO'] <- 2
}
factor(x = tbl$MDRO,
levels = c(1:4),
labels = c('Unknown', 'Negative', 'Unconfirmed', 'Positive'),
ordered = TRUE)
}
#' @rdname MDRO
#' @export
BRMO <- function(tbl, country = "nl", ...) {
MDRO(tbl = tbl, country = "nl", ...)
}
#' @rdname MDRO
#' @export
MRGN <- function(tbl, country = "de", ...) {
MDRO(tbl = tbl, country = "de", ...)
}
#' @rdname MDRO
#' @export
EUCAST_exceptional_phenotypes <- function(tbl, country = "EUCAST", ...) {
MDRO(tbl = tbl, country = "EUCAST", ...)
}
Executable
+211
View File
@@ -0,0 +1,211 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
# No export, no Rd
addin_insert_in <- function() {
rstudioapi::insertText(" %in% ")
}
# No export, no Rd
addin_insert_like <- function() {
rstudioapi::insertText(" %like% ")
}
# No export, no Rd
#' @importFrom utils View
addin_open_antibiotics <- function() {
View(antibiotics)
}
# No export, no Rd
#' @importFrom utils View
addin_open_microorganisms <- function() {
View(microorganisms)
}
# No export, no Rd
#' @importFrom utils View
addin_open_septic_patients <- function() {
View(septic_patients)
}
# No export, no Rd
percent <- function(x, round = 1, force_zero = FALSE, ...) {
val <- base::round(x * 100, digits = round)
if (force_zero == TRUE & any(val == as.integer(val) & !is.na(val))) {
val[val == as.integer(val)] <- paste0(val[val == as.integer(val)], ".", strrep(0, round))
}
pct <- base::paste0(val, "%")
pct[pct == "NA%"] <- NA_character_
pct
}
check_available_columns <- function(tbl, col.list, info = TRUE) {
# check columns
col.list <- col.list[!is.na(col.list)]
names(col.list) <- col.list
col.list.bak <- col.list
# are they available as upper case or lower case then?
for (i in 1:length(col.list)) {
if (toupper(col.list[i]) %in% colnames(tbl)) {
col.list[i] <- toupper(col.list[i])
} else if (tolower(col.list[i]) %in% colnames(tbl)) {
col.list[i] <- tolower(col.list[i])
} else if (!col.list[i] %in% colnames(tbl)) {
col.list[i] <- NA
}
}
if (!all(col.list %in% colnames(tbl))) {
if (info == TRUE) {
warning('These columns do not exist and will be ignored: ',
col.list.bak[!(col.list %in% colnames(tbl))] %>% toString(),
'.\nTHIS MAY STRONGLY INFLUENCE THE OUTCOME.',
immediate. = TRUE,
call. = FALSE)
}
}
col.list
}
# Coefficient of variation (CV)
cv <- function(x, na.rm = TRUE) {
stats::sd(x, na.rm = na.rm) / base::abs(base::mean(x, na.rm = na.rm))
}
# Coefficient of dispersion, or coefficient of quartile variation (CQV).
# (Bonett et al., 2006: Confidence interval for a coefficient of quartile variation).
cqv <- function(x, na.rm = TRUE) {
fives <- stats::fivenum(x, na.rm = na.rm)
(fives[4] - fives[2]) / (fives[4] + fives[2])
}
# show bytes as kB/MB/GB
# size_humanreadable(123456) # 121 kB
# size_humanreadable(12345678) # 11.8 MB
size_humanreadable <- function(bytes, decimals = 1) {
bytes <- bytes %>% as.double()
# Adapted from:
# http://jeffreysambells.com/2012/10/25/human-readable-filesize-php
size <- c('B','kB','MB','GB','TB','PB','EB','ZB','YB')
factor <- floor((nchar(bytes) - 1) / 3)
# added slight improvement; no decimals for B and kB:
decimals <- rep(decimals, length(bytes))
decimals[size[factor + 1] %in% c('B', 'kB')] <- 0
out <- paste(sprintf(paste0("%.", decimals, "f"), bytes / (1024 ^ factor)), size[factor + 1])
out
}
# based on readr::parse_guess
tbl_parse_guess <- function(tbl,
date_names = 'en',
date_format = '%Y-%m-%d',
time_format = '%H:%M',
decimal_mark = '.',
tz = "UTC",
encoding = "UTF-8",
remove_ASCII_escape_char = FALSE,
na = c("", "NA", "NULL")) {
date_format <- date_generic(date_format)
time_format <- date_generic(time_format)
# set col types with readr
for (i in 1:ncol(tbl)) {
if (!all(tbl %>% pull(i) %>% class() %in% c('list', 'matrix'))) {
tbl[, i] <- readr::parse_guess(x = tbl %>% pull(i) %>% as.character(),
na = na,
locale = readr::locale(date_names = date_names,
date_format = date_format,
time_format = time_format,
decimal_mark = decimal_mark,
encoding = encoding,
tz = tz,
asciify = FALSE))
}
if (any(tbl %>% pull(i) %>% class() %in% c('factor', 'character'))) {
# get values
distinct_val <- tbl %>% pull(i) %>% unique() %>% sort()
if (remove_ASCII_escape_char == TRUE) {
# remove ASCII escape character: https://en.wikipedia.org/wiki/Escape_character#ASCII_escape_character
tbl[, i] <- tbl %>% pull(i) %>% gsub('\033', ' ', ., fixed = TRUE)
}
# look for RSI, shouldn't all be "" and must be valid antibiotic interpretations
if (!all(distinct_val[!is.na(distinct_val)] == '')
& all(distinct_val[!is.na(distinct_val)] %in% c('', 'I', 'I;I', 'R', 'R;R', 'S', 'S;S'))) {
tbl[, i] <- tbl %>% pull(i) %>% as.rsi()
}
}
# convert to MIC class
if (colnames(tbl)[i] %like% '_mic$') {
tbl[, i] <- tbl %>% pull(i) %>% as.mic()
}
}
tbl
}
# transforms date format like "dddd d mmmm yyyy" to "%A %e %B %Y"
date_generic <- function(format) {
if (!grepl('%', format, fixed = TRUE)) {
# first months and minutes, after that everything is case INsensitive
format <- gsub('mmmm', '%B1', format, fixed = TRUE)
format <- gsub('mmm', '%b', format, fixed = TRUE)
format <- gsub('mm', '%m', format, fixed = TRUE)
format <- gsub('MM', '%M1', format, fixed = TRUE)
format <- format %>%
tolower() %>%
gsub('%b1', '%B', ., fixed = TRUE) %>%
gsub('%m1', '%M', ., fixed = TRUE)
# dates
format <- gsub('dddd', '%A', format, fixed = TRUE)
format <- gsub('ddd', '%a', format, fixed = TRUE)
format <- gsub('dd', '%!', format, fixed = TRUE)
format <- gsub('d', '%e', format, fixed = TRUE)
format <- gsub('%!', '%d', format, fixed = TRUE)
format <- gsub('ww', '%V', format, fixed = TRUE)
format <- gsub('w', '%V', format, fixed = TRUE)
format <- gsub('qq', 'Qq', format, fixed = TRUE) # so will be 'Q%%q' after this
format <- gsub('kk', 'Kq', format, fixed = TRUE)
format <- gsub('k', 'q', format, fixed = TRUE)
format <- gsub('q', '%%q', format, fixed = TRUE)
format <- gsub('yyyy_iso', '%G', format, fixed = TRUE)
format <- gsub('jjjj_iso', '%G', format, fixed = TRUE)
format <- gsub('yyyy', '%Y', format, fixed = TRUE)
format <- gsub('jjjj', '%Y', format, fixed = TRUE)
format <- gsub('yy_iso', '%g', format, fixed = TRUE)
format <- gsub('jj_iso', '%g', format, fixed = TRUE)
format <- gsub('yy', '%y', format, fixed = TRUE)
format <- gsub('jj', '%y', format, fixed = TRUE)
# time
format <- gsub('hh', '%H', format, fixed = TRUE)
format <- gsub('h', '%k', format, fixed = TRUE)
format <- gsub('ss', '%S', format, fixed = TRUE)
# seconds since the Epoch, 1970-01-01 00:00:00
format <- gsub('unix', '%s', format, fixed = TRUE)
# Equivalent to %Y-%m-%d (the ISO 8601 date format)
format <- gsub('iso', '%F', format, fixed = TRUE)
}
format
}
+54
View File
@@ -0,0 +1,54 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Count cases with antimicrobial results
#'
#' This counts all cases where antimicrobial interpretations are available. Its use is equal to \code{\link{n_distinct}}.
#' @param ab1,ab2 vector of antibiotic interpretations, they will be transformed internally with \code{\link{as.rsi}} if needed
#' @export
#' @seealso The \code{\link{portion}} functions to calculate resistance and susceptibility.
#' @examples
#' library(dplyr)
#'
#' septic_patients %>%
#' group_by(hospital_id) %>%
#' summarise(cipro_p = portion_S(cipr, as_percent = TRUE),
#' cipro_n = n_rsi(cipr),
#' genta_p = portion_S(gent, as_percent = TRUE),
#' genta_n = n_rsi(gent),
#' combination_p = portion_S(cipr, gent, as_percent = TRUE),
#' combination_n = n_rsi(cipr, gent))
n_rsi <- function(ab1, ab2 = NULL) {
if (NCOL(ab1) > 1) {
stop('`ab1` must be a vector of antimicrobial interpretations', call. = FALSE)
}
if (!is.rsi(ab1)) {
ab1 <- as.rsi(ab1)
}
if (!is.null(ab2)) {
if (NCOL(ab2) > 1) {
stop('`ab2` must be a vector of antimicrobial interpretations', call. = FALSE)
}
if (!is.rsi(ab2)) {
ab2 <- as.rsi(ab2)
}
sum(!is.na(ab1) & !is.na(ab2))
} else {
sum(!is.na(ab1))
}
}
+56
View File
@@ -0,0 +1,56 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Symbol of a p value
#'
#' Return the symbol related to the p value: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1. Values above \code{p = 1} will return \code{NA}.
#' @param p p value
#' @param emptychar text to show when \code{p > 0.1}
#' @return Text
#' @export
p.symbol <- function(p, emptychar = " ") {
setting.bak <- options()$scipen
options(scipen = 999)
s <- vector(mode = "character", length = length(p))
for (i in 1:length(p)) {
if (is.na(p[i])) {
s[i] <- NA_character_
next
}
if (p[i] > 1) {
s[i] <- NA_character_
next
} else {
p_test <- p[i]
}
if (p_test > 0.1) {
s[i] <- emptychar
} else if (p_test > 0.05) {
s[i] <- '.'
} else if (p_test > 0.01) {
s[i] <- '*'
} else if (p_test > 0.001) {
s[i] <- '**'
} else if (p_test >= 0) {
s[i] <- '***'
}
}
options(scipen = setting.bak)
s
}
Executable
+307
View File
@@ -0,0 +1,307 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Calculate resistance of isolates
#'
#' @description These functions can be used to calculate the (co-)resistance of microbial isolates (i.e. percentage S, SI, I, IR or R). All functions can be used in \code{dplyr}s \code{\link[dplyr]{summarise}} and support grouped variables, see \emph{Examples}.
#'
#' \code{portion_R} and \code{portion_IR} can be used to calculate resistance, \code{portion_S} and \code{portion_SI} can be used to calculate susceptibility.\cr
#' @param ab1 vector of antibiotic interpretations, they will be transformed internally with \code{\link{as.rsi}} if needed
#' @param ab2 like \code{ab}, a vector of antibiotic interpretations. Use this to calculate (the lack of) co-resistance: the probability where one of two drugs have a resistant or susceptible result. See Examples.
#' @param minimum minimal amount of available isolates. Any number lower than \code{minimum} will return \code{NA}. The default number of \code{30} isolates is advised by the CLSI as best practice, see Source.
#' @param as_percent logical to indicate whether the output must be returned as percent (text), will else be a double
#' @param data a code{data.frame} containing columns with class \code{rsi} (see \code{\link{as.rsi}})
#' @param translate_ab a column name of the \code{\link{antibiotics}} data set to translate the antibiotic abbreviations to, using \code{\link{abname}}. This can be set with \code{\link{getOption}("get_antibiotic_names")}.
#' @details \strong{Remember that you should filter your table to let it contain only first isolates!} Use \code{\link{first_isolate}} to determine them in your data set.
#'
#' \code{portion_df} takes any variable from \code{data} that has an \code{"rsi"} class (created with \code{\link{as.rsi}}) and calculates the portions R, I and S. The resulting \emph{tidy data} (see Source) \code{data.frame} will have three rows (S/I/R) and a column for each variable with class \code{"rsi"}.
#'
#' The old \code{\link{rsi}} function is still available for backwards compatibility but is deprecated.
#' \if{html}{
#' \cr\cr
#' To calculate the probability (\emph{p}) of susceptibility of one antibiotic, we use this formula:
#' \out{<div style="text-align: center">}\figure{mono_therapy.png}\out{</div>}
#' To calculate the probability (\emph{p}) of susceptibility of more antibiotics (i.e. combination therapy), we need to check whether one of them has a susceptible result (as numerator) and count all cases where all antibiotics were tested (as denominator). \cr
#' \cr
#' For two antibiotics:
#' \out{<div style="text-align: center">}\figure{combi_therapy_2.png}\out{</div>}
#' \cr
#' Theoretically for three antibiotics:
#' \out{<div style="text-align: center">}\figure{combi_therapy_3.png}\out{</div>}
#' }
#' @source \strong{M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 4th Edition}, 2014, \emph{Clinical and Laboratory Standards Institute (CLSI)}. \url{https://clsi.org/standards/products/microbiology/documents/m39/}.
#'
#' Wickham H. \strong{Tidy Data.} The Journal of Statistical Software, vol. 59, 2014. \url{http://vita.had.co.nz/papers/tidy-data.html}
#' @seealso \code{\link{n_rsi}} to count cases with antimicrobial results.
#' @keywords resistance susceptibility rsi_df rsi antibiotics isolate isolates
#' @return Double or, when \code{as_percent = TRUE}, a character.
#' @rdname portion
#' @name portion
#' @export
#' @examples
#' # septic_patients is a data set available in the AMR package. It is true, genuine data.
#' ?septic_patients
#'
#' # Calculate resistance
#' portion_R(septic_patients$amox)
#' portion_IR(septic_patients$amox)
#'
#' # Or susceptibility
#' portion_S(septic_patients$amox)
#' portion_SI(septic_patients$amox)
#'
#' # Since n_rsi counts available isolates (and is used as denominator),
#' # you can calculate back to count e.g. non-susceptible isolates:
#' portion_IR(septic_patients$amox) * n_rsi(septic_patients$amox)
#'
#' library(dplyr)
#' septic_patients %>%
#' group_by(hospital_id) %>%
#' summarise(p = portion_S(cipr),
#' n = n_rsi(cipr)) # n_rsi works like n_distinct in dplyr
#'
#' septic_patients %>%
#' group_by(hospital_id) %>%
#' summarise(R = portion_R(cipr, as_percent = TRUE),
#' I = portion_I(cipr, as_percent = TRUE),
#' S = portion_S(cipr, as_percent = TRUE),
#' n = n_rsi(cipr), # works like n_distinct in dplyr
#' total = n()) # NOT the amount of tested isolates!
#'
#' # Calculate co-resistance between amoxicillin/clav acid and gentamicin,
#' # so we can see that combination therapy does a lot more than mono therapy:
#' portion_S(septic_patients$amcl) # S = 67.3%
#' n_rsi(septic_patients$amcl) # n = 1570
#'
#' portion_S(septic_patients$gent) # S = 74.0%
#' n_rsi(septic_patients$gent) # n = 1842
#'
#' with(septic_patients,
#' portion_S(amcl, gent)) # S = 92.1%
#' with(septic_patients, # n = 1504
#' n_rsi(amcl, gent))
#'
#' septic_patients %>%
#' group_by(hospital_id) %>%
#' summarise(cipro_p = portion_S(cipr, as_percent = TRUE),
#' cipro_n = n_rsi(cipr),
#' genta_p = portion_S(gent, as_percent = TRUE),
#' genta_n = n_rsi(gent),
#' combination_p = portion_S(cipr, gent, as_percent = TRUE),
#' combination_n = n_rsi(cipr, gent))
#'
#' # Get portions S/I/R immediately of all rsi columns
#' septic_patients %>%
#' select(amox, cipr) %>%
#' portion_df(translate = FALSE)
#'
#' # It also supports grouping variables
#' septic_patients %>%
#' select(hospital_id, amox, cipr) %>%
#' group_by(hospital_id) %>%
#' portion_df(translate = FALSE)
#'
#'
#' \dontrun{
#'
#' # calculate current empiric combination therapy of Helicobacter gastritis:
#' my_table %>%
#' filter(first_isolate == TRUE,
#' genus == "Helicobacter") %>%
#' summarise(p = portion_S(amox, metr), # amoxicillin with metronidazole
#' n = n_rsi(amox, metr))
#' }
portion_R <- function(ab1,
ab2 = NULL,
minimum = 30,
as_percent = FALSE) {
rsi_calc(type = "R",
ab1 = ab1,
ab2 = ab2,
include_I = FALSE,
minimum = minimum,
as_percent = as_percent)
}
#' @rdname portion
#' @export
portion_IR <- function(ab1,
ab2 = NULL,
minimum = 30,
as_percent = FALSE) {
rsi_calc(type = "R",
ab1 = ab1,
ab2 = ab2,
include_I = TRUE,
minimum = minimum,
as_percent = as_percent)
}
#' @rdname portion
#' @export
portion_I <- function(ab1,
minimum = 30,
as_percent = FALSE) {
rsi_calc(type = "I",
ab1 = ab1,
ab2 = NULL,
include_I = FALSE,
minimum = minimum,
as_percent = as_percent)
}
#' @rdname portion
#' @export
portion_SI <- function(ab1,
ab2 = NULL,
minimum = 30,
as_percent = FALSE) {
rsi_calc(type = "S",
ab1 = ab1,
ab2 = ab2,
include_I = TRUE,
minimum = minimum,
as_percent = as_percent)
}
#' @rdname portion
#' @export
portion_S <- function(ab1,
ab2 = NULL,
minimum = 30,
as_percent = FALSE) {
rsi_calc(type = "S",
ab1 = ab1,
ab2 = ab2,
include_I = FALSE,
minimum = minimum,
as_percent = as_percent)
}
#' @rdname portion
#' @importFrom dplyr bind_rows summarise_if mutate group_vars select everything
#' @export
portion_df <- function(data, translate_ab = getOption("get_antibiotic_names", "official")) {
if (as.character(translate_ab) == "TRUE") {
translate_ab <- "official"
}
options(get_antibiotic_names = translate_ab)
resS <- summarise_if(.tbl = data,
.predicate = is.rsi,
.funs = portion_S) %>%
mutate(Interpretation = "S") %>%
select(Interpretation, everything())
resI <- summarise_if(.tbl = data,
.predicate = is.rsi,
.funs = portion_I) %>%
mutate(Interpretation = "I") %>%
select(Interpretation, everything())
resR <- summarise_if(.tbl = data,
.predicate = is.rsi,
.funs = portion_R) %>%
mutate(Interpretation = "R") %>%
select(Interpretation, everything())
data.groups <- group_vars(data)
res <- bind_rows(resS, resI, resR) %>%
mutate(Interpretation = factor(Interpretation, levels = c("R", "I", "S"), ordered = TRUE)) %>%
tidyr::gather(Antibiotic, Percentage, -Interpretation, -data.groups)
if (!translate_ab == FALSE) {
if (!tolower(translate_ab) %in% tolower(colnames(AMR::antibiotics))) {
stop("Parameter `translate_ab` does not occur in the `antibiotics` data set.", call. = FALSE)
}
res <- res %>% mutate(Antibiotic = abname(Antibiotic, from = "guess", to = translate_ab))
}
res
}
rsi_calc <- function(type,
ab1,
ab2,
include_I,
minimum,
as_percent) {
if (NCOL(ab1) > 1) {
stop('`ab1` must be a vector of antimicrobial interpretations', call. = FALSE)
}
if (!is.logical(include_I)) {
stop('`include_I` must be logical', call. = FALSE)
}
if (!is.numeric(minimum)) {
stop('`minimum` must be numeric', call. = FALSE)
}
if (!is.logical(as_percent)) {
stop('`as_percent` must be logical', call. = FALSE)
}
print_warning <- FALSE
if (!is.rsi(ab1)) {
ab1 <- as.rsi(ab1)
print_warning <- TRUE
}
if (!is.null(ab2)) {
# ab_name <- paste(deparse(substitute(ab1)), "and", deparse(substitute(ab2)))
if (NCOL(ab2) > 1) {
stop('`ab2` must be a vector of antimicrobial interpretations', call. = FALSE)
}
if (!is.rsi(ab2)) {
ab2 <- as.rsi(ab2)
print_warning <- TRUE
}
x <- apply(X = data.frame(ab1 = as.integer(ab1),
ab2 = as.integer(ab2)),
MARGIN = 1,
FUN = min)
} else {
x <- ab1
# ab_name <- deparse(substitute(ab1))
}
if (print_warning == TRUE) {
warning("Increase speed by transforming to class `rsi` on beforehand: df %>% mutate_at(vars(col10:col20), as.rsi)")
}
total <- length(x) - sum(is.na(x))
if (total < minimum) {
return(NA)
}
if (type == "S") {
found <- sum(as.integer(x) <= 1 + include_I, na.rm = TRUE)
} else if (type == "I") {
found <- sum(as.integer(x) == 2, na.rm = TRUE)
} else if (type == "R") {
found <- sum(as.integer(x) >= 3 - include_I, na.rm = TRUE)
} else {
stop("invalid type")
}
if (as_percent == TRUE) {
percent(found / total, force_zero = TRUE)
} else {
found / total
}
}
+293
View File
@@ -0,0 +1,293 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Predict antimicrobial resistance
#'
#' Create a prediction model to predict antimicrobial resistance for the next years on statistical solid ground. Standard errors (SE) will be returned as columns \code{se_min} and \code{se_max}. See Examples for a real live example.
#' @inheritParams first_isolate
#' @param col_ab column name of \code{tbl} with antimicrobial interpretations (\code{R}, \code{I} and \code{S})
#' @param col_date column name of the date, will be used to calculate years if this column doesn't consist of years already
#' @param year_min lowest year to use in the prediction model, dafaults the lowest year in \code{col_date}
#' @param year_max highest year to use in the prediction model, defaults to 15 years after today
#' @param year_every unit of sequence between lowest year found in the data and \code{year_max}
#' @param minimum minimal amount of available isolates per year to include. Years containing less observations will be estimated by the model.
#' @param model the statistical model of choice. Valid values are \code{"binomial"} (or \code{"binom"} or \code{"logit"}) or \code{"loglin"} or \code{"linear"} (or \code{"lin"}).
#' @param I_as_R treat \code{I} as \code{R}
#' @param preserve_measurements logical to indicate whether predictions of years that are actually available in the data should be overwritten with the original data. The standard errors of those years will be \code{NA}.
#' @param info print textual analysis with the name and \code{\link{summary}} of the model.
#' @return \code{data.frame} with columns:
#' \itemize{
#' \item{\code{year}}
#' \item{\code{value}, the same as \code{estimated} when \code{preserve_measurements = FALSE}, and a combination of \code{observed} and \code{estimated} otherwise}
#' \item{\code{se_min}, the lower bound of the standard error with a minimum of \code{0}}
#' \item{\code{se_max} the upper bound of the standard error with a maximum of \code{1}}
#' \item{\code{observations}, the total number of observations, i.e. S + I + R}
#' \item{\code{observed}, the original observed values}
#' \item{\code{estimated}, the estimated values, calculated by the model}
#' }
#' @seealso The \code{\link{portion}} function to calculate resistance, \cr \code{\link{lm}} \code{\link{glm}}
#' @rdname resistance_predict
#' @export
#' @importFrom stats predict glm lm
#' @importFrom dplyr %>% pull mutate group_by_at summarise filter n_distinct arrange case_when
# @importFrom tidyr spread
#' @examples
#' \dontrun{
#' # use it with base R:
#' resistance_predict(tbl = tbl[which(first_isolate == TRUE & genus == "Haemophilus"),],
#' col_ab = "amcl", col_date = "date")
#'
#' # or use dplyr so you can actually read it:
#' library(dplyr)
#' tbl %>%
#' filter(first_isolate == TRUE,
#' genus == "Haemophilus") %>%
#' resistance_predict(amcl, date)
#' }
#'
#'
#' # real live example:
#' library(dplyr)
#' septic_patients %>%
#' # get bacteria properties like genus and species
#' left_join_microorganisms("bactid") %>%
#' # calculate first isolates
#' mutate(first_isolate =
#' first_isolate(.,
#' "date",
#' "patient_id",
#' "bactid",
#' col_specimen = NA,
#' col_icu = NA)) %>%
#' # filter on first E. coli isolates
#' filter(genus == "Escherichia",
#' species == "coli",
#' first_isolate == TRUE) %>%
#' # predict resistance of cefotaxime for next years
#' resistance_predict(col_ab = "cfot",
#' col_date = "date",
#' year_max = 2025,
#' preserve_measurements = TRUE,
#' minimum = 0)
#'
#' # create nice plots with ggplot
#' if (!require(ggplot2)) {
#'
#' data <- septic_patients %>%
#' filter(bactid == "ESCCOL") %>%
#' resistance_predict(col_ab = "amox",
#' col_date = "date",
#' info = FALSE,
#' minimum = 15)
#'
#' ggplot(data,
#' aes(x = year)) +
#' geom_col(aes(y = value),
#' fill = "grey75") +
#' geom_errorbar(aes(ymin = se_min,
#' ymax = se_max),
#' colour = "grey50") +
#' scale_y_continuous(limits = c(0, 1),
#' breaks = seq(0, 1, 0.1),
#' labels = paste0(seq(0, 100, 10), "%")) +
#' labs(title = expression(paste("Forecast of amoxicillin resistance in ",
#' italic("E. coli"))),
#' y = "%IR",
#' x = "Year") +
#' theme_minimal(base_size = 13)
#' }
resistance_predict <- function(tbl,
col_ab,
col_date,
year_min = NULL,
year_max = NULL,
year_every = 1,
minimum = 30,
model = 'binomial',
I_as_R = TRUE,
preserve_measurements = TRUE,
info = TRUE) {
if (nrow(tbl) == 0) {
stop('This table does not contain any observations.')
}
if (!col_ab %in% colnames(tbl)) {
stop('Column ', col_ab, ' not found.')
}
if (!col_date %in% colnames(tbl)) {
stop('Column ', col_date, ' not found.')
}
if ('grouped_df' %in% class(tbl)) {
# no grouped tibbles please, mutate will throw errors
tbl <- base::as.data.frame(tbl, stringsAsFactors = FALSE)
}
if (I_as_R == TRUE) {
tbl[, col_ab] <- gsub('I', 'R', tbl %>% pull(col_ab))
}
if (!tbl %>% pull(col_ab) %>% is.rsi()) {
tbl[, col_ab] <- tbl %>% pull(col_ab) %>% as.rsi()
}
year <- function(x) {
if (all(grepl('^[0-9]{4}$', x))) {
x
} else {
as.integer(format(as.Date(x), '%Y'))
}
}
df <- tbl %>%
mutate(year = tbl %>% pull(col_date) %>% year()) %>%
group_by_at(c('year', col_ab)) %>%
summarise(n())
if (df %>% pull(col_ab) %>% n_distinct(na.rm = TRUE) < 2) {
stop("No variety in antimicrobial interpretations - all isolates are '",
df %>% pull(col_ab) %>% unique() %>% .[!is.na(.)], "'.",
call. = FALSE)
}
colnames(df) <- c('year', 'antibiotic', 'observations')
df <- df %>%
filter(!is.na(antibiotic)) %>%
tidyr::spread(antibiotic, observations, fill = 0) %>%
mutate(total = R + S) %>%
filter(total >= minimum)
if (NROW(df) == 0) {
stop('There are no observations.')
}
year_lowest <- min(df$year)
if (is.null(year_min)) {
year_min <- year_lowest
} else {
year_min <- max(year_min, year_lowest, na.rm = TRUE)
}
if (is.null(year_max)) {
year_max <- year(Sys.Date()) + 15
}
years_predict <- seq(from = year_min, to = year_max, by = year_every)
if (model %in% c('binomial', 'binom', 'logit')) {
logitmodel <- with(df, glm(cbind(R, S) ~ year, family = binomial))
if (info == TRUE) {
cat('\nLogistic regression model (logit) with binomial distribution')
cat('\n------------------------------------------------------------\n')
print(summary(logitmodel))
}
predictmodel <- predict(logitmodel, newdata = with(df, list(year = years_predict)), type = "response", se.fit = TRUE)
prediction <- predictmodel$fit
se <- predictmodel$se.fit
} else if (model == 'loglin') {
loglinmodel <- with(df, glm(R ~ year, family = poisson))
if (info == TRUE) {
cat('\nLog-linear regression model (loglin) with poisson distribution')
cat('\n--------------------------------------------------------------\n')
print(summary(loglinmodel))
}
predictmodel <- predict(loglinmodel, newdata = with(df, list(year = years_predict)), type = "response", se.fit = TRUE)
prediction <- predictmodel$fit
se <- predictmodel$se.fit
} else if (model %in% c('lin', 'linear')) {
linmodel <- with(df, lm((R / (R + S)) ~ year))
if (info == TRUE) {
cat('\nLinear regression model')
cat('\n-----------------------\n')
print(summary(linmodel))
}
predictmodel <- predict(linmodel, newdata = with(df, list(year = years_predict)), se.fit = TRUE)
prediction <- predictmodel$fit
se <- predictmodel$se.fit
} else {
stop('No valid model selected.')
}
# prepare the output dataframe
prediction <- data.frame(year = years_predict, value = prediction, stringsAsFactors = FALSE)
prediction$se_min <- prediction$value - se
prediction$se_max <- prediction$value + se
if (model == 'loglin') {
prediction$value <- prediction$value %>%
format(scientific = FALSE) %>%
as.integer()
prediction$se_min <- prediction$se_min %>% as.integer()
prediction$se_max <- prediction$se_max %>% as.integer()
colnames(prediction) <- c('year', 'amountR', 'se_max', 'se_min')
} else {
prediction$se_max[which(prediction$se_max > 1)] <- 1
}
prediction$se_min[which(prediction$se_min < 0)] <- 0
prediction$observations = NA
total <- prediction
if (preserve_measurements == TRUE) {
# replace estimated data by observed data
if (I_as_R == TRUE) {
if (!'I' %in% colnames(df)) {
df$I <- 0
}
df$value <- df$R / rowSums(df[, c('R', 'S', 'I')])
} else {
df$value <- df$R / rowSums(df[, c('R', 'S')])
}
measurements <- data.frame(year = df$year,
value = df$value,
se_min = NA,
se_max = NA,
observations = df$total,
stringsAsFactors = FALSE)
colnames(measurements) <- colnames(prediction)
total <- rbind(measurements,
prediction %>% filter(!year %in% df$year))
if (model %in% c('binomial', 'binom', 'logit')) {
total <- total %>% mutate(observed = ifelse(is.na(observations), NA, value),
estimated = prediction$value)
}
}
if ("value" %in% colnames(total)) {
total <- total %>%
mutate(value = case_when(value > 1 ~ 1,
value < 0 ~ 0,
TRUE ~ value))
}
total %>% arrange(year)
}
#' @rdname resistance_predict
#' @export
rsi_predict <- resistance_predict
+53
View File
@@ -0,0 +1,53 @@
# ==================================================================== #
# TITLE #
# Antimicrobial Resistance (AMR) Analysis #
# #
# AUTHORS #
# Berends MS (m.s.berends@umcg.nl), Luz CF (c.f.luz@umcg.nl) #
# #
# LICENCE #
# This program is free software; you can redistribute it and/or modify #
# it under the terms of the GNU General Public License version 2.0, #
# as published by the Free Software Foundation. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# ==================================================================== #
#' Calculate resistance of isolates
#'
#' This function is deprecated. Use the \code{\link{portion}} functions instead.
#' @inheritParams portion
#' @param interpretation antimicrobial interpretation to check for
#' @param ... deprecated parameters to support usage on older versions
#' @importFrom dplyr case_when
#' @export
rsi <- function(ab1,
ab2 = NULL,
interpretation = "IR",
minimum = 30,
as_percent = FALSE,
...) {
result <- case_when(
interpretation == "S" ~ portion_S(ab1 = ab1, ab2 = ab2, minimum = minimum, as_percent = FALSE),
interpretation %in% c("SI", "IS") ~ portion_SI(ab1 = ab1, ab2 = ab2, minimum = minimum, as_percent = FALSE),
interpretation == "I" ~ portion_I(ab1 = ab1, minimum = minimum, as_percent = FALSE),
interpretation %in% c("RI", "IR") ~ portion_IR(ab1 = ab1, ab2 = ab2, minimum = minimum, as_percent = FALSE),
interpretation == "R" ~ portion_R(ab1 = ab1, ab2 = ab2, minimum = minimum, as_percent = FALSE),
TRUE ~ -1
)
if (result == -1) {
stop("invalid interpretation")
}
.Deprecated(new = paste0("portion_", interpretation))
if (as_percent == TRUE) {
percent(result, force_zero = TRUE)
} else {
result
}
}
+40
View File
@@ -0,0 +1,40 @@
#' Skewness of the sample
#'
#' @description Skewness is a measure of the asymmetry of the probability distribution of a real-valued random variable about its mean.
#'
#' When negative: the left tail is longer; the mass of the distribution is concentrated on the right of the figure. When positive: the right tail is longer; the mass of the distribution is concentrated on the left of the figure.
#' @param x a vector of values, a \code{matrix} or a \code{data frame}
#' @param na.rm a logical value indicating whether \code{NA} values should be stripped before the computation proceeds.
#' @exportMethod skewness
#' @seealso \code{\link{kurtosis}}
#' @rdname skewness
#' @export
skewness <- function(x, na.rm = FALSE) {
UseMethod("skewness")
}
#' @exportMethod skewness.default
#' @rdname skewness
#' @export
skewness.default <- function (x, na.rm = FALSE) {
x <- as.vector(x)
if (na.rm == TRUE) {
x <- x[!is.na(x)]
}
n <- length(x)
(base::sum((x - base::mean(x))^3) / n) / (base::sum((x - base::mean(x))^2) / n)^(3/2)
}
#' @exportMethod skewness.matrix
#' @rdname skewness
#' @export
skewness.matrix <- function (x, na.rm = FALSE) {
base::apply(x, 2, skewness.default, na.rm = na.rm)
}
#' @exportMethod skewness.data.frame
#' @rdname skewness
#' @export
skewness.data.frame <- function (x, na.rm = FALSE) {
base::sapply(x, skewness.default, na.rm = na.rm)
}
Executable
+3
View File
@@ -0,0 +1,3 @@
.onLoad <- function(libname, pkgname) {
backports::import(pkgname)
}
Executable
+397
View File
@@ -0,0 +1,397 @@
# `AMR`
### An [R package](https://www.r-project.org) to simplify the analysis and prediction of Antimicrobial Resistance (AMR) and work with antibiotic properties by using evidence-based methods.
This R package was created for academic research by PhD students of the Faculty of Medical Sciences of the [University of Groningen](https://www.rug.nl) and the Medical Microbiology & Infection Prevention (MMBI) department of the [University Medical Center Groningen (UMCG)](https://www.umcg.nl).
:arrow_forward: Download it with `install.packages("AMR")` or see below for other possibilities.
## Authors
<a href="https://orcid.org/0000-0001-7620-1800"><img src="https://cran.r-project.org/web/orcid.svg" height="16px"></a> Matthijs S. Berends<sup>1,2,a</sup>,
<a href="https://orcid.org/0000-0001-5809-5995"><img src="https://cran.r-project.org/web/orcid.svg" height="16px"></a> Christian F. Luz<sup>1,a</sup>,
Erwin E.A. Hassing<sup>2</sup>,
<a href="https://orcid.org/0000-0003-1241-1328"><img src="https://cran.r-project.org/web/orcid.svg" height="16px"></a> Corinna Glasner<sup>1,b</sup>,
<a href="https://orcid.org/0000-0003-4881-038X"><img src="https://cran.r-project.org/web/orcid.svg" height="16px"></a> Alex W. Friedrich<sup>1,b</sup>,
<a href="https://orcid.org/0000-0003-1634-0010"><img src="https://cran.r-project.org/web/orcid.svg" height="16px"></a> Bhanu Sinha<sup>1,b</sup>
<sup>1</sup> Department of Medical Microbiology, University of Groningen, University Medical Center Groningen, Groningen, the Netherlands - [rug.nl](http://www.rug.nl) [umcg.nl](http://www.umcg.nl)<br>
<sup>2</sup> Certe Medical Diagnostics & Advice, Groningen, the Netherlands - [certe.nl](http://www.certe.nl)<br>
<sup>a</sup> R package author and thesis dissertant<br>
<sup>b</sup> Thesis advisor
<a href="https://www.rug.nl"><img src="man/figures/logo_rug.png" height="60px"></a>
<a href="https://www.umcg.nl"><img src="man/figures/logo_umcg.png" height="60px"></a>
<a href="https://www.certe.nl"><img src="man/figures/logo_certe.png" height="60px"></a>
<a href="http://www.eurhealth-1health.eu"><img src="man/figures/logo_eh1h.png" height="60px"></a>
<a href="http://www.eurhealth-1health.eu"><img src="man/figures/logo_interreg.png" height="60px"></a>
## Contents
* [Why this package?](#why-this-package)
* [How to get it?](#how-to-get-it)
* [Install from CRAN](#install-from-cran)
* [Install from GitHub](#install-from-github)
* [How to use it?](#how-to-use-it)
* [New classes](#new-classes)
* [Overwrite/force resistance based on EUCAST rules](#overwriteforce-resistance-based-on-eucast-rules)
* [Other (microbial) epidemiological functions](#other-microbial-epidemiological-functions)
* [Frequency tables](#frequency-tables)
* [Data sets included in package](#data-sets-included-in-package)
* [Copyright](#copyright)
## Why this package?
This R package was intended to make microbial epidemiology easier. Most functions contain extensive help pages to get started.
With `AMR` you can:
* Calculate the resistance (and even co-resistance) of microbial isolates with the `portion_R`, `portion_IR`, `portion_I`, `portion_SI` and `portion_S` functions, that can also be used with the `dplyr` package (e.g. in conjunction with `summarise`)
* Plot AMR results with `geom_rsi`, a function made for the `ggplot2` package
* Predict antimicrobial resistance for the nextcoming years using logistic regression models with the `resistance_predict` function
* Apply [EUCAST rules to isolates](http://www.eucast.org/expert_rules_and_intrinsic_resistance/) with the `EUCAST_rules` function
* Identify first isolates of every patient [using guidelines from the CLSI](https://clsi.org/standards/products/microbiology/documents/m39/) (Clinical and Laboratory Standards Institute) with the `first_isolate` function
* You can also identify first *weighted* isolates of every patient, an adjusted version of the CLSI guideline. This takes into account key antibiotics of every strain and compares them. The following 12 antibiotics will be used as key antibiotics at default:
* Universal: amoxicillin, amoxicillin/clavlanic acid, cefuroxime, piperacillin/tazobactam, ciprofloxacin, trimethoprim/sulfamethoxazole
* Specific for Gram-positives: vancomycin, teicoplanin, tetracycline, erythromycin, oxacillin, rifampicin
* Specific for Gram-negatives: gentamicin, tobramycin, colistin, cefotaxime, ceftazidime, meropenem
* Categorise *Staphylococci* into Coagulase Negative *Staphylococci* (CoNS) and Coagulase Positve *Staphylococci* (CoPS) according to [Karsten Becker *et al.*](https://www.ncbi.nlm.nih.gov/pmc/articles/pmid/25278577/)
* Categorise *Streptococci* into Lancefield groups
* Get antimicrobial ATC properties from the WHO Collaborating Centre for Drug Statistics Methodology ([WHOCC](https://www.whocc.no/atc_ddd_methodology/who_collaborating_centre/)), to be able to:
* Translate antibiotic codes (like *AMOX*), official names (like *amoxicillin*) and even trade names (like *Amoxil* or *Trimox*) to an [ATC code](https://www.whocc.no/atc_ddd_index/?code=J01CA04&showdescription=no) (like *J01CA04*) and vice versa with the `abname` function
* Get the latest antibiotic properties like hierarchic groups and [defined daily dose](https://en.wikipedia.org/wiki/Defined_daily_dose) (DDD) with units and administration form from the WHOCC website with the `atc_property` function
* Conduct descriptive statistics: calculate kurtosis, skewness and create frequency tables
And it contains:
* A recent data set with ~2500 human pathogenic microorganisms, including family, genus, species, gram stain and aerobic/anaerobic
* A recent data set with all antibiotics as defined by the [WHOCC](https://www.whocc.no/atc_ddd_methodology/who_collaborating_centre/), including ATC code, official name and DDD's
* An example data set `septic_patients`, consisting of 2000 blood culture isolates from anonymised septic patients between 2001 and 2017.
With the `MDRO` function (abbreviation of Multi Drug Resistant Organisms), you can check your isolates for exceptional resistance with country-specific guidelines or EUCAST rules. Currently guidelines for Germany and the Netherlands are supported. Please suggest addition of your own country here: [https://github.com/msberends/AMR/issues/new](https://github.com/msberends/AMR/issues/new?title=New%20guideline%20for%20MDRO&body=%3C--%20Please%20add%20your%20country%20code,%20guideline%20name,%20version%20and%20source%20below%20and%20remove%20this%20line--%3E).
**Read all changes and new functions in [NEWS.md](NEWS.md).**
## How to get it?
This package [is published on CRAN](http://cran.r-project.org/package=AMR), the official R network.
### Install from CRAN
[![CRAN_Badge](https://www.r-pkg.org/badges/version/AMR)](http://cran.r-project.org/package=AMR) [![CRAN_Downloads](https://cranlogs.r-pkg.org/badges/grand-total/AMR)](http://cran.r-project.org/package=AMR)
(Note: Downloads measured only by [cran.rstudio.com](https://cran.rstudio.com/package=AMR), this excludes e.g. the official [cran.r-project.org](https://cran.r-project.org/package=AMR))
- <img src="http://www.rstudio.com/favicon.ico" alt="RStudio favicon" height="20px"> Install using [RStudio](http://www.rstudio.com) (recommended):
- Click on `Tools` and then `Install Packages...`
- Type in `AMR` and press <kbd>Install</kbd>
- <img src="https://cran.r-project.org/favicon.ico" alt="R favicon" height="20px"> Install in R directly:
- `install.packages("AMR")`
### Install from GitHub
[![Travis_Build](https://travis-ci.org/msberends/AMR.svg?branch=master)](https://travis-ci.org/msberends/AMR)
[![AppVeyor_Build](https://ci.appveyor.com/api/projects/status/github/msberends/AMR?branch=master&svg=true)](https://ci.appveyor.com/project/msberends/AMR)
[![Last_Commit](https://img.shields.io/github/last-commit/msberends/AMR.svg)](https://github.com/msberends/AMR/commits/master)
[![Code_Coverage](https://codecov.io/gh/msberends/AMR/branch/master/graph/badge.svg)](https://codecov.io/gh/msberends/AMR)
```r install.packages("devtools")
devtools::install_github("msberends/AMR")
```
## How to use it?
```r
# Call it with:
library(AMR)
# For a list of functions:
help(package = "AMR")
```
### New classes
This package contains two new S3 classes: `mic` for MIC values (e.g. from Vitek or Phoenix) and `rsi` for antimicrobial drug interpretations (i.e. S, I and R). Both are actually ordered factors under the hood (an MIC of `2` being higher than `<=1` but lower than `>=32`, and for class `rsi` factors are ordered as `S < I < R`).
Both classes have extensions for existing generic functions like `print`, `summary` and `plot`.
These functions also try to coerce valid values.
#### RSI
The `septic_patients` data set comes with antimicrobial results of more than 40 different drugs. For example, columns `amox` and `cipr` contain results of amoxicillin and ciprofloxacin, respectively.
```r
summary(septic_patients[, c("amox", "cipr")])
# amox cipr
# Mode :rsi Mode :rsi
# <NA> :1002 <NA> :596
# Sum S :336 Sum S :1108
# Sum IR:662 Sum IR:296
# -Sum R:659 -Sum R:227
# -Sum I:3 -Sum I:69
```
You can use the `plot` function from base R:
```r
plot(septic_patients$cipr)
```
![example_1_rsi](man/figures/rsi_example1.png)
Or use the `ggplot2` and `dplyr` packages to create more appealing plots:
```r
library(dplyr)
library(ggplot2)
septic_patients %>%
select(amox, cipr) %>%
ggplot_rsi()
```
![example_2_rsi](man/figures/rsi_example2.png)
```r
septic_patients %>%
select(amox, cipr) %>%
ggplot_rsi(x = "Interpretation", facet = "Antibiotic")
```
![example_3_rsi](man/figures/rsi_example3.png)
It also supports grouping variables. Let's say we want to compare resistance of drugs against Urine Tract Infections (UTI) between hospitals A to D (variable `hospital_id`):
```r
septic_patients %>%
select(hospital_id, amox, nitr, fosf, trim, cipr) %>%
group_by(hospital_id) %>%
ggplot_rsi(x = "hospital_id",
facet = "Antibiotic",
nrow = 1) +
labs(title = "AMR of Anti-UTI Drugs Per Hospital",
x = "Hospital")
```
![example_4_rsi](man/figures/rsi_example4.png)
You could use this to group on anything in your plots: Gram stain, age (group), genus, geographic location, et cetera.
#### MIC
```r
# Transform values to new class
mic_data <- as.mic(c(">=32", "1.0", "8", "<=0.128", "8", "16", "16"))
summary(mic_data)
# Mode:mic
# <NA>:0
# Min.:<=0.128
# Max.:>=32
plot(mic_data)
```
![example_mic](man/figures/mic_example.png)
### Overwrite/force resistance based on EUCAST rules
This is also called *interpretive reading*.
```r
before <- data.frame(bactid = c("STAAUR", # Staphylococcus aureus
"ENCFAE", # Enterococcus faecalis
"ESCCOL", # Escherichia coli
"KLEPNE", # Klebsiella pneumoniae
"PSEAER"), # Pseudomonas aeruginosa
vanc = "-", # Vancomycin
amox = "-", # Amoxicillin
coli = "-", # Colistin
cfta = "-", # Ceftazidime
cfur = "-", # Cefuroxime
stringsAsFactors = FALSE)
before
# bactid vanc amox coli cfta cfur
# 1 STAAUR - - - - -
# 2 ENCFAE - - - - -
# 3 ESCCOL - - - - -
# 4 KLEPNE - - - - -
# 5 PSEAER - - - - -
# Now apply those rules; just need a column with bacteria ID's and antibiotic results:
after <- EUCAST_rules(before)
after
# bactid vanc amox coli cfta cfur
# 1 STAAUR - - R R -
# 2 ENCFAE - - R R R
# 3 ESCCOL R - - - -
# 4 KLEPNE R R - - -
# 5 PSEAER R R - - R
```
Bacteria ID's can be retrieved with the `guess_bactid` function. It uses any type of info about a microorganism as input. For example, all these will return value `STAAUR`, the ID of *S. aureus*:
```r
guess_bactid("stau")
guess_bactid("STAU")
guess_bactid("staaur")
guess_bactid("S. aureus")
guess_bactid("S aureus")
guess_bactid("Staphylococcus aureus")
guess_bactid("MRSA") # Methicillin Resistant S. aureus
guess_bactid("VISA") # Vancomycin Intermediate S. aureus
guess_bactid("VRSA") # Vancomycin Resistant S. aureus
```
### Other (microbial) epidemiological functions
```r
# G-test to replace Chi squared test
g.test(...)
# Determine key antibiotic based on bacteria ID
key_antibiotics(...)
# Selection of first isolates of any patient
first_isolate(...)
# Calculate resistance levels of antibiotics, can be used with `summarise` (dplyr)
rsi(...)
# Predict resistance levels of antibiotics
rsi_predict(...)
# Get name of antibiotic by ATC code
abname(...)
abname("J01CR02", from = "atc", to = "umcg") # "AMCL"
```
### Frequency tables
Base R lacks a simple function to create frequency tables. We created such a function that works with almost all data types: `freq` (or `frequency_tbl`). It can be used in two ways:
```r
# Like base R:
freq(mydata$myvariable)
# And like tidyverse:
mydata %>% freq(myvariable)
```
Factors sort on item by default:
```r
septic_patients %>% freq(hospital_id)
# Frequency table of `hospital_id`
# Class: factor
# Length: 2000 (of which NA: 0 = 0.0%)
# Unique: 4
#
# Item Count Percent Cum. Count Cum. Percent (Factor Level)
# --- ----- ------ -------- ----------- ------------- ---------------
# 1 A 319 16.0% 319 16.0% 1
# 2 B 661 33.1% 980 49.0% 2
# 3 C 256 12.8% 1236 61.8% 3
# 4 D 764 38.2% 2000 100.0% 4
```
This can be changed with the `sort.count` parameter:
```r
septic_patients %>% freq(hospital_id, sort.count = TRUE)
# Frequency table of `hospital_id`
# Class: factor
# Length: 2000 (of which NA: 0 = 0.0%)
# Unique: 4
#
# Item Count Percent Cum. Count Cum. Percent (Factor Level)
# --- ----- ------ -------- ----------- ------------- ---------------
# 1 D 764 38.2% 764 38.2% 4
# 2 B 661 33.1% 1425 71.2% 2
# 3 A 319 16.0% 1744 87.2% 1
# 4 C 256 12.8% 2000 100.0% 3
```
All other types, like numbers, characters and dates, sort on count by default:
```r
septic_patients %>% freq(date)
# Frequency table of `date`
# Class: Date
# Length: 2000 (of which NA: 0 = 0.0%)
# Unique: 1151
#
# Oldest: 2 January 2002
# Newest: 28 December 2017 (+5839)
# Median: 7 Augustus 2009 (~48%)
#
# Item Count Percent Cum. Count Cum. Percent
# --- ----------- ------ -------- ----------- -------------
# 1 2016-05-21 10 0.5% 10 0.5%
# 2 2004-11-15 8 0.4% 18 0.9%
# 3 2013-07-29 8 0.4% 26 1.3%
# 4 2017-06-12 8 0.4% 34 1.7%
# 5 2015-11-19 7 0.4% 41 2.1%
# 6 2005-12-22 6 0.3% 47 2.4%
# 7 2015-10-12 6 0.3% 53 2.6%
# 8 2002-05-16 5 0.2% 58 2.9%
# 9 2004-02-02 5 0.2% 63 3.1%
# 10 2004-02-18 5 0.2% 68 3.4%
# 11 2005-08-16 5 0.2% 73 3.6%
# 12 2005-09-01 5 0.2% 78 3.9%
# 13 2006-06-29 5 0.2% 83 4.2%
# 14 2007-08-10 5 0.2% 88 4.4%
# 15 2008-08-29 5 0.2% 93 4.7%
# [ reached getOption("max.print.freq") -- omitted 1136 entries, n = 1907 (95.3%) ]
```
For numeric values, some extra descriptive statistics will be calculated:
```r
freq(runif(n = 10, min = 1, max = 5))
# Frequency table
# Class: numeric
# Length: 10 (of which NA: 0 = 0.0%)
# Unique: 10
#
# Mean: 3.4
# Std. dev.: 1.3 (CV: 0.38, MAD: 1.3)
# Five-Num: 1.6 | 2.0 | 3.9 | 4.7 | 4.8 (IQR: 2.7, CQV: 0.4)
# Outliers: 0
#
# Item Count Percent Cum. Count Cum. Percent
# --- --------- ------ -------- ----------- -------------
# 1 1.568997 1 10.0% 1 10.0%
# 2 1.993575 1 10.0% 2 20.0%
# 3 2.022348 1 10.0% 3 30.0%
# 4 2.236038 1 10.0% 4 40.0%
# 5 3.579828 1 10.0% 5 50.0%
# 6 4.178081 1 10.0% 6 60.0%
# 7 4.394818 1 10.0% 7 70.0%
# 8 4.689871 1 10.0% 8 80.0%
# 9 4.698626 1 10.0% 9 90.0%
# 10 4.751488 1 10.0% 10 100.0%
#
# Warning message:
# All observations are unique.
```
Learn more about this function with:
```r
?freq
```
### Data sets included in package
Datasets to work with antibiotics and bacteria properties.
```r
# Dataset with 2000 random blood culture isolates from anonymised
# septic patients between 2001 and 2017 in 5 Dutch hospitals
septic_patients # A tibble: 2,000 x 49
# Dataset with ATC antibiotics codes, official names, trade names
# and DDD's (oral and parenteral)
antibiotics # A tibble: 420 x 18
# Dataset with bacteria codes and properties like gram stain and
# aerobic/anaerobic
microorganisms # A tibble: 2,453 x 12
```
## Copyright
[![License](https://img.shields.io/github/license/msberends/AMR.svg?colorB=3679BC)](https://github.com/msberends/AMR/blob/master/LICENSE)
This R package is licensed under the [GNU General Public License (GPL) v2.0](https://github.com/msberends/AMR/blob/master/LICENSE). In a nutshell, this means that this package:
- May be used for commercial purposes
- May be used for private purposes
- May **not** be used for patent purposes
- May be modified, although:
- Modifications **must** be released under the same license when distributing the package
- Changes made to the code **must** be documented
- May be distributed, although:
- Source code **must** be made available when the package is distributed
- A copy of the license and copyright notice **must** be included with the package.
- Comes with a LIMITATION of liability
- Comes with NO warranty
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

+64
View File
@@ -0,0 +1,64 @@
# DO NOT CHANGE the "init" and "install" sections below
# Download script file from GitHub
init:
ps: |
$ErrorActionPreference = "Stop"
Invoke-WebRequest http://raw.github.com/krlmlr/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1"
Import-Module '..\appveyor-tool.ps1'
install:
ps: Bootstrap
cache:
- C:\RLibrary
# Adapt as necessary starting from here
environment:
global:
R_ARCH: x64
GCC_PATH: mingw_64
WARNINGS_ARE_ERRORS: 1
matrix:
- R_VERSION: release
- R_VERSION: devel
notifications:
- provider: Email
to: m.s.berends@umcg.nl
subject: 'AppVeyor: status changed'
message: The status of https://ci.appveyor.com/project/msberends/amr has changed.
on_build_success: false
on_build_failure: false
on_build_status_changed: true
build_script:
- travis-tool.sh install_deps
test_script:
- travis-tool.sh run_tests
on_failure:
- 7z a failure.zip *.Rcheck\*
- appveyor PushArtifact failure.zip
artifacts:
- path: '*.Rcheck\**\*.log'
name: Logs
- path: '*.Rcheck\**\*.out'
name: Logs
- path: '*.Rcheck\**\*.fail'
name: Logs
- path: '*.Rcheck\**\*.Rout'
name: Logs
- path: '\*_*.tar.gz'
name: Bits
- path: '\*_*.zip'
name: Bits
-1442
View File
File diff suppressed because it is too large Load Diff
-1033
View File
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

-660
View File
@@ -1,660 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>AMR for Python • AMR (for R)</title>
<!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="../favicon-96x96.png">
<link rel="icon" type="”image/svg+xml”" href="../favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="../apple-touch-icon.png">
<link rel="icon" sizes="any" href="../favicon.ico">
<link rel="manifest" href="../site.webmanifest">
<script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="../deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet">
<script src="../deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="../deps/Lato-0.4.10/font.css" rel="stylesheet">
<link href="../deps/Fira_Code-0.4.10/font.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet">
<script src="../deps/headroom-0.11.0/headroom.min.js"></script><script src="../deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="../deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="../deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="../deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="../deps/search-1.0.0/fuse.min.js"></script><script src="../deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
<script src="../extra.js"></script><meta property="og:title" content="AMR for Python">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
</head>
<body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="../index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto">
<li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to">
<li><a class="dropdown-item" href="../articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="../reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="../articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="../articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="../reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="../articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="../reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="../articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="../articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="../reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="../reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="../reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul>
</li>
<li class="active nav-item"><a class="nav-link" href="../articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="../reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="../authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul>
<ul class="navbar-nav">
<li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="../search.json">
</form></li>
<li class="nav-item"><a class="nav-link" href="../news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul>
</div>
</div>
</nav><div class="container template-article">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="../logo.svg" class="logo" alt=""><h1>AMR for Python</h1>
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/main/vignettes/AMR_for_Python.Rmd" class="external-link"><code>vignettes/AMR_for_Python.Rmd</code></a></small>
<div class="d-none name"><code>AMR_for_Python.Rmd</code></div>
</div>
<div class="section level2">
<h2 id="introduction">Introduction<a class="anchor" aria-label="anchor" href="#introduction"></a>
</h2>
<p>The <code>AMR</code> package for R is a powerful tool for
antimicrobial resistance (AMR) analysis. It provides extensive features
for handling microbial and antimicrobial data. However, for those who
work primarily in Python, we now have a more intuitive option available:
the <a href="https://pypi.org/project/AMR/" class="external-link"><code>AMR</code> Python
package</a>.</p>
<p>This Python package is a wrapper around the <code>AMR</code> R
package. It uses the <code>rpy2</code> package internally. Despite the
need to have R installed, Python users can now easily work with AMR data
directly through Python code.</p>
</div>
<div class="section level2">
<h2 id="prerequisites">Prerequisites<a class="anchor" aria-label="anchor" href="#prerequisites"></a>
</h2>
<p>This package was only tested with a <a href="https://docs.python.org/3/library/venv.html" class="external-link">virtual environment
(venv)</a>. You can set up such an environment by running:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" tabindex="-1"></a><span class="co"># linux and macOS:</span></span>
<span id="cb1-2"><a href="#cb1-2" tabindex="-1"></a>python <span class="op">-</span>m venv <span class="op">/</span>path<span class="op">/</span>to<span class="op">/</span>new<span class="op">/</span>virtual<span class="op">/</span>environment</span>
<span id="cb1-3"><a href="#cb1-3" tabindex="-1"></a></span>
<span id="cb1-4"><a href="#cb1-4" tabindex="-1"></a><span class="co"># Windows:</span></span>
<span id="cb1-5"><a href="#cb1-5" tabindex="-1"></a>python <span class="op">-</span>m venv C:\path\to\new\virtual\environment</span></code></pre></div>
<p>Then you can <a href="https://docs.python.org/3/library/venv.html#how-venvs-work" class="external-link">activate
the environment</a>, after which the venv is ready to work with.</p>
</div>
<div class="section level2">
<h2 id="install-amr">Install AMR<a class="anchor" aria-label="anchor" href="#install-amr"></a>
</h2>
<ol style="list-style-type: decimal">
<li>
<p>Since the Python package is available on the official <a href="https://pypi.org/project/AMR/" class="external-link">Python Package Index</a>, you can
just run:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" tabindex="-1"></a><span class="ex">pip</span> install AMR</span></code></pre></div>
</li>
<li>
<p>Make sure you have R installed. There is <strong>no need to
install the <code>AMR</code> R package</strong>, as it will be installed
automatically.</p>
<p>For Linux:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb3-1"><a href="#cb3-1" tabindex="-1"></a><span class="co"># Ubuntu / Debian</span></span>
<span id="cb3-2"><a href="#cb3-2" tabindex="-1"></a><span class="fu">sudo</span> apt install r-base</span>
<span id="cb3-3"><a href="#cb3-3" tabindex="-1"></a><span class="co"># Fedora:</span></span>
<span id="cb3-4"><a href="#cb3-4" tabindex="-1"></a><span class="fu">sudo</span> dnf install R</span>
<span id="cb3-5"><a href="#cb3-5" tabindex="-1"></a><span class="co"># CentOS/RHEL</span></span>
<span id="cb3-6"><a href="#cb3-6" tabindex="-1"></a><span class="fu">sudo</span> yum install R</span></code></pre></div>
<p>For macOS (using <a href="https://brew.sh" class="external-link">Homebrew</a>):</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" tabindex="-1"></a><span class="ex">brew</span> install r</span></code></pre></div>
<p>For Windows, visit the <a href="https://cran.r-project.org" class="external-link">CRAN
download page</a> to download and install R.</p>
</li>
</ol>
</div>
<div class="section level2">
<h2 id="examples-of-usage">Examples of Usage<a class="anchor" aria-label="anchor" href="#examples-of-usage"></a>
</h2>
<div class="section level3">
<h3 id="cleaning-taxonomy">Cleaning Taxonomy<a class="anchor" aria-label="anchor" href="#cleaning-taxonomy"></a>
</h3>
<p>Heres an example that demonstrates how to clean microorganism and
drug names using the <code>AMR</code> Python package:</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb5-1"><a href="#cb5-1" tabindex="-1"></a><span class="im">import</span> pandas <span class="im">as</span> pd</span>
<span id="cb5-2"><a href="#cb5-2" tabindex="-1"></a><span class="im">import</span> AMR</span>
<span id="cb5-3"><a href="#cb5-3" tabindex="-1"></a></span>
<span id="cb5-4"><a href="#cb5-4" tabindex="-1"></a><span class="co"># Sample data</span></span>
<span id="cb5-5"><a href="#cb5-5" tabindex="-1"></a>data <span class="op">=</span> {</span>
<span id="cb5-6"><a href="#cb5-6" tabindex="-1"></a> <span class="st">"MOs"</span>: [<span class="st">'E. coli'</span>, <span class="st">'ESCCOL'</span>, <span class="st">'esco'</span>, <span class="st">'Esche coli'</span>],</span>
<span id="cb5-7"><a href="#cb5-7" tabindex="-1"></a> <span class="st">"Drug"</span>: [<span class="st">'Cipro'</span>, <span class="st">'CIP'</span>, <span class="st">'J01MA02'</span>, <span class="st">'Ciproxin'</span>]</span>
<span id="cb5-8"><a href="#cb5-8" tabindex="-1"></a>}</span>
<span id="cb5-9"><a href="#cb5-9" tabindex="-1"></a>df <span class="op">=</span> pd.DataFrame(data)</span>
<span id="cb5-10"><a href="#cb5-10" tabindex="-1"></a></span>
<span id="cb5-11"><a href="#cb5-11" tabindex="-1"></a><span class="co"># Use AMR functions to clean microorganism and drug names</span></span>
<span id="cb5-12"><a href="#cb5-12" tabindex="-1"></a>df[<span class="st">'MO_clean'</span>] <span class="op">=</span> AMR.mo_name(df[<span class="st">'MOs'</span>])</span>
<span id="cb5-13"><a href="#cb5-13" tabindex="-1"></a>df[<span class="st">'Drug_clean'</span>] <span class="op">=</span> AMR.ab_name(df[<span class="st">'Drug'</span>])</span>
<span id="cb5-14"><a href="#cb5-14" tabindex="-1"></a></span>
<span id="cb5-15"><a href="#cb5-15" tabindex="-1"></a><span class="co"># Display the results</span></span>
<span id="cb5-16"><a href="#cb5-16" tabindex="-1"></a><span class="bu">print</span>(df)</span></code></pre></div>
<table class="table">
<thead><tr class="header">
<th>MOs</th>
<th>Drug</th>
<th>MO_clean</th>
<th>Drug_clean</th>
</tr></thead>
<tbody>
<tr class="odd">
<td>E. coli</td>
<td>Cipro</td>
<td>Escherichia coli</td>
<td>Ciprofloxacin</td>
</tr>
<tr class="even">
<td>ESCCOL</td>
<td>CIP</td>
<td>Escherichia coli</td>
<td>Ciprofloxacin</td>
</tr>
<tr class="odd">
<td>esco</td>
<td>J01MA02</td>
<td>Escherichia coli</td>
<td>Ciprofloxacin</td>
</tr>
<tr class="even">
<td>Esche coli</td>
<td>Ciproxin</td>
<td>Escherichia coli</td>
<td>Ciprofloxacin</td>
</tr>
</tbody>
</table>
<div class="section level4">
<h4 id="explanation">Explanation<a class="anchor" aria-label="anchor" href="#explanation"></a>
</h4>
<ul>
<li><p><strong>mo_name:</strong> This function standardises
microorganism names. Here, different variations of <em>Escherichia
coli</em> (such as “E. coli”, “ESCCOL”, “esco”, and “Esche coli”) are
all converted into the correct, standardised form, “Escherichia
coli”.</p></li>
<li><p><strong>ab_name</strong>: Similarly, this function standardises
antimicrobial names. The different representations of ciprofloxacin
(e.g., “Cipro”, “CIP”, “J01MA02”, and “Ciproxin”) are all converted to
the standard name, “Ciprofloxacin”.</p></li>
</ul>
</div>
</div>
<div class="section level3">
<h3 id="calculating-amr">Calculating AMR<a class="anchor" aria-label="anchor" href="#calculating-amr"></a>
</h3>
<div class="sourceCode" id="cb6"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb6-1"><a href="#cb6-1" tabindex="-1"></a><span class="im">import</span> AMR</span>
<span id="cb6-2"><a href="#cb6-2" tabindex="-1"></a><span class="im">import</span> pandas <span class="im">as</span> pd</span>
<span id="cb6-3"><a href="#cb6-3" tabindex="-1"></a></span>
<span id="cb6-4"><a href="#cb6-4" tabindex="-1"></a>df <span class="op">=</span> AMR.example_isolates</span>
<span id="cb6-5"><a href="#cb6-5" tabindex="-1"></a>result <span class="op">=</span> AMR.resistance(df[<span class="st">"AMX"</span>])</span>
<span id="cb6-6"><a href="#cb6-6" tabindex="-1"></a><span class="bu">print</span>(result)</span></code></pre></div>
<pre><code>[0.59555556]</code></pre>
</div>
<div class="section level3">
<h3 id="generating-antibiograms">Generating Antibiograms<a class="anchor" aria-label="anchor" href="#generating-antibiograms"></a>
</h3>
<p>One of the core functions of the <code>AMR</code> package is
generating an antibiogram, a table that summarises the antimicrobial
susceptibility of bacterial isolates. Heres how you can generate an
antibiogram from Python:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb8-1"><a href="#cb8-1" tabindex="-1"></a>result2a <span class="op">=</span> AMR.antibiogram(df[[<span class="st">"mo"</span>, <span class="st">"AMX"</span>, <span class="st">"CIP"</span>, <span class="st">"TZP"</span>]])</span>
<span id="cb8-2"><a href="#cb8-2" tabindex="-1"></a><span class="bu">print</span>(result2a)</span></code></pre></div>
<table class="table">
<colgroup>
<col width="22%">
<col width="22%">
<col width="22%">
<col width="33%">
</colgroup>
<thead><tr class="header">
<th>Pathogen</th>
<th>Amoxicillin</th>
<th>Ciprofloxacin</th>
<th>Piperacillin/tazobactam</th>
</tr></thead>
<tbody>
<tr class="odd">
<td>CoNS</td>
<td>7% (10/142)</td>
<td>73% (183/252)</td>
<td>30% (10/33)</td>
</tr>
<tr class="even">
<td>E. coli</td>
<td>50% (196/392)</td>
<td>88% (399/456)</td>
<td>94% (393/416)</td>
</tr>
<tr class="odd">
<td>K. pneumoniae</td>
<td>0% (0/58)</td>
<td>96% (53/55)</td>
<td>89% (47/53)</td>
</tr>
<tr class="even">
<td>P. aeruginosa</td>
<td>0% (0/30)</td>
<td>100% (30/30)</td>
<td>None</td>
</tr>
<tr class="odd">
<td>P. mirabilis</td>
<td>None</td>
<td>94% (34/36)</td>
<td>None</td>
</tr>
<tr class="even">
<td>S. aureus</td>
<td>6% (8/131)</td>
<td>90% (171/191)</td>
<td>None</td>
</tr>
<tr class="odd">
<td>S. epidermidis</td>
<td>1% (1/91)</td>
<td>64% (87/136)</td>
<td>None</td>
</tr>
<tr class="even">
<td>S. hominis</td>
<td>None</td>
<td>80% (56/70)</td>
<td>None</td>
</tr>
<tr class="odd">
<td>S. pneumoniae</td>
<td>100% (112/112)</td>
<td>None</td>
<td>100% (112/112)</td>
</tr>
</tbody>
</table>
<div class="sourceCode" id="cb9"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb9-1"><a href="#cb9-1" tabindex="-1"></a>result2b <span class="op">=</span> AMR.antibiogram(df[[<span class="st">"mo"</span>, <span class="st">"AMX"</span>, <span class="st">"CIP"</span>, <span class="st">"TZP"</span>]], mo_transform <span class="op">=</span> <span class="st">"gramstain"</span>)</span>
<span id="cb9-2"><a href="#cb9-2" tabindex="-1"></a><span class="bu">print</span>(result2b)</span></code></pre></div>
<table class="table">
<colgroup>
<col width="20%">
<col width="22%">
<col width="23%">
<col width="33%">
</colgroup>
<thead><tr class="header">
<th>Pathogen</th>
<th>Amoxicillin</th>
<th>Ciprofloxacin</th>
<th>Piperacillin/tazobactam</th>
</tr></thead>
<tbody>
<tr class="odd">
<td>Gram-negative</td>
<td>36% (226/631)</td>
<td>91% (621/684)</td>
<td>88% (565/641)</td>
</tr>
<tr class="even">
<td>Gram-positive</td>
<td>43% (305/703)</td>
<td>77% (560/724)</td>
<td>86% (296/345)</td>
</tr>
</tbody>
</table>
<p>In this example, we generate an antibiogram by selecting various
antibiotics.</p>
</div>
<div class="section level3">
<h3 id="taxonomic-data-sets-now-in-python">Taxonomic Data Sets Now in Python!<a class="anchor" aria-label="anchor" href="#taxonomic-data-sets-now-in-python"></a>
</h3>
<p>As a Python user, you might like that the most important data sets of
the <code>AMR</code> R package, <code>microorganisms</code>,
<code>antimicrobials</code>, <code>clinical_breakpoints</code>, and
<code>example_isolates</code>, are now available as regular Python data
frames:</p>
<div class="sourceCode" id="cb10"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb10-1"><a href="#cb10-1" tabindex="-1"></a>AMR.microorganisms</span></code></pre></div>
<table class="table">
<colgroup>
<col width="11%">
<col width="29%">
<col width="8%">
<col width="8%">
<col width="8%">
<col width="10%">
<col width="13%">
<col width="9%">
</colgroup>
<thead><tr class="header">
<th>mo</th>
<th>fullname</th>
<th>status</th>
<th>kingdom</th>
<th>gbif</th>
<th>gbif_parent</th>
<th>gbif_renamed_to</th>
<th>prevalence</th>
</tr></thead>
<tbody>
<tr class="odd">
<td>B_GRAMN</td>
<td>(unknown Gram-negatives)</td>
<td>unknown</td>
<td>Bacteria</td>
<td>None</td>
<td>None</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="even">
<td>B_GRAMP</td>
<td>(unknown Gram-positives)</td>
<td>unknown</td>
<td>Bacteria</td>
<td>None</td>
<td>None</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="odd">
<td>B_ANAER-NEG</td>
<td>(unknown anaerobic Gram-negatives)</td>
<td>unknown</td>
<td>Bacteria</td>
<td>None</td>
<td>None</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="even">
<td>B_ANAER-POS</td>
<td>(unknown anaerobic Gram-positives)</td>
<td>unknown</td>
<td>Bacteria</td>
<td>None</td>
<td>None</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="odd">
<td>B_ANAER</td>
<td>(unknown anaerobic bacteria)</td>
<td>unknown</td>
<td>Bacteria</td>
<td>None</td>
<td>None</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="even">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="odd">
<td>B_ZYMMN_POMC</td>
<td>Zymomonas pomaceae</td>
<td>accepted</td>
<td>Bacteria</td>
<td>10744418</td>
<td>3221412</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="even">
<td>B_ZYMPH</td>
<td>Zymophilus</td>
<td>synonym</td>
<td>Bacteria</td>
<td>None</td>
<td>9475166</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="odd">
<td>B_ZYMPH_PCVR</td>
<td>Zymophilus paucivorans</td>
<td>synonym</td>
<td>Bacteria</td>
<td>None</td>
<td>None</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="even">
<td>B_ZYMPH_RFFN</td>
<td>Zymophilus raffinosivorans</td>
<td>synonym</td>
<td>Bacteria</td>
<td>None</td>
<td>None</td>
<td>None</td>
<td>2.0</td>
</tr>
<tr class="odd">
<td>F_ZYZYG</td>
<td>Zyzygomyces</td>
<td>unknown</td>
<td>Fungi</td>
<td>None</td>
<td>7581</td>
<td>None</td>
<td>2.0</td>
</tr>
</tbody>
</table>
<div class="sourceCode" id="cb11"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb11-1"><a href="#cb11-1" tabindex="-1"></a>AMR.antimicrobials</span></code></pre></div>
<table style="width:100%;" class="table">
<colgroup>
<col width="4%">
<col width="12%">
<col width="20%">
<col width="25%">
<col width="9%">
<col width="11%">
<col width="7%">
<col width="9%">
</colgroup>
<thead><tr class="header">
<th>ab</th>
<th>cid</th>
<th>name</th>
<th>group</th>
<th>oral_ddd</th>
<th>oral_units</th>
<th>iv_ddd</th>
<th>iv_units</th>
</tr></thead>
<tbody>
<tr class="odd">
<td>AMA</td>
<td>4649.0</td>
<td>4-aminosalicylic acid</td>
<td>Antimycobacterials</td>
<td>12.00</td>
<td>g</td>
<td>NaN</td>
<td>None</td>
</tr>
<tr class="even">
<td>ACM</td>
<td>6450012.0</td>
<td>Acetylmidecamycin</td>
<td>Macrolides/lincosamides</td>
<td>NaN</td>
<td>None</td>
<td>NaN</td>
<td>None</td>
</tr>
<tr class="odd">
<td>ASP</td>
<td>49787020.0</td>
<td>Acetylspiramycin</td>
<td>Macrolides/lincosamides</td>
<td>NaN</td>
<td>None</td>
<td>NaN</td>
<td>None</td>
</tr>
<tr class="even">
<td>ALS</td>
<td>8954.0</td>
<td>Aldesulfone sodium</td>
<td>Other antibacterials</td>
<td>0.33</td>
<td>g</td>
<td>NaN</td>
<td>None</td>
</tr>
<tr class="odd">
<td>AMK</td>
<td>37768.0</td>
<td>Amikacin</td>
<td>Aminoglycosides</td>
<td>NaN</td>
<td>None</td>
<td>1.0</td>
<td>g</td>
</tr>
<tr class="even">
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr class="odd">
<td>VIR</td>
<td>11979535.0</td>
<td>Virginiamycine</td>
<td>Other antibacterials</td>
<td>NaN</td>
<td>None</td>
<td>NaN</td>
<td>None</td>
</tr>
<tr class="even">
<td>VOR</td>
<td>71616.0</td>
<td>Voriconazole</td>
<td>Antifungals/antimycotics</td>
<td>0.40</td>
<td>g</td>
<td>0.4</td>
<td>g</td>
</tr>
<tr class="odd">
<td>XBR</td>
<td>72144.0</td>
<td>Xibornol</td>
<td>Other antibacterials</td>
<td>NaN</td>
<td>None</td>
<td>NaN</td>
<td>None</td>
</tr>
<tr class="even">
<td>ZID</td>
<td>77846445.0</td>
<td>Zidebactam</td>
<td>Other antibacterials</td>
<td>NaN</td>
<td>None</td>
<td>NaN</td>
<td>None</td>
</tr>
<tr class="odd">
<td>ZFD</td>
<td>NaN</td>
<td>Zoliflodacin</td>
<td>None</td>
<td>NaN</td>
<td>None</td>
<td>NaN</td>
<td>None</td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="section level2">
<h2 id="conclusion">Conclusion<a class="anchor" aria-label="anchor" href="#conclusion"></a>
</h2>
<p>With the <code>AMR</code> Python package, Python users can now
effortlessly call R functions from the <code>AMR</code> R package. This
eliminates the need for complex <code>rpy2</code> configurations and
provides a clean, easy-to-use interface for antimicrobial resistance
analysis. The examples provided above demonstrate how this can be
applied to typical workflows, such as standardising microorganism and
antimicrobial names or calculating resistance.</p>
<p>By just running <code>import AMR</code>, users can seamlessly
integrate the robust features of the R <code>AMR</code> package into
Python workflows.</p>
<p>Whether youre cleaning data or analysing resistance patterns, the
<code>AMR</code> Python package makes it easy to work with AMR data in
Python.</p>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside>
</div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer>
</div>
</body>
</html>
-217
View File
@@ -1,217 +0,0 @@
# AMR for Python
## Introduction
The `AMR` package for R is a powerful tool for antimicrobial resistance
(AMR) analysis. It provides extensive features for handling microbial
and antimicrobial data. However, for those who work primarily in Python,
we now have a more intuitive option available: the [`AMR` Python
package](https://pypi.org/project/AMR/).
This Python package is a wrapper around the `AMR` R package. It uses the
`rpy2` package internally. Despite the need to have R installed, Python
users can now easily work with AMR data directly through Python code.
## Prerequisites
This package was only tested with a [virtual environment
(venv)](https://docs.python.org/3/library/venv.html). You can set up
such an environment by running:
``` python
# linux and macOS:
python -m venv /path/to/new/virtual/environment
# Windows:
python -m venv C:\path\to\new\virtual\environment
```
Then you can [activate the
environment](https://docs.python.org/3/library/venv.html#how-venvs-work),
after which the venv is ready to work with.
## Install AMR
1. Since the Python package is available on the official [Python
Package Index](https://pypi.org/project/AMR/), you can just run:
``` bash
pip install AMR
```
2. Make sure you have R installed. There is **no need to install the
`AMR` R package**, as it will be installed automatically.
For Linux:
``` bash
# Ubuntu / Debian
sudo apt install r-base
# Fedora:
sudo dnf install R
# CentOS/RHEL
sudo yum install R
```
For macOS (using [Homebrew](https://brew.sh)):
``` bash
brew install r
```
For Windows, visit the [CRAN download
page](https://cran.r-project.org) to download and install R.
## Examples of Usage
### Cleaning Taxonomy
Heres an example that demonstrates how to clean microorganism and drug
names using the `AMR` Python package:
``` python
import pandas as pd
import AMR
# Sample data
data = {
"MOs": ['E. coli', 'ESCCOL', 'esco', 'Esche coli'],
"Drug": ['Cipro', 'CIP', 'J01MA02', 'Ciproxin']
}
df = pd.DataFrame(data)
# Use AMR functions to clean microorganism and drug names
df['MO_clean'] = AMR.mo_name(df['MOs'])
df['Drug_clean'] = AMR.ab_name(df['Drug'])
# Display the results
print(df)
```
| MOs | Drug | MO_clean | Drug_clean |
|------------|----------|------------------|---------------|
| E. coli | Cipro | Escherichia coli | Ciprofloxacin |
| ESCCOL | CIP | Escherichia coli | Ciprofloxacin |
| esco | J01MA02 | Escherichia coli | Ciprofloxacin |
| Esche coli | Ciproxin | Escherichia coli | Ciprofloxacin |
#### Explanation
- **mo_name:** This function standardises microorganism names. Here,
different variations of *Escherichia coli* (such as “E. coli”,
“ESCCOL”, “esco”, and “Esche coli”) are all converted into the
correct, standardised form, “Escherichia coli”.
- **ab_name**: Similarly, this function standardises antimicrobial
names. The different representations of ciprofloxacin (e.g., “Cipro”,
“CIP”, “J01MA02”, and “Ciproxin”) are all converted to the standard
name, “Ciprofloxacin”.
### Calculating AMR
``` python
import AMR
import pandas as pd
df = AMR.example_isolates
result = AMR.resistance(df["AMX"])
print(result)
```
[0.59555556]
### Generating Antibiograms
One of the core functions of the `AMR` package is generating an
antibiogram, a table that summarises the antimicrobial susceptibility of
bacterial isolates. Heres how you can generate an antibiogram from
Python:
``` python
result2a = AMR.antibiogram(df[["mo", "AMX", "CIP", "TZP"]])
print(result2a)
```
| Pathogen | Amoxicillin | Ciprofloxacin | Piperacillin/tazobactam |
|----------------|----------------|---------------|-------------------------|
| CoNS | 7% (10/142) | 73% (183/252) | 30% (10/33) |
| E. coli | 50% (196/392) | 88% (399/456) | 94% (393/416) |
| K. pneumoniae | 0% (0/58) | 96% (53/55) | 89% (47/53) |
| P. aeruginosa | 0% (0/30) | 100% (30/30) | None |
| P. mirabilis | None | 94% (34/36) | None |
| S. aureus | 6% (8/131) | 90% (171/191) | None |
| S. epidermidis | 1% (1/91) | 64% (87/136) | None |
| S. hominis | None | 80% (56/70) | None |
| S. pneumoniae | 100% (112/112) | None | 100% (112/112) |
``` python
result2b = AMR.antibiogram(df[["mo", "AMX", "CIP", "TZP"]], mo_transform = "gramstain")
print(result2b)
```
| Pathogen | Amoxicillin | Ciprofloxacin | Piperacillin/tazobactam |
|---------------|---------------|---------------|-------------------------|
| Gram-negative | 36% (226/631) | 91% (621/684) | 88% (565/641) |
| Gram-positive | 43% (305/703) | 77% (560/724) | 86% (296/345) |
In this example, we generate an antibiogram by selecting various
antibiotics.
### Taxonomic Data Sets Now in Python!
As a Python user, you might like that the most important data sets of
the `AMR` R package, `microorganisms`, `antimicrobials`,
`clinical_breakpoints`, and `example_isolates`, are now available as
regular Python data frames:
``` python
AMR.microorganisms
```
| mo | fullname | status | kingdom | gbif | gbif_parent | gbif_renamed_to | prevalence |
|----|----|----|----|----|----|----|----|
| B_GRAMN | (unknown Gram-negatives) | unknown | Bacteria | None | None | None | 2.0 |
| B_GRAMP | (unknown Gram-positives) | unknown | Bacteria | None | None | None | 2.0 |
| B_ANAER-NEG | (unknown anaerobic Gram-negatives) | unknown | Bacteria | None | None | None | 2.0 |
| B_ANAER-POS | (unknown anaerobic Gram-positives) | unknown | Bacteria | None | None | None | 2.0 |
| B_ANAER | (unknown anaerobic bacteria) | unknown | Bacteria | None | None | None | 2.0 |
| … | … | … | … | … | … | … | … |
| B_ZYMMN_POMC | Zymomonas pomaceae | accepted | Bacteria | 10744418 | 3221412 | None | 2.0 |
| B_ZYMPH | Zymophilus | synonym | Bacteria | None | 9475166 | None | 2.0 |
| B_ZYMPH_PCVR | Zymophilus paucivorans | synonym | Bacteria | None | None | None | 2.0 |
| B_ZYMPH_RFFN | Zymophilus raffinosivorans | synonym | Bacteria | None | None | None | 2.0 |
| F_ZYZYG | Zyzygomyces | unknown | Fungi | None | 7581 | None | 2.0 |
``` python
AMR.antimicrobials
```
| ab | cid | name | group | oral_ddd | oral_units | iv_ddd | iv_units |
|----|----|----|----|----|----|----|----|
| AMA | 4649.0 | 4-aminosalicylic acid | Antimycobacterials | 12.00 | g | NaN | None |
| ACM | 6450012.0 | Acetylmidecamycin | Macrolides/lincosamides | NaN | None | NaN | None |
| ASP | 49787020.0 | Acetylspiramycin | Macrolides/lincosamides | NaN | None | NaN | None |
| ALS | 8954.0 | Aldesulfone sodium | Other antibacterials | 0.33 | g | NaN | None |
| AMK | 37768.0 | Amikacin | Aminoglycosides | NaN | None | 1.0 | g |
| … | … | … | … | … | … | … | … |
| VIR | 11979535.0 | Virginiamycine | Other antibacterials | NaN | None | NaN | None |
| VOR | 71616.0 | Voriconazole | Antifungals/antimycotics | 0.40 | g | 0.4 | g |
| XBR | 72144.0 | Xibornol | Other antibacterials | NaN | None | NaN | None |
| ZID | 77846445.0 | Zidebactam | Other antibacterials | NaN | None | NaN | None |
| ZFD | NaN | Zoliflodacin | None | NaN | None | NaN | None |
## Conclusion
With the `AMR` Python package, Python users can now effortlessly call R
functions from the `AMR` R package. This eliminates the need for complex
`rpy2` configurations and provides a clean, easy-to-use interface for
antimicrobial resistance analysis. The examples provided above
demonstrate how this can be applied to typical workflows, such as
standardising microorganism and antimicrobial names or calculating
resistance.
By just running `import AMR`, users can seamlessly integrate the robust
features of the R `AMR` package into Python workflows.
Whether youre cleaning data or analysing resistance patterns, the `AMR`
Python package makes it easy to work with AMR data in Python.
File diff suppressed because it is too large Load Diff
-903
View File
@@ -1,903 +0,0 @@
# AMR with tidymodels
> This page was almost entirely written by our [AMR for R
> Assistant](https://chat.amr-for-r.org), a ChatGPT manually-trained
> model able to answer any question about the `AMR` package.
Antimicrobial resistance (AMR) is a global health crisis, and
understanding resistance patterns is crucial for managing effective
treatments. The `AMR` R package provides robust tools for analysing AMR
data, including convenient antimicrobial selector functions like
[`aminoglycosides()`](https://amr-for-r.org/reference/antimicrobial_selectors.md)
and
[`betalactams()`](https://amr-for-r.org/reference/antimicrobial_selectors.md).
In this post, we will explore how to use the `tidymodels` framework to
predict resistance patterns in the `example_isolates` dataset in two
examples.
This post contains the following examples:
1. Using Antimicrobial Selectors
2. Predicting ESBL Presence Using Raw MICs
3. Predicting AMR Over Time
## Example 1: Using Antimicrobial Selectors
By leveraging the power of `tidymodels` and the `AMR` package, well
build a reproducible machine learning workflow to predict the Gramstain
of the microorganism to two important antibiotic classes:
aminoglycosides and beta-lactams.
### **Objective**
Our goal is to build a predictive model using the `tidymodels` framework
to determine the Gramstain of the microorganism based on microbial data.
We will:
1. Preprocess data using the selector functions
[`aminoglycosides()`](https://amr-for-r.org/reference/antimicrobial_selectors.md)
and
[`betalactams()`](https://amr-for-r.org/reference/antimicrobial_selectors.md).
2. Define a logistic regression model for prediction.
3. Use a structured `tidymodels` workflow to preprocess, train, and
evaluate the model.
### **Data Preparation**
We begin by loading the required libraries and preparing the
`example_isolates` dataset from the `AMR` package.
``` r
# Load required libraries
library(AMR) # For AMR data analysis
library(tidymodels) # For machine learning workflows, and data manipulation (dplyr, tidyr, ...)
```
Prepare the data:
``` r
# Your data could look like this:
example_isolates
#> # A tibble: 2,000 × 46
#> date patient age gender ward mo PEN OXA FLC AMX
#> <date> <chr> <dbl> <chr> <chr> <mo> <sir> <sir> <sir> <sir>
#> 1 2002-01-02 A77334 65 F Clinical B_ESCHR_COLI R NA NA NA
#> 2 2002-01-03 A77334 65 F Clinical B_ESCHR_COLI R NA NA NA
#> 3 2002-01-07 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 4 2002-01-07 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 5 2002-01-13 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 6 2002-01-13 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 7 2002-01-14 462729 78 M Clinical B_STPHY_AURS R NA S R
#> 8 2002-01-14 462729 78 M Clinical B_STPHY_AURS R NA S R
#> 9 2002-01-16 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 10 2002-01-17 858515 79 F ICU B_STPHY_EPDR R NA S NA
#> # 1,990 more rows
#> # 36 more variables: AMC <sir>, AMP <sir>, TZP <sir>, CZO <sir>, FEP <sir>,
#> # CXM <sir>, FOX <sir>, CTX <sir>, CAZ <sir>, CRO <sir>, GEN <sir>,
#> # TOB <sir>, AMK <sir>, KAN <sir>, TMP <sir>, SXT <sir>, NIT <sir>,
#> # FOS <sir>, LNZ <sir>, CIP <sir>, MFX <sir>, VAN <sir>, TEC <sir>,
#> # TCY <sir>, TGC <sir>, DOX <sir>, ERY <sir>, CLI <sir>, AZM <sir>,
#> # IPM <sir>, MEM <sir>, MTR <sir>, CHL <sir>, COL <sir>, MUP <sir>, …
# Select relevant columns for prediction
data <- example_isolates %>%
# select AB results dynamically
select(mo, aminoglycosides(), betalactams()) %>%
# replace NAs with NI (not-interpretable)
mutate(
across(
where(is.sir),
~ replace_na(.x, "NI")
),
# make factors of SIR columns
across(
where(is.sir),
as.integer
),
# get Gramstain of microorganisms
mo = as.factor(mo_gramstain(mo))
) %>%
# drop NAs - the ones without a Gramstain (fungi, etc.)
drop_na()
#> For `aminoglycosides()` using columns GEN (gentamicin), TOB (tobramycin), AMK
#> (amikacin), and KAN (kanamycin)
#> For `betalactams()` using columns PEN (benzylpenicillin), OXA (oxacillin),
#> FLC (flucloxacillin), AMX (amoxicillin), AMC (amoxicillin/clavulanic acid),
#> AMP (ampicillin), TZP (piperacillin/tazobactam), CZO (cefazolin), FEP
#> (cefepime), CXM (cefuroxime), FOX (cefoxitin), CTX (cefotaxime), CAZ
#> (ceftazidime), CRO (ceftriaxone), IPM (imipenem), and MEM (meropenem)
```
**Explanation:**
- [`aminoglycosides()`](https://amr-for-r.org/reference/antimicrobial_selectors.md)
and
[`betalactams()`](https://amr-for-r.org/reference/antimicrobial_selectors.md)
dynamically select columns for antimicrobials in these classes.
- `drop_na()` ensures the model receives complete cases for training.
### **Defining the Workflow**
We now define the `tidymodels` workflow, which consists of three steps:
preprocessing, model specification, and fitting.
#### 1. Preprocessing with a Recipe
We create a recipe to preprocess the data for modelling.
``` r
# Define the recipe for data preprocessing
resistance_recipe <- recipe(mo ~ ., data = data) %>%
step_corr(c(aminoglycosides(), betalactams()), threshold = 0.9)
resistance_recipe
#>
#> ── Recipe ──────────────────────────────────────────────────────────────────────
#>
#> ── Inputs
#> Number of variables by role
#> outcome: 1
#> predictor: 20
#>
#> ── Operations
#> • Correlation filter on: c(aminoglycosides(), betalactams())
```
For a recipe that includes at least one preprocessing operation, like we
have with `step_corr()`, the necessary parameters can be estimated from
a training set using `prep()`:
``` r
prep(resistance_recipe)
#> For `aminoglycosides()` using columns GEN (gentamicin), TOB (tobramycin), AMK
#> (amikacin), and KAN (kanamycin)
#> For `betalactams()` using columns PEN (benzylpenicillin), OXA (oxacillin),
#> FLC (flucloxacillin), AMX (amoxicillin), AMC (amoxicillin/clavulanic acid),
#> AMP (ampicillin), TZP (piperacillin/tazobactam), CZO (cefazolin), FEP
#> (cefepime), CXM (cefuroxime), FOX (cefoxitin), CTX (cefotaxime), CAZ
#> (ceftazidime), CRO (ceftriaxone), IPM (imipenem), and MEM (meropenem)
#>
#>
#> ── Recipe ──────────────────────────────────────────────────────────────────────
#>
#>
#>
#> ── Inputs
#>
#> Number of variables by role
#>
#> outcome: 1
#> predictor: 20
#>
#>
#>
#> ── Training information
#>
#> Training data contained 1968 data points and no incomplete rows.
#>
#>
#>
#> ── Operations
#>
#> • Correlation filter on: AMX CTX | Trained
```
**Explanation:**
- `recipe(mo ~ ., data = data)` will take the `mo` column as outcome and
all other columns as predictors.
- `step_corr()` removes predictors (i.e., antibiotic columns) that have
a higher correlation than 90%.
Notice how the recipe contains just the antimicrobial selector
functions - no need to define the columns specifically. In the
preparation (retrieved with `prep()`) we can see that the columns or
variables AMX and CTX were removed as they correlate too much with
existing, other variables.
#### 2. Specifying the Model
We define a logistic regression model since resistance prediction is a
binary classification task.
``` r
# Specify a logistic regression model
logistic_model <- logistic_reg() %>%
set_engine("glm") # Use the Generalised Linear Model engine
logistic_model
#> Logistic Regression Model Specification (classification)
#>
#> Computational engine: glm
```
**Explanation:**
- `logistic_reg()` sets up a logistic regression model.
- `set_engine("glm")` specifies the use of Rs built-in GLM engine.
#### 3. Building the Workflow
We bundle the recipe and model together into a `workflow`, which
organises the entire modelling process.
``` r
# Combine the recipe and model into a workflow
resistance_workflow <- workflow() %>%
add_recipe(resistance_recipe) %>% # Add the preprocessing recipe
add_model(logistic_model) # Add the logistic regression model
resistance_workflow
#> ══ Workflow ════════════════════════════════════════════════════════════════════
#> Preprocessor: Recipe
#> Model: logistic_reg()
#>
#> ── Preprocessor ────────────────────────────────────────────────────────────────
#> 1 Recipe Step
#>
#> • step_corr()
#>
#> ── Model ───────────────────────────────────────────────────────────────────────
#> Logistic Regression Model Specification (classification)
#>
#> Computational engine: glm
```
### **Training and Evaluating the Model**
To train the model, we split the data into training and testing sets.
Then, we fit the workflow on the training set and evaluate its
performance.
``` r
# Split data into training and testing sets
set.seed(123) # For reproducibility
data_split <- initial_split(data, prop = 0.8) # 80% training, 20% testing
training_data <- training(data_split) # Training set
testing_data <- testing(data_split) # Testing set
# Fit the workflow to the training data
fitted_workflow <- resistance_workflow %>%
fit(training_data) # Train the model
```
**Explanation:**
- `initial_split()` splits the data into training and testing sets.
- `fit()` trains the workflow on the training set.
Notice how in `fit()`, the antimicrobial selector functions are
internally called again. For training, these functions are called since
they are stored in the recipe.
Next, we evaluate the model on the testing data.
``` r
# Make predictions on the testing set
predictions <- fitted_workflow %>%
predict(testing_data) # Generate predictions
probabilities <- fitted_workflow %>%
predict(testing_data, type = "prob") # Generate probabilities
predictions <- predictions %>%
bind_cols(probabilities) %>%
bind_cols(testing_data) # Combine with true labels
predictions
#> # A tibble: 394 × 24
#> .pred_class `.pred_Gram-negative` `.pred_Gram-positive` mo GEN TOB
#> <fct> <dbl> <dbl> <fct> <int> <int>
#> 1 Gram-positive 1.07e- 1 8.93 e- 1 Gram-p… 5 5
#> 2 Gram-positive 3.17e- 8 1.000e+ 0 Gram-p… 5 1
#> 3 Gram-negative 9.99e- 1 1.42 e- 3 Gram-n… 5 5
#> 4 Gram-positive 2.22e-16 1 e+ 0 Gram-p… 5 5
#> 5 Gram-negative 9.46e- 1 5.42 e- 2 Gram-n… 5 5
#> 6 Gram-positive 1.07e- 1 8.93 e- 1 Gram-p… 5 5
#> 7 Gram-positive 2.22e-16 1 e+ 0 Gram-p… 1 5
#> 8 Gram-positive 2.22e-16 1 e+ 0 Gram-p… 4 4
#> 9 Gram-negative 1 e+ 0 2.22 e-16 Gram-n… 1 1
#> 10 Gram-positive 6.05e-11 1.000e+ 0 Gram-p… 4 4
#> # 384 more rows
#> # 18 more variables: AMK <int>, KAN <int>, PEN <int>, OXA <int>, FLC <int>,
#> # AMX <int>, AMC <int>, AMP <int>, TZP <int>, CZO <int>, FEP <int>,
#> # CXM <int>, FOX <int>, CTX <int>, CAZ <int>, CRO <int>, IPM <int>, MEM <int>
# Evaluate model performance
metrics <- predictions %>%
metrics(truth = mo, estimate = .pred_class) # Calculate performance metrics
metrics
#> # A tibble: 2 × 3
#> .metric .estimator .estimate
#> <chr> <chr> <dbl>
#> 1 accuracy binary 0.995
#> 2 kap binary 0.989
# To assess some other model properties, you can make our own `metrics()` function
our_metrics <- metric_set(accuracy, kap, ppv, npv) # add Positive Predictive Value and Negative Predictive Value
metrics2 <- predictions %>%
our_metrics(truth = mo, estimate = .pred_class) # run again on our `our_metrics()` function
metrics2
#> # A tibble: 4 × 3
#> .metric .estimator .estimate
#> <chr> <chr> <dbl>
#> 1 accuracy binary 0.995
#> 2 kap binary 0.989
#> 3 ppv binary 0.987
#> 4 npv binary 1
```
**Explanation:**
- [`predict()`](https://rdrr.io/r/stats/predict.html) generates
predictions on the testing set.
- `metrics()` computes evaluation metrics like accuracy and kappa.
It appears we can predict the Gram stain with a 99.5% accuracy based on
AMR results of only aminoglycosides and beta-lactam antibiotics. The ROC
curve looks like this:
``` r
predictions %>%
roc_curve(mo, `.pred_Gram-negative`) %>%
autoplot()
```
![](AMR_with_tidymodels_files/figure-html/unnamed-chunk-8-1.png)
### **Conclusion**
In this example, we demonstrated how to build a machine learning
pipeline with the `tidymodels` framework and the `AMR` package. By
combining selector functions like
[`aminoglycosides()`](https://amr-for-r.org/reference/antimicrobial_selectors.md)
and
[`betalactams()`](https://amr-for-r.org/reference/antimicrobial_selectors.md)
with `tidymodels`, we efficiently prepared data, trained a model, and
evaluated its performance.
This workflow is extensible to other antimicrobial classes and
resistance patterns, empowering users to analyse AMR data systematically
and reproducibly.
------------------------------------------------------------------------
## Example 2: Predicting ESBL Presence Using Raw MICs
In this second example, we demonstrate how to use `<mic>` columns
directly in `tidymodels` workflows using AMR-specific recipe steps. This
includes a transformation to `log2` scale using
[`step_mic_log2()`](https://amr-for-r.org/reference/amr-tidymodels.md),
which prepares MIC values for use in classification models.
This approach and idea formed the basis for the publication [DOI:
10.3389/fmicb.2025.1582703](https://doi.org/10.3389/fmicb.2025.1582703)
to model the presence of extended-spectrum beta-lactamases (ESBL) based
on MIC values.
### **Objective**
Our goal is to:
1. Use raw MIC values to predict whether a bacterial isolate produces
ESBL.
2. Apply AMR-aware preprocessing in a `tidymodels` recipe.
3. Train a classification model and evaluate its predictive
performance.
### **Data Preparation**
We use the `esbl_isolates` dataset that comes with the AMR package.
``` r
# Load required libraries
library(AMR)
library(tidymodels)
# View the esbl_isolates data set
esbl_isolates
#> # A tibble: 500 × 19
#> esbl genus AMC AMP TZP CXM FOX CTX CAZ GEN TOB TMP SXT
#> <lgl> <chr> <mic> <mic> <mic> <mic> <mic> <mic> <mic> <mic> <mic> <mic> <mic>
#> 1 FALSE Esch… 32 32 4 64 64 8.00 8.00 1 1 16.0 20
#> 2 FALSE Esch… 32 32 4 64 64 4.00 8.00 1 1 16.0 320
#> 3 FALSE Esch… 4 2 64 8 4 8.00 0.12 16 16 0.5 20
#> 4 FALSE Kleb… 32 32 16 64 64 8.00 8.00 1 1 0.5 20
#> 5 FALSE Esch… 32 32 4 4 4 0.25 2.00 1 1 16.0 320
#> 6 FALSE Citr… 32 32 16 64 64 64.00 32.00 1 1 0.5 20
#> 7 FALSE Morg… 32 32 4 64 64 16.00 2.00 1 1 0.5 20
#> 8 FALSE Prot… 16 32 4 1 4 8.00 0.12 1 1 16.0 320
#> 9 FALSE Ente… 32 32 8 64 64 32.00 4.00 1 1 0.5 20
#> 10 FALSE Citr… 32 32 32 64 64 8.00 64.00 1 1 16.0 320
#> # 490 more rows
#> # 6 more variables: NIT <mic>, FOS <mic>, CIP <mic>, IPM <mic>, MEM <mic>,
#> # COL <mic>
# Prepare a binary outcome and convert to ordered factor
data <- esbl_isolates %>%
mutate(esbl = factor(esbl, levels = c(FALSE, TRUE), ordered = TRUE))
```
**Explanation:**
- `esbl_isolates`: Contains MIC test results and ESBL status for each
isolate.
- `mutate(esbl = ...)`: Converts the target column to an ordered factor
for classification.
### **Defining the Workflow**
#### 1. Preprocessing with a Recipe
We use our
[`step_mic_log2()`](https://amr-for-r.org/reference/amr-tidymodels.md)
function to log2-transform MIC values, ensuring that MICs are numeric
and properly scaled. All MIC predictors can easily and agnostically
selected using the new
[`all_mic_predictors()`](https://amr-for-r.org/reference/amr-tidymodels.md):
``` r
# Split into training and testing sets
set.seed(123)
split <- initial_split(data)
training_data <- training(split)
testing_data <- testing(split)
# Define the recipe
mic_recipe <- recipe(esbl ~ ., data = training_data) %>%
remove_role(genus, old_role = "predictor") %>% # Remove non-informative variable
step_mic_log2(all_mic_predictors()) # Log2 transform all MIC predictors
prep(mic_recipe)
#>
#> ── Recipe ──────────────────────────────────────────────────────────────────────
#>
#> ── Inputs
#> Number of variables by role
#> outcome: 1
#> predictor: 17
#> undeclared role: 1
#>
#> ── Training information
#> Training data contained 375 data points and no incomplete rows.
#>
#> ── Operations
#> • Log2 transformation of MIC columns: AMC, AMP, TZP, CXM, FOX, ... | Trained
```
**Explanation:**
- `remove_role()`: Removes irrelevant variables like genus.
- [`step_mic_log2()`](https://amr-for-r.org/reference/amr-tidymodels.md):
Applies `log2(as.numeric(...))` to all MIC predictors in one go.
- `prep()`: Finalises the recipe based on training data.
#### 2. Specifying the Model
We use a simple logistic regression to model ESBL presence, though
recent models such as xgboost ([link to `parsnip`
manual](https://parsnip.tidymodels.org/reference/details_boost_tree_xgboost.html))
could be much more precise.
``` r
# Define the model
model <- logistic_reg(mode = "classification") %>%
set_engine("glm")
model
#> Logistic Regression Model Specification (classification)
#>
#> Computational engine: glm
```
**Explanation:**
- `logistic_reg()`: Specifies a binary classification model.
- `set_engine("glm")`: Uses the base R GLM engine.
#### 3. Building the Workflow
``` r
# Create workflow
workflow_model <- workflow() %>%
add_recipe(mic_recipe) %>%
add_model(model)
workflow_model
#> ══ Workflow ════════════════════════════════════════════════════════════════════
#> Preprocessor: Recipe
#> Model: logistic_reg()
#>
#> ── Preprocessor ────────────────────────────────────────────────────────────────
#> 1 Recipe Step
#>
#> • step_mic_log2()
#>
#> ── Model ───────────────────────────────────────────────────────────────────────
#> Logistic Regression Model Specification (classification)
#>
#> Computational engine: glm
```
### **Training and Evaluating the Model**
``` r
# Fit the model
fitted <- fit(workflow_model, training_data)
# Generate predictions
predictions <- predict(fitted, testing_data) %>%
bind_cols(predict(fitted, testing_data, type = "prob")) %>% # add probabilities
bind_cols(testing_data)
# Evaluate model performance
our_metrics <- metric_set(accuracy, recall, precision, sensitivity, specificity, ppv, npv)
metrics <- our_metrics(predictions, truth = esbl, estimate = .pred_class)
metrics
#> # A tibble: 7 × 3
#> .metric .estimator .estimate
#> <chr> <chr> <dbl>
#> 1 accuracy binary 0.92
#> 2 recall binary 0.921
#> 3 precision binary 0.921
#> 4 sensitivity binary 0.921
#> 5 specificity binary 0.919
#> 6 ppv binary 0.921
#> 7 npv binary 0.919
```
**Explanation:**
- `fit()`: Trains the model on the processed training data.
- [`predict()`](https://rdrr.io/r/stats/predict.html): Produces
predictions for unseen test data.
- `metric_set()`: Allows evaluating multiple classification metrics.
This will make `our_metrics` to become a function that we can use to
check the predictions with.
It appears we can predict ESBL gene presence with a positive predictive
value (PPV) of 92.1% and a negative predictive value (NPV) of 91.9%
using a simplistic logistic regression model.
### **Visualising Predictions**
We can visualise predictions by comparing predicted and actual ESBL
status.
``` r
library(ggplot2)
ggplot(predictions, aes(x = esbl, fill = .pred_class)) +
geom_bar(position = "stack") +
labs(
title = "Predicted vs Actual ESBL Status",
x = "Actual ESBL",
y = "Count"
) +
theme_minimal()
```
![](AMR_with_tidymodels_files/figure-html/unnamed-chunk-14-1.png)
And plot the certainties too - how certain were the actual predictions?
``` r
predictions %>%
mutate(
certainty = ifelse(.pred_class == "FALSE",
.pred_FALSE,
.pred_TRUE
),
correct = ifelse(esbl == .pred_class, "Right", "Wrong")
) %>%
ggplot(aes(
x = seq_len(nrow(predictions)),
y = certainty,
colour = correct
)) +
scale_colour_manual(
values = c(Right = "green3", Wrong = "red2"),
name = "Correct?"
) +
geom_point() +
scale_y_continuous(
labels = function(x) paste0(x * 100, "%"),
limits = c(0.5, 1)
) +
theme_minimal()
```
![](AMR_with_tidymodels_files/figure-html/unnamed-chunk-15-1.png)
### **Conclusion**
In this example, we showcased how the new `AMR`-specific recipe steps
simplify working with `<mic>` columns in `tidymodels`. The
[`step_mic_log2()`](https://amr-for-r.org/reference/amr-tidymodels.md)
transformation converts MICs (with or without operators) to
log2-transformed numerics, improving compatibility with classification
models.
This pipeline enables realistic, reproducible, and interpretable
modelling of antimicrobial resistance data.
------------------------------------------------------------------------
## Example 3: Predicting AMR Over Time
In this third example, we aim to predict antimicrobial resistance (AMR)
trends over time using `tidymodels`. We will model resistance to three
antibiotics (amoxicillin `AMX`, amoxicillin-clavulanic acid `AMC`, and
ciprofloxacin `CIP`), based on historical data grouped by year and
hospital ward.
### **Objective**
Our goal is to:
1. Prepare the dataset by aggregating resistance data over time.
2. Define a regression model to predict AMR trends.
3. Use `tidymodels` to preprocess, train, and evaluate the model.
### **Data Preparation**
We start by transforming the `example_isolates` dataset into a
structured time-series format.
``` r
# Load required libraries
library(AMR)
library(tidymodels)
# Transform dataset
data_time <- example_isolates %>%
top_n_microorganisms(n = 10) %>% # Filter on the top #10 species
mutate(
year = as.integer(format(date, "%Y")), # Extract year from date
gramstain = mo_gramstain(mo)
) %>% # Get taxonomic names
group_by(year, gramstain) %>%
summarise(
across(c(AMX, AMC, CIP),
function(x) resistance(x, minimum = 0),
.names = "res_{.col}"
),
.groups = "drop"
) %>%
filter(!is.na(res_AMX) & !is.na(res_AMC) & !is.na(res_CIP)) # Drop missing values
#> Using column mo as input for `col_mo`.
#> `resistance()` assumes the EUCAST guideline and thus considers the 'I'
#> category susceptible. Set the `guideline` argument or the `AMR_guideline`
#> option to either "CLSI" or "EUCAST", see `?AMR-options`.
#> This message will be shown once per session.
data_time
#> # A tibble: 32 × 5
#> year gramstain res_AMX res_AMC res_CIP
#> <int> <chr> <dbl> <dbl> <dbl>
#> 1 2002 Gram-negative 1 0.105 0.0606
#> 2 2002 Gram-positive 0.838 0.182 0.162
#> 3 2003 Gram-negative 1 0.0714 0
#> 4 2003 Gram-positive 0.714 0.244 0.154
#> 5 2004 Gram-negative 0.464 0.0938 0
#> 6 2004 Gram-positive 0.849 0.299 0.244
#> 7 2005 Gram-negative 0.412 0.132 0.0588
#> 8 2005 Gram-positive 0.882 0.382 0.154
#> 9 2006 Gram-negative 0.379 0 0.1
#> 10 2006 Gram-positive 0.778 0.333 0.353
#> # 22 more rows
```
**Explanation:**
- `mo_name(mo)`: Converts microbial codes into proper species names.
- [`resistance()`](https://amr-for-r.org/reference/proportion.md):
Converts AMR results into numeric values (proportion of resistant
isolates).
- `group_by(year, ward, species)`: Aggregates resistance rates by year
and ward.
### **Defining the Workflow**
We now define the modelling workflow, which consists of a preprocessing
step, a model specification, and the fitting process.
#### 1. Preprocessing with a Recipe
``` r
# Define the recipe
resistance_recipe_time <- recipe(res_AMX ~ year + gramstain, data = data_time) %>%
step_dummy(gramstain, one_hot = TRUE) %>% # Convert categorical to numerical
step_normalize(year) %>% # Normalise year for better model performance
step_nzv(all_predictors()) # Remove near-zero variance predictors
resistance_recipe_time
#>
#> ── Recipe ──────────────────────────────────────────────────────────────────────
#>
#> ── Inputs
#> Number of variables by role
#> outcome: 1
#> predictor: 2
#>
#> ── Operations
#> • Dummy variables from: gramstain
#> • Centering and scaling for: year
#> • Sparse, unbalanced variable filter on: all_predictors()
```
**Explanation:**
- `step_dummy()`: Encodes categorical variables (`ward`, `species`) as
numerical indicators.
- `step_normalize()`: Normalises the `year` variable.
- `step_nzv()`: Removes near-zero variance predictors.
#### 2. Specifying the Model
We use a linear regression model to predict resistance trends.
``` r
# Define the linear regression model
lm_model <- linear_reg() %>%
set_engine("lm") # Use linear regression
lm_model
#> Linear Regression Model Specification (regression)
#>
#> Computational engine: lm
```
**Explanation:**
- `linear_reg()`: Defines a linear regression model.
- `set_engine("lm")`: Uses Rs built-in linear regression engine.
#### 3. Building the Workflow
We combine the preprocessing recipe and model into a workflow.
``` r
# Create workflow
resistance_workflow_time <- workflow() %>%
add_recipe(resistance_recipe_time) %>%
add_model(lm_model)
resistance_workflow_time
#> ══ Workflow ════════════════════════════════════════════════════════════════════
#> Preprocessor: Recipe
#> Model: linear_reg()
#>
#> ── Preprocessor ────────────────────────────────────────────────────────────────
#> 3 Recipe Steps
#>
#> • step_dummy()
#> • step_normalize()
#> • step_nzv()
#>
#> ── Model ───────────────────────────────────────────────────────────────────────
#> Linear Regression Model Specification (regression)
#>
#> Computational engine: lm
```
### **Training and Evaluating the Model**
We split the data into training and testing sets, fit the model, and
evaluate performance.
``` r
# Split the data
set.seed(123)
data_split_time <- initial_split(data_time, prop = 0.8)
train_time <- training(data_split_time)
test_time <- testing(data_split_time)
# Train the model
fitted_workflow_time <- resistance_workflow_time %>%
fit(train_time)
# Make predictions
predictions_time <- fitted_workflow_time %>%
predict(test_time) %>%
bind_cols(test_time)
# Evaluate model
metrics_time <- predictions_time %>%
metrics(truth = res_AMX, estimate = .pred)
metrics_time
#> # A tibble: 3 × 3
#> .metric .estimator .estimate
#> <chr> <chr> <dbl>
#> 1 rmse standard 0.0774
#> 2 rsq standard 0.711
#> 3 mae standard 0.0704
```
**Explanation:**
- `initial_split()`: Splits data into training and testing sets.
- `fit()`: Trains the workflow.
- [`predict()`](https://rdrr.io/r/stats/predict.html): Generates
resistance predictions.
- `metrics()`: Evaluates model performance.
### **Visualising Predictions**
We plot resistance trends over time for amoxicillin.
``` r
library(ggplot2)
# Plot actual vs predicted resistance over time
ggplot(predictions_time, aes(x = year)) +
geom_point(aes(y = res_AMX, color = "Actual")) +
geom_line(aes(y = .pred, color = "Predicted")) +
labs(
title = "Predicted vs Actual AMX Resistance Over Time",
x = "Year",
y = "Resistance Proportion"
) +
theme_minimal()
```
![](AMR_with_tidymodels_files/figure-html/unnamed-chunk-21-1.png)
Additionally, we can visualise resistance trends in `ggplot2` and
directly add linear models there:
``` r
ggplot(data_time, aes(x = year, y = res_AMX, color = gramstain)) +
geom_line() +
labs(
title = "AMX Resistance Trends",
x = "Year",
y = "Resistance Proportion"
) +
# add a linear model directly in ggplot2:
geom_smooth(
method = "lm",
formula = y ~ x,
alpha = 0.25
) +
theme_minimal()
```
![](AMR_with_tidymodels_files/figure-html/unnamed-chunk-22-1.png)
### **Conclusion**
In this example, we demonstrated how to analyze AMR trends over time
using `tidymodels`. By aggregating resistance rates by year and hospital
ward, we built a predictive model to track changes in resistance to
amoxicillin (`AMX`), amoxicillin-clavulanic acid (`AMC`), and
ciprofloxacin (`CIP`).
This method can be extended to other antibiotics and resistance
patterns, providing valuable insights into AMR dynamics in healthcare
settings.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

-337
View File
@@ -1,337 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Apply EUCAST rules • AMR (for R)</title>
<!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="../favicon-96x96.png">
<link rel="icon" type="”image/svg+xml”" href="../favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="../apple-touch-icon.png">
<link rel="icon" sizes="any" href="../favicon.ico">
<link rel="manifest" href="../site.webmanifest">
<script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="../deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet">
<script src="../deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="../deps/Lato-0.4.10/font.css" rel="stylesheet">
<link href="../deps/Fira_Code-0.4.10/font.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet">
<script src="../deps/headroom-0.11.0/headroom.min.js"></script><script src="../deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="../deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="../deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="../deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="../deps/search-1.0.0/fuse.min.js"></script><script src="../deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
<script src="../extra.js"></script><meta property="og:title" content="Apply EUCAST rules">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
</head>
<body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="../index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto">
<li class="active nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to">
<li><a class="dropdown-item" href="../articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="../reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="../articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="../articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="../reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="../articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="../reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="../articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="../articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="../reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="../reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="../reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="../articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="../reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="../authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul>
<ul class="navbar-nav">
<li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="../search.json">
</form></li>
<li class="nav-item"><a class="nav-link" href="../news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul>
</div>
</div>
</nav><div class="container template-article">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="../logo.svg" class="logo" alt=""><h1>Apply EUCAST rules</h1>
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/main/vignettes/EUCAST.Rmd" class="external-link"><code>vignettes/EUCAST.Rmd</code></a></small>
<div class="d-none name"><code>EUCAST.Rmd</code></div>
</div>
<div class="section level2">
<h2 id="introduction">Introduction<a class="anchor" aria-label="anchor" href="#introduction"></a>
</h2>
<p>What are EUCAST rules? The European Committee on Antimicrobial
Susceptibility Testing (EUCAST) states <a href="https://www.eucast.org/expert_rules_and_expected_phenotypes" class="external-link">on
their website</a>:</p>
<blockquote>
<p><em>EUCAST expert rules (see below) are a tabulated collection of
expert knowledge on interpretive rules, expected resistant phenotypes
and expected susceptible phenotypes which should be applied to
antimicrobial susceptibility testing in order to reduce testing, reduce
errors and make appropriate recommendations for reporting particular
resistances.</em></p>
</blockquote>
<p>In Europe, a lot of medical microbiological laboratories already
apply these rules (<a href="https://www.eurosurveillance.org/content/10.2807/1560-7917.ES2015.20.2.21008" class="external-link">Brown
<em>et al.</em>, 2015</a>). Our package features their latest insights
on expected resistant phenotypes (v1.2, 2023).</p>
</div>
<div class="section level2">
<h2 id="examples">Examples<a class="anchor" aria-label="anchor" href="#examples"></a>
</h2>
<p>These rules can be used to discard improbable bug-drug combinations
in your data. For example, <em>Klebsiella</em> produces beta-lactamase
that prevents ampicillin (or amoxicillin) from working against it. In
other words, practically every strain of <em>Klebsiella</em> is
resistant to ampicillin.</p>
<p>Sometimes, laboratory data can still contain such strains with
<em>Klebsiella</em> being susceptible to ampicillin. This could be
because an antibiogram is available before an identification is
available, and the antibiogram is then not re-interpreted based on the
identification. The <code><a href="../reference/interpretive_rules.html">eucast_rules()</a></code> function resolves this,
by applying the latest EUCAST Expected Resistant Phenotypes
guideline:</p>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">oops</span> <span class="op">&lt;-</span> <span class="fu">tibble</span><span class="fu">::</span><span class="fu"><a href="https://tibble.tidyverse.org/reference/tibble.html" class="external-link">tibble</a></span><span class="op">(</span></span>
<span> mo <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span></span>
<span> <span class="st">"Klebsiella pneumoniae"</span>,</span>
<span> <span class="st">"Escherichia coli"</span></span>
<span> <span class="op">)</span>,</span>
<span> ampicillin <span class="op">=</span> <span class="fu"><a href="../reference/as.sir.html">as.sir</a></span><span class="op">(</span><span class="st">"S"</span><span class="op">)</span></span>
<span><span class="op">)</span></span>
<span><span class="va">oops</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 2 × 2</span></span></span>
<span><span class="co">#&gt; mo ampicillin</span></span>
<span><span class="co">#&gt; <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">1</span> Klebsiella pneumoniae <span style="color: #080808; background-color: #5FD7AF;"> S </span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">2</span> Escherichia coli <span style="color: #080808; background-color: #5FD7AF;"> S </span></span></span>
<span></span>
<span><span class="fu"><a href="../reference/interpretive_rules.html">eucast_rules</a></span><span class="op">(</span><span class="va">oops</span>, info <span class="op">=</span> <span class="cn">FALSE</span>, overwrite <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 2 × 2</span></span></span>
<span><span class="co">#&gt; mo ampicillin</span></span>
<span><span class="co">#&gt; <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">1</span> Klebsiella pneumoniae <span style="color: #080808; background-color: #FF5F5F;"> R </span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">2</span> Escherichia coli <span style="color: #080808; background-color: #5FD7AF;"> S </span></span></span></code></pre></div>
<p>A more convenient function is
<code><a href="../reference/mo_property.html">mo_is_intrinsic_resistant()</a></code> that uses the same guideline,
but allows to check for one or more specific microorganisms or
antimicrobials:</p>
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/mo_property.html">mo_is_intrinsic_resistant</a></span><span class="op">(</span></span>
<span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"Klebsiella pneumoniae"</span>, <span class="st">"Escherichia coli"</span><span class="op">)</span>,</span>
<span> <span class="st">"ampicillin"</span></span>
<span><span class="op">)</span></span>
<span><span class="co">#&gt; [1] TRUE FALSE</span></span>
<span></span>
<span><span class="fu"><a href="../reference/mo_property.html">mo_is_intrinsic_resistant</a></span><span class="op">(</span></span>
<span> <span class="st">"Klebsiella pneumoniae"</span>,</span>
<span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"ampicillin"</span>, <span class="st">"kanamycin"</span><span class="op">)</span></span>
<span><span class="op">)</span></span>
<span><span class="co">#&gt; [1] TRUE FALSE</span></span></code></pre></div>
<p>EUCAST rules can not only be used for correction, they can also be
used for filling in known resistance and susceptibility based on results
of other antimicrobials drugs. This process is called <em>interpretive
reading</em>, and is basically a form of imputation:</p>
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">data</span> <span class="op">&lt;-</span> <span class="fu">tibble</span><span class="fu">::</span><span class="fu"><a href="https://tibble.tidyverse.org/reference/tibble.html" class="external-link">tibble</a></span><span class="op">(</span></span>
<span> mo <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span></span>
<span> <span class="st">"Staphylococcus aureus"</span>,</span>
<span> <span class="st">"Enterococcus faecalis"</span>,</span>
<span> <span class="st">"Escherichia coli"</span>,</span>
<span> <span class="st">"Klebsiella pneumoniae"</span>,</span>
<span> <span class="st">"Pseudomonas aeruginosa"</span></span>
<span> <span class="op">)</span>,</span>
<span> VAN <span class="op">=</span> <span class="st">"-"</span>, <span class="co"># Vancomycin</span></span>
<span> AMX <span class="op">=</span> <span class="st">"-"</span>, <span class="co"># Amoxicillin</span></span>
<span> COL <span class="op">=</span> <span class="st">"-"</span>, <span class="co"># Colistin</span></span>
<span> CAZ <span class="op">=</span> <span class="st">"-"</span>, <span class="co"># Ceftazidime</span></span>
<span> CXM <span class="op">=</span> <span class="st">"-"</span>, <span class="co"># Cefuroxime</span></span>
<span> PEN <span class="op">=</span> <span class="st">"S"</span>, <span class="co"># Benzylenicillin</span></span>
<span> FOX <span class="op">=</span> <span class="st">"S"</span> <span class="co"># Cefoxitin</span></span>
<span><span class="op">)</span></span></code></pre></div>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">data</span></span></code></pre></div>
<table class="table">
<thead><tr class="header">
<th align="left">mo</th>
<th align="center">VAN</th>
<th align="center">AMX</th>
<th align="center">COL</th>
<th align="center">CAZ</th>
<th align="center">CXM</th>
<th align="center">PEN</th>
<th align="center">FOX</th>
</tr></thead>
<tbody>
<tr class="odd">
<td align="left">Staphylococcus aureus</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">S</td>
<td align="center">S</td>
</tr>
<tr class="even">
<td align="left">Enterococcus faecalis</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">S</td>
<td align="center">S</td>
</tr>
<tr class="odd">
<td align="left">Escherichia coli</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">S</td>
<td align="center">S</td>
</tr>
<tr class="even">
<td align="left">Klebsiella pneumoniae</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">S</td>
<td align="center">S</td>
</tr>
<tr class="odd">
<td align="left">Pseudomonas aeruginosa</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">S</td>
<td align="center">S</td>
</tr>
</tbody>
</table>
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/interpretive_rules.html">eucast_rules</a></span><span class="op">(</span><span class="va">data</span>, overwrite <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></span></code></pre></div>
<table class="table">
<thead><tr class="header">
<th align="left">mo</th>
<th align="center">VAN</th>
<th align="center">AMX</th>
<th align="center">COL</th>
<th align="center">CAZ</th>
<th align="center">CXM</th>
<th align="center">PEN</th>
<th align="center">FOX</th>
</tr></thead>
<tbody>
<tr class="odd">
<td align="left">Staphylococcus aureus</td>
<td align="center">-</td>
<td align="center">S</td>
<td align="center">R</td>
<td align="center">R</td>
<td align="center">S</td>
<td align="center">S</td>
<td align="center">S</td>
</tr>
<tr class="even">
<td align="left">Enterococcus faecalis</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">R</td>
<td align="center">R</td>
<td align="center">R</td>
<td align="center">S</td>
<td align="center">R</td>
</tr>
<tr class="odd">
<td align="left">Escherichia coli</td>
<td align="center">R</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">R</td>
<td align="center">S</td>
</tr>
<tr class="even">
<td align="left">Klebsiella pneumoniae</td>
<td align="center">R</td>
<td align="center">R</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">R</td>
<td align="center">S</td>
</tr>
<tr class="odd">
<td align="left">Pseudomonas aeruginosa</td>
<td align="center">R</td>
<td align="center">R</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">R</td>
<td align="center">R</td>
<td align="center">R</td>
</tr>
</tbody>
</table>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside>
</div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer>
</div>
</body>
</html>
-131
View File
@@ -1,131 +0,0 @@
# Apply EUCAST rules
## Introduction
What are EUCAST rules? The European Committee on Antimicrobial
Susceptibility Testing (EUCAST) states [on their
website](https://www.eucast.org/expert_rules_and_expected_phenotypes):
> *EUCAST expert rules (see below) are a tabulated collection of expert
> knowledge on interpretive rules, expected resistant phenotypes and
> expected susceptible phenotypes which should be applied to
> antimicrobial susceptibility testing in order to reduce testing,
> reduce errors and make appropriate recommendations for reporting
> particular resistances.*
In Europe, a lot of medical microbiological laboratories already apply
these rules ([Brown *et al.*,
2015](https://www.eurosurveillance.org/content/10.2807/1560-7917.ES2015.20.2.21008)).
Our package features their latest insights on expected resistant
phenotypes (v1.2, 2023).
## Examples
These rules can be used to discard improbable bug-drug combinations in
your data. For example, *Klebsiella* produces beta-lactamase that
prevents ampicillin (or amoxicillin) from working against it. In other
words, practically every strain of *Klebsiella* is resistant to
ampicillin.
Sometimes, laboratory data can still contain such strains with
*Klebsiella* being susceptible to ampicillin. This could be because an
antibiogram is available before an identification is available, and the
antibiogram is then not re-interpreted based on the identification. The
[`eucast_rules()`](https://amr-for-r.org/reference/interpretive_rules.md)
function resolves this, by applying the latest EUCAST Expected
Resistant Phenotypes guideline:
``` r
oops <- tibble::tibble(
mo = c(
"Klebsiella pneumoniae",
"Escherichia coli"
),
ampicillin = as.sir("S")
)
oops
#> # A tibble: 2 × 2
#> mo ampicillin
#> <chr> <sir>
#> 1 Klebsiella pneumoniae S
#> 2 Escherichia coli S
eucast_rules(oops, info = FALSE, overwrite = TRUE)
#> # A tibble: 2 × 2
#> mo ampicillin
#> <chr> <sir>
#> 1 Klebsiella pneumoniae R
#> 2 Escherichia coli S
```
A more convenient function is
[`mo_is_intrinsic_resistant()`](https://amr-for-r.org/reference/mo_property.md)
that uses the same guideline, but allows to check for one or more
specific microorganisms or antimicrobials:
``` r
mo_is_intrinsic_resistant(
c("Klebsiella pneumoniae", "Escherichia coli"),
"ampicillin"
)
#> [1] TRUE FALSE
mo_is_intrinsic_resistant(
"Klebsiella pneumoniae",
c("ampicillin", "kanamycin")
)
#> [1] TRUE FALSE
```
EUCAST rules can not only be used for correction, they can also be used
for filling in known resistance and susceptibility based on results of
other antimicrobials drugs. This process is called *interpretive
reading*, and is basically a form of imputation:
``` r
data <- tibble::tibble(
mo = c(
"Staphylococcus aureus",
"Enterococcus faecalis",
"Escherichia coli",
"Klebsiella pneumoniae",
"Pseudomonas aeruginosa"
),
VAN = "-", # Vancomycin
AMX = "-", # Amoxicillin
COL = "-", # Colistin
CAZ = "-", # Ceftazidime
CXM = "-", # Cefuroxime
PEN = "S", # Benzylenicillin
FOX = "S" # Cefoxitin
)
```
``` r
data
```
| mo | VAN | AMX | COL | CAZ | CXM | PEN | FOX |
|:-----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Staphylococcus aureus | \- | \- | \- | \- | \- | S | S |
| Enterococcus faecalis | \- | \- | \- | \- | \- | S | S |
| Escherichia coli | \- | \- | \- | \- | \- | S | S |
| Klebsiella pneumoniae | \- | \- | \- | \- | \- | S | S |
| Pseudomonas aeruginosa | \- | \- | \- | \- | \- | S | S |
``` r
eucast_rules(data, overwrite = TRUE)
```
| mo | VAN | AMX | COL | CAZ | CXM | PEN | FOX |
|:-----------------------|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Staphylococcus aureus | \- | S | R | R | S | S | S |
| Enterococcus faecalis | \- | \- | R | R | R | S | R |
| Escherichia coli | R | \- | \- | \- | \- | R | S |
| Klebsiella pneumoniae | R | R | \- | \- | \- | R | S |
| Pseudomonas aeruginosa | R | R | \- | \- | R | R | R |
-254
View File
@@ -1,254 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Conduct principal component analysis (PCA) for AMR • AMR (for R)</title>
<!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="../favicon-96x96.png">
<link rel="icon" type="”image/svg+xml”" href="../favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="../apple-touch-icon.png">
<link rel="icon" sizes="any" href="../favicon.ico">
<link rel="manifest" href="../site.webmanifest">
<script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="../deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet">
<script src="../deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="../deps/Lato-0.4.10/font.css" rel="stylesheet">
<link href="../deps/Fira_Code-0.4.10/font.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet">
<script src="../deps/headroom-0.11.0/headroom.min.js"></script><script src="../deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="../deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="../deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="../deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="../deps/search-1.0.0/fuse.min.js"></script><script src="../deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
<script src="../extra.js"></script><meta property="og:title" content="Conduct principal component analysis (PCA) for AMR">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
</head>
<body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="../index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto">
<li class="active nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to">
<li><a class="dropdown-item" href="../articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="../reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="../articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="../articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="../reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="../articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="../reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="../articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="../articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="../reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="../reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="../reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="../articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="../reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="../authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul>
<ul class="navbar-nav">
<li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="../search.json">
</form></li>
<li class="nav-item"><a class="nav-link" href="../news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul>
</div>
</div>
</nav><div class="container template-article">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="../logo.svg" class="logo" alt=""><h1>Conduct principal component analysis (PCA) for AMR</h1>
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/main/vignettes/PCA.Rmd" class="external-link"><code>vignettes/PCA.Rmd</code></a></small>
<div class="d-none name"><code>PCA.Rmd</code></div>
</div>
<p><strong>NOTE: This page will be updated soon, as the pca() function
is currently being developed.</strong></p>
<div class="section level2">
<h2 id="introduction">Introduction<a class="anchor" aria-label="anchor" href="#introduction"></a>
</h2>
</div>
<div class="section level2">
<h2 id="transforming">Transforming<a class="anchor" aria-label="anchor" href="#transforming"></a>
</h2>
<p>For PCA, we need to transform our AMR data first. This is what the
<code>example_isolates</code> data set in this package looks like:</p>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://amr-for-r.org">AMR</a></span><span class="op">)</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://dplyr.tidyverse.org" class="external-link">dplyr</a></span><span class="op">)</span></span>
<span><span class="fu"><a href="https://pillar.r-lib.org/reference/glimpse.html" class="external-link">glimpse</a></span><span class="op">(</span><span class="va">example_isolates</span><span class="op">)</span></span>
<span><span class="co">#&gt; Rows: 2,000</span></span>
<span><span class="co">#&gt; Columns: 46</span></span>
<span><span class="co">#&gt; $ date <span style="color: #949494; font-style: italic;">&lt;date&gt;</span> 2002-01-02<span style="color: #949494;">, </span>2002-01-03<span style="color: #949494;">, </span>2002-01-07<span style="color: #949494;">, </span>2002-01-07<span style="color: #949494;">, </span>2002-01-13<span style="color: #949494;">, </span>2…</span></span>
<span><span class="co">#&gt; $ patient <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> "A77334"<span style="color: #949494;">, </span>"A77334"<span style="color: #949494;">, </span>"067927"<span style="color: #949494;">, </span>"067927"<span style="color: #949494;">, </span>"067927"<span style="color: #949494;">, </span>"067927"<span style="color: #949494;">, </span>"4…</span></span>
<span><span class="co">#&gt; $ age <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> 65<span style="color: #949494;">, </span>65<span style="color: #949494;">, </span>45<span style="color: #949494;">, </span>45<span style="color: #949494;">, </span>45<span style="color: #949494;">, </span>45<span style="color: #949494;">, </span>78<span style="color: #949494;">, </span>78<span style="color: #949494;">, </span>45<span style="color: #949494;">, </span>79<span style="color: #949494;">, </span>67<span style="color: #949494;">, </span>67<span style="color: #949494;">, </span>71<span style="color: #949494;">, </span>71<span style="color: #949494;">, </span>75<span style="color: #949494;">, </span>50…</span></span>
<span><span class="co">#&gt; $ gender <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> "F"<span style="color: #949494;">, </span>"F"<span style="color: #949494;">, </span>"F"<span style="color: #949494;">, </span>"F"<span style="color: #949494;">, </span>"F"<span style="color: #949494;">, </span>"F"<span style="color: #949494;">, </span>"M"<span style="color: #949494;">, </span>"M"<span style="color: #949494;">, </span>"F"<span style="color: #949494;">, </span>"F"<span style="color: #949494;">, </span>"M"<span style="color: #949494;">, </span>"M"<span style="color: #949494;">, </span>"M…</span></span>
<span><span class="co">#&gt; $ ward <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> "Clinical"<span style="color: #949494;">, </span>"Clinical"<span style="color: #949494;">, </span>"ICU"<span style="color: #949494;">, </span>"ICU"<span style="color: #949494;">, </span>"ICU"<span style="color: #949494;">, </span>"ICU"<span style="color: #949494;">, </span>"Clinical"…</span></span>
<span><span class="co">#&gt; $ mo <span style="color: #949494; font-style: italic;">&lt;mo&gt;</span> "B_ESCHR_COLI"<span style="color: #949494;">, </span>"B_ESCHR_COLI"<span style="color: #949494;">, </span>"B_STPHY_EPDR"<span style="color: #949494;">, </span>"B_STPHY_EPDR"<span style="color: #949494;">,</span></span></span>
<span><span class="co">#&gt; $ PEN <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">,</span></span></span>
<span><span class="co">#&gt; $ OXA <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ FLC <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R…</span></span>
<span><span class="co">#&gt; $ AMX <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">N</span></span></span>
<span><span class="co">#&gt; $ AMC <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> I<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">N</span></span></span>
<span><span class="co">#&gt; $ AMP <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">N</span></span></span>
<span><span class="co">#&gt; $ TZP <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ CZO <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">,</span></span></span>
<span><span class="co">#&gt; $ FEP <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ CXM <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> I<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S…</span></span>
<span><span class="co">#&gt; $ FOX <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">,</span></span></span>
<span><span class="co">#&gt; $ CTX <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S…</span></span>
<span><span class="co">#&gt; $ CAZ <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span></span></span>
<span><span class="co">#&gt; $ CRO <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S…</span></span>
<span><span class="co">#&gt; $ GEN <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ TOB <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ AMK <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ KAN <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ TMP <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span></span></span>
<span><span class="co">#&gt; $ SXT <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">N</span></span></span>
<span><span class="co">#&gt; $ NIT <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">,</span></span></span>
<span><span class="co">#&gt; $ FOS <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ LNZ <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">N</span></span></span>
<span><span class="co">#&gt; $ CIP <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S…</span></span>
<span><span class="co">#&gt; $ MFX <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ VAN <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span></span></span>
<span><span class="co">#&gt; $ TEC <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">N</span></span></span>
<span><span class="co">#&gt; $ TCY <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>I<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>I<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span></span></span>
<span><span class="co">#&gt; $ TGC <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ DOX <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ ERY <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">,</span></span></span>
<span><span class="co">#&gt; $ CLI <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ AZM <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>S<span style="color: #949494;">,</span></span></span>
<span><span class="co">#&gt; $ IPM <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>S<span style="color: #949494;">, </span>S…</span></span>
<span><span class="co">#&gt; $ MEM <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ MTR <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ CHL <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ COL <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span></span></span>
<span><span class="co">#&gt; $ MUP <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; $ RIF <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span><span style="color: #BB0000;">NA</span><span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span>R<span style="color: #949494;">, </span><span style="color: #BB0000;">N</span></span></span></code></pre></div>
<p>Now to transform this to a data set with only resistance percentages
per taxonomic order and genus:</p>
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">resistance_data</span> <span class="op">&lt;-</span> <span class="va">example_isolates</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/group_by.html" class="external-link">group_by</a></span><span class="op">(</span></span>
<span> order <span class="op">=</span> <span class="fu"><a href="../reference/mo_property.html">mo_order</a></span><span class="op">(</span><span class="va">mo</span><span class="op">)</span>, <span class="co"># group on anything, like order</span></span>
<span> genus <span class="op">=</span> <span class="fu"><a href="../reference/mo_property.html">mo_genus</a></span><span class="op">(</span><span class="va">mo</span><span class="op">)</span></span>
<span> <span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span> <span class="co"># and genus as we do here</span></span>
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/summarise_all.html" class="external-link">summarise_if</a></span><span class="op">(</span><span class="va">is.sir</span>, <span class="va">resistance</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span> <span class="co"># then get resistance of all drugs</span></span>
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/select.html" class="external-link">select</a></span><span class="op">(</span></span>
<span> <span class="va">order</span>, <span class="va">genus</span>, <span class="va">AMC</span>, <span class="va">CXM</span>, <span class="va">CTX</span>,</span>
<span> <span class="va">CAZ</span>, <span class="va">GEN</span>, <span class="va">TOB</span>, <span class="va">TMP</span>, <span class="va">SXT</span></span>
<span> <span class="op">)</span> <span class="co"># and select only relevant columns</span></span>
<span><span class="co">#&gt; <span style="color: #00BBBB;"></span> `resistance()` assumes the EUCAST guideline and thus considers the 'I'</span></span>
<span><span class="co">#&gt; category susceptible. Set the `guideline` argument or the `AMR_guideline`</span></span>
<span><span class="co">#&gt; option to either "CLSI" or "EUCAST", see `?AMR-options`.</span></span>
<span><span class="co">#&gt; <span style="color: #00BBBB;"></span> This message will be shown once per session.</span></span>
<span></span>
<span><span class="fu"><a href="https://rdrr.io/r/utils/head.html" class="external-link">head</a></span><span class="op">(</span><span class="va">resistance_data</span><span class="op">)</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 6 × 10</span></span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># Groups: order [5]</span></span></span>
<span><span class="co">#&gt; order genus AMC CXM CTX CAZ GEN TOB TMP SXT</span></span>
<span><span class="co">#&gt; <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">1</span> (unknown order) (unknown ge… <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">2</span> Actinomycetales Schaalia <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">3</span> Bacteroidales Bacteroides <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">4</span> Campylobacterales Campylobact… <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">5</span> Caryophanales Gemella <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">6</span> Caryophanales Listeria <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span></span></span></code></pre></div>
</div>
<div class="section level2">
<h2 id="perform-principal-component-analysis">Perform principal component analysis<a class="anchor" aria-label="anchor" href="#perform-principal-component-analysis"></a>
</h2>
<p>The new <code><a href="../reference/pca.html">pca()</a></code> function will automatically filter on rows
that contain numeric values in all selected variables, so we now only
need to do:</p>
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">pca_result</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/pca.html">pca</a></span><span class="op">(</span><span class="va">resistance_data</span><span class="op">)</span></span>
<span><span class="co">#&gt; <span style="color: #00BBBB;"></span> Columns selected for PCA: <span style="color: #0000BB;">"\033[1mAMC\033[22m"</span>, <span style="color: #0000BB;">"\033[1mCAZ\033[22m"</span>,</span></span>
<span><span class="co">#&gt; <span style="color: #0000BB;">"\033[1mCTX\033[22m"</span>, <span style="color: #0000BB;">"\033[1mCXM\033[22m"</span>, <span style="color: #0000BB;">"\033[1mGEN\033[22m"</span>,</span></span>
<span><span class="co">#&gt; <span style="color: #0000BB;">"\033[1mSXT\033[22m"</span>, <span style="color: #0000BB;">"\033[1mTMP\033[22m"</span>, and <span style="color: #0000BB;">"\033[1mTOB\033[22m"</span>. Total</span></span>
<span><span class="co">#&gt; observations available: 7.</span></span></code></pre></div>
<p>The result can be reviewed with the good old <code><a href="https://rdrr.io/r/base/summary.html" class="external-link">summary()</a></code>
function:</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/base/summary.html" class="external-link">summary</a></span><span class="op">(</span><span class="va">pca_result</span><span class="op">)</span></span>
<span><span class="co">#&gt; Groups (n=4, named as 'order'):</span></span>
<span><span class="co">#&gt; [1] "Caryophanales" "Enterobacterales" "Lactobacillales" "Pseudomonadales"</span></span>
<span><span class="co">#&gt; Importance of components:</span></span>
<span><span class="co">#&gt; PC1 PC2 PC3 PC4 PC5 PC6 PC7</span></span>
<span><span class="co">#&gt; Standard deviation 2.1539 1.6807 0.6138 0.33879 0.20808 0.03140 1.232e-16</span></span>
<span><span class="co">#&gt; Proportion of Variance 0.5799 0.3531 0.0471 0.01435 0.00541 0.00012 0.000e+00</span></span>
<span><span class="co">#&gt; Cumulative Proportion 0.5799 0.9330 0.9801 0.99446 0.99988 1.00000 1.000e+00</span></span></code></pre></div>
<pre><code><span><span class="co">#&gt; Groups (n=4, named as 'order'):</span></span>
<span><span class="co">#&gt; [1] "Caryophanales" "Enterobacterales" "Lactobacillales" "Pseudomonadales"</span></span></code></pre>
<p>Good news. The first two components explain a total of 93.3% of the
variance (see the PC1 and PC2 values of the <em>Proportion of
Variance</em>. We can create a so-called biplot with the base R
<code><a href="https://rdrr.io/r/stats/biplot.html" class="external-link">biplot()</a></code> function, to see which antimicrobial resistance
per drug explain the difference per microorganism.</p>
</div>
<div class="section level2">
<h2 id="plotting-the-results">Plotting the results<a class="anchor" aria-label="anchor" href="#plotting-the-results"></a>
</h2>
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="https://rdrr.io/r/stats/biplot.html" class="external-link">biplot</a></span><span class="op">(</span><span class="va">pca_result</span><span class="op">)</span></span></code></pre></div>
<p><img src="PCA_files/figure-html/unnamed-chunk-5-1.png" class="r-plt" alt="" width="750"></p>
<p>But we cant see the explanation of the points. Perhaps this works
better with our new <code><a href="../reference/ggplot_pca.html">ggplot_pca()</a></code> function, that
automatically adds the right labels and even groups:</p>
<div class="sourceCode" id="cb7"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/ggplot_pca.html">ggplot_pca</a></span><span class="op">(</span><span class="va">pca_result</span><span class="op">)</span></span></code></pre></div>
<p><img src="PCA_files/figure-html/unnamed-chunk-6-1.png" class="r-plt" alt="" width="750"></p>
<p>You can also print an ellipse per group, and edit the appearance:</p>
<div class="sourceCode" id="cb8"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/ggplot_pca.html">ggplot_pca</a></span><span class="op">(</span><span class="va">pca_result</span>, ellipse <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span> <span class="op">+</span></span>
<span> <span class="fu">ggplot2</span><span class="fu">::</span><span class="fu"><a href="https://ggplot2.tidyverse.org/reference/labs.html" class="external-link">labs</a></span><span class="op">(</span>title <span class="op">=</span> <span class="st">"An AMR/PCA biplot!"</span><span class="op">)</span></span></code></pre></div>
<p><img src="PCA_files/figure-html/unnamed-chunk-7-1.png" class="r-plt" alt="" width="750"></p>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside>
</div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer>
</div>
</body>
</html>
-170
View File
@@ -1,170 +0,0 @@
# Conduct principal component analysis (PCA) for AMR
**NOTE: This page will be updated soon, as the pca() function is
currently being developed.**
## Introduction
## Transforming
For PCA, we need to transform our AMR data first. This is what the
`example_isolates` data set in this package looks like:
``` r
library(AMR)
library(dplyr)
glimpse(example_isolates)
#> Rows: 2,000
#> Columns: 46
#> $ date <date> 2002-01-02, 2002-01-03, 2002-01-07, 2002-01-07, 2002-01-13, 2…
#> $ patient <chr> "A77334", "A77334", "067927", "067927", "067927", "067927", "4…
#> $ age <dbl> 65, 65, 45, 45, 45, 45, 78, 78, 45, 79, 67, 67, 71, 71, 75, 50…
#> $ gender <chr> "F", "F", "F", "F", "F", "F", "M", "M", "F", "F", "M", "M", "M…
#> $ ward <chr> "Clinical", "Clinical", "ICU", "ICU", "ICU", "ICU", "Clinical"…
#> $ mo <mo> "B_ESCHR_COLI", "B_ESCHR_COLI", "B_STPHY_EPDR", "B_STPHY_EPDR",…
#> $ PEN <sir> R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, S,…
#> $ OXA <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ FLC <sir> NA, NA, R, R, R, R, S, S, R, S, S, S, NA, NA, NA, NA, NA, R, R…
#> $ AMX <sir> NA, NA, NA, NA, NA, NA, R, R, NA, NA, NA, NA, NA, NA, R, NA, N…
#> $ AMC <sir> I, I, NA, NA, NA, NA, S, S, NA, NA, S, S, I, I, R, I, I, NA, N…
#> $ AMP <sir> NA, NA, NA, NA, NA, NA, R, R, NA, NA, NA, NA, NA, NA, R, NA, N…
#> $ TZP <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ CZO <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, NA,…
#> $ FEP <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ CXM <sir> I, I, R, R, R, R, S, S, R, S, S, S, S, S, NA, S, S, R, R, S, S…
#> $ FOX <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, NA,…
#> $ CTX <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, S, S…
#> $ CAZ <sir> NA, NA, R, R, R, R, R, R, R, R, R, R, NA, NA, NA, S, S, R, R, …
#> $ CRO <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, S, S…
#> $ GEN <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ TOB <sir> NA, NA, NA, NA, NA, NA, S, S, NA, NA, NA, NA, S, S, NA, NA, NA…
#> $ AMK <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ KAN <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ TMP <sir> R, R, S, S, R, R, R, R, S, S, NA, NA, S, S, S, S, S, R, R, R, …
#> $ SXT <sir> R, R, S, S, NA, NA, NA, NA, S, S, NA, NA, S, S, S, S, S, NA, N…
#> $ NIT <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R,…
#> $ FOS <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ LNZ <sir> R, R, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, R, R, R, R, N…
#> $ CIP <sir> NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, NA, NA, NA, NA, S, S…
#> $ MFX <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ VAN <sir> R, R, S, S, S, S, S, S, S, S, NA, NA, R, R, R, R, R, S, S, S, …
#> $ TEC <sir> R, R, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, R, R, R, R, N…
#> $ TCY <sir> R, R, S, S, S, S, S, S, S, I, S, S, NA, NA, I, R, R, S, I, R, …
#> $ TGC <sir> NA, NA, S, S, S, S, S, S, S, NA, S, S, NA, NA, NA, R, R, S, NA…
#> $ DOX <sir> NA, NA, S, S, S, S, S, S, S, NA, S, S, NA, NA, NA, R, R, S, NA…
#> $ ERY <sir> R, R, R, R, R, R, S, S, R, S, S, S, R, R, R, R, R, R, R, R, S,…
#> $ CLI <sir> R, R, NA, NA, NA, R, NA, NA, NA, NA, NA, NA, R, R, R, R, R, NA…
#> $ AZM <sir> R, R, R, R, R, R, S, S, R, S, S, S, R, R, R, R, R, R, R, R, S,…
#> $ IPM <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, S, S…
#> $ MEM <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ MTR <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ CHL <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ COL <sir> NA, NA, R, R, R, R, R, R, R, R, R, R, NA, NA, NA, R, R, R, R, …
#> $ MUP <sir> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
#> $ RIF <sir> R, R, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, R, R, R, R, N…
```
Now to transform this to a data set with only resistance percentages per
taxonomic order and genus:
``` r
resistance_data <- example_isolates %>%
group_by(
order = mo_order(mo), # group on anything, like order
genus = mo_genus(mo)
) %>% # and genus as we do here
summarise_if(is.sir, resistance) %>% # then get resistance of all drugs
select(
order, genus, AMC, CXM, CTX,
CAZ, GEN, TOB, TMP, SXT
) # and select only relevant columns
#> `resistance()` assumes the EUCAST guideline and thus considers the 'I'
#> category susceptible. Set the `guideline` argument or the `AMR_guideline`
#> option to either "CLSI" or "EUCAST", see `?AMR-options`.
#> This message will be shown once per session.
head(resistance_data)
#> # A tibble: 6 × 10
#> # Groups: order [5]
#> order genus AMC CXM CTX CAZ GEN TOB TMP SXT
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 (unknown order) (unknown ge… NA NA NA NA NA NA NA NA
#> 2 Actinomycetales Schaalia NA NA NA NA NA NA NA NA
#> 3 Bacteroidales Bacteroides NA NA NA NA NA NA NA NA
#> 4 Campylobacterales Campylobact… NA NA NA NA NA NA NA NA
#> 5 Caryophanales Gemella NA NA NA NA NA NA NA NA
#> 6 Caryophanales Listeria NA NA NA NA NA NA NA NA
```
## Perform principal component analysis
The new [`pca()`](https://amr-for-r.org/reference/pca.md) function will
automatically filter on rows that contain numeric values in all selected
variables, so we now only need to do:
``` r
pca_result <- pca(resistance_data)
#> Columns selected for PCA: "\033[1mAMC\033[22m", "\033[1mCAZ\033[22m",
#> "\033[1mCTX\033[22m", "\033[1mCXM\033[22m", "\033[1mGEN\033[22m",
#> "\033[1mSXT\033[22m", "\033[1mTMP\033[22m", and "\033[1mTOB\033[22m". Total
#> observations available: 7.
```
The result can be reviewed with the good old
[`summary()`](https://rdrr.io/r/base/summary.html) function:
``` r
summary(pca_result)
#> Groups (n=4, named as 'order'):
#> [1] "Caryophanales" "Enterobacterales" "Lactobacillales" "Pseudomonadales"
#> Importance of components:
#> PC1 PC2 PC3 PC4 PC5 PC6 PC7
#> Standard deviation 2.1539 1.6807 0.6138 0.33879 0.20808 0.03140 1.232e-16
#> Proportion of Variance 0.5799 0.3531 0.0471 0.01435 0.00541 0.00012 0.000e+00
#> Cumulative Proportion 0.5799 0.9330 0.9801 0.99446 0.99988 1.00000 1.000e+00
```
#> Groups (n=4, named as 'order'):
#> [1] "Caryophanales" "Enterobacterales" "Lactobacillales" "Pseudomonadales"
Good news. The first two components explain a total of 93.3% of the
variance (see the PC1 and PC2 values of the *Proportion of Variance*. We
can create a so-called biplot with the base R
[`biplot()`](https://rdrr.io/r/stats/biplot.html) function, to see which
antimicrobial resistance per drug explain the difference per
microorganism.
## Plotting the results
``` r
biplot(pca_result)
```
![](PCA_files/figure-html/unnamed-chunk-5-1.png)
But we cant see the explanation of the points. Perhaps this works
better with our new
[`ggplot_pca()`](https://amr-for-r.org/reference/ggplot_pca.md)
function, that automatically adds the right labels and even groups:
``` r
ggplot_pca(pca_result)
```
![](PCA_files/figure-html/unnamed-chunk-6-1.png)
You can also print an ellipse per group, and edit the appearance:
``` r
ggplot_pca(pca_result, ellipse = TRUE) +
ggplot2::labs(title = "An AMR/PCA biplot!")
```
![](PCA_files/figure-html/unnamed-chunk-7-1.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

-343
View File
@@ -1,343 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Work with WHONET data • AMR (for R)</title>
<!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="../favicon-96x96.png">
<link rel="icon" type="”image/svg+xml”" href="../favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="../apple-touch-icon.png">
<link rel="icon" sizes="any" href="../favicon.ico">
<link rel="manifest" href="../site.webmanifest">
<script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="../deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet">
<script src="../deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="../deps/Lato-0.4.10/font.css" rel="stylesheet">
<link href="../deps/Fira_Code-0.4.10/font.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet">
<script src="../deps/headroom-0.11.0/headroom.min.js"></script><script src="../deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="../deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="../deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="../deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="../deps/search-1.0.0/fuse.min.js"></script><script src="../deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
<script src="../extra.js"></script><meta property="og:title" content="Work with WHONET data">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
</head>
<body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="../index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto">
<li class="active nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to">
<li><a class="dropdown-item" href="../articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="../reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="../articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="../articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="../reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="../articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="../reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="../articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="../articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="../reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="../reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="../reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="../articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="../reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="../authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul>
<ul class="navbar-nav">
<li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="../search.json">
</form></li>
<li class="nav-item"><a class="nav-link" href="../news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul>
</div>
</div>
</nav><div class="container template-article">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="../logo.svg" class="logo" alt=""><h1>Work with WHONET data</h1>
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/main/vignettes/WHONET.Rmd" class="external-link"><code>vignettes/WHONET.Rmd</code></a></small>
<div class="d-none name"><code>WHONET.Rmd</code></div>
</div>
<div class="section level3">
<h3 id="import-of-data">Import of data<a class="anchor" aria-label="anchor" href="#import-of-data"></a>
</h3>
<p>This tutorial assumes you already imported the WHONET data with
e.g. the <a href="https://readxl.tidyverse.org/" class="external-link"><code>readxl</code>
package</a>. In RStudio, this can be done using the menu button Import
Dataset in the tab Environment. Choose the option From Excel and
select your exported file. Make sure date fields are imported
correctly.</p>
<p>An example syntax could look like this:</p>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://readxl.tidyverse.org" class="external-link">readxl</a></span><span class="op">)</span></span>
<span><span class="va">data</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://readxl.tidyverse.org/reference/read_excel.html" class="external-link">read_excel</a></span><span class="op">(</span>path <span class="op">=</span> <span class="st">"path/to/your/file.xlsx"</span><span class="op">)</span></span></code></pre></div>
<p>This package comes with an <a href="https://amr-for-r.org/reference/WHONET.html">example data set
<code>WHONET</code></a>. We will use it for this analysis.</p>
</div>
<div class="section level3">
<h3 id="preparation">Preparation<a class="anchor" aria-label="anchor" href="#preparation"></a>
</h3>
<p>First, load the relevant packages if you did not yet did this. I use
the tidyverse for all of my analyses. All of them. If you dont know it
yet, I suggest you read about it on their website: <a href="https://www.tidyverse.org/" class="external-link uri">https://www.tidyverse.org/</a>.</p>
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://dplyr.tidyverse.org" class="external-link">dplyr</a></span><span class="op">)</span> <span class="co"># part of tidyverse</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://ggplot2.tidyverse.org" class="external-link">ggplot2</a></span><span class="op">)</span> <span class="co"># part of tidyverse</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://amr-for-r.org">AMR</a></span><span class="op">)</span> <span class="co"># this package</span></span>
<span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://msberends.github.io/cleaner/" class="external-link">cleaner</a></span><span class="op">)</span> <span class="co"># to create frequency tables</span></span></code></pre></div>
<p>We will have to transform some variables to simplify and automate the
analysis:</p>
<ul>
<li>Microorganisms should be transformed to our own microorganism codes
(called an <code>mo</code>) using <a href="https://amr-for-r.org/reference/catalogue_of_life">our Catalogue
of Life reference data set</a>, which contains all ~70,000
microorganisms from the taxonomic kingdoms Bacteria, Fungi and Protozoa.
We do the tranformation with <code><a href="../reference/as.mo.html">as.mo()</a></code>. This function also
recognises almost all WHONET abbreviations of microorganisms.</li>
<li>Antimicrobial results or interpretations have to be clean and valid.
In other words, they should only contain values <code>"S"</code>,
<code>"I"</code> or <code>"R"</code>. That is exactly where the
<code><a href="../reference/as.sir.html">as.sir()</a></code> function is for.</li>
</ul>
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># transform variables</span></span>
<span><span class="va">data</span> <span class="op">&lt;-</span> <span class="va">WHONET</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span> <span class="co"># get microbial ID based on given organism</span></span>
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/mutate.html" class="external-link">mutate</a></span><span class="op">(</span>mo <span class="op">=</span> <span class="fu"><a href="../reference/as.mo.html">as.mo</a></span><span class="op">(</span><span class="va">Organism</span><span class="op">)</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span> <span class="co"># transform everything from "AMP_ND10" to "CIP_EE" to the new `sir` class</span></span>
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/mutate_all.html" class="external-link">mutate_at</a></span><span class="op">(</span><span class="fu"><a href="https://dplyr.tidyverse.org/reference/vars.html" class="external-link">vars</a></span><span class="op">(</span><span class="va">AMP_ND10</span><span class="op">:</span><span class="va">CIP_EE</span><span class="op">)</span>, <span class="va">as.sir</span><span class="op">)</span></span></code></pre></div>
<p>No errors or warnings, so all values are transformed succesfully.</p>
<p>We also created a package dedicated to data cleaning and checking,
called the <code>cleaner</code> package. Its <code><a href="https://msberends.github.io/cleaner/reference/freq.html" class="external-link">freq()</a></code>
function can be used to create frequency tables.</p>
<p>So lets check our data, with a couple of frequency tables:</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># our newly created `mo` variable, put in the mo_name() function</span></span>
<span><span class="va">data</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span> <span class="fu"><a href="https://msberends.github.io/cleaner/reference/freq.html" class="external-link">freq</a></span><span class="op">(</span><span class="fu"><a href="../reference/mo_property.html">mo_name</a></span><span class="op">(</span><span class="va">mo</span><span class="op">)</span>, nmax <span class="op">=</span> <span class="fl">10</span><span class="op">)</span></span></code></pre></div>
<p><strong>Frequency table</strong></p>
<p>Class: character<br>
Length: 500<br>
Available: 500 (100%, NA: 0 = 0%)<br>
Unique: 38</p>
<p>Shortest: 11<br>
Longest: 40</p>
<table class="table">
<colgroup>
<col width="4%">
<col width="47%">
<col width="7%">
<col width="10%">
<col width="13%">
<col width="15%">
</colgroup>
<thead><tr class="header">
<th align="left"></th>
<th align="left">Item</th>
<th align="right">Count</th>
<th align="right">Percent</th>
<th align="right">Cum. Count</th>
<th align="right">Cum. Percent</th>
</tr></thead>
<tbody>
<tr class="odd">
<td align="left">1</td>
<td align="left">Escherichia coli</td>
<td align="right">245</td>
<td align="right">49.0%</td>
<td align="right">245</td>
<td align="right">49.0%</td>
</tr>
<tr class="even">
<td align="left">2</td>
<td align="left">Coagulase-negative Staphylococcus (CoNS)</td>
<td align="right">74</td>
<td align="right">14.8%</td>
<td align="right">319</td>
<td align="right">63.8%</td>
</tr>
<tr class="odd">
<td align="left">3</td>
<td align="left">Staphylococcus epidermidis</td>
<td align="right">38</td>
<td align="right">7.6%</td>
<td align="right">357</td>
<td align="right">71.4%</td>
</tr>
<tr class="even">
<td align="left">4</td>
<td align="left">Streptococcus pneumoniae</td>
<td align="right">31</td>
<td align="right">6.2%</td>
<td align="right">388</td>
<td align="right">77.6%</td>
</tr>
<tr class="odd">
<td align="left">5</td>
<td align="left">Staphylococcus hominis</td>
<td align="right">21</td>
<td align="right">4.2%</td>
<td align="right">409</td>
<td align="right">81.8%</td>
</tr>
<tr class="even">
<td align="left">6</td>
<td align="left">Proteus mirabilis</td>
<td align="right">9</td>
<td align="right">1.8%</td>
<td align="right">418</td>
<td align="right">83.6%</td>
</tr>
<tr class="odd">
<td align="left">7</td>
<td align="left">Enterococcus faecium</td>
<td align="right">8</td>
<td align="right">1.6%</td>
<td align="right">426</td>
<td align="right">85.2%</td>
</tr>
<tr class="even">
<td align="left">8</td>
<td align="left">Staphylococcus capitis urealyticus</td>
<td align="right">8</td>
<td align="right">1.6%</td>
<td align="right">434</td>
<td align="right">86.8%</td>
</tr>
<tr class="odd">
<td align="left">9</td>
<td align="left">Enterobacter cloacae</td>
<td align="right">5</td>
<td align="right">1.0%</td>
<td align="right">439</td>
<td align="right">87.8%</td>
</tr>
<tr class="even">
<td align="left">10</td>
<td align="left">Enterococcus columbae</td>
<td align="right">4</td>
<td align="right">0.8%</td>
<td align="right">443</td>
<td align="right">88.6%</td>
</tr>
</tbody>
</table>
<p>(omitted 28 entries, n = 57 [11.4%])</p>
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="co"># our transformed antibiotic columns</span></span>
<span><span class="co"># amoxicillin/clavulanic acid (J01CR02) as an example</span></span>
<span><span class="va">data</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span> <span class="fu"><a href="https://msberends.github.io/cleaner/reference/freq.html" class="external-link">freq</a></span><span class="op">(</span><span class="va">AMC_ND2</span><span class="op">)</span></span>
<span><span class="co">#&gt; <span style="color: #00BBBB;"></span> `susceptibility()` assumes the EUCAST guideline and thus considers the 'I'</span></span>
<span><span class="co">#&gt; category susceptible. Set the `guideline` argument or the `AMR_guideline`</span></span>
<span><span class="co">#&gt; option to either "CLSI" or "EUCAST", see `?AMR-options`.</span></span>
<span><span class="co">#&gt; <span style="color: #00BBBB;"></span> This message will be shown once per session.</span></span></code></pre></div>
<p><strong>Frequency table</strong></p>
<p>Class: factor &gt; ordered &gt; sir (numeric)<br>
Length: 500<br>
Levels: 8: S &lt; SDD &lt; I &lt; R &lt; NI &lt; WT &lt; NWT &lt;
NS<br>
Available: 481 (96.2%, NA: 19 = 3.8%)<br>
Unique: 3</p>
<p>Drug: Amoxicillin/clavulanic acid (AMC, J01CR02/QJ01CR02)<br>
Drug group: Aminopenicillins<br>
%SI: 78.59%</p>
<table class="table">
<thead><tr class="header">
<th align="left"></th>
<th align="left">Item</th>
<th align="right">Count</th>
<th align="right">Percent</th>
<th align="right">Cum. Count</th>
<th align="right">Cum. Percent</th>
</tr></thead>
<tbody>
<tr class="odd">
<td align="left">1</td>
<td align="left">S</td>
<td align="right">356</td>
<td align="right">74.01%</td>
<td align="right">356</td>
<td align="right">74.01%</td>
</tr>
<tr class="even">
<td align="left">2</td>
<td align="left">R</td>
<td align="right">103</td>
<td align="right">21.41%</td>
<td align="right">459</td>
<td align="right">95.43%</td>
</tr>
<tr class="odd">
<td align="left">3</td>
<td align="left">I</td>
<td align="right">22</td>
<td align="right">4.57%</td>
<td align="right">481</td>
<td align="right">100.00%</td>
</tr>
</tbody>
</table>
</div>
<div class="section level3">
<h3 id="a-first-glimpse-at-results">A first glimpse at results<a class="anchor" aria-label="anchor" href="#a-first-glimpse-at-results"></a>
</h3>
<p>An easy <code>ggplot</code> will already give a lot of information,
using the included <code><a href="../reference/ggplot_sir.html">ggplot_sir()</a></code> function:</p>
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">data</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/group_by.html" class="external-link">group_by</a></span><span class="op">(</span><span class="va">Country</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/select.html" class="external-link">select</a></span><span class="op">(</span><span class="va">Country</span>, <span class="va">AMP_ND2</span>, <span class="va">AMC_ED20</span>, <span class="va">CAZ_ED10</span>, <span class="va">CIP_ED5</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%&gt;%</a></span></span>
<span> <span class="fu"><a href="../reference/ggplot_sir.html">ggplot_sir</a></span><span class="op">(</span>translate_ab <span class="op">=</span> <span class="st">"ab"</span>, facet <span class="op">=</span> <span class="st">"Country"</span>, datalabels <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span></span></code></pre></div>
<p><img src="WHONET_files/figure-html/unnamed-chunk-7-1.png" class="r-plt" alt="" width="720"></p>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside>
</div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer>
</div>
</body>
</html>
-147
View File
@@ -1,147 +0,0 @@
# Work with WHONET data
### Import of data
This tutorial assumes you already imported the WHONET data with e.g. the
[`readxl` package](https://readxl.tidyverse.org/). In RStudio, this can
be done using the menu button Import Dataset in the tab Environment.
Choose the option From Excel and select your exported file. Make sure
date fields are imported correctly.
An example syntax could look like this:
``` r
library(readxl)
data <- read_excel(path = "path/to/your/file.xlsx")
```
This package comes with an [example data set
`WHONET`](https://amr-for-r.org/reference/WHONET.html). We will use it
for this analysis.
### Preparation
First, load the relevant packages if you did not yet did this. I use the
tidyverse for all of my analyses. All of them. If you dont know it yet,
I suggest you read about it on their website:
<https://www.tidyverse.org/>.
``` r
library(dplyr) # part of tidyverse
library(ggplot2) # part of tidyverse
library(AMR) # this package
library(cleaner) # to create frequency tables
```
We will have to transform some variables to simplify and automate the
analysis:
- Microorganisms should be transformed to our own microorganism codes
(called an `mo`) using [our Catalogue of Life reference data
set](https://amr-for-r.org/reference/catalogue_of_life), which
contains all ~70,000 microorganisms from the taxonomic kingdoms
Bacteria, Fungi and Protozoa. We do the tranformation with
[`as.mo()`](https://amr-for-r.org/reference/as.mo.md). This function
also recognises almost all WHONET abbreviations of microorganisms.
- Antimicrobial results or interpretations have to be clean and valid.
In other words, they should only contain values `"S"`, `"I"` or `"R"`.
That is exactly where the
[`as.sir()`](https://amr-for-r.org/reference/as.sir.md) function is
for.
``` r
# transform variables
data <- WHONET %>%
# get microbial ID based on given organism
mutate(mo = as.mo(Organism)) %>%
# transform everything from "AMP_ND10" to "CIP_EE" to the new `sir` class
mutate_at(vars(AMP_ND10:CIP_EE), as.sir)
```
No errors or warnings, so all values are transformed succesfully.
We also created a package dedicated to data cleaning and checking,
called the `cleaner` package. Its
[`freq()`](https://msberends.github.io/cleaner/reference/freq.html)
function can be used to create frequency tables.
So lets check our data, with a couple of frequency tables:
``` r
# our newly created `mo` variable, put in the mo_name() function
data %>% freq(mo_name(mo), nmax = 10)
```
**Frequency table**
Class: character
Length: 500
Available: 500 (100%, NA: 0 = 0%)
Unique: 38
Shortest: 11
Longest: 40
| | Item | Count | Percent | Cum. Count | Cum. Percent |
|:---|:---|---:|---:|---:|---:|
| 1 | Escherichia coli | 245 | 49.0% | 245 | 49.0% |
| 2 | Coagulase-negative Staphylococcus (CoNS) | 74 | 14.8% | 319 | 63.8% |
| 3 | Staphylococcus epidermidis | 38 | 7.6% | 357 | 71.4% |
| 4 | Streptococcus pneumoniae | 31 | 6.2% | 388 | 77.6% |
| 5 | Staphylococcus hominis | 21 | 4.2% | 409 | 81.8% |
| 6 | Proteus mirabilis | 9 | 1.8% | 418 | 83.6% |
| 7 | Enterococcus faecium | 8 | 1.6% | 426 | 85.2% |
| 8 | Staphylococcus capitis urealyticus | 8 | 1.6% | 434 | 86.8% |
| 9 | Enterobacter cloacae | 5 | 1.0% | 439 | 87.8% |
| 10 | Enterococcus columbae | 4 | 0.8% | 443 | 88.6% |
(omitted 28 entries, n = 57 \[11.4%\])
``` r
# our transformed antibiotic columns
# amoxicillin/clavulanic acid (J01CR02) as an example
data %>% freq(AMC_ND2)
#> `susceptibility()` assumes the EUCAST guideline and thus considers the 'I'
#> category susceptible. Set the `guideline` argument or the `AMR_guideline`
#> option to either "CLSI" or "EUCAST", see `?AMR-options`.
#> This message will be shown once per session.
```
**Frequency table**
Class: factor \> ordered \> sir (numeric)
Length: 500
Levels: 8: S \< SDD \< I \< R \< NI \< WT \< NWT \< NS
Available: 481 (96.2%, NA: 19 = 3.8%)
Unique: 3
Drug: Amoxicillin/clavulanic acid (AMC, J01CR02/QJ01CR02)
Drug group: Aminopenicillins
%SI: 78.59%
| | Item | Count | Percent | Cum. Count | Cum. Percent |
|:----|:-----|------:|--------:|-----------:|-------------:|
| 1 | S | 356 | 74.01% | 356 | 74.01% |
| 2 | R | 103 | 21.41% | 459 | 95.43% |
| 3 | I | 22 | 4.57% | 481 | 100.00% |
### A first glimpse at results
An easy `ggplot` will already give a lot of information, using the
included [`ggplot_sir()`](https://amr-for-r.org/reference/ggplot_sir.md)
function:
``` r
data %>%
group_by(Country) %>%
select(Country, AMP_ND2, AMC_ED20, CAZ_ED10, CIP_ED5) %>%
ggplot_sir(translate_ab = "ab", facet = "Country", datalabels = FALSE)
```
![](WHONET_files/figure-html/unnamed-chunk-7-1.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

-672
View File
@@ -1,672 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Estimating Empirical Coverage with WISCA • AMR (for R)</title>
<!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="../favicon-96x96.png">
<link rel="icon" type="”image/svg+xml”" href="../favicon.svg">
<link rel="apple-touch-icon" sizes="180x180" href="../apple-touch-icon.png">
<link rel="icon" sizes="any" href="../favicon.ico">
<link rel="manifest" href="../site.webmanifest">
<script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="../deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet">
<script src="../deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="../deps/Lato-0.4.10/font.css" rel="stylesheet">
<link href="../deps/Fira_Code-0.4.10/font.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet">
<link href="../deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet">
<script src="../deps/headroom-0.11.0/headroom.min.js"></script><script src="../deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="../deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="../deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="../deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="../deps/search-1.0.0/fuse.min.js"></script><script src="../deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
<script src="../extra.js"></script><meta property="og:title" content="Estimating Empirical Coverage with WISCA">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script>
</head>
<body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="../index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto">
<li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to">
<li><a class="dropdown-item" href="../articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="../reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="../articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="../articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="../reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="../articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="../reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="../articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="../articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="../reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="../reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="../reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul>
</li>
<li class="nav-item"><a class="nav-link" href="../articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="../reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="../authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul>
<ul class="navbar-nav">
<li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="../search.json">
</form></li>
<li class="nav-item"><a class="nav-link" href="../news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul>
</div>
</div>
</nav><div class="container template-article">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="../logo.svg" class="logo" alt=""><h1>Estimating Empirical Coverage with WISCA</h1>
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/main/vignettes/WISCA.Rmd" class="external-link"><code>vignettes/WISCA.Rmd</code></a></small>
<div class="d-none name"><code>WISCA.Rmd</code></div>
</div>
<div class="section level2">
<h2 id="why-wisca">Why WISCA?<a class="anchor" aria-label="anchor" href="#why-wisca"></a>
</h2>
<p>When a clinician starts empirical antimicrobial therapy, the
causative pathogen is unknown. The question they need answered is not
<em>“what proportion of</em> E. coli <em>is susceptible to
ciprofloxacin?“</em> but rather <em>“what is the probability that this
regimen will adequately cover whatever pathogen turns out to be causing
my patients infection?”</em></p>
<p>The traditional cumulative antibiogram, as standardised by CLSI M39,
cannot answer that question. It presents susceptibility percentages per
species per antibiotic, but:</p>
<ul>
<li>
<strong>It fragments information by organism.</strong> The clinician
must mentally combine susceptibility rates across multiple species,
weighting by how often each species causes the syndrome, a calculation
nobody does at the bedside.</li>
<li>
<strong>It ignores pathogen incidence.</strong> A species that
causes 2% of infections is given the same visual weight as one that
causes 60%.</li>
<li>
<strong>It does not evaluate combination regimens.</strong> Much
empirical therapy consists of two or more agents, but the traditional
antibiogram only shows monotherapy per organism.</li>
<li>
<strong>It provides no measure of uncertainty.</strong> A reported
“90% susceptible” based on 50 isolates has a 95% confidence interval of
roughly 78-97% (Clopper-Pearson), yet the antibiogram presents it as a
point estimate without context.</li>
</ul>
<p><strong>WISCA</strong> (Weighted-Incidence Syndromic Combination
Antibiogram) resolves all four limitations. It estimates the probability
that a regimen will provide adequate empirical coverage for a given
infection syndrome, weighted by local pathogen incidence, with full
uncertainty quantification via Bayesian inference.</p>
<p>The concept was introduced by Hebert <em>et al.</em> (2012), who
demonstrated that traditional antibiogram susceptibility rates could be
misleading: ciprofloxacin appeared 84% effective against <em>E.
coli</em> in the traditional antibiogram, but WISCA revealed only 62%
coverage for UTI and 37% for abdominal infections, because enterococci
(intrinsically resistant) and other species contribute substantially to
these syndromes. Randhawa <em>et al.</em> (2014) showed that
WISCA-guided regimen selection could improve time-to-adequate-coverage
on the ICU by over 40%. Bielicki <em>et al.</em> (2016) introduced the
Bayesian framework now used in this package, enabling credible intervals
and multi-centre pooling. Cook <em>et al.</em> (2022) applied it
globally across 52 hospitals in 23 countries.</p>
</div>
<div class="section level2">
<h2 id="the-idea">The idea<a class="anchor" aria-label="anchor" href="#the-idea"></a>
</h2>
<p>WISCA asks:</p>
<blockquote>
<p>“What is the <strong>probability</strong> that this regimen
<strong>will cover</strong> the pathogen, given the syndrome?”</p>
</blockquote>
<p>This means combining two quantities:</p>
<ul>
<li>
<strong>Pathogen incidence</strong> in the syndrome (how often each
species causes it),</li>
<li>
<strong>Susceptibility</strong> of each pathogen to the
regimen.</li>
</ul>
<p>We can write this as:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Coverage</mtext><mo>=</mo><munder><mo></mo><mi>i</mi></munder><mo stretchy="false" form="prefix">(</mo><msub><mtext mathvariant="normal">Incidence</mtext><mi>i</mi></msub><mo>×</mo><msub><mtext mathvariant="normal">Susceptibility</mtext><mi>i</mi></msub><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\text{Coverage} = \sum_i (\text{Incidence}_i \times \text{Susceptibility}_i)</annotation></semantics></math></p>
<p>For example, suppose in your hospital:</p>
<ul>
<li>
<em>E. coli</em> causes 60% of UTIs, and 90% of <em>E. coli</em> are
susceptible to a drug.</li>
<li>
<em>Klebsiella</em> causes 40% of UTIs, and 70% of
<em>Klebsiella</em> are susceptible.</li>
</ul>
<p>Then:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Coverage</mtext><mo>=</mo><mo stretchy="false" form="prefix">(</mo><mn>0.6</mn><mo>×</mo><mn>0.9</mn><mo stretchy="false" form="postfix">)</mo><mo>+</mo><mo stretchy="false" form="prefix">(</mo><mn>0.4</mn><mo>×</mo><mn>0.7</mn><mo stretchy="false" form="postfix">)</mo><mo>=</mo><mn>0.82</mn></mrow><annotation encoding="application/x-tex">\text{Coverage} = (0.6 \times 0.9) + (0.4 \times 0.7) = 0.82</annotation></semantics></math></p>
<p>That 82% is a far more clinically meaningful number than the
species-level “90% of <em>E. coli</em>” and “70% of <em>Klebsiella</em>
reported separately in a traditional antibiogram, because it directly
answers the question the clinician actually faces.</p>
<p>But in real data, both incidence and susceptibility are
<strong>estimated from finite samples</strong>, so they carry
uncertainty. A sample of 50 isolates is not a census. WISCA models this
uncertainty <strong>probabilistically</strong>, using conjugate Bayesian
distributions.</p>
</div>
<div class="section level2">
<h2 id="the-bayesian-engine">The Bayesian engine<a class="anchor" aria-label="anchor" href="#the-bayesian-engine"></a>
</h2>
<div class="section level3">
<h3 id="pathogen-incidence">Pathogen incidence<a class="anchor" aria-label="anchor" href="#pathogen-incidence"></a>
</h3>
<p>Let:</p>
<ul>
<li>
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>K</mi><annotation encoding="application/x-tex">K</annotation></semantics></math>
be the number of pathogens,</li>
<li>
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝛂</mi><mo>=</mo><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo>,</mo><mn>1</mn><mo>,</mo><mi></mi><mo>,</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\boldsymbol{\alpha} = (1, 1, \ldots, 1)</annotation></semantics></math>
be a
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mtext mathvariant="normal">Dirichlet</mtext><annotation encoding="application/x-tex">\text{Dirichlet}</annotation></semantics></math>
prior (uniform, non-informative),</li>
<li>
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝐧</mi><mo>=</mo><mo stretchy="false" form="prefix">(</mo><msub><mi>n</mi><mn>1</mn></msub><mo>,</mo><mi></mi><mo>,</mo><msub><mi>n</mi><mi>K</mi></msub><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\boldsymbol{n} = (n_1, \ldots, n_K)</annotation></semantics></math>
be the observed isolate counts per species.</li>
</ul>
<p>Then the posterior incidence is:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝐩</mi><mo></mo><mtext mathvariant="normal">Dirichlet</mtext><mo stretchy="false" form="prefix">(</mo><msub><mi>α</mi><mn>1</mn></msub><mo>+</mo><msub><mi>n</mi><mn>1</mn></msub><mo>,</mo><mi></mi><mo>,</mo><msub><mi>α</mi><mi>K</mi></msub><mo>+</mo><msub><mi>n</mi><mi>K</mi></msub><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\boldsymbol{p} \sim \text{Dirichlet}(\alpha_1 + n_1, \ldots, \alpha_K + n_K)</annotation></semantics></math></p>
<p>To simulate from this, we use:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>x</mi><mi>i</mi></msub><mo></mo><mtext mathvariant="normal">Gamma</mtext><mo stretchy="false" form="prefix">(</mo><msub><mi>α</mi><mi>i</mi></msub><mo>+</mo><msub><mi>n</mi><mi>i</mi></msub><mo>,</mo><mspace width="0.222em"></mspace><mn>1</mn><mo stretchy="false" form="postfix">)</mo><mo>,</mo><mspace width="1.0em"></mspace><msub><mi>p</mi><mi>i</mi></msub><mo>=</mo><mfrac><msub><mi>x</mi><mi>i</mi></msub><mrow><munderover><mo></mo><mrow><mi>j</mi><mo>=</mo><mn>1</mn></mrow><mi>K</mi></munderover><msub><mi>x</mi><mi>j</mi></msub></mrow></mfrac></mrow><annotation encoding="application/x-tex">x_i \sim \text{Gamma}(\alpha_i + n_i,\ 1), \quad p_i = \frac{x_i}{\sum_{j=1}^{K} x_j}</annotation></semantics></math></p>
<p>The Dirichlet is the conjugate prior for multinomial data. With the
non-informative prior
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Dirichlet</mtext><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo>,</mo><mn>1</mn><mo>,</mo><mi></mi><mo>,</mo><mn>1</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\text{Dirichlet}(1, 1, \ldots, 1)</annotation></semantics></math>,
the posterior is dominated by the data once sample sizes are reasonable.
With small samples, the posterior is appropriately more diffuse,
reflecting genuine uncertainty, and the resulting credible intervals
will be wider.</p>
</div>
<div class="section level3">
<h3 id="susceptibility">Susceptibility<a class="anchor" aria-label="anchor" href="#susceptibility"></a>
</h3>
<p>Each pathogen-regimen pair has a prior and observed data:</p>
<ul>
<li>Default prior:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Beta</mtext><mo stretchy="false" form="prefix">(</mo><mn>0.5</mn><mo>,</mo><mn>0.5</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\text{Beta}(0.5, 0.5)</annotation></semantics></math>
(Jeffreys prior)</li>
<li>Intrinsically resistant pairs:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Beta</mtext><mo stretchy="false" form="prefix">(</mo><mn>1</mn><mo>,</mo><mn>9999</mn><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\text{Beta}(1, 9999)</annotation></semantics></math>,
forcing near-zero susceptibility regardless of observed data (based on
EUCAST Expected Resistant Phenotypes)</li>
<li>Data:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>S</mi><annotation encoding="application/x-tex">S</annotation></semantics></math>
susceptible out of
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>N</mi><annotation encoding="application/x-tex">N</annotation></semantics></math>
tested</li>
</ul>
<p>The
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mi>S</mi><annotation encoding="application/x-tex">S</annotation></semantics></math>
category could also include values SDD (susceptible, dose-dependent) and
I (intermediate [CLSI], or susceptible, increased exposure
[EUCAST]).</p>
<p>Then the posterior is:</p>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>θ</mi><mo></mo><mtext mathvariant="normal">Beta</mtext><mo stretchy="false" form="prefix">(</mo><msub><mi>α</mi><mn>0</mn></msub><mo>+</mo><mi>S</mi><mo>,</mo><mspace width="0.222em"></mspace><msub><mi>β</mi><mn>0</mn></msub><mo>+</mo><mi>N</mi><mo></mo><mi>S</mi><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\theta \sim \text{Beta}(\alpha_0 + S,\ \beta_0 + N - S)</annotation></semantics></math></p>
</div>
<div class="section level3">
<h3 id="final-coverage-estimate">Final coverage estimate<a class="anchor" aria-label="anchor" href="#final-coverage-estimate"></a>
</h3>
<p>Putting it together:</p>
<ol style="list-style-type: decimal">
<li>Simulate pathogen incidence:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>𝐩</mi><mo></mo><mtext mathvariant="normal">Dirichlet</mtext></mrow><annotation encoding="application/x-tex">\boldsymbol{p} \sim \text{Dirichlet}</annotation></semantics></math>
</li>
<li>Simulate susceptibility:
<math display="inline" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><msub><mi>θ</mi><mi>i</mi></msub><mo></mo><mtext mathvariant="normal">Beta</mtext><mo stretchy="false" form="prefix">(</mo><msub><mi>α</mi><mn>0</mn></msub><mo>+</mo><msub><mi>S</mi><mi>i</mi></msub><mo>,</mo><mspace width="0.222em"></mspace><msub><mi>β</mi><mn>0</mn></msub><mo>+</mo><msub><mi>N</mi><mi>i</mi></msub><mo></mo><msub><mi>S</mi><mi>i</mi></msub><mo stretchy="false" form="postfix">)</mo></mrow><annotation encoding="application/x-tex">\theta_i \sim \text{Beta}(\alpha_0 + S_i,\ \beta_0 + N_i - S_i)</annotation></semantics></math>
</li>
<li>Combine:</li>
</ol>
<p><math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mtext mathvariant="normal">Coverage</mtext><mo>=</mo><munderover><mo></mo><mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow><mi>K</mi></munderover><msub><mi>p</mi><mi>i</mi></msub><mo></mo><msub><mi>θ</mi><mi>i</mi></msub></mrow><annotation encoding="application/x-tex">\text{Coverage} = \sum_{i=1}^{K} p_i \cdot \theta_i</annotation></semantics></math></p>
<p>Repeat this simulation (e.g., 1000 times) and summarise:</p>
<ul>
<li>
<strong>Mean</strong> = expected coverage</li>
<li>
<strong>Quantiles</strong> = credible interval (95% by default)</li>
</ul>
<p>Because each simulation draws from the full posterior, the resulting
distribution of coverage estimates naturally captures the joint
uncertainty in both pathogen incidence and susceptibility. The credible
interval tells you how confident you can be in the coverage estimate,
something a traditional antibiogram never provides.</p>
</div>
</div>
<div class="section level2">
<h2 id="when-to-use-wisca-vs--traditional-antibiograms">When to use WISCA vs. traditional antibiograms<a class="anchor" aria-label="anchor" href="#when-to-use-wisca-vs--traditional-antibiograms"></a>
</h2>
<table class="table">
<thead><tr class="header">
<th>Goal</th>
<th>Recommended approach</th>
</tr></thead>
<tbody>
<tr class="odd">
<td>Guide empirical therapy decisions</td>
<td><strong>WISCA</strong></td>
</tr>
<tr class="even">
<td>Compare regimens for a syndrome</td>
<td><strong>WISCA</strong></td>
</tr>
<tr class="odd">
<td>Evaluate combination regimens</td>
<td><strong>WISCA</strong></td>
</tr>
<tr class="even">
<td>Antimicrobial stewardship (A-team)</td>
<td><strong>WISCA</strong></td>
</tr>
<tr class="odd">
<td>Track resistance trends per species</td>
<td>Traditional / Combination</td>
</tr>
<tr class="even">
<td>AMR surveillance reporting</td>
<td>Traditional / Syndromic</td>
</tr>
<tr class="odd">
<td>Understand species-level epidemiology</td>
<td>Traditional</td>
</tr>
</tbody>
</table>
<p>In short: if the end goal involves a <em>patient</em> who does not
yet have a culture result, WISCA is the appropriate tool. If the end
goal is <em>surveillance</em> of resistance at the species level, the
traditional antibiogram remains fit for purpose.</p>
</div>
<div class="section level2">
<h2 id="practical-use-in-the-amr-package">Practical use in the <code>AMR</code> package<a class="anchor" aria-label="anchor" href="#practical-use-in-the-amr-package"></a>
</h2>
<div class="section level3">
<h3 id="prepare-data">Prepare data<a class="anchor" aria-label="anchor" href="#prepare-data"></a>
</h3>
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="kw"><a href="https://rdrr.io/r/base/library.html" class="external-link">library</a></span><span class="op">(</span><span class="va"><a href="https://amr-for-r.org">AMR</a></span><span class="op">)</span></span>
<span><span class="va">data</span> <span class="op">&lt;-</span> <span class="va">example_isolates</span></span>
<span></span>
<span><span class="co"># Structure of our data</span></span>
<span><span class="va">data</span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># A tibble: 2,000 × 46</span></span></span>
<span><span class="co">#&gt; date patient age gender ward mo PEN OXA FLC AMX </span></span>
<span><span class="co">#&gt; <span style="color: #949494; font-style: italic;">&lt;date&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;dbl&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;chr&gt;</span> <span style="color: #949494; font-style: italic;">&lt;mo&gt;</span> <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span> <span style="color: #949494; font-style: italic;">&lt;sir&gt;</span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 1</span> 2002-01-02 A77334 65 F Clinical <span style="color: #949494;">B_</span>ESCHR<span style="color: #949494;">_</span>COLI <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #949494;"> NA</span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 2</span> 2002-01-03 A77334 65 F Clinical <span style="color: #949494;">B_</span>ESCHR<span style="color: #949494;">_</span>COLI <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #949494;"> NA</span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 3</span> 2002-01-07 067927 45 F ICU <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>EPDR <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 4</span> 2002-01-07 067927 45 F ICU <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>EPDR <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 5</span> 2002-01-13 067927 45 F ICU <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>EPDR <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 6</span> 2002-01-13 067927 45 F ICU <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>EPDR <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 7</span> 2002-01-14 462729 78 M Clinical <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>AURS <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #5FD7AF;"> S </span> <span style="color: #080808; background-color: #FF5F5F;"> R </span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 8</span> 2002-01-14 462729 78 M Clinical <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>AURS <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #5FD7AF;"> S </span> <span style="color: #080808; background-color: #FF5F5F;"> R </span></span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;"> 9</span> 2002-01-16 067927 45 F ICU <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>EPDR <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #BCBCBC;">10</span> 2002-01-17 858515 79 F ICU <span style="color: #949494;">B_</span>STPHY<span style="color: #949494;">_</span>EPDR <span style="color: #080808; background-color: #FF5F5F;"> R </span> <span style="color: #949494;"> NA</span> <span style="color: #080808; background-color: #5FD7AF;"> S </span> <span style="color: #949494;"> NA</span> </span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># 1,990 more rows</span></span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># 36 more variables: AMC &lt;sir&gt;, AMP &lt;sir&gt;, TZP &lt;sir&gt;, CZO &lt;sir&gt;, FEP &lt;sir&gt;,</span></span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># CXM &lt;sir&gt;, FOX &lt;sir&gt;, CTX &lt;sir&gt;, CAZ &lt;sir&gt;, CRO &lt;sir&gt;, GEN &lt;sir&gt;,</span></span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># TOB &lt;sir&gt;, AMK &lt;sir&gt;, KAN &lt;sir&gt;, TMP &lt;sir&gt;, SXT &lt;sir&gt;, NIT &lt;sir&gt;,</span></span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># FOS &lt;sir&gt;, LNZ &lt;sir&gt;, CIP &lt;sir&gt;, MFX &lt;sir&gt;, VAN &lt;sir&gt;, TEC &lt;sir&gt;,</span></span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># TCY &lt;sir&gt;, TGC &lt;sir&gt;, DOX &lt;sir&gt;, ERY &lt;sir&gt;, CLI &lt;sir&gt;, AZM &lt;sir&gt;,</span></span></span>
<span><span class="co">#&gt; <span style="color: #949494;"># IPM &lt;sir&gt;, MEM &lt;sir&gt;, MTR &lt;sir&gt;, CHL &lt;sir&gt;, COL &lt;sir&gt;, MUP &lt;sir&gt;, …</span></span></span>
<span></span>
<span><span class="co"># Add a synthetic syndrome column for demonstration</span></span>
<span><span class="va">data</span><span class="op">$</span><span class="va">syndrome</span> <span class="op">&lt;-</span> <span class="fu"><a href="https://rdrr.io/r/base/ifelse.html" class="external-link">ifelse</a></span><span class="op">(</span><span class="va">data</span><span class="op">$</span><span class="va">mo</span> <span class="op"><a href="../reference/like.html">%like%</a></span> <span class="st">"coli"</span>, <span class="st">"UTI"</span>, <span class="st">"Non-UTI"</span><span class="op">)</span></span>
<span></span>
<span><span class="co"># Keep only 10 most common microorganisms</span></span>
<span><span class="va">data</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/top_n_microorganisms.html">top_n_microorganisms</a></span><span class="op">(</span><span class="va">data</span>, n <span class="op">=</span> <span class="fl">10</span>, property <span class="op">=</span> <span class="st">"species"</span><span class="op">)</span></span>
<span><span class="co">#&gt; <span style="color: #00BBBB;"></span> Using column <span style="color: #00BB00; font-weight: bold;">mo</span> as input for `col_mo`.</span></span></code></pre></div>
</div>
<div class="section level3">
<h3 id="basic-wisca">Basic WISCA<a class="anchor" aria-label="anchor" href="#basic-wisca"></a>
</h3>
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/antibiogram.html">wisca</a></span><span class="op">(</span><span class="va">data</span>,</span>
<span> antimicrobials <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"AMC"</span>, <span class="st">"CIP"</span>, <span class="st">"GEN"</span><span class="op">)</span></span>
<span><span class="op">)</span></span></code></pre></div>
<table class="table">
<thead><tr class="header">
<th align="left">Amoxicillin/clavulanic acid</th>
<th align="left">Ciprofloxacin</th>
<th align="left">Gentamicin</th>
</tr></thead>
<tbody><tr class="odd">
<td align="left">76.8% (74.7-79.1%)</td>
<td align="left">81.5% (78.9-84.1%)</td>
<td align="left">82.9% (81-84.8%)</td>
</tr></tbody>
</table>
</div>
<div class="section level3">
<h3 id="use-combination-regimens">Use combination regimens<a class="anchor" aria-label="anchor" href="#use-combination-regimens"></a>
</h3>
<p>Combination regimens are specified with a <code>+</code> separator.
WISCA evaluates whether <em>at least one</em> agent in the combination
covers the pathogen:</p>
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/antibiogram.html">wisca</a></span><span class="op">(</span><span class="va">data</span>,</span>
<span> antimicrobials <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"AMC"</span>, <span class="st">"AMC + CIP"</span>, <span class="st">"AMC + GEN"</span><span class="op">)</span></span>
<span><span class="op">)</span></span></code></pre></div>
<table class="table">
<colgroup>
<col width="24%">
<col width="38%">
<col width="36%">
</colgroup>
<thead><tr class="header">
<th align="left">Amoxicillin/clavulanic acid</th>
<th align="left">Amoxicillin/clavulanic acid + Ciprofloxacin</th>
<th align="left">Amoxicillin/clavulanic acid + Gentamicin</th>
</tr></thead>
<tbody><tr class="odd">
<td align="left">76.8% (74.6-78.9%)</td>
<td align="left">89.6% (88-91.1%)</td>
<td align="left">93.7% (92.5-94.9%)</td>
</tr></tbody>
</table>
</div>
<div class="section level3">
<h3 id="stratify-by-syndrome">Stratify by syndrome<a class="anchor" aria-label="anchor" href="#stratify-by-syndrome"></a>
</h3>
<p>Use <code>syndromic_group</code> to produce separate WISCA estimates
per clinical stratum. You can pass a column name or any expression:</p>
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="va">wisca_out</span> <span class="op">&lt;-</span> <span class="fu"><a href="../reference/antibiogram.html">wisca</a></span><span class="op">(</span><span class="va">data</span>,</span>
<span> antimicrobials <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"AMC"</span>, <span class="st">"AMC + CIP"</span>, <span class="st">"AMC + GEN"</span><span class="op">)</span>,</span>
<span> syndromic_group <span class="op">=</span> <span class="st">"syndrome"</span></span>
<span><span class="op">)</span></span>
<span><span class="va">wisca_out</span></span></code></pre></div>
<table class="table">
<colgroup>
<col width="12%">
<col width="21%">
<col width="34%">
<col width="31%">
</colgroup>
<thead><tr class="header">
<th align="left">Syndromic Group</th>
<th align="left">Amoxicillin/clavulanic acid</th>
<th align="left">Amoxicillin/clavulanic acid + Ciprofloxacin</th>
<th align="left">Amoxicillin/clavulanic acid + Gentamicin</th>
</tr></thead>
<tbody>
<tr class="odd">
<td align="left">Non-UTI</td>
<td align="left">72.5% (69.9-75.1%)</td>
<td align="left">86.9% (84.8-89%)</td>
<td align="left">91.4% (89.5-93%)</td>
</tr>
<tr class="even">
<td align="left">UTI</td>
<td align="left">86% (82.5-89%)</td>
<td align="left">94.8% (92.5-96.6%)</td>
<td align="left">97.9% (96.3-99%)</td>
</tr>
</tbody>
</table>
<p>The <code>AMR</code> package is available in 28 languages, which can
all be used for the <code><a href="../reference/antibiogram.html">wisca()</a></code> function too:</p>
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/antibiogram.html">wisca</a></span><span class="op">(</span><span class="va">data</span>,</span>
<span> antimicrobials <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/c.html" class="external-link">c</a></span><span class="op">(</span><span class="st">"AMC"</span>, <span class="st">"AMC + CIP"</span>, <span class="st">"AMC + GEN"</span><span class="op">)</span>,</span>
<span> syndromic_group <span class="op">=</span> <span class="fu"><a href="https://rdrr.io/r/base/grep.html" class="external-link">gsub</a></span><span class="op">(</span><span class="st">"UTI"</span>, <span class="st">"UCI"</span>, <span class="va">data</span><span class="op">$</span><span class="va">syndrome</span><span class="op">)</span>,</span>
<span> language <span class="op">=</span> <span class="st">"Spanish"</span></span>
<span><span class="op">)</span></span></code></pre></div>
<table class="table">
<colgroup>
<col width="12%">
<col width="21%">
<col width="34%">
<col width="31%">
</colgroup>
<thead><tr class="header">
<th align="left">Grupo sindrómico</th>
<th align="left">Amoxicilina/ácido clavulánico</th>
<th align="left">Amoxicilina/ácido clavulánico + Ciprofloxacina</th>
<th align="left">Amoxicilina/ácido clavulánico + Gentamicina</th>
</tr></thead>
<tbody>
<tr class="odd">
<td align="left">Non-UCI</td>
<td align="left">72.6% (69.9-75.3%)</td>
<td align="left">87% (84.9-89.1%)</td>
<td align="left">91.4% (89.7-92.9%)</td>
</tr>
<tr class="even">
<td align="left">UCI</td>
<td align="left">86% (82.7-89%)</td>
<td align="left">94.8% (92.7-96.4%)</td>
<td align="left">97.9% (96.5-99%)</td>
</tr>
</tbody>
</table>
</div>
<div class="section level3">
<h3 id="interpreting-the-output">Interpreting the output<a class="anchor" aria-label="anchor" href="#interpreting-the-output"></a>
</h3>
<p>Each row shows the estimated empirical coverage for a regimen, with a
95% credible interval. When comparing regimens:</p>
<ul>
<li>
<strong>Overlapping credible intervals</strong> mean there is no
statistically significant difference in coverage. If a narrower-spectrum
regimen overlaps with a broader one, the narrower-spectrum option can be
preferred on stewardship grounds.</li>
<li>
<strong>Non-overlapping credible intervals</strong> indicate a
clinically meaningful difference in coverage.</li>
</ul>
</div>
<div class="section level3">
<h3 id="plotting">Plotting<a class="anchor" aria-label="anchor" href="#plotting"></a>
</h3>
<p>WISCA results can be visualised in several ways. All plot functions
work on the output of <code><a href="../reference/antibiogram.html">wisca()</a></code> (or
<code>antibiogram(..., wisca = TRUE)</code>).</p>
<p>Below we use the <code>wisca_out</code> object that was generated
above.</p>
<div class="section level4">
<h4 id="coverage-with-credible-intervals">Coverage with credible intervals<a class="anchor" aria-label="anchor" href="#coverage-with-credible-intervals"></a>
</h4>
<p>The extended <code><a href="https://ggplot2.tidyverse.org/reference/autoplot.html" class="external-link">autoplot()</a></code> method from the
<code>ggplot2()</code> package produces a point-and-interval plot
showing the coverage estimate and 95% credible interval for each
regimen, grouped by syndromic stratum. This is the most direct way to
compare regimens: overlapping intervals suggest clinical
non-inferiority, non-overlapping intervals indicate a meaningful
difference.</p>
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu">ggplot2</span><span class="fu">::</span><span class="fu"><a href="https://ggplot2.tidyverse.org/reference/autoplot.html" class="external-link">autoplot</a></span><span class="op">(</span><span class="va">wisca_out</span><span class="op">)</span></span></code></pre></div>
<p><img src="WISCA_files/figure-html/unnamed-chunk-6-1.png" class="r-plt" alt="" width="720"></p>
</div>
<div class="section level4">
<h4 id="susceptibility-vs--incidence-weight">Susceptibility vs. incidence weight<a class="anchor" aria-label="anchor" href="#susceptibility-vs--incidence-weight"></a>
</h4>
<p><code><a href="../reference/antibiogram.html">wisca_plot()</a></code> produces a scatter plot of the Monte Carlo
simulation draws, showing each pathogens susceptibility (x-axis)
against its incidence weight (y-axis) for each regimen. Each dot
represents one of 1,000 simulated draws, so the spread reflects
posterior uncertainty. This plot reveals <em>why</em> a regimen achieves
its coverage: you can see which pathogens dominate the syndrome (high on
the y-axis), how susceptible they are (position on the x-axis), and how
uncertain both estimates are (spread of the cloud). The dashed vertical
lines denote the point estimates, i.e., the coverage percentages. The
ribbon behind the dashed lines denote the credible interval, which is
95% at default.</p>
<div class="sourceCode" id="cb7"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/antibiogram.html">wisca_plot</a></span><span class="op">(</span><span class="va">wisca_out</span><span class="op">)</span></span></code></pre></div>
<p><img src="WISCA_files/figure-html/unnamed-chunk-7-1.png" class="r-plt" alt="" width="720"></p>
</div>
<div class="section level4">
<h4 id="posterior-coverage-distributions">Posterior coverage distributions<a class="anchor" aria-label="anchor" href="#posterior-coverage-distributions"></a>
</h4>
<p>Setting <code>wisca_plot_type = "posterior_coverage"</code> shows the
full posterior distribution of coverage for each regimen as a density
curve. This is the most complete representation of what the Bayesian
model produces: each curve shows the relative likelihood of each
coverage value across all 1,000 simulations. Narrow, tall peaks indicate
high certainty; wide, flat curves indicate greater uncertainty. Where
two curves overlap, the regimens cannot be confidently
distinguished.</p>
<div class="sourceCode" id="cb8"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/antibiogram.html">wisca_plot</a></span><span class="op">(</span><span class="va">wisca_out</span>, wisca_plot_type <span class="op">=</span> <span class="st">"posterior_coverage"</span><span class="op">)</span></span></code></pre></div>
<p><img src="WISCA_files/figure-html/unnamed-chunk-8-1.png" class="r-plt" alt="" width="720"></p>
</div>
</div>
</div>
<div class="section level2">
<h2 id="sensible-defaults-which-can-be-customised">Sensible defaults, which can be customised<a class="anchor" aria-label="anchor" href="#sensible-defaults-which-can-be-customised"></a>
</h2>
<ul>
<li>
<code>simulations = 1000</code>: number of Monte Carlo draws</li>
<li>
<code>conf_interval = 0.95</code>: coverage interval width</li>
<li>
<code>combine_SI = TRUE</code>: count “I” and “SDD” as
susceptible</li>
</ul>
</div>
<div class="section level2">
<h2 id="practical-considerations">Practical considerations<a class="anchor" aria-label="anchor" href="#practical-considerations"></a>
</h2>
<ul>
<li>
<strong>First isolates only</strong>: always deduplicate using
<code><a href="../reference/first_isolate.html">first_isolate()</a></code> before running WISCA. Repeat isolates
introduce bias.</li>
<li>
<strong>Pathogen selection</strong>: consider filtering with
<code><a href="../reference/top_n_microorganisms.html">top_n_microorganisms()</a></code>. Including rare contaminants
(e.g. CoNS without clinical context) can distort estimates and may
artificially lower coverage (Cook <em>et al.</em>, 2022).</li>
<li>
<strong>Sample size</strong>: coverage estimates become reliable
with approximately 100+ isolates. For smaller datasets, consider pooling
data from multiple sites, but only after verifying that pathogen
distributions are sufficiently similar (Bielicki <em>et al.</em>,
2016).</li>
<li>
<strong>Culture request bias</strong>: WISCA is only as good as the
data it is based on. If cultures are selectively requested (e.g. only
after treatment failure), the dataset will be biased towards resistant
isolates. A robust culture policy is essential for reliable
estimates.</li>
</ul>
</div>
<div class="section level2">
<h2 id="limitations">Limitations<a class="anchor" aria-label="anchor" href="#limitations"></a>
</h2>
<ul>
<li>It assumes your data are representative of the patient population
you are treating</li>
<li>No direct adjustment for patient-level covariates, although these
can be passed onto the <code>syndromic_group</code> argument for
stratification</li>
<li>WISCA does not model resistance trends over time; for that, you
might want to use <code>tidymodels</code>, for which we <a href="https://amr-for-r.org/articles/AMR_with_tidymodels.html">wrote a
basic introduction</a>
</li>
</ul>
</div>
<div class="section level2">
<h2 id="summary">Summary<a class="anchor" aria-label="anchor" href="#summary"></a>
</h2>
<p>WISCA enables:</p>
<ul>
<li>
<strong>Empirical regimen comparison</strong>, answering the
clinicians actual question</li>
<li>
<strong>Syndrome-specific coverage estimation</strong>, stratifiable
by any clinical variable</li>
<li>
<strong>Fully probabilistic interpretation</strong>, with credible
intervals that honestly communicate uncertainty</li>
</ul>
<p>It is available in the <code>AMR</code> package via either:</p>
<div class="sourceCode" id="cb9"><pre class="downlit sourceCode r">
<code class="sourceCode R"><span><span class="fu"><a href="../reference/antibiogram.html">wisca</a></span><span class="op">(</span><span class="va">...</span><span class="op">)</span></span>
<span></span>
<span><span class="fu"><a href="../reference/antibiogram.html">antibiogram</a></span><span class="op">(</span><span class="va">...</span>, wisca <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></span></code></pre></div>
</div>
<div class="section level2">
<h2 id="references">References<a class="anchor" aria-label="anchor" href="#references"></a>
</h2>
<ol style="list-style-type: decimal">
<li>Hebert C, Ridgway J, Vekhter B, Brown EC, Weber SG, Robicsek A.
Demonstration of the weighted-incidence syndromic combination
antibiogram: an empiric prescribing decision aid. <em>Infect Control
Hosp Epidemiol.</em> 2012;33(4):381-388. <a href="https://doi.org/10.1086/664768" class="external-link uri">https://doi.org/10.1086/664768</a>
</li>
<li>Randhawa V, Sarwar S, Walker S, Elligsen M, Palmay L, Daneman N.
Weighted-incidence syndromic combination antibiograms to guide empiric
treatment of critical care infections: a retrospective cohort study.
<em>Crit Care.</em> 2014;18(3):R112. <a href="https://doi.org/10.1186/cc13901" class="external-link uri">https://doi.org/10.1186/cc13901</a>
</li>
<li>Bielicki JA, Sharland M, Johnson AP, Henderson KL, Cromwell DA.
Selecting appropriate empirical antibiotic regimens for paediatric
bloodstream infections: application of a Bayesian decision model to
local and pooled antimicrobial resistance surveillance data. <em>J
Antimicrob Chemother.</em> 2016;71(3):794-802. <a href="https://doi.org/10.1093/jac/dkv397" class="external-link uri">https://doi.org/10.1093/jac/dkv397</a>
</li>
<li>Cook A, Sharland M, Yau Y, Bielicki J. Improving empiric antibiotic
prescribing in pediatric bloodstream infections: a potential application
of weighted-incidence syndromic combination antibiograms (WISCA).
<em>Expert Rev Anti Infect Ther.</em> 2022;20(3):445-456. <a href="https://doi.org/10.1080/14787210.2021.1967145" class="external-link uri">https://doi.org/10.1080/14787210.2021.1967145</a>
</li>
</ol>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside>
</div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer>
</div>
</body>
</html>
-443
View File
@@ -1,443 +0,0 @@
# Estimating Empirical Coverage with WISCA
## Why WISCA?
When a clinician starts empirical antimicrobial therapy, the causative
pathogen is unknown. The question they need answered is not *“what
proportion of* E. coli *is susceptible to ciprofloxacin?“* but rather
*“what is the probability that this regimen will adequately cover
whatever pathogen turns out to be causing my patients infection?”*
The traditional cumulative antibiogram, as standardised by CLSI M39,
cannot answer that question. It presents susceptibility percentages per
species per antibiotic, but:
- **It fragments information by organism.** The clinician must mentally
combine susceptibility rates across multiple species, weighting by how
often each species causes the syndrome, a calculation nobody does at
the bedside.
- **It ignores pathogen incidence.** A species that causes 2% of
infections is given the same visual weight as one that causes 60%.
- **It does not evaluate combination regimens.** Much empirical therapy
consists of two or more agents, but the traditional antibiogram only
shows monotherapy per organism.
- **It provides no measure of uncertainty.** A reported “90%
susceptible” based on 50 isolates has a 95% confidence interval of
roughly 78-97% (Clopper-Pearson), yet the antibiogram presents it as a
point estimate without context.
**WISCA** (Weighted-Incidence Syndromic Combination Antibiogram)
resolves all four limitations. It estimates the probability that a
regimen will provide adequate empirical coverage for a given infection
syndrome, weighted by local pathogen incidence, with full uncertainty
quantification via Bayesian inference.
The concept was introduced by Hebert *et al.* (2012), who demonstrated
that traditional antibiogram susceptibility rates could be misleading:
ciprofloxacin appeared 84% effective against *E. coli* in the
traditional antibiogram, but WISCA revealed only 62% coverage for UTI
and 37% for abdominal infections, because enterococci (intrinsically
resistant) and other species contribute substantially to these
syndromes. Randhawa *et al.* (2014) showed that WISCA-guided regimen
selection could improve time-to-adequate-coverage on the ICU by over
40%. Bielicki *et al.* (2016) introduced the Bayesian framework now used
in this package, enabling credible intervals and multi-centre pooling.
Cook *et al.* (2022) applied it globally across 52 hospitals in 23
countries.
## The idea
WISCA asks:
> “What is the **probability** that this regimen **will cover** the
> pathogen, given the syndrome?”
This means combining two quantities:
- **Pathogen incidence** in the syndrome (how often each species causes
it),
- **Susceptibility** of each pathogen to the regimen.
We can write this as:
``` math
\text{Coverage} = \sum_i (\text{Incidence}_i \times \text{Susceptibility}_i)
```
For example, suppose in your hospital:
- *E. coli* causes 60% of UTIs, and 90% of *E. coli* are susceptible to
a drug.
- *Klebsiella* causes 40% of UTIs, and 70% of *Klebsiella* are
susceptible.
Then:
``` math
\text{Coverage} = (0.6 \times 0.9) + (0.4 \times 0.7) = 0.82
```
That 82% is a far more clinically meaningful number than the
species-level “90% of *E. coli*” and “70% of *Klebsiella*” reported
separately in a traditional antibiogram, because it directly answers the
question the clinician actually faces.
But in real data, both incidence and susceptibility are **estimated from
finite samples**, so they carry uncertainty. A sample of 50 isolates is
not a census. WISCA models this uncertainty **probabilistically**, using
conjugate Bayesian distributions.
## The Bayesian engine
### Pathogen incidence
Let:
- $`K`$ be the number of pathogens,
- $`\boldsymbol{\alpha} = (1, 1, \ldots, 1)`$ be a $`\text{Dirichlet}`$
prior (uniform, non-informative),
- $`\boldsymbol{n} = (n_1, \ldots, n_K)`$ be the observed isolate counts
per species.
Then the posterior incidence is:
``` math
\boldsymbol{p} \sim \text{Dirichlet}(\alpha_1 + n_1, \ldots, \alpha_K + n_K)
```
To simulate from this, we use:
``` math
x_i \sim \text{Gamma}(\alpha_i + n_i,\ 1), \quad p_i = \frac{x_i}{\sum_{j=1}^{K} x_j}
```
The Dirichlet is the conjugate prior for multinomial data. With the
non-informative prior $`\text{Dirichlet}(1, 1, \ldots, 1)`$, the
posterior is dominated by the data once sample sizes are reasonable.
With small samples, the posterior is appropriately more diffuse,
reflecting genuine uncertainty, and the resulting credible intervals
will be wider.
### Susceptibility
Each pathogen-regimen pair has a prior and observed data:
- Default prior: $`\text{Beta}(0.5, 0.5)`$ (Jeffreys prior)
- Intrinsically resistant pairs: $`\text{Beta}(1, 9999)`$, forcing
near-zero susceptibility regardless of observed data (based on EUCAST
Expected Resistant Phenotypes)
- Data: $`S`$ susceptible out of $`N`$ tested
The $`S`$ category could also include values SDD (susceptible,
dose-dependent) and I (intermediate \[CLSI\], or susceptible, increased
exposure \[EUCAST\]).
Then the posterior is:
``` math
\theta \sim \text{Beta}(\alpha_0 + S,\ \beta_0 + N - S)
```
### Final coverage estimate
Putting it together:
1. Simulate pathogen incidence:
$`\boldsymbol{p} \sim \text{Dirichlet}`$
2. Simulate susceptibility:
$`\theta_i \sim \text{Beta}(\alpha_0 + S_i,\ \beta_0 + N_i - S_i)`$
3. Combine:
``` math
\text{Coverage} = \sum_{i=1}^{K} p_i \cdot \theta_i
```
Repeat this simulation (e.g., 1000 times) and summarise:
- **Mean** = expected coverage
- **Quantiles** = credible interval (95% by default)
Because each simulation draws from the full posterior, the resulting
distribution of coverage estimates naturally captures the joint
uncertainty in both pathogen incidence and susceptibility. The credible
interval tells you how confident you can be in the coverage estimate,
something a traditional antibiogram never provides.
## When to use WISCA vs. traditional antibiograms
| Goal | Recommended approach |
|---------------------------------------|---------------------------|
| Guide empirical therapy decisions | **WISCA** |
| Compare regimens for a syndrome | **WISCA** |
| Evaluate combination regimens | **WISCA** |
| Antimicrobial stewardship (A-team) | **WISCA** |
| Track resistance trends per species | Traditional / Combination |
| AMR surveillance reporting | Traditional / Syndromic |
| Understand species-level epidemiology | Traditional |
In short: if the end goal involves a *patient* who does not yet have a
culture result, WISCA is the appropriate tool. If the end goal is
*surveillance* of resistance at the species level, the traditional
antibiogram remains fit for purpose.
## Practical use in the `AMR` package
### Prepare data
``` r
library(AMR)
data <- example_isolates
# Structure of our data
data
#> # A tibble: 2,000 × 46
#> date patient age gender ward mo PEN OXA FLC AMX
#> <date> <chr> <dbl> <chr> <chr> <mo> <sir> <sir> <sir> <sir>
#> 1 2002-01-02 A77334 65 F Clinical B_ESCHR_COLI R NA NA NA
#> 2 2002-01-03 A77334 65 F Clinical B_ESCHR_COLI R NA NA NA
#> 3 2002-01-07 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 4 2002-01-07 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 5 2002-01-13 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 6 2002-01-13 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 7 2002-01-14 462729 78 M Clinical B_STPHY_AURS R NA S R
#> 8 2002-01-14 462729 78 M Clinical B_STPHY_AURS R NA S R
#> 9 2002-01-16 067927 45 F ICU B_STPHY_EPDR R NA R NA
#> 10 2002-01-17 858515 79 F ICU B_STPHY_EPDR R NA S NA
#> # 1,990 more rows
#> # 36 more variables: AMC <sir>, AMP <sir>, TZP <sir>, CZO <sir>, FEP <sir>,
#> # CXM <sir>, FOX <sir>, CTX <sir>, CAZ <sir>, CRO <sir>, GEN <sir>,
#> # TOB <sir>, AMK <sir>, KAN <sir>, TMP <sir>, SXT <sir>, NIT <sir>,
#> # FOS <sir>, LNZ <sir>, CIP <sir>, MFX <sir>, VAN <sir>, TEC <sir>,
#> # TCY <sir>, TGC <sir>, DOX <sir>, ERY <sir>, CLI <sir>, AZM <sir>,
#> # IPM <sir>, MEM <sir>, MTR <sir>, CHL <sir>, COL <sir>, MUP <sir>, …
# Add a synthetic syndrome column for demonstration
data$syndrome <- ifelse(data$mo %like% "coli", "UTI", "Non-UTI")
# Keep only 10 most common microorganisms
data <- top_n_microorganisms(data, n = 10, property = "species")
#> Using column mo as input for `col_mo`.
```
### Basic WISCA
``` r
wisca(data,
antimicrobials = c("AMC", "CIP", "GEN")
)
```
| Amoxicillin/clavulanic acid | Ciprofloxacin | Gentamicin |
|:----------------------------|:-------------------|:-----------------|
| 76.8% (74.7-79.1%) | 81.5% (78.9-84.1%) | 82.9% (81-84.8%) |
### Use combination regimens
Combination regimens are specified with a `+` separator. WISCA evaluates
whether *at least one* agent in the combination covers the pathogen:
``` r
wisca(data,
antimicrobials = c("AMC", "AMC + CIP", "AMC + GEN")
)
```
| Amoxicillin/clavulanic acid | Amoxicillin/clavulanic acid + Ciprofloxacin | Amoxicillin/clavulanic acid + Gentamicin |
|:---|:---|:---|
| 76.8% (74.6-78.9%) | 89.6% (88-91.1%) | 93.7% (92.5-94.9%) |
### Stratify by syndrome
Use `syndromic_group` to produce separate WISCA estimates per clinical
stratum. You can pass a column name or any expression:
``` r
wisca_out <- wisca(data,
antimicrobials = c("AMC", "AMC + CIP", "AMC + GEN"),
syndromic_group = "syndrome"
)
wisca_out
```
| Syndromic Group | Amoxicillin/clavulanic acid | Amoxicillin/clavulanic acid + Ciprofloxacin | Amoxicillin/clavulanic acid + Gentamicin |
|:---|:---|:---|:---|
| Non-UTI | 72.5% (69.9-75.1%) | 86.9% (84.8-89%) | 91.4% (89.5-93%) |
| UTI | 86% (82.5-89%) | 94.8% (92.5-96.6%) | 97.9% (96.3-99%) |
The `AMR` package is available in 28 languages, which can all be used
for the [`wisca()`](https://amr-for-r.org/reference/antibiogram.md)
function too:
``` r
wisca(data,
antimicrobials = c("AMC", "AMC + CIP", "AMC + GEN"),
syndromic_group = gsub("UTI", "UCI", data$syndrome),
language = "Spanish"
)
```
| Grupo sindrómico | Amoxicilina/ácido clavulánico | Amoxicilina/ácido clavulánico + Ciprofloxacina | Amoxicilina/ácido clavulánico + Gentamicina |
|:---|:---|:---|:---|
| Non-UCI | 72.6% (69.9-75.3%) | 87% (84.9-89.1%) | 91.4% (89.7-92.9%) |
| UCI | 86% (82.7-89%) | 94.8% (92.7-96.4%) | 97.9% (96.5-99%) |
### Interpreting the output
Each row shows the estimated empirical coverage for a regimen, with a
95% credible interval. When comparing regimens:
- **Overlapping credible intervals** mean there is no statistically
significant difference in coverage. If a narrower-spectrum regimen
overlaps with a broader one, the narrower-spectrum option can be
preferred on stewardship grounds.
- **Non-overlapping credible intervals** indicate a clinically
meaningful difference in coverage.
### Plotting
WISCA results can be visualised in several ways. All plot functions work
on the output of
[`wisca()`](https://amr-for-r.org/reference/antibiogram.md) (or
`antibiogram(..., wisca = TRUE)`).
Below we use the `wisca_out` object that was generated above.
#### Coverage with credible intervals
The extended
[`autoplot()`](https://ggplot2.tidyverse.org/reference/autoplot.html)
method from the `ggplot2()` package produces a point-and-interval plot
showing the coverage estimate and 95% credible interval for each
regimen, grouped by syndromic stratum. This is the most direct way to
compare regimens: overlapping intervals suggest clinical
non-inferiority, non-overlapping intervals indicate a meaningful
difference.
``` r
ggplot2::autoplot(wisca_out)
```
![](WISCA_files/figure-html/unnamed-chunk-6-1.png)
#### Susceptibility vs. incidence weight
[`wisca_plot()`](https://amr-for-r.org/reference/antibiogram.md)
produces a scatter plot of the Monte Carlo simulation draws, showing
each pathogens susceptibility (x-axis) against its incidence weight
(y-axis) for each regimen. Each dot represents one of 1,000 simulated
draws, so the spread reflects posterior uncertainty. This plot reveals
*why* a regimen achieves its coverage: you can see which pathogens
dominate the syndrome (high on the y-axis), how susceptible they are
(position on the x-axis), and how uncertain both estimates are (spread
of the cloud). The dashed vertical lines denote the point estimates,
i.e., the coverage percentages. The ribbon behind the dashed lines
denote the credible interval, which is 95% at default.
``` r
wisca_plot(wisca_out)
```
![](WISCA_files/figure-html/unnamed-chunk-7-1.png)
#### Posterior coverage distributions
Setting `wisca_plot_type = "posterior_coverage"` shows the full
posterior distribution of coverage for each regimen as a density curve.
This is the most complete representation of what the Bayesian model
produces: each curve shows the relative likelihood of each coverage
value across all 1,000 simulations. Narrow, tall peaks indicate high
certainty; wide, flat curves indicate greater uncertainty. Where two
curves overlap, the regimens cannot be confidently distinguished.
``` r
wisca_plot(wisca_out, wisca_plot_type = "posterior_coverage")
```
![](WISCA_files/figure-html/unnamed-chunk-8-1.png)
## Sensible defaults, which can be customised
- `simulations = 1000`: number of Monte Carlo draws
- `conf_interval = 0.95`: coverage interval width
- `combine_SI = TRUE`: count “I” and “SDD” as susceptible
## Practical considerations
- **First isolates only**: always deduplicate using
[`first_isolate()`](https://amr-for-r.org/reference/first_isolate.md)
before running WISCA. Repeat isolates introduce bias.
- **Pathogen selection**: consider filtering with
[`top_n_microorganisms()`](https://amr-for-r.org/reference/top_n_microorganisms.md).
Including rare contaminants (e.g. CoNS without clinical context) can
distort estimates and may artificially lower coverage (Cook *et al.*,
2022).
- **Sample size**: coverage estimates become reliable with approximately
100+ isolates. For smaller datasets, consider pooling data from
multiple sites, but only after verifying that pathogen distributions
are sufficiently similar (Bielicki *et al.*, 2016).
- **Culture request bias**: WISCA is only as good as the data it is
based on. If cultures are selectively requested (e.g. only after
treatment failure), the dataset will be biased towards resistant
isolates. A robust culture policy is essential for reliable estimates.
## Limitations
- It assumes your data are representative of the patient population you
are treating
- No direct adjustment for patient-level covariates, although these can
be passed onto the `syndromic_group` argument for stratification
- WISCA does not model resistance trends over time; for that, you might
want to use `tidymodels`, for which we [wrote a basic
introduction](https://amr-for-r.org/articles/AMR_with_tidymodels.html)
## Summary
WISCA enables:
- **Empirical regimen comparison**, answering the clinicians actual
question
- **Syndrome-specific coverage estimation**, stratifiable by any
clinical variable
- **Fully probabilistic interpretation**, with credible intervals that
honestly communicate uncertainty
It is available in the `AMR` package via either:
``` r
wisca(...)
antibiogram(..., wisca = TRUE)
```
## References
1. Hebert C, Ridgway J, Vekhter B, Brown EC, Weber SG, Robicsek A.
Demonstration of the weighted-incidence syndromic combination
antibiogram: an empiric prescribing decision aid. *Infect Control
Hosp Epidemiol.* 2012;33(4):381-388.
<https://doi.org/10.1086/664768>
2. Randhawa V, Sarwar S, Walker S, Elligsen M, Palmay L, Daneman N.
Weighted-incidence syndromic combination antibiograms to guide
empiric treatment of critical care infections: a retrospective
cohort study. *Crit Care.* 2014;18(3):R112.
<https://doi.org/10.1186/cc13901>
3. Bielicki JA, Sharland M, Johnson AP, Henderson KL, Cromwell DA.
Selecting appropriate empirical antibiotic regimens for paediatric
bloodstream infections: application of a Bayesian decision model to
local and pooled antimicrobial resistance surveillance data. *J
Antimicrob Chemother.* 2016;71(3):794-802.
<https://doi.org/10.1093/jac/dkv397>
4. Cook A, Sharland M, Yau Y, Bielicki J. Improving empiric antibiotic
prescribing in pediatric bloodstream infections: a potential
application of weighted-incidence syndromic combination antibiograms
(WISCA). *Expert Rev Anti Infect Ther.* 2022;20(3):445-456.
<https://doi.org/10.1080/14787210.2021.1967145>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

File diff suppressed because it is too large Load Diff
-565
View File
@@ -1,565 +0,0 @@
# Download data sets for download / own use
All reference data (about microorganisms, antimicrobials, SIR
interpretation, EUCAST rules, etc.) in this `AMR` package are reliable,
up-to-date and freely available. We continually export our data sets to
formats for use in R, MS Excel, Apache Feather, Apache Parquet, SPSS,
and Stata. We also provide tab-separated text files that are
machine-readable and suitable for input in any software program, such as
laboratory information systems.
> If you are working in Python, be sure to use our [AMR for
> Python](https://amr-for-r.org/articles/AMR_for_Python.html) package.
> It allows all relevant AMR data sets to be natively available in
> Python.
## `microorganisms`: Full Microbial Taxonomy
A data set with 96 982 rows and 28 columns, containing the following
column names:
*mo*, *fullname*, *status*, *domain*, *kingdom*, *phylum*, *class*,
*order*, *family*, *genus*, *species*, *subspecies*, *rank*, *ref*,
*oxygen_tolerance*, *morphology*, *source*, *lpsn*, *lpsn_parent*,
*lpsn_renamed_to*, *mycobank*, *mycobank_parent*, *mycobank_renamed_to*,
*gbif*, *gbif_parent*, *gbif_renamed_to*, *prevalence*, and *snomed*.
This data set is in R available as `microorganisms`, after you load the
`AMR` package.
It was last updated on 22 June 2026 23:38:13 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/microorganisms.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.rds)
(2.2 MB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.txt)
(23.1 MB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.xlsx)
(11.4 MB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.feather)
(11 MB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.parquet)
(4.6 MB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.sav)
(35.2 MB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.dta)
(96.6 MB)
**NOTE: The exported files for SPSS and Stata contain only the first 50
SNOMED codes per record, as their file size would otherwise exceed 100
MB; the file size limit of GitHub.** Their file structures and
compression techniques are very inefficient. Advice? Use R instead. Its
free and much better in many ways.
The tab-separated text file and Microsoft Excel workbook both contain
all SNOMED codes as comma separated values.
**Example content**
Included (sub)species per taxonomic kingdom:
| Kingdom | Number of (sub)species |
|:-----------------:|:----------------------:|
| | 20 |
| (unknown kingdom) | 8 |
| Animalia | 2 015 |
| Archaea | 150 |
| Bacillati | 24 200 |
| Bacteria | 2 |
First 6 rows when filtering on genus *Escherichia*:
| mo | fullname | status | domain | kingdom | phylum | class | order | family | genus | species | subspecies | rank | ref | oxygen_tolerance | morphology | source | lpsn | lpsn_parent | lpsn_renamed_to | mycobank | mycobank_parent | mycobank_renamed_to | gbif | gbif_parent | gbif_renamed_to | prevalence | snomed |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| B_ESCHR | Escherichia | accepted | Bacteria | Pseudomonadati | Pseudomonadota | Gammaproteobacteria | Enterobacterales | Enterobacteriaceae | Escherichia | | | genus | Castellani et al., 1919 | facultative anaerobe | rods | LPSN | 515602 | 482 | | | | | CS33H | CRYWR | | 1 | 407310004, 407251000, 407281008, … |
| B_ESCHR_ADCR | Escherichia adecarboxylata | synonym | Bacteria | Pseudomonadati | Pseudomonadota | Gammaproteobacteria | Enterobacterales | Enterobacteriaceae | Escherichia | adecarboxylata | | species | Leclerc, 1962 | likely facultative anaerobe | rods | LPSN | 776052 | 515602 | 777447 | | | | CS33J | CS33H | 3SVX6 | 1 | |
| B_ESCHR_ALBR | Escherichia albertii | accepted | Bacteria | Pseudomonadati | Pseudomonadota | Gammaproteobacteria | Enterobacterales | Enterobacteriaceae | Escherichia | albertii | | species | Huys et al., 2003 | facultative anaerobe | rods | LPSN | 776053 | 515602 | | | | | 3BGTB | CS33H | | 1 | 419388003 |
| B_ESCHR_BLTT | Escherichia blattae | synonym | Bacteria | Pseudomonadati | Pseudomonadota | Gammaproteobacteria | Enterobacterales | Enterobacteriaceae | Escherichia | blattae | | species | Burgess et al., 1973 | likely facultative anaerobe | rods | LPSN | 776056 | 515602 | 788468 | | | | CS33K | CS33H | 4X4P7 | 1 | |
| B_ESCHR_COLI | Escherichia coli | accepted | Bacteria | Pseudomonadati | Pseudomonadota | Gammaproteobacteria | Enterobacterales | Enterobacteriaceae | Escherichia | coli | | species | Castellani et al., 1919 | facultative anaerobe | rods | LPSN | 776057 | 515602 | | | | | NT3L7 | CS33H | | 1 | 1095001000112106, 715307006, 737528008, … |
| B_ESCHR_COLI_COLI | Escherichia coli coli | accepted | Bacteria | Pseudomonadati | Pseudomonadota | Gammaproteobacteria | Enterobacterales | Enterobacteriaceae | Escherichia | coli | coli | subspecies | | | | GBIF | | 776057 | | | | | 12233256 | NT3L7 | | 1 | |
------------------------------------------------------------------------
## `antimicrobials`: Antibiotic and Antifungal Drugs
A data set with 505 rows and 14 columns, containing the following column
names:
*ab*, *cid*, *name*, *group*, *atc*, *atc_group1*, *atc_group2*,
*abbreviations*, *synonyms*, *oral_ddd*, *oral_units*, *iv_ddd*,
*iv_units*, and *loinc*.
This data set is in R available as `antimicrobials`, after you load the
`AMR` package.
It was last updated on 23 June 2026 12:38:59 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/antimicrobials.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antimicrobials.rds)
(44 kB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antimicrobials.txt)
(0.1 MB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antimicrobials.xlsx)
(79 kB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antimicrobials.feather)
(0.1 MB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antimicrobials.parquet)
(94 kB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antimicrobials.sav)
(0.4 MB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antimicrobials.dta)
(10 kB)
The tab-separated text, Microsoft Excel, SPSS, and Stata files all
contain the ATC codes, common abbreviations, trade names and LOINC codes
as comma separated values.
**Example content**
| ab | cid | name | group | atc | atc_group1 | atc_group2 | abbreviations | synonyms | oral_ddd | oral_units | iv_ddd | iv_units | loinc |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| AMK | 37768 | Amikacin | Aminoglycosides | D06AX12, J01GB06, QD06AX12, … | Aminoglycoside antibacterials | Other aminoglycosides | ak, ami, amik, … | amikacillin, amikacina, amikacine, … | | | 1.0 | g | 101493-5, 11-7, 12-5, … |
| AMX | 33613 | Amoxicillin | Aminopenicillins, Penicillins, Beta-lactams | J01CA04, QG51AA03, QJ01CA04 | Beta-lactam antibacterials, penicillins | Penicillins with extended spectrum | ac, amox, amoxic, … | acuotricina, alfamox, alfida, … | 1.5 | g | 3.0 | g | 101498-4, 15-8, 16-6, … |
| AMC | 23665637 | Amoxicillin/clavulanic acid | Aminopenicillins, Penicillins, Beta-lactams, … | J01CR02, QJ01CR02 | Beta-lactam antibacterials, penicillins | Combinations of penicillins, incl. beta-lactamase inhibitors | a/c, amcl, aml, … | amocla, amoclan, amoclav, … | 1.5 | g | 3.0 | g | |
| AMP | 6249 | Ampicillin | Aminopenicillins, Penicillins, Beta-lactams | J01CA01, QJ01CA01, QJ51CA01, … | Beta-lactam antibacterials, penicillins | Penicillins with extended spectrum | am, amp, amp100, … | adobacillin, alpen, amblosin, … | 2.0 | g | 6.0 | g | 101477-8, 101478-6, 18864-9, … |
| AZM | 447043 | Azithromycin | Macrolides | J01FA10, QJ01FA10, QS01AA26, … | Macrolides, lincosamides and streptogramins | Macrolides | az, azi, azit, … | aritromicina, aruzilina, azasite, … | 0.3 | g | 0.5 | g | 100043-9, 16420-2, 16421-0, … |
| PEN | 5904 | Benzylpenicillin | Penicillins, Beta-lactams | J01CE01, QJ01CE01, QJ51CE01, … | Combinations of antibacterials | Combinations of antibacterials | bepe, pen, peni, … | bencilpenicilina, benzopenicillin, benzylpenicilline, … | | | 3.6 | g | |
------------------------------------------------------------------------
## `clinical_breakpoints`: Interpretation from MIC values & disk diameters to SIR
A data set with 45 555 rows and 14 columns, containing the following
column names:
*guideline*, *type*, *host*, *method*, *site*, *mo*, *rank_index*, *ab*,
*ref_tbl*, *disk_dose*, *breakpoint_S*, *breakpoint_R*, *uti*, and
*is_SDD*.
This data set is in R available as `clinical_breakpoints`, after you
load the `AMR` package.
It was last updated on 22 June 2026 23:38:13 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/clinical_breakpoints.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/clinical_breakpoints.rds)
(92 kB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/clinical_breakpoints.txt)
(4.2 MB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/clinical_breakpoints.xlsx)
(2.7 MB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/clinical_breakpoints.feather)
(2 MB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/clinical_breakpoints.parquet)
(0.1 MB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/clinical_breakpoints.sav)
(7.5 MB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/clinical_breakpoints.dta)
(12.6 MB)
**Example content**
| guideline | type | host | method | site | mo | mo_name | rank_index | ab | ab_name | ref_tbl | disk_dose | breakpoint_S | breakpoint_R | uti | is_SDD |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| EUCAST 2026 | human | human | DISK | | B_ACHRMB_XYLS | Achromobacter xylosoxidans | 2 | MEM | Meropenem | A. xylosoxidans | 10 mcg | 26.000 | 20.000 | FALSE | FALSE |
| EUCAST 2026 | human | human | MIC | | B_ACHRMB_XYLS | Achromobacter xylosoxidans | 2 | MEM | Meropenem | A. xylosoxidans | | 1.000 | 4.000 | FALSE | FALSE |
| EUCAST 2026 | human | human | DISK | | B_ACHRMB_XYLS | Achromobacter xylosoxidans | 2 | SXT | Trimethoprim/sulfamethoxazole | A. xylosoxidans | 1.25/23.75 mcg | 26.000 | 26.000 | FALSE | FALSE |
| EUCAST 2026 | human | human | MIC | | B_ACHRMB_XYLS | Achromobacter xylosoxidans | 2 | SXT | Trimethoprim/sulfamethoxazole | A. xylosoxidans | | 0.125 | 0.125 | FALSE | FALSE |
| EUCAST 2026 | human | human | DISK | | B_ACHRMB_XYLS | Achromobacter xylosoxidans | 2 | TZP | Piperacillin/tazobactam | A. xylosoxidans | 30/6 mcg | 26.000 | 26.000 | FALSE | FALSE |
| EUCAST 2026 | human | human | MIC | | B_ACHRMB_XYLS | Achromobacter xylosoxidans | 2 | TZP | Piperacillin/tazobactam | A. xylosoxidans | | 4.000 | 4.000 | FALSE | FALSE |
------------------------------------------------------------------------
## `microorganisms.groups`: Species Groups and Microbiological Complexes
A data set with 530 rows and 4 columns, containing the following column
names:
*mo_group*, *mo*, *mo_group_name*, and *mo_name*.
This data set is in R available as `microorganisms.groups`, after you
load the `AMR` package.
It was last updated on 22 June 2026 23:38:13 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/microorganisms.groups.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.groups.rds)
(6 kB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.groups.txt)
(50 kB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.groups.xlsx)
(19 kB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.groups.feather)
(19 kB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.groups.parquet)
(13 kB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.groups.sav)
(64 kB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.groups.dta)
(82 kB)
**Example content**
| mo_group | mo | mo_group_name | mo_name |
|:--:|:--:|:--:|:--:|
| B_ACNTB_BMNN-C | B_ACNTB_BMNN | Acinetobacter baumannii complex | Acinetobacter baumannii |
| B_ACNTB_BMNN-C | B_ACNTB_CLCC | Acinetobacter baumannii complex | Acinetobacter calcoaceticus |
| B_ACNTB_BMNN-C | B_ACNTB_LCTC | Acinetobacter baumannii complex | Acinetobacter dijkshoorniae |
| B_ACNTB_BMNN-C | B_ACNTB_NSCM | Acinetobacter baumannii complex | Acinetobacter nosocomialis |
| B_ACNTB_BMNN-C | B_ACNTB_PITT | Acinetobacter baumannii complex | Acinetobacter pittii |
| B_ACNTB_BMNN-C | B_ACNTB_SFRT | Acinetobacter baumannii complex | Acinetobacter seifertii |
------------------------------------------------------------------------
## `intrinsic_resistant`: Intrinsic Bacterial Resistance
A data set with 294 079 rows and 2 columns, containing the following
column names:
*mo* and *ab*.
This data set is in R available as `intrinsic_resistant`, after you load
the `AMR` package.
It was last updated on 22 June 2026 23:38:13 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/intrinsic_resistant.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/intrinsic_resistant.rds)
(0.1 MB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/intrinsic_resistant.txt)
(10.9 MB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/intrinsic_resistant.xlsx)
(3.1 MB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/intrinsic_resistant.feather)
(2.5 MB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/intrinsic_resistant.parquet)
(0.3 MB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/intrinsic_resistant.sav)
(16 MB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/intrinsic_resistant.dta)
(28.6 MB)
**Example content**
Example rows when filtering on *Enterobacter cloacae*:
| microorganism | antibiotic |
|:--------------------:|:---------------------------:|
| Enterobacter cloacae | Acetylmidecamycin |
| Enterobacter cloacae | Acetylspiramycin |
| Enterobacter cloacae | Amoxicillin |
| Enterobacter cloacae | Amoxicillin/clavulanic acid |
| Enterobacter cloacae | Ampicillin |
| Enterobacter cloacae | Ampicillin/sulbactam |
| Enterobacter cloacae | Avoparcin |
| Enterobacter cloacae | Azithromycin |
| Enterobacter cloacae | Benzylpenicillin |
| Enterobacter cloacae | Bleomycin |
| Enterobacter cloacae | Cadazolid |
| Enterobacter cloacae | Cefadroxil |
| Enterobacter cloacae | Cefalexin |
| Enterobacter cloacae | Cefalotin |
| Enterobacter cloacae | Cefazolin |
| Enterobacter cloacae | Cefoxitin |
| Enterobacter cloacae | Clarithromycin |
| Enterobacter cloacae | Clindamycin |
| Enterobacter cloacae | Cycloserine |
| Enterobacter cloacae | Dalbavancin |
| Enterobacter cloacae | Dirithromycin |
| Enterobacter cloacae | Erythromycin |
| Enterobacter cloacae | Flurithromycin |
| Enterobacter cloacae | Fusidic acid |
| Enterobacter cloacae | Gamithromycin |
| Enterobacter cloacae | Josamycin |
| Enterobacter cloacae | Kitasamycin |
| Enterobacter cloacae | Lincomycin |
| Enterobacter cloacae | Linezolid |
| Enterobacter cloacae | Meleumycin |
| Enterobacter cloacae | Midecamycin |
| Enterobacter cloacae | Miocamycin |
| Enterobacter cloacae | Nafithromycin |
| Enterobacter cloacae | Norvancomycin |
| Enterobacter cloacae | Oleandomycin |
| Enterobacter cloacae | Oritavancin |
| Enterobacter cloacae | Ostreogrycin |
| Enterobacter cloacae | Pirlimycin |
| Enterobacter cloacae | Primycin |
| Enterobacter cloacae | Pristinamycin |
| Enterobacter cloacae | Quinupristin/dalfopristin |
| Enterobacter cloacae | Ramoplanin |
| Enterobacter cloacae | Rifampicin |
| Enterobacter cloacae | Rokitamycin |
| Enterobacter cloacae | Roxithromycin |
| Enterobacter cloacae | Solithromycin |
| Enterobacter cloacae | Spiramycin |
| Enterobacter cloacae | Tedizolid |
| Enterobacter cloacae | Teicoplanin |
| Enterobacter cloacae | Telavancin |
| Enterobacter cloacae | Telithromycin |
| Enterobacter cloacae | Thiacetazone |
| Enterobacter cloacae | Tildipirosin |
| Enterobacter cloacae | Tilmicosin |
| Enterobacter cloacae | Troleandomycin |
| Enterobacter cloacae | Tulathromycin |
| Enterobacter cloacae | Tylosin |
| Enterobacter cloacae | Tylvalosin |
| Enterobacter cloacae | Vancomycin |
| Enterobacter cloacae | Virginiamycine |
| Enterobacter cloacae | Zorbamycin |
------------------------------------------------------------------------
## `dosage`: Dosage Guidelines from EUCAST
A data set with 759 rows and 9 columns, containing the following column
names:
*ab*, *name*, *type*, *dose*, *dose_times*, *administration*, *notes*,
*original_txt*, and *eucast_version*.
This data set is in R available as `dosage`, after you load the `AMR`
package.
It was last updated on 20 April 2025 10:55:31 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/dosage.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/dosage.rds)
(4 kB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/dosage.txt)
(66 kB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/dosage.xlsx)
(37 kB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/dosage.feather)
(28 kB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/dosage.parquet)
(9 kB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/dosage.sav)
(97 kB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/dosage.dta)
(0.2 MB)
**Example content**
| ab | name | type | dose | dose_times | administration | notes | original_txt | eucast_version |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| AMK | Amikacin | standard_dosage | 25-30 mg/kg | 1 | iv | | 25-30 mg/kg x 1 iv | 15 |
| AMX | Amoxicillin | high_dosage | 2 g | 6 | iv | | 2 g x 6 iv | 15 |
| AMX | Amoxicillin | standard_dosage | 1 g | 3 | iv | | 1 g x 3-4 iv | 15 |
| AMX | Amoxicillin | high_dosage | 0.75-1 g | 3 | oral | | 0.75-1 g x 3 oral | 15 |
| AMX | Amoxicillin | standard_dosage | 0.5 g | 3 | oral | | 0.5 g x 3 oral | 15 |
| AMX | Amoxicillin | uncomplicated_uti | 0.5 g | 3 | oral | | 0.5 g x 3 oral | 15 |
------------------------------------------------------------------------
## `example_isolates`: Example Data for Practice
A data set with 2 000 rows and 46 columns, containing the following
column names:
*date*, *patient*, *age*, *gender*, *ward*, *mo*, *PEN*, *OXA*, *FLC*,
*AMX*, *AMC*, *AMP*, *TZP*, *CZO*, *FEP*, *CXM*, *FOX*, *CTX*, *CAZ*,
*CRO*, *GEN*, *TOB*, *AMK*, *KAN*, *TMP*, *SXT*, *NIT*, *FOS*, *LNZ*,
*CIP*, *MFX*, *VAN*, *TEC*, *TCY*, *TGC*, *DOX*, *ERY*, *CLI*, *AZM*,
*IPM*, *MEM*, *MTR*, *CHL*, *COL*, *MUP*, and *RIF*.
This data set is in R available as `example_isolates`, after you load
the `AMR` package.
It was last updated on 24 June 2026 16:36:47 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/example_isolates.html).
**Example content**
| date | patient | age | gender | ward | mo | PEN | OXA | FLC | AMX | AMC | AMP | TZP | CZO | FEP | CXM | FOX | CTX | CAZ | CRO | GEN | TOB | AMK | KAN | TMP | SXT | NIT | FOS | LNZ | CIP | MFX | VAN | TEC | TCY | TGC | DOX | ERY | CLI | AZM | IPM | MEM | MTR | CHL | COL | MUP | RIF |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| 2002-01-02 | A77334 | 65 | F | Clinical | B_ESCHR_COLI | R | | | | I | | | | | I | | | | | | | | | R | R | | | R | | | R | R | R | | | R | R | R | | | | | | | R |
| 2002-01-03 | A77334 | 65 | F | Clinical | B_ESCHR_COLI | R | | | | I | | | | | I | | | | | | | | | R | R | | | R | | | R | R | R | | | R | R | R | | | | | | | R |
| 2002-01-07 | 067927 | 45 | F | ICU | B_STPHY_EPDR | R | | R | | | | | | | R | | | R | | | | | | S | S | | | | | | S | | S | S | S | R | | R | | | | | R | | |
| 2002-01-07 | 067927 | 45 | F | ICU | B_STPHY_EPDR | R | | R | | | | | | | R | | | R | | | | | | S | S | | | | | | S | | S | S | S | R | | R | | | | | R | | |
| 2002-01-13 | 067927 | 45 | F | ICU | B_STPHY_EPDR | R | | R | | | | | | | R | | | R | | | | | | R | | | | | | | S | | S | S | S | R | | R | | | | | R | | |
| 2002-01-13 | 067927 | 45 | F | ICU | B_STPHY_EPDR | R | | R | | | | | | | R | | | R | | | | | | R | | | | | | | S | | S | S | S | R | R | R | | | | | R | | |
------------------------------------------------------------------------
## `example_isolates_unclean`: Example Data for Practice
A data set with 3 000 rows and 8 columns, containing the following
column names:
*patient_id*, *hospital*, *date*, *bacteria*, *AMX*, *AMC*, *CIP*, and
*GEN*.
This data set is in R available as `example_isolates_unclean`, after you
load the `AMR` package.
It was last updated on 27 August 2022 18:49:37 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/example_isolates_unclean.html).
**Example content**
| patient_id | hospital | date | bacteria | AMX | AMC | CIP | GEN |
|:----------:|:--------:|:----------:|:-------------:|:---:|:---:|:---:|:---:|
| J3 | A | 2012-11-21 | E. coli | R | I | S | S |
| R7 | A | 2018-04-03 | K. pneumoniae | R | I | S | S |
| P3 | A | 2014-09-19 | E. coli | R | S | S | S |
| P10 | A | 2015-12-10 | E. coli | S | I | S | S |
| B7 | A | 2015-03-02 | E. coli | S | S | S | S |
| W3 | A | 2018-03-31 | S. aureus | R | S | R | S |
------------------------------------------------------------------------
## `microorganisms.codes`: Common Laboratory Codes
A data set with 6 029 rows and 2 columns, containing the following
column names:
*code* and *mo*.
This data set is in R available as `microorganisms.codes`, after you
load the `AMR` package.
It was last updated on 22 June 2026 23:38:13 UTC. Find more info about
the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/microorganisms.codes.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.codes.rds)
(27 kB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.codes.txt)
(0.1 MB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.codes.xlsx)
(98 kB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.codes.feather)
(0.1 MB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.codes.parquet)
(68 kB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.codes.sav)
(0.2 MB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/microorganisms.codes.dta)
(0.2 MB)
**Example content**
| code | mo |
|:----:|:------------:|
| 1011 | B_GRAMP |
| 1012 | B_GRAMP |
| 1013 | B_GRAMN |
| 1014 | B_GRAMN |
| 1015 | F_YEAST |
| 103 | B_ESCHR_COLI |
------------------------------------------------------------------------
## `antivirals`: Antiviral Drugs
A data set with 120 rows and 11 columns, containing the following column
names:
*av*, *name*, *atc*, *cid*, *atc_group*, *synonyms*, *oral_ddd*,
*oral_units*, *iv_ddd*, *iv_units*, and *loinc*.
This data set is in R available as `antivirals`, after you load the
`AMR` package.
It was last updated on 20 October 2023 12:51:48 UTC. Find more info
about the contents, (scientific) source, and structure of this [data set
here](https://amr-for-r.org/reference/antimicrobials.html).
**Direct download links:**
- Download as [original R Data Structure (RDS)
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antivirals.rds)
(6 kB)
- Download as [tab-separated text
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antivirals.txt)
(17 kB)
- Download as [Microsoft Excel
workbook](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antivirals.xlsx)
(16 kB)
- Download as [Apache Feather
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antivirals.feather)
(16 kB)
- Download as [Apache Parquet
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antivirals.parquet)
(13 kB)
- Download as [IBM SPSS Statistics data
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antivirals.sav)
(32 kB)
- Download as [Stata DTA
file](https://github.com/msberends/AMR/raw/main/data-raw/datasets/antivirals.dta)
(78 kB)
The tab-separated text, Microsoft Excel, SPSS, and Stata files all
contain the trade names and LOINC codes as comma separated values.
**Example content**
| av | name | atc | cid | atc_group | synonyms | oral_ddd | oral_units | iv_ddd | iv_units | loinc |
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| ABA | Abacavir | J05AF06 | 441300 | Nucleoside and nucleotide reverse transcriptase inhibitors | abacavir sulfate, avacavir, ziagen | 0.6 | g | | | 29113-8, 30273-7, 30287-7, … |
| ACI | Aciclovir | J05AB01 | 135398513 | Nucleosides and nucleotides excl. reverse transcriptase inhibitors | acicloftal, aciclovier, aciclovirum, … | 4.0 | g | 4 | g | |
| ADD | Adefovir dipivoxil | J05AF08 | 60871 | Nucleoside and nucleotide reverse transcriptase inhibitors | adefovir di, adefovir di ester, adefovir dipivoxyl, … | 10.0 | mg | | | |
| AME | Amenamevir | J05AX26 | 11397521 | Other antivirals | amenalief | 0.4 | g | | | |
| AMP | Amprenavir | J05AE05 | 65016 | Protease inhibitors | agenerase, carbamate, prozei | 1.2 | g | | | 29114-6, 30296-8, 30297-6, … |
| ASU | Asunaprevir | J05AP06 | 16076883 | Antivirals for treatment of HCV infections | sunvepra, sunvepratrade | 0.2 | g | | | |
-89
View File
@@ -1,89 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>Articles • AMR (for R)</title><!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="../favicon-96x96.png"><link rel="icon" type="”image/svg+xml”" href="../favicon.svg"><link rel="apple-touch-icon" sizes="180x180" href="../apple-touch-icon.png"><link rel="icon" sizes="any" href="../favicon.ico"><link rel="manifest" href="../site.webmanifest"><script src="../deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link href="../deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet"><script src="../deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="../deps/Lato-0.4.10/font.css" rel="stylesheet"><link href="../deps/Fira_Code-0.4.10/font.css" rel="stylesheet"><link href="../deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet"><link href="../deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet"><script src="../deps/headroom-0.11.0/headroom.min.js"></script><script src="../deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="../deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="../deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="../deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="../deps/search-1.0.0/fuse.min.js"></script><script src="../deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet"><script src="../extra.js"></script><meta property="og:title" content="Articles"><meta property="og:image" content="https://amr-for-r.org/logo.svg"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous"><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script></head><body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="../index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto"><li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to"><li><a class="dropdown-item" href="../articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="../reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="../articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="../articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="../reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="../articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="../reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="../articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="../articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="../reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="../reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="../reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul></li>
<li class="nav-item"><a class="nav-link" href="../articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="../reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="nav-item"><a class="nav-link" href="../authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul><ul class="navbar-nav"><li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="../search.json"></form></li>
<li class="nav-item"><a class="nav-link" href="../news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul></div>
</div>
</nav><div class="container template-article-index">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="../logo.svg" class="logo" alt=""><h1>Articles</h1>
</div>
<div class="section ">
<h3>All vignettes</h3>
<div class="section-desc"></div>
<dl><dt><a href="AMR_for_Python.html">AMR for Python</a></dt>
<dd>
</dd><dt><a href="AMR_with_tidymodels.html">AMR with tidymodels</a></dt>
<dd>
</dd><dt><a href="AMR.html">Conduct AMR data analysis</a></dt>
<dd>
</dd><dt><a href="datasets.html">Download data sets for download / own use</a></dt>
<dd>
</dd><dt><a href="EUCAST.html">Apply EUCAST rules</a></dt>
<dd>
</dd><dt><a href="PCA.html">Conduct principal component analysis (PCA) for AMR</a></dt>
<dd>
</dd><dt><a href="WHONET.html">Work with WHONET data</a></dt>
<dd>
</dd><dt><a href="WISCA.html">Estimating Empirical Coverage with WISCA</a></dt>
<dd>
</dd></dl></div>
</main></div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer></div>
</body></html>
-16
View File
@@ -1,16 +0,0 @@
# Articles
### All vignettes
- [AMR for Python](https://amr-for-r.org/articles/AMR_for_Python.md):
- [AMR with
tidymodels](https://amr-for-r.org/articles/AMR_with_tidymodels.md):
- [Conduct AMR data analysis](https://amr-for-r.org/articles/AMR.md):
- [Download data sets for download / own
use](https://amr-for-r.org/articles/datasets.md):
- [Apply EUCAST rules](https://amr-for-r.org/articles/EUCAST.md):
- [Conduct principal component analysis (PCA) for
AMR](https://amr-for-r.org/articles/PCA.md):
- [Work with WHONET data](https://amr-for-r.org/articles/WHONET.md):
- [Estimating Empirical Coverage with
WISCA](https://amr-for-r.org/articles/WISCA.md):
-215
View File
@@ -1,215 +0,0 @@
<!DOCTYPE html>
<!-- Generated by pkgdown: do not edit by hand --><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><title>Authors and Citation • AMR (for R)</title><!-- favicons --><link rel="icon" type="image/png" sizes="96x96" href="favicon-96x96.png"><link rel="icon" type="”image/svg+xml”" href="favicon.svg"><link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png"><link rel="icon" sizes="any" href="favicon.ico"><link rel="manifest" href="site.webmanifest"><script src="deps/jquery-3.6.0/jquery-3.6.0.min.js"></script><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"><link href="deps/bootstrap-5.3.8/bootstrap.min.css" rel="stylesheet"><script src="deps/bootstrap-5.3.8/bootstrap.bundle.min.js"></script><link href="deps/Lato-0.4.10/font.css" rel="stylesheet"><link href="deps/Fira_Code-0.4.10/font.css" rel="stylesheet"><link href="deps/font-awesome-6.5.2/css/all.min.css" rel="stylesheet"><link href="deps/font-awesome-6.5.2/css/v4-shims.min.css" rel="stylesheet"><script src="deps/headroom-0.11.0/headroom.min.js"></script><script src="deps/headroom-0.11.0/jQuery.headroom.min.js"></script><script src="deps/bootstrap-toc-1.0.1/bootstrap-toc.min.js"></script><script src="deps/clipboard.js-2.0.11/clipboard.min.js"></script><script src="deps/search-1.0.0/autocomplete.jquery.min.js"></script><script src="deps/search-1.0.0/fuse.min.js"></script><script src="deps/search-1.0.0/mark.min.js"></script><!-- pkgdown --><script src="pkgdown.js"></script><link href="extra.css" rel="stylesheet"><script src="extra.js"></script><meta property="og:title" content="Authors and Citation"><meta property="og:image" content="https://amr-for-r.org/logo.svg"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous"><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.js" integrity="sha384-7zkQWkzuo3B5mTepMUcHkMB5jZaolc2xDwL6VFqjFALcbeS9Ggm/Yr2r3Dy4lfFg" crossorigin="anonymous"></script><script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/contrib/auto-render.min.js" integrity="sha384-43gviWU0YVjaDtb/GhzOouOXtZMP/7XUzwPTstBeZFe/+rCMvRwr4yROQP43s0Xk" crossorigin="anonymous" onload="renderMathInElement(document.body);"></script></head><body>
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
<nav class="navbar navbar-expand-lg fixed-top bg-primary" data-bs-theme="dark" aria-label="Site navigation"><div class="container">
<a class="navbar-brand me-2" href="index.html">AMR (for R)</a>
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">3.0.1.9065</small>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div id="navbar" class="collapse navbar-collapse ms-3">
<ul class="navbar-nav me-auto"><li class="nav-item dropdown">
<button class="nav-link dropdown-toggle" type="button" id="dropdown-how-to" data-bs-toggle="dropdown" aria-expanded="false" aria-haspopup="true"><span class="fa fa-question-circle"></span> How to</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-how-to"><li><a class="dropdown-item" href="articles/AMR.html"><span class="fa fa-directions"></span> Conduct AMR Analysis</a></li>
<li><a class="dropdown-item" href="reference/antibiogram.html"><span class="fa fa-file-prescription"></span> Generate Antibiogram (Trad./Syndromic/WISCA)</a></li>
<li><a class="dropdown-item" href="articles/AMR_with_tidymodels.html"><span class="fa fa-square-root-variable"></span> Use AMR for Predictive Modelling (tidymodels)</a></li>
<li><a class="dropdown-item" href="articles/datasets.html"><span class="fa fa-database"></span> Download Data Sets for Own Use</a></li>
<li><a class="dropdown-item" href="reference/AMR-options.html"><span class="fa fa-gear"></span> Set User- Or Team-specific Package Settings</a></li>
<li><a class="dropdown-item" href="articles/PCA.html"><span class="fa fa-compress"></span> Conduct Principal Component Analysis for AMR</a></li>
<li><a class="dropdown-item" href="reference/mdro.html"><span class="fa fa-skull-crossbones"></span> Determine Multi-Drug Resistance (MDR)</a></li>
<li><a class="dropdown-item" href="articles/WHONET.html"><span class="fa fa-globe-americas"></span> Work with WHONET Data</a></li>
<li><a class="dropdown-item" href="articles/EUCAST.html"><span class="fa fa-exchange-alt"></span> Apply EUCAST Rules</a></li>
<li><a class="dropdown-item" href="reference/mo_property.html"><span class="fa fa-bug"></span> Get Taxonomy of a Microorganism</a></li>
<li><a class="dropdown-item" href="reference/ab_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antibiotic Drug</a></li>
<li><a class="dropdown-item" href="reference/av_property.html"><span class="fa fa-capsules"></span> Get Properties of an Antiviral Drug</a></li>
</ul></li>
<li class="nav-item"><a class="nav-link" href="articles/AMR_for_Python.html"><span class="fa fab fa-python"></span> AMR for Python</a></li>
<li class="nav-item"><a class="nav-link" href="reference/index.html"><span class="fa fa-book-open"></span> Manual</a></li>
<li class="active nav-item"><a class="nav-link" href="authors.html"><span class="fa fa-users"></span> Authors</a></li>
</ul><ul class="navbar-nav"><li class="nav-item"><form class="form-inline" role="search">
<input class="form-control" type="search" name="search-input" id="search-input" autocomplete="off" aria-label="Search site" placeholder="Search for" data-search-index="search.json"></form></li>
<li class="nav-item"><a class="nav-link" href="news/index.html"><span class="fa fa-newspaper"></span> Changelog</a></li>
<li class="nav-item"><a class="external-link nav-link" href="https://github.com/msberends/AMR"><span class="fa fa-github"></span> Source Code</a></li>
</ul></div>
</div>
</nav><div class="container template-citation-authors">
<div class="row">
<main id="main" class="col-md-9"><div class="page-header">
<img src="logo.svg" class="logo" alt=""><h1>Authors and Citation</h1>
</div>
<div class="section level2">
<h2>Authors</h2>
<ul class="list-unstyled"><li>
<p><strong>Matthijs S. Berends</strong>. Author, maintainer. <a href="https://orcid.org/0000-0001-7620-1800" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Dennis Souverein</strong>. Author, contributor. <a href="https://orcid.org/0000-0003-0455-0336" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Erwin E. A. Hassing</strong>. Author, contributor.
</p>
</li>
<li>
<p><strong>Aislinn Cook</strong>. Contributor. <a href="https://orcid.org/0000-0002-9189-7815" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Andrew P. Norgan</strong>. Contributor. <a href="https://orcid.org/0000-0002-2955-2066" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Anita Williams</strong>. Contributor. <a href="https://orcid.org/0000-0002-5295-8451" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Annick Lenglet</strong>. Contributor. <a href="https://orcid.org/0000-0003-2013-8405" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Anthony Underwood</strong>. Contributor. <a href="https://orcid.org/0000-0002-8547-4277" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Anton Mymrikov</strong>. Contributor.
</p>
</li>
<li>
<p><strong>Bart C. Meijer</strong>. Contributor.
</p>
</li>
<li>
<p><strong>Christian F. Luz</strong>. Contributor. <a href="https://orcid.org/0000-0001-5809-5995" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Dmytro Mykhailenko</strong>. Contributor.
</p>
</li>
<li>
<p><strong>Eric H. L. C. M. Hazenberg</strong>. Contributor.
</p>
</li>
<li>
<p><strong>Gwen Knight</strong>. Contributor. <a href="https://orcid.org/0000-0002-7263-9896" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Jane Hawkey</strong>. Contributor. <a href="https://orcid.org/0000-0001-9661-5293" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Jason Stull</strong>. Contributor. <a href="https://orcid.org/0000-0002-9028-8153" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Javier Sanchez</strong>. Contributor. <a href="https://orcid.org/0000-0003-2605-8094" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Jonas Salm</strong>. Contributor.
</p>
</li>
<li>
<p><strong>Judith M. Fonville</strong>. Contributor.
</p>
</li>
<li>
<p><strong>Kathryn Holt</strong>. Contributor. <a href="https://orcid.org/0000-0003-3949-2471" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Larisse Bolton</strong>. Contributor. <a href="https://orcid.org/0000-0001-7879-2173" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Matthew Saab</strong>. Contributor. <a href="https://orcid.org/0009-0008-6626-7919" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Natacha Couto</strong>. Contributor. <a href="https://orcid.org/0000-0002-9152-5464" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Peter Dutey-Magni</strong>. Contributor. <a href="https://orcid.org/0000-0002-8942-9836" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Rogier P. Schade</strong>. Contributor. <a href="https://orcid.org/0000-0002-9487-4467" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Sofia Ny</strong>. Contributor. <a href="https://orcid.org/0000-0002-2017-1363" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Alex W. Friedrich</strong>. Thesis advisor. <a href="https://orcid.org/0000-0003-4881-038X" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Bhanu N. M. Sinha</strong>. Thesis advisor. <a href="https://orcid.org/0000-0003-1634-0010" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Casper J. Albers</strong>. Thesis advisor. <a href="https://orcid.org/0000-0002-9213-6743" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
<li>
<p><strong>Corinna Glasner</strong>. Thesis advisor. <a href="https://orcid.org/0000-0003-1241-1328" target="orcid.widget" aria-label="ORCID" class="external-link"><span class="fab fa-orcid orcid" aria-hidden="true"></span></a>
</p>
</li>
</ul></div>
<div class="section level2">
<h2 id="citation">Citation</h2>
<p><small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/main/inst/CITATION" class="external-link"><code>inst/CITATION</code></a></small></p>
<p>Berends MS, Luz CF, Friedrich AW, Sinha BNM, Albers CJ, Glasner C (2022).
“AMR: An R Package for Working with Antimicrobial Resistance Data.”
<em>Journal of Statistical Software</em>, <b>104</b>(3), 131.
<a href="https://doi.org/10.18637/jss.v104.i03" class="external-link">doi:10.18637/jss.v104.i03</a>.
</p>
<pre>@Article{,
title = {{AMR}: An {R} Package for Working with Antimicrobial Resistance Data},
author = {Matthijs S. Berends and Christian F. Luz and Alexander W. Friedrich and Bhanu N. M. Sinha and Casper J. Albers and Corinna Glasner},
journal = {Journal of Statistical Software},
year = {2022},
volume = {104},
number = {3},
pages = {1--31},
doi = {10.18637/jss.v104.i03},
}</pre>
</div>
</main><aside class="col-md-3"><nav id="toc" aria-label="Table of contents"><h2>On this page</h2>
</nav></aside></div>
<footer><div class="pkgdown-footer-left">
<p><code>AMR</code> (for R). Free and open-source, licenced under the <a target="_blank" href="https://github.com/msberends/AMR/blob/main/LICENSE" class="external-link">GNU GPL 2.0</a>. Developed at the <a target="_blank" href="https://www.rug.nl" class="external-link">University of Groningen</a> and <a target="_blank" href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a> in The Netherlands, in collaboration with <a href="https://amr-for-r.org/authors.html">many colleagues from around the world</a>.</p>
</div>
<div class="pkgdown-footer-right">
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://amr-for-r.org/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://amr-for-r.org/logo_umcg.svg" style="max-width: 150px;"></a></p>
</div>
</footer></div>
</body></html>
-106
View File
@@ -1,106 +0,0 @@
# Authors and Citation
## Authors
- **Matthijs S. Berends**. Author, maintainer.
[](https://orcid.org/0000-0001-7620-1800)
- **Dennis Souverein**. Author, contributor.
[](https://orcid.org/0000-0003-0455-0336)
- **Erwin E. A. Hassing**. Author, contributor.
- **Aislinn Cook**. Contributor.
[](https://orcid.org/0000-0002-9189-7815)
- **Andrew P. Norgan**. Contributor.
[](https://orcid.org/0000-0002-2955-2066)
- **Anita Williams**. Contributor.
[](https://orcid.org/0000-0002-5295-8451)
- **Annick Lenglet**. Contributor.
[](https://orcid.org/0000-0003-2013-8405)
- **Anthony Underwood**. Contributor.
[](https://orcid.org/0000-0002-8547-4277)
- **Anton Mymrikov**. Contributor.
- **Bart C. Meijer**. Contributor.
- **Christian F. Luz**. Contributor.
[](https://orcid.org/0000-0001-5809-5995)
- **Dmytro Mykhailenko**. Contributor.
- **Eric H. L. C. M. Hazenberg**. Contributor.
- **Gwen Knight**. Contributor.
[](https://orcid.org/0000-0002-7263-9896)
- **Jane Hawkey**. Contributor.
[](https://orcid.org/0000-0001-9661-5293)
- **Jason Stull**. Contributor.
[](https://orcid.org/0000-0002-9028-8153)
- **Javier Sanchez**. Contributor.
[](https://orcid.org/0000-0003-2605-8094)
- **Jonas Salm**. Contributor.
- **Judith M. Fonville**. Contributor.
- **Kathryn Holt**. Contributor.
[](https://orcid.org/0000-0003-3949-2471)
- **Larisse Bolton**. Contributor.
[](https://orcid.org/0000-0001-7879-2173)
- **Matthew Saab**. Contributor.
[](https://orcid.org/0009-0008-6626-7919)
- **Natacha Couto**. Contributor.
[](https://orcid.org/0000-0002-9152-5464)
- **Peter Dutey-Magni**. Contributor.
[](https://orcid.org/0000-0002-8942-9836)
- **Rogier P. Schade**. Contributor.
[](https://orcid.org/0000-0002-9487-4467)
- **Sofia Ny**. Contributor. [](https://orcid.org/0000-0002-2017-1363)
- **Alex W. Friedrich**. Thesis advisor.
[](https://orcid.org/0000-0003-4881-038X)
- **Bhanu N. M. Sinha**. Thesis advisor.
[](https://orcid.org/0000-0003-1634-0010)
- **Casper J. Albers**. Thesis advisor.
[](https://orcid.org/0000-0002-9213-6743)
- **Corinna Glasner**. Thesis advisor.
[](https://orcid.org/0000-0003-1241-1328)
## Citation
Source:
[`inst/CITATION`](https://github.com/msberends/AMR/blob/main/inst/CITATION)
Berends MS, Luz CF, Friedrich AW, Sinha BNM, Albers CJ, Glasner C
(2022). “AMR: An R Package for Working with Antimicrobial Resistance
Data.” *Journal of Statistical Software*, **104**(3), 131.
[doi:10.18637/jss.v104.i03](https://doi.org/10.18637/jss.v104.i03).
@Article{,
title = {{AMR}: An {R} Package for Working with Antimicrobial Resistance Data},
author = {Matthijs S. Berends and Christian F. Luz and Alexander W. Friedrich and Bhanu N. M. Sinha and Casper J. Albers and Corinna Glasner},
journal = {Journal of Statistical Software},
year = {2022},
volume = {104},
number = {3},
pages = {1--31},
doi = {10.18637/jss.v104.i03},
}
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
-63
View File
@@ -1,63 +0,0 @@
/* cyrillic-ext */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJV37Nv7g.woff2) format('woff2');
unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
/* cyrillic */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJVT7Nv7g.woff2) format('woff2');
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
/* greek-ext */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJVz7Nv7g.woff2) format('woff2');
unicode-range: U+1F00-1FFF;
}
/* greek */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJVP7Nv7g.woff2) format('woff2');
unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}
/* symbols2 */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJeraE8PZqw.woff2) format('woff2');
unicode-range: U+2000-2001, U+2004-2008, U+200A, U+23B8-23BD, U+2500-259F;
}
/* latin-ext */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJV77Nv7g.woff2) format('woff2');
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sJVD7Ng.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

Some files were not shown because too many files have changed in this diff Show More