diff --git a/DESCRIPTION b/DESCRIPTION
index 0b343ec4..103df4b8 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,6 +1,6 @@
Package: AMR
-Version: 0.7.1.9026
-Date: 2019-08-06
+Version: 0.7.1.9028
+Date: 2019-08-07
Title: Antimicrobial Resistance Analysis
Authors@R: c(
person(
@@ -53,6 +53,7 @@ Imports:
hms,
knitr (>= 1.0.0),
microbenchmark,
+ pillar,
rlang (>= 0.3.1),
scales,
tidyr (>= 0.7.0)
@@ -67,7 +68,7 @@ Suggests:
VignetteBuilder: knitr
URL: https://msberends.gitlab.io/AMR, https://gitlab.com/msberends/AMR
BugReports: https://gitlab.com/msberends/AMR/issues
-License: GPL-2
+License: GPL-2 | file LICENSE
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.1.1
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..e29e4408
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,280 @@
+GNU GENERAL PUBLIC LICENSE
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 +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. +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 +Preamble - The licenses for most software are designed to take away your +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 @@ -279,21 +279,21 @@ 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 +The precise terms and conditions for copying, distribution and modification follow. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +GNU GENERAL PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. This License applies to any program or other work which contains +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, + 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". + 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 @@ -302,7 +302,7 @@ 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 +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 @@ -420,10 +420,10 @@ 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 +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 + 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 @@ -452,7 +452,7 @@ 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 +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 @@ -460,7 +460,7 @@ 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 +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. @@ -473,7 +473,7 @@ 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 +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 @@ -481,9 +481,9 @@ 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 +NO WARRANTY - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS 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 @@ -493,76 +493,17 @@ 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 +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 + 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. +END OF TERMS AND CONDITIONSdiff --git a/docs/articles/AMR.html b/docs/articles/AMR.html index 7a45e304..6e853524 100644 --- a/docs/articles/AMR.html +++ b/docs/articles/AMR.html @@ -40,7 +40,7 @@ @@ -185,7 +185,7 @@How to conduct AMR analysis
Matthijs S. Berends
-06 August 2019
+07 August 2019
@@ -194,7 +194,7 @@ -AMR.Rmd
Note: values on this page will change with every website update since they are based on randomly created values and the page was written in R Markdown. However, the methodology remains unchanged. This page was generated on 06 August 2019.
+Note: values on this page will change with every website update since they are based on randomly created values and the page was written in R Markdown. However, the methodology remains unchanged. This page was generated on 07 August 2019.
Introduction
@@ -210,21 +210,21 @@- 2019-08-06 +2019-08-07 abcd Escherichia coli S S - 2019-08-06 +2019-08-07 abcd Escherichia coli S R - 2019-08-06 +2019-08-07 efgh Escherichia coli R @@ -320,71 +320,71 @@- 2017-03-10 -Q5 -Hospital C -Escherichia coli -S +2017-01-02 +V8 +Hospital A +Klebsiella pneumoniae S +I S S F - +2011-12-26 -G6 -Hospital C +2013-05-08 +W2 +Hospital B +Staphylococcus aureus +R +S +S +S +F ++ +2015-08-15 +R1 +Hospital B +Streptococcus pneumoniae +S +S +S +R +F ++ +2012-01-09 +X9 +Hospital D +Staphylococcus aureus +S +I +R +S +F ++ -2014-06-18 +Z7 +Hospital D Streptococcus pneumoniae S S S S -M -- -2011-07-01 -L6 -Hospital C -Escherichia coli -S -S -S -S -M -- -2015-08-22 -A9 -Hospital B -Escherichia coli -R -S -S -S -M -- -2017-03-16 -H1 -Hospital A -Staphylococcus aureus -S -I -S -S -M -- +2017-06-20 -V2 -Hospital D -Escherichia coli -I -S -R -S F + 2015-02-18 +F4 +Hospital A +Escherichia coli +R +S +S +S +M +Now, let’s start the cleaning and the analysis!
@@ -406,8 +406,8 @@ # # Item Count Percent Cum. Count Cum. Percent # --- ----- ------- -------- ----------- ------------- -# 1 M 10,366 51.8% 10,366 51.8% -# 2 F 9,634 48.2% 20,000 100.0% +# 1 M 10,401 52.0% 10,401 52.0% +# 2 F 9,599 48.0% 20,000 100.0%So, we can draw at least two conclusions immediately. From a data scientists perspective, the data looks clean: only values
M
andF
. From a researchers perspective: there are slightly more men. Nothing we didn’t already know.The data is already quite clean, but we still need to transform some variables. The
bacteria
column now consists of text, and we want to add more variables based on microbial IDs later on. So, we will transform this column to valid IDs. Themutate()
function of thedplyr
package makes this really easy:+# Use eucast_rules(..., verbose = TRUE) (on your original data) to get a data.frame with all specified edits instead.data <- data %>% @@ -423,56 +423,56 @@ # http://eucast.org/ # # EUCAST Clinical Breakpoints (v9.0, 2019) -# Aerococcus sanguinicola (no new changes) -# Aerococcus urinae (no new changes) -# Anaerobic Gram-negatives (no new changes) -# Anaerobic Gram-positives (no new changes) -# Campylobacter coli (no new changes) -# Campylobacter jejuni (no new changes) -# Enterobacteriales (Order) (no new changes) -# Enterococcus (no new changes) -# Haemophilus influenzae (no new changes) -# Kingella kingae (no new changes) -# Moraxella catarrhalis (no new changes) -# Pasteurella multocida (no new changes) -# Staphylococcus (no new changes) -# Streptococcus groups A, B, C, G (no new changes) -# Streptococcus pneumoniae (1,439 new changes) -# Viridans group streptococci (no new changes) +# Aerococcus sanguinicola (no values changed) +# Aerococcus urinae (no values changed) +# Anaerobic Gram-negatives (no values changed) +# Anaerobic Gram-positives (no values changed) +# Campylobacter coli (no values changed) +# Campylobacter jejuni (no values changed) +# Enterobacteriales (Order) (no values changed) +# Enterococcus (no values changed) +# Haemophilus influenzae (no values changed) +# Kingella kingae (no values changed) +# Moraxella catarrhalis (no values changed) +# Pasteurella multocida (no values changed) +# Staphylococcus (no values changed) +# Streptococcus groups A, B, C, G (no values changed) +# Streptococcus pneumoniae (1,456 values changed) +# Viridans group streptococci (no values changed) # # EUCAST Expert Rules, Intrinsic Resistance and Exceptional Phenotypes (v3.1, 2016) -# Table 01: Intrinsic resistance in Enterobacteriaceae (1,329 new changes) -# Table 02: Intrinsic resistance in non-fermentative Gram-negative bacteria (no new changes) -# Table 03: Intrinsic resistance in other Gram-negative bacteria (no new changes) -# Table 04: Intrinsic resistance in Gram-positive bacteria (2,679 new changes) -# Table 08: Interpretive rules for B-lactam agents and Gram-positive cocci (no new changes) -# Table 09: Interpretive rules for B-lactam agents and Gram-negative rods (no new changes) -# Table 11: Interpretive rules for macrolides, lincosamides, and streptogramins (no new changes) -# Table 12: Interpretive rules for aminoglycosides (no new changes) -# Table 13: Interpretive rules for quinolones (no new changes) +# Table 01: Intrinsic resistance in Enterobacteriaceae (1,287 values changed) +# Table 02: Intrinsic resistance in non-fermentative Gram-negative bacteria (no values changed) +# Table 03: Intrinsic resistance in other Gram-negative bacteria (no values changed) +# Table 04: Intrinsic resistance in Gram-positive bacteria (2,759 values changed) +# Table 08: Interpretive rules for B-lactam agents and Gram-positive cocci (no values changed) +# Table 09: Interpretive rules for B-lactam agents and Gram-negative rods (no values changed) +# Table 11: Interpretive rules for macrolides, lincosamides, and streptogramins (no values changed) +# Table 12: Interpretive rules for aminoglycosides (no values changed) +# Table 13: Interpretive rules for quinolones (no values changed) # # Other rules -# Non-EUCAST: amoxicillin/clav acid = S where ampicillin = S (2,347 new changes) -# Non-EUCAST: ampicillin = R where amoxicillin/clav acid = R (114 new changes) -# Non-EUCAST: piperacillin = R where piperacillin/tazobactam = R (no new changes) -# Non-EUCAST: piperacillin/tazobactam = S where piperacillin = S (no new changes) -# Non-EUCAST: trimethoprim = R where trimethoprim/sulfa = R (no new changes) -# Non-EUCAST: trimethoprim/sulfa = S where trimethoprim = S (no new changes) +# Non-EUCAST: amoxicillin/clav acid = S where ampicillin = S (2,330 values changed) +# Non-EUCAST: ampicillin = R where amoxicillin/clav acid = R (108 values changed) +# Non-EUCAST: piperacillin = R where piperacillin/tazobactam = R (no values changed) +# Non-EUCAST: piperacillin/tazobactam = S where piperacillin = S (no values changed) +# Non-EUCAST: trimethoprim = R where trimethoprim/sulfa = R (no values changed) +# Non-EUCAST: trimethoprim/sulfa = S where trimethoprim = S (no values changed) # # -------------------------------------------------------------------------- -# EUCAST rules affected 6,589 out of 20,000 rows, making a total of 7,908 edits +# EUCAST rules affected 6,604 out of 20,000 rows, making a total of 7,940 edits # => added 0 test results # -# => changed 7,908 test results -# - 110 test results changed from S to I -# - 4,680 test results changed from S to R -# - 1,068 test results changed from I to S -# - 326 test results changed from I to R -# - 1,711 test results changed from R to S -# - 13 test results changed from R to I +# => changed 7,940 test results +# * 110 test results changed from S to I +# * 4,715 test results changed from S to R +# * 1,119 test results changed from I to S +# * 307 test results changed from I to R +# * 1,664 test results changed from R to S +# * 25 test results changed from R to I # -------------------------------------------------------------------------- # -# Use verbose = TRUE (on your original data) to get a data.frame with all specified edits instead.
+# => Found 5,676 first isolates (28.4% of total)@@ -497,7 +497,7 @@ # NOTE: Using column `bacteria` as input for `col_mo`. # NOTE: Using column `date` as input for `col_date`. # NOTE: Using column `patient_id` as input for `col_patient_id`. -# => Found 5,681 first isolates (28.4% of total)
So only is suitable for resistance analysis! We can now filter on it with the filter()
function, also from the dplyr
package:
We made a slight twist to the CLSI algorithm, to take into account the antimicrobial susceptibility profile. Have a look at all isolates of patient C10, sorted on date:
+We made a slight twist to the CLSI algorithm, to take into account the antimicrobial susceptibility profile. Have a look at all isolates of patient M4, sorted on date:
isolate | @@ -524,21 +524,21 @@|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | -2010-07-24 | -C10 | +2010-04-02 | +M4 | B_ESCHR_COL | +R | S | -S | -S | +R | S | TRUE | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | -2010-12-03 | -C10 | +2010-05-26 | +M4 | B_ESCHR_COL | -R | +S | S | S | S | @@ -546,10 +546,10 @@|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3 | -2010-12-19 | -C10 | +2010-07-15 | +M4 | B_ESCHR_COL | -S | +R | S | S | S | @@ -557,10 +557,10 @@|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | -2011-02-18 | -C10 | +2010-09-11 | +M4 | B_ESCHR_COL | -R | +S | S | S | S | @@ -568,21 +568,21 @@|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
5 | -2011-06-26 | -C10 | +2010-11-13 | +M4 | B_ESCHR_COL | +R | +S | S | S | -R | -R | FALSE | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | -2011-06-28 | -C10 | +2010-11-16 | +M4 | B_ESCHR_COL | -S | +R | S | S | S | @@ -590,43 +590,43 @@|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
7 | -2011-06-30 | -C10 | +2011-01-03 | +M4 | B_ESCHR_COL | -S | -S | R | S | +S | +S | FALSE | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
8 | -2011-08-29 | -C10 | +2011-03-16 | +M4 | B_ESCHR_COL | S | S | -R | -R | -TRUE | +S | +S | +FALSE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
9 | -2011-10-03 | -C10 | +2011-04-21 | +M4 | B_ESCHR_COL | S | S | S | S | -FALSE | +TRUE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
10 | -2011-12-30 | -C10 | +2011-04-24 | +M4 | B_ESCHR_COL | -R | +S | S | S | S | @@ -645,7 +645,7 @@ # NOTE: Using column `patient_id` as input for `col_patient_id`. # NOTE: Using column `keyab` as input for `col_keyantibiotics`. Use col_keyantibiotics = FALSE to prevent this. # [Criterion] Inclusion based on key antibiotics, ignoring I. -# => Found 15,027 first weighted isolates (75.1% of total) +# => Found 14,973 first weighted isolates (74.9% of total)
isolate | @@ -662,22 +662,22 @@||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | -2010-07-24 | -C10 | +2010-04-02 | +M4 | B_ESCHR_COL | +R | S | -S | -S | +R | S | TRUE | TRUE | |
2 | -2010-12-03 | -C10 | +2010-05-26 | +M4 | B_ESCHR_COL | -R | +S | S | S | S | @@ -686,10 +686,10 @@||||
3 | -2010-12-19 | -C10 | +2010-07-15 | +M4 | B_ESCHR_COL | -S | +R | S | S | S | @@ -698,10 +698,10 @@||||
4 | -2011-02-18 | -C10 | +2010-09-11 | +M4 | B_ESCHR_COL | -R | +S | S | S | S | @@ -710,83 +710,83 @@||||
5 | -2011-06-26 | -C10 | +2010-11-13 | +M4 | B_ESCHR_COL | +R | +S | S | S | -R | -R | FALSE | TRUE | |
6 | -2011-06-28 | -C10 | +2010-11-16 | +M4 | B_ESCHR_COL | -S | +R | S | S | S | FALSE | -TRUE | +FALSE | |
7 | -2011-06-30 | -C10 | +2011-01-03 | +M4 | B_ESCHR_COL | -S | -S | R | S | +S | +S | +FALSE | FALSE | -TRUE |
8 | -2011-08-29 | -C10 | +2011-03-16 | +M4 | B_ESCHR_COL | S | S | -R | -R | -TRUE | +S | +S | +FALSE | TRUE |
9 | -2011-10-03 | -C10 | +2011-04-21 | +M4 | B_ESCHR_COL | S | S | S | S | -FALSE | +TRUE | TRUE | ||
10 | -2011-12-30 | -C10 | +2011-04-24 | +M4 | B_ESCHR_COL | -R | +S | S | S | S | FALSE | -TRUE | +FALSE |
Instead of 2, now 10 isolates are flagged. In total, of all isolates are marked ‘first weighted’ - more than when using the CLSI guideline. In real life, this novel algorithm will yield 5-10% more isolates than the classic CLSI guideline.
+Instead of 2, now 7 isolates are flagged. In total, of all isolates are marked ‘first weighted’ - more than when using the CLSI guideline. In real life, this novel algorithm will yield 5-10% more isolates than the classic CLSI guideline.
As with filter_first_isolate()
, there’s a shortcut for this new algorithm too:
So we end up with 15,027 isolates for analysis.
+So we end up with 14,973 isolates for analysis.
We can remove unneeded columns:
@@ -811,64 +811,64 @@Frequency table
Class: character
-Length: 15,027 (of which NA: 0 = 0.00%)
+Length: 14,973 (of which NA: 0 = 0.00%)
Unique: 4
Shortest: 16
Longest: 24
The functions portion_S()
, portion_SI()
, portion_I()
, portion_IR()
and portion_R()
can be used to determine the portion of a specific antimicrobial outcome. As per the EUCAST guideline of 2019, we calculate resistance as the portion of R (portion_R()
) and susceptibility as the portion of S and I (portion_SI()
). These functions can be used on their own:
Or can be used in conjuction with group_by()
and summarise()
, both from the dplyr
package:
data_1st %>%
group_by(hospital) %>%
@@ -992,19 +992,19 @@ Longest: 24
Hospital A
-0.4574111
+0.4721851
Hospital B
-0.4789054
+0.4554570
Hospital C
-0.4639895
+0.4683715
Hospital D
-0.4705098
+0.4663838
MDR.Rmd
The data set looks like this now:
head(my_TB_data)
# rifampicin isoniazid gatifloxacin ethambutol pyrazinamide moxifloxacin
-# 1 R R S R S S
-# 2 R R S R S S
-# 3 R S R S S R
-# 4 R I S R R R
-# 5 I S S R I S
-# 6 R R R S I S
+# 1 R R S S I S
+# 2 S S S R R R
+# 3 S S S S R R
+# 4 S S S R S R
+# 5 S R R R R R
+# 6 S S R S S I
# kanamycin
-# 1 I
-# 2 S
-# 3 I
+# 1 S
+# 2 R
+# 3 S
# 4 S
# 5 S
# 6 S
WHONET.Rmd
eucast_rules()
that caused an error when the input was a specific kind of tibble
+eucast_rules()
+Added tibble printing support for classes rsi
, mic
, ab
and mo
. When using tibbles containing antibiotic columns, values S
will print in green, values I
will print in yellow and values R
will print in red:
(run this on your own console, as this page does not support colour printing)
+tibble(mo = sample(AMR::microorganisms$fullname, 10),
+ drug1 = as.rsi(sample(c("S", "I", "R"), 10, replace = TRUE,
+ prob = c(0.6, 0.1, 0.3))),
+ drug2 = as.rsi(sample(c("S", "I", "R"), 10, replace = TRUE,
+ prob = c(0.6, 0.1, 0.3))),
+ drug3 = as.rsi(sample(c("S", "I", "R"), 10, replace = TRUE,
+ prob = c(0.6, 0.1, 0.3))))
atc
- using as.atc()
is now deprecated in favour of ab_atc()
and this will return a character, not the atc
class anymoreabname()
, ab_official()
, atc_name()
, atc_official()
, atc_property()
, atc_tradenames()
, atc_trivial_nl()
@@ -294,6 +305,7 @@
antibiotics
data set is now sorted by nameeucast_rules(..., verbose = TRUE)
returns more informative and readable outputguess_ab_col()
which is now 30 times faster for antibiotic abbreviationsUsing factors as input for eucast_rules()
now adds missing factors levels when the function changes antibiotic results
Function rsi_df()
to transform a data.frame
to a data set containing only the microbial interpretation (S, I, R), the antibiotic, the percentage of S/I/R and the number of available isolates. This is a convenient combination of the existing functions count_df()
and portion_df()
to immediately show resistance percentages and number of available isolates:
Support for all scientifically published pathotypes of E. coli to date (that we could find). Supported are:
@@ -332,12 +344,12 @@All these lead to the microbial ID of E. coli:
-as.mo("UPEC")
-# B_ESCHR_COL
-mo_name("UPEC")
-# "Escherichia coli"
-mo_gramstain("EHEC")
-# "Gram-negative"
as.mo("UPEC")
+# B_ESCHR_COL
+mo_name("UPEC")
+# "Escherichia coli"
+mo_gramstain("EHEC")
+# "Gram-negative"
mo_info()
as an analogy to ab_info()
. The mo_info()
prints a list with the full taxonomy, authors, and the URL to the online database of a microorganismFunction mo_synonyms()
to get all previously accepted taxonomic names of a microorganism
septic_patients %>%
- freq(age) %>%
- boxplot()
-# grouped boxplots:
-septic_patients %>%
- group_by(hospital_id) %>%
- freq(age) %>%
- boxplot()
septic_patients %>%
+ freq(age) %>%
+ boxplot()
+# grouped boxplots:
+septic_patients %>%
+ group_by(hospital_id) %>%
+ freq(age) %>%
+ boxplot()
New filters for antimicrobial classes. Use these functions to filter isolates on results in one of more antibiotics from a specific class:
-filter_aminoglycosides()
-filter_carbapenems()
-filter_cephalosporins()
-filter_1st_cephalosporins()
-filter_2nd_cephalosporins()
-filter_3rd_cephalosporins()
-filter_4th_cephalosporins()
-filter_fluoroquinolones()
-filter_glycopeptides()
-filter_macrolides()
-filter_tetracyclines()
filter_aminoglycosides()
+filter_carbapenems()
+filter_cephalosporins()
+filter_1st_cephalosporins()
+filter_2nd_cephalosporins()
+filter_3rd_cephalosporins()
+filter_4th_cephalosporins()
+filter_fluoroquinolones()
+filter_glycopeptides()
+filter_macrolides()
+filter_tetracyclines()
The antibiotics
data set will be searched, after which the input data will be checked for column names with a value in any abbreviations, codes or official names found in the antibiotics
data set. For example:
All ab_*
functions are deprecated and replaced by atc_*
functions:
ab_property -> atc_property()
-ab_name -> atc_name()
-ab_official -> atc_official()
-ab_trivial_nl -> atc_trivial_nl()
-ab_certe -> atc_certe()
-ab_umcg -> atc_umcg()
-ab_tradenames -> atc_tradenames()
ab_property -> atc_property()
+ab_name -> atc_name()
+ab_official -> atc_official()
+ab_trivial_nl -> atc_trivial_nl()
+ab_certe -> atc_certe()
+ab_umcg -> atc_umcg()
+ab_tradenames -> atc_tradenames()
as.atc()
internally. The old atc_property
has been renamed atc_online_property()
. This is done for two reasons: firstly, not all ATC codes are of antibiotics (ab) but can also be of antivirals or antifungals. Secondly, the input must have class atc
or must be coerable to this class. Properties of these classes should start with the same class name, analogous to as.mo()
and e.g. mo_genus
.set_mo_source()
and get_mo_source()
to use your own predefined MO codes as input for as.mo()
and consequently all mo_*
functionsdplyr
version 0.8.0as.atc()New function age_groups()
to split ages into custom or predefined groups (like children or elderly). This allows for easier demographic antimicrobial resistance analysis per age group.
New function ggplot_rsi_predict()
as well as the base R plot()
function can now be used for resistance prediction calculated with resistance_predict()
:
-
+
Functions filter_first_isolate()
and filter_first_weighted_isolate()
to shorten and fasten filtering on data sets with antimicrobial results, e.g.:
-
+
is equal to:
-
+
New function availability()
to check the number of available (non-empty) results in a data.frame
@@ -607,33 +619,33 @@ These functions use as.atc()
Now handles incorrect spelling, like i
instead of y
and f
instead of ph
:
-
+
Uncertainty of the algorithm is now divided into four levels, 0 to 3, where the default allow_uncertain = TRUE
is equal to uncertainty level 2. Run ?as.mo
for more info about these levels.
-# equal:
-as.mo(..., allow_uncertain = TRUE)
-as.mo(..., allow_uncertain = 2)
-
-# also equal:
-as.mo(..., allow_uncertain = FALSE)
-as.mo(..., allow_uncertain = 0)
+# equal:
+as.mo(..., allow_uncertain = TRUE)
+as.mo(..., allow_uncertain = 2)
+
+# also equal:
+as.mo(..., allow_uncertain = FALSE)
+as.mo(..., allow_uncertain = 0)
Using as.mo(..., allow_uncertain = 3)
could lead to very unreliable results.
Implemented the latest publication of Becker et al. (2019), for categorising coagulase-negative Staphylococci
All microbial IDs that found are now saved to a local file ~/.Rhistory_mo
. Use the new function clean_mo_history()
to delete this file, which resets the algorithms.
Incoercible results will now be considered ‘unknown’, MO code UNKNOWN
. On foreign systems, properties of these will be translated to all languages already previously supported: German, Dutch, French, Italian, Spanish and Portuguese:
-
+
Fix for vector containing only empty values
Finds better results when input is in other languages
@@ -679,19 +691,19 @@ Using as.mo(..., allow_uncertain = 3)
Support for tidyverse quasiquotation! Now you can create frequency tables of function outcomes:
-# Determine genus of microorganisms (mo) in `septic_patients` data set:
-# OLD WAY
-septic_patients %>%
- mutate(genus = mo_genus(mo)) %>%
- freq(genus)
-# NEW WAY
-septic_patients %>%
- freq(mo_genus(mo))
-
-# Even supports grouping variables:
-septic_patients %>%
- group_by(gender) %>%
- freq(mo_genus(mo))
+# Determine genus of microorganisms (mo) in `septic_patients` data set:
+# OLD WAY
+septic_patients %>%
+ mutate(genus = mo_genus(mo)) %>%
+ freq(genus)
+# NEW WAY
+septic_patients %>%
+ freq(mo_genus(mo))
+
+# Even supports grouping variables:
+septic_patients %>%
+ group_by(gender) %>%
+ freq(mo_genus(mo))
Header info is now available as a list, with the header
function
The parameter header
is now set to TRUE
at default, even for markdown
@@ -766,10 +778,10 @@ Using as.mo(..., allow_uncertain = 3)Fewer than 3 characters as input for as.mo
will return NA
Function as.mo
(and all mo_*
wrappers) now supports genus abbreviations with “species” attached
-
+
Added parameter combine_IR
(TRUE/FALSE) to functions portion_df
and count_df
, to indicate that all values of I and R must be merged into one, so the output only consists of S vs. IR (susceptible vs. non-susceptible)
Fix for portion_*(..., as_percent = TRUE)
when minimal number of isolates would not be met
@@ -782,15 +794,15 @@ Using as.mo(..., allow_uncertain = 3)
Support for grouping variables, test with:
-
+
Support for (un)selecting columns:
-
+
Check for hms::is.hms
@@ -870,18 +882,18 @@ Using as.mo(..., allow_uncertain = 3)
They also come with support for German, Dutch, French, Italian, Spanish and Portuguese:
-mo_gramstain("E. coli")
-# [1] "Gram negative"
-mo_gramstain("E. coli", language = "de") # German
-# [1] "Gramnegativ"
-mo_gramstain("E. coli", language = "es") # Spanish
-# [1] "Gram negativo"
-mo_fullname("S. group A", language = "pt") # Portuguese
-# [1] "Streptococcus grupo A"
+mo_gramstain("E. coli")
+# [1] "Gram negative"
+mo_gramstain("E. coli", language = "de") # German
+# [1] "Gramnegativ"
+mo_gramstain("E. coli", language = "es") # Spanish
+# [1] "Gram negativo"
+mo_fullname("S. group A", language = "pt") # Portuguese
+# [1] "Streptococcus grupo A"
Furthermore, former taxonomic names will give a note about the current taxonomic name:
-mo_gramstain("Esc blattae")
-# Note: 'Escherichia blattae' (Burgess et al., 1973) was renamed 'Shimwellia blattae' (Priest and Barker, 2010)
-# [1] "Gram negative"
+mo_gramstain("Esc blattae")
+# Note: 'Escherichia blattae' (Burgess et al., 1973) was renamed 'Shimwellia blattae' (Priest and Barker, 2010)
+# [1] "Gram negative"
Functions count_R
, count_IR
, count_I
, count_SI
and count_S
to selectively count resistant or susceptible isolates
@@ -892,18 +904,18 @@ Using as.mo(..., allow_uncertain = 3)
-
Functions as.mo
and is.mo
as replacements for as.bactid
and is.bactid
(since the microoganisms
data set not only contains bacteria). These last two functions are deprecated and will be removed in a future release. The as.mo
function determines microbial IDs using intelligent rules:
-as.mo("E. coli")
-# [1] B_ESCHR_COL
-as.mo("MRSA")
-# [1] B_STPHY_AUR
-as.mo("S group A")
-# [1] B_STRPTC_GRA
+as.mo("E. coli")
+# [1] B_ESCHR_COL
+as.mo("MRSA")
+# [1] B_STPHY_AUR
+as.mo("S group A")
+# [1] B_STRPTC_GRA
And with great speed too - on a quite regular Linux server from 2007 it takes us less than 0.02 seconds to transform 25,000 items:
-
+
- Added parameter
reference_df
for as.mo
, so users can supply their own microbial IDs, name or codes as a reference table
- Renamed all previous references to
bactid
to mo
, like:
@@ -931,12 +943,12 @@ Using as.mo(..., allow_uncertain = 3)Added three antimicrobial agents to the antibiotics
data set: Terbinafine (D01BA02), Rifaximin (A07AA11) and Isoconazole (D01AC05)
-
Added 163 trade names to the antibiotics
data set, it now contains 298 different trade names in total, e.g.:
-
+
- For
first_isolate
, rows will be ignored when there’s no species available
- Function
ratio
is now deprecated and will be removed in a future release, as it is not really the scope of this package
@@ -947,13 +959,13 @@ Using as.mo(..., allow_uncertain = 3)
-
Support for quasiquotation in the functions series count_*
and portions_*
, and n_rsi
. This allows to check for more than 2 vectors or columns.
-
+
- Edited
ggplot_rsi
and geom_rsi
so they can cope with count_df
. The new fun
parameter has value portion_df
at default, but can be set to count_df
.
- Fix for
ggplot_rsi
when the ggplot2
package was not loaded
@@ -967,12 +979,12 @@ Using as.mo(..., allow_uncertain = 3)
-
Support for types (classes) list and matrix for freq
-
+
For lists, subsetting is possible:
-
+
@@ -1206,7 +1218,7 @@ Using as.mo(..., allow_uncertain = 3)
Contents
resistance_predict(x, col_ab, col_date = NULL, year_min = NULL,
- year_max = NULL, year_every = 1, minimum = 30,
- model = "binomial", I_as_S = TRUE, preserve_measurements = TRUE,
- info = TRUE, ...)
+ year_max = NULL, year_every = 1, minimum = 30, model = NULL,
+ I_as_S = TRUE, preserve_measurements = TRUE, info = TRUE, ...)
rsi_predict(x, col_ab, col_date = NULL, year_min = NULL,
- year_max = NULL, year_every = 1, minimum = 30,
- model = "binomial", I_as_S = TRUE, preserve_measurements = TRUE,
- info = TRUE, ...)
+ year_max = NULL, year_every = 1, minimum = 30, model = NULL,
+ I_as_S = TRUE, preserve_measurements = TRUE, info = TRUE, ...)
# S3 method for resistance_predict
plot(x,
@@ -284,7 +282,7 @@
the statistical model of choice. Defaults to a generalised linear regression model with binomial distribution (i.e. using glm(..., family = binomial)
), assuming that a period of zero resistance was followed by a period of increasing resistance leading slowly to more and more resistance. See Details for valid options.
the statistical model of choice. This could be a generalised linear regression model with binomial distribution (i.e. using glm(..., family = binomial)
), assuming that a period of zero resistance was followed by a period of increasing resistance leading slowly to more and more resistance. See Details for all valid options.
# NOT RUN { -x <- resistance_predict(septic_patients, col_ab = "AMX", year_min = 2010) +x <- resistance_predict(septic_patients, col_ab = "AMX", year_min = 2010, model = "binomial") plot(x) ggplot_rsi_predict(x) @@ -353,7 +351,7 @@ x <- septic_patients %>% filter_first_isolate() %>% filter(mo_genus(mo) == "Staphylococcus") %>% - resistance_predict("PEN") + resistance_predict("PEN", model = "binomial") plot(x) @@ -369,6 +367,7 @@ filter(mo == as.mo("E. coli")) %>% resistance_predict(col_ab = "AMX", col_date = "date", + model = "binomial", info = FALSE, minimum = 15) diff --git a/man/resistance_predict.Rd b/man/resistance_predict.Rd index 3862a718..6824f899 100644 --- a/man/resistance_predict.Rd +++ b/man/resistance_predict.Rd @@ -8,14 +8,12 @@ \title{Predict antimicrobial resistance} \usage{ resistance_predict(x, col_ab, col_date = NULL, year_min = NULL, - year_max = NULL, year_every = 1, minimum = 30, - model = "binomial", I_as_S = TRUE, preserve_measurements = TRUE, - info = TRUE, ...) + year_max = NULL, year_every = 1, minimum = 30, model = NULL, + I_as_S = TRUE, preserve_measurements = TRUE, info = TRUE, ...) rsi_predict(x, col_ab, col_date = NULL, year_min = NULL, - year_max = NULL, year_every = 1, minimum = 30, - model = "binomial", I_as_S = TRUE, preserve_measurements = TRUE, - info = TRUE, ...) + year_max = NULL, year_every = 1, minimum = 30, model = NULL, + I_as_S = TRUE, preserve_measurements = TRUE, info = TRUE, ...) \method{plot}{resistance_predict}(x, main = paste("Resistance Prediction of", x_name), ...) @@ -38,7 +36,7 @@ ggplot_rsi_predict(x, main = paste("Resistance Prediction of", x_name), \item{minimum}{minimal amount of available isolates per year to include. Years containing less observations will be estimated by the model.} -\item{model}{the statistical model of choice. Defaults to a generalised linear regression model with binomial distribution (i.e. using \code{\link{glm}(..., family = \link{binomial})}), assuming that a period of zero resistance was followed by a period of increasing resistance leading slowly to more and more resistance. See Details for valid options.} +\item{model}{the statistical model of choice. This could be a generalised linear regression model with binomial distribution (i.e. using \code{\link{glm}(..., family = \link{binomial})}), assuming that a period of zero resistance was followed by a period of increasing resistance leading slowly to more and more resistance. See Details for all valid options.} \item{I_as_S}{a logical to indicate whether values \code{I} should be treated as \code{S} (will otherwise be treated as \code{R})} @@ -82,7 +80,7 @@ On our website \url{https://msberends.gitlab.io/AMR} you can find \href{https:// } \examples{ -x <- resistance_predict(septic_patients, col_ab = "AMX", year_min = 2010) +x <- resistance_predict(septic_patients, col_ab = "AMX", year_min = 2010, model = "binomial") plot(x) ggplot_rsi_predict(x) @@ -91,7 +89,7 @@ library(dplyr) x <- septic_patients \%>\% filter_first_isolate() \%>\% filter(mo_genus(mo) == "Staphylococcus") \%>\% - resistance_predict("PEN") + resistance_predict("PEN", model = "binomial") plot(x) @@ -107,6 +105,7 @@ if (!require(ggplot2)) { filter(mo == as.mo("E. coli")) \%>\% resistance_predict(col_ab = "AMX", col_date = "date", + model = "binomial", info = FALSE, minimum = 15) diff --git a/tests/testthat/test-eucast_rules.R b/tests/testthat/test-eucast_rules.R index e471de06..e10c1a55 100755 --- a/tests/testthat/test-eucast_rules.R +++ b/tests/testthat/test-eucast_rules.R @@ -34,6 +34,8 @@ test_that("EUCAST rules work", { expect_error(eucast_rules(x = "text")) expect_error(eucast_rules(data.frame(a = "test"))) expect_error(eucast_rules(data.frame(mo = "test"), rules = "invalid rules set")) + + expect_warning(eucast_rules(data.frame(mo = "Escherichia coli", vancomycin = "S"))) expect_identical(colnames(septic_patients), colnames(suppressWarnings(eucast_rules(septic_patients)))) diff --git a/tests/testthat/test-portion.R b/tests/testthat/test-portion.R index 47c473e9..ef8ff46b 100755 --- a/tests/testthat/test-portion.R +++ b/tests/testthat/test-portion.R @@ -115,6 +115,7 @@ test_that("portions works", { septic_patients$AMX %>% portion_I(), septic_patients$AMX %>% portion_R()) ) - - + + expect_error(portion_df(c("A", "B", "C"))) + expect_error(portion_df(septic_patients[,"date"])) }) diff --git a/tests/testthat/test-resistance_predict.R b/tests/testthat/test-resistance_predict.R index bb9eaca6..9767b4f6 100644 --- a/tests/testthat/test-resistance_predict.R +++ b/tests/testthat/test-resistance_predict.R @@ -32,7 +32,7 @@ test_that("prediction of rsi works", { # AMX resistance will increase according to data set `septic_patients` expect_true(AMX_R[3] < AMX_R[20]) - x <- resistance_predict(septic_patients, col_ab = "AMX", year_min = 2010) + x <- resistance_predict(septic_patients, col_ab = "AMX", year_min = 2010, model = "binomial") plot(x) ggplot_rsi_predict(x) expect_error(ggplot_rsi_predict(septic_patients)) @@ -61,19 +61,27 @@ test_that("prediction of rsi works", { col_date = "date", info = TRUE)) expect_error(rsi_predict(x = filter(septic_patients, mo == "B_ESCHR_COL"), + model = "binomial", col_ab = "NOT EXISTING COLUMN", col_date = "date", info = TRUE)) + expect_error(rsi_predict(x = filter(septic_patients, mo == "B_ESCHR_COL"), + model = "binomial", + col_ab = "AMX", + col_date = "NOT EXISTING COLUMN", + info = TRUE)) expect_error(rsi_predict(x = filter(septic_patients, mo == "B_ESCHR_COL"), col_ab = "AMX", col_date = "NOT EXISTING COLUMN", info = TRUE)) + expect_error(rsi_predict(x = filter(septic_patients, mo == "B_ESCHR_COL"), + col_ab = "AMX", + col_date = "date", + info = TRUE)) # almost all E. coli are MEM S in the Netherlands :) expect_error(resistance_predict(x = filter(septic_patients, mo == "B_ESCHR_COL"), + model = "binomial", col_ab = "MEM", col_date = "date", info = TRUE)) - - expect_error(portion_df(c("A", "B", "C"))) - expect_error(portion_df(septic_patients[,"date"])) })