Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3feb675608 | ||
|
|
e96db55bc2 | ||
|
|
49cc52e916 | ||
|
|
e665f73c92 | ||
|
|
72f176330e | ||
|
|
8ae4799471 | ||
|
|
784ee0812f | ||
|
|
d3e437e13a | ||
|
|
ec8f871100 | ||
|
|
6a000be49b | ||
|
|
d81e09bddd | ||
|
|
2c1a204ab6 | ||
|
|
e731388cb5 | ||
|
|
b3effa8a4e | ||
|
|
e81f9bcf5e | ||
|
|
8cd53d7ba4 | ||
|
|
fe6945bfad | ||
|
|
c5a5383b7b | ||
|
|
29c310e535 | ||
|
|
d247365476 | ||
|
|
64384886d7 | ||
|
|
7b50c6e9f7 | ||
|
|
100f3d6fe0 | ||
|
|
4dff2dbe6b | ||
|
|
09ffdc91e6 | ||
|
|
d6a732817a | ||
|
|
a153eb2626 | ||
|
|
0bc2afafe9 | ||
|
|
8c6795ca53 | ||
|
|
a994768452 | ||
|
|
4b476d056c | ||
|
|
eb998f6989 | ||
|
|
bdc43910ae | ||
|
|
6fd5ff2a24 | ||
|
|
68a0b3f94a | ||
|
|
d31b599825 | ||
|
|
7fe29a8401 | ||
|
|
f74da6c86a | ||
|
|
863a83ee08 | ||
|
|
b248bcc62a | ||
|
|
40b8ed3a1a | ||
|
|
90b951a48a | ||
|
|
05ea686a1e | ||
|
|
ec6f7db383 | ||
|
|
0d936e8905 | ||
|
|
f988c3273a | ||
|
|
9a91fdfb99 | ||
|
|
8438e68df5 | ||
|
|
8211647fb0 | ||
|
|
560396124f | ||
|
|
b45431b86c | ||
|
|
9667f42d3b | ||
|
|
49a3324340 | ||
|
|
ca3fb70197 | ||
|
|
f137d1a9e0 | ||
|
|
e2e3fa9184 | ||
|
|
205bfb053c | ||
|
|
553d074b96 | ||
|
|
4cc1967eab | ||
|
|
491cd94189 | ||
|
|
976d5292c7 | ||
|
|
1a10d0f4ee | ||
|
|
a1d8ec7d4a | ||
|
|
4f02b97c70 | ||
|
|
fee4bb45b1 | ||
|
|
2d869c2796 | ||
|
|
d2ff8027d1 | ||
|
|
cfc4fd0c0c | ||
|
|
f3f4586286 | ||
|
|
3f99e4a668 | ||
|
|
97c789d01f | ||
|
|
ac481f348b | ||
|
|
50592d10f1 | ||
|
|
a62a35d91d | ||
|
|
44b99f8875 | ||
|
|
964b71aedb | ||
|
|
f08c645b0c | ||
|
|
bcd6e333f0 | ||
|
|
cb53936bd3 | ||
|
|
37f397b1f3 |
@@ -1,31 +0,0 @@
|
||||
^.*\.Rproj$
|
||||
^\.Renviron$
|
||||
^\.Rprofile$
|
||||
^\.Rproj\.user$
|
||||
^\.travis\.yml$
|
||||
^\.zenodo\.json$
|
||||
^_noinclude$
|
||||
^_pkgdown\.yml$
|
||||
^appveyor\.yml$
|
||||
^codecov\.yml$
|
||||
^cran-comments\.md$
|
||||
^CRAN-RELEASE$
|
||||
^\.github$
|
||||
^doc$
|
||||
^docs$
|
||||
^git_.*\.sh$
|
||||
^index\.md$
|
||||
^installed_deps$
|
||||
^Meta$
|
||||
^pkgdown$
|
||||
^public$
|
||||
^data-raw$
|
||||
^\.lintr$
|
||||
^vignettes/AMR.Rmd$
|
||||
^vignettes/benchmarks.Rmd$
|
||||
^vignettes/EUCAST.Rmd$
|
||||
^vignettes/MDR.Rmd$
|
||||
^vignettes/PCA.Rmd$
|
||||
^vignettes/resistance_predict.Rmd$
|
||||
^vignettes/SPSS.Rmd$
|
||||
^vignettes/WHONET.Rmd$
|
||||
@@ -1,124 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- premaster
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
name: R-code-check
|
||||
|
||||
jobs:
|
||||
R-code-check:
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
|
||||
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {os: windows-latest, r: 'release'}
|
||||
- {os: macOS-latest, r: 'release'}
|
||||
- {os: ubuntu-16.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
|
||||
# - {os: windows-latest, r: 'oldrel'}
|
||||
# - {os: macOS-latest, r: 'oldrel'}
|
||||
# - {os: ubuntu-16.04, r: 'oldrel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
|
||||
- {os: windows-latest, r: 'devel'}
|
||||
- {os: macOS-latest, r: 'devel'}
|
||||
# - {os: ubuntu-16.04, r: '4.0', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
|
||||
# - {os: windows-latest, r: '3.6'}
|
||||
# - {os: ubuntu-16.04, r: '3.5', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
|
||||
# - {os: ubuntu-16.04, r: '3.4', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
|
||||
# - {os: ubuntu-16.04, r: '3.3', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
|
||||
|
||||
env:
|
||||
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
|
||||
RSPM: ${{ matrix.config.rspm }}
|
||||
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
with:
|
||||
r-version: ${{ matrix.config.r }}
|
||||
|
||||
- uses: r-lib/actions/setup-pandoc@master
|
||||
|
||||
- name: Query dependencies
|
||||
run: |
|
||||
install.packages('remotes')
|
||||
saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
|
||||
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Cache R packages
|
||||
if: runner.os != 'Windows'
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
|
||||
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-
|
||||
|
||||
- name: Install system dependencies
|
||||
if: runner.os == 'Linux'
|
||||
env:
|
||||
RHUB_PLATFORM: linux-x86_64-ubuntu-gcc
|
||||
run: |
|
||||
Rscript -e "remotes::install_github('r-hub/sysreqs')"
|
||||
sysreqs=$(Rscript -e "cat(sysreqs::sysreq_commands('DESCRIPTION'))")
|
||||
sudo -s eval "$sysreqs"
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
remotes::install_deps(dependencies = TRUE)
|
||||
remotes::install_cran("rcmdcheck")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Session info
|
||||
run: |
|
||||
options(width = 100)
|
||||
pkgs <- installed.packages()[, "Package"]
|
||||
sessioninfo::session_info(pkgs, include_base = TRUE)
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Check
|
||||
env:
|
||||
_R_CHECK_CRAN_INCOMING_: false
|
||||
run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Show testthat output
|
||||
if: always()
|
||||
run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true
|
||||
shell: bash
|
||||
|
||||
- name: Upload check results
|
||||
if: failure()
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
|
||||
path: check
|
||||
@@ -1,67 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
name: code-tested
|
||||
|
||||
jobs:
|
||||
code-tested:
|
||||
runs-on: macOS-latest
|
||||
env:
|
||||
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
|
||||
- uses: r-lib/actions/setup-pandoc@master
|
||||
|
||||
- name: Query dependencies
|
||||
run: |
|
||||
install.packages('remotes')
|
||||
saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
|
||||
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Cache R packages
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
|
||||
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
install.packages(c("remotes"))
|
||||
remotes::install_deps(dependencies = TRUE)
|
||||
remotes::install_cran("covr")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Test coverage
|
||||
run: covr::codecov(line_exclusions = list("R/atc_online.R", "R/mo_source.R", "R/resistance_predict.R", "R/aa_helper_functions_dplyr.R"))
|
||||
shell: Rscript {0}
|
||||
@@ -1,67 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- premaster
|
||||
- master
|
||||
pull_request:
|
||||
branches:
|
||||
- premaster
|
||||
- master
|
||||
|
||||
name: lintr
|
||||
|
||||
jobs:
|
||||
lintr:
|
||||
runs-on: macOS-latest
|
||||
env:
|
||||
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- uses: r-lib/actions/setup-r@master
|
||||
|
||||
- name: Query dependencies
|
||||
run: |
|
||||
install.packages('remotes')
|
||||
saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
|
||||
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Cache R packages
|
||||
uses: actions/cache@v1
|
||||
with:
|
||||
path: ${{ env.R_LIBS_USER }}
|
||||
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
|
||||
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
install.packages(c("remotes"))
|
||||
remotes::install_deps(dependencies = TRUE)
|
||||
remotes::install_cran("lintr")
|
||||
shell: Rscript {0}
|
||||
|
||||
- name: Lint
|
||||
run: lintr::lint_package(linters = lintr::with_defaults(line_length_linter = NULL, trailing_whitespace_linter = NULL, object_name_linter = NULL, cyclocomp_linter = NULL, object_usage_linter = NULL, object_length_linter = lintr::object_length_linter(length = 50L)), exclusions = list("R/aa_helper_functions_dplyr.R"))
|
||||
shell: Rscript {0}
|
||||
@@ -1,26 +0,0 @@
|
||||
Meta
|
||||
doc
|
||||
.Renviron
|
||||
.Rproj.user
|
||||
.Rhistory
|
||||
.RData
|
||||
.Ruserdata
|
||||
AMR.Rproj
|
||||
tests/testthat/Rplots.pdf
|
||||
inst/doc
|
||||
/src/*.o
|
||||
/src/*.o-*
|
||||
/src/*.d
|
||||
/src/*.so
|
||||
_noinclude
|
||||
*.dll
|
||||
vignettes/*.R
|
||||
.DS_Store
|
||||
.Rprofile
|
||||
^CRAN-RELEASE$
|
||||
packrat/lib*/
|
||||
packrat/src/
|
||||
data-raw/taxa.txt
|
||||
data-raw/taxon.tab
|
||||
data-raw/DSMZ_bactnames.xlsx
|
||||
data-raw/country_analysis_url_token.R
|
||||
@@ -0,0 +1,189 @@
|
||||
<!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="16x16" href="https://msberends.github.io/AMR/favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="https://msberends.github.io/AMR/favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="https://msberends.github.io/AMR/apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="https://msberends.github.io/AMR/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="https://msberends.github.io/AMR/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="https://msberends.github.io/AMR/apple-touch-icon-60x60.png">
|
||||
<script src="https://msberends.github.io/AMR/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://msberends.github.io/AMR/deps/bootstrap-5.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="https://msberends.github.io/AMR/deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="https://msberends.github.io/AMR/deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="https://msberends.github.io/AMR/pkgdown.js"></script><link href="https://msberends.github.io/AMR/extra.css" rel="stylesheet">
|
||||
<script src="https://msberends.github.io/AMR/extra.js"></script><meta property="og:title" content="Page not found (404)">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="https://msberends.github.io/AMR/#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><div class="container">
|
||||
|
||||
<a class="navbar-brand me-2" href="https://msberends.github.io/AMR/index.html">AMR (for R)</a>
|
||||
|
||||
<small class="nav-text text-muted me-auto" data-bs-toggle="tooltip" data-bs-placement="bottom" title="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="https://msberends.github.io/AMR/index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="https://msberends.github.io/AMR/#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="https://msberends.github.io/AMR/reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://msberends.github.io/AMR/reference/index.html">
|
||||
<span class="fa fa-book-open"></span>
|
||||
|
||||
Manual
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://msberends.github.io/AMR/authors.html">
|
||||
<span class="fa fa-users"></span>
|
||||
|
||||
Authors
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://msberends.github.io/AMR/news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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://msberends.github.io/AMR/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></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 359 KiB |
@@ -1,56 +0,0 @@
|
||||
Package: AMR
|
||||
Version: 1.3.0
|
||||
Date: 2020-07-31
|
||||
Title: Antimicrobial Resistance Analysis
|
||||
Authors@R: c(
|
||||
person(role = c("aut", "cre"),
|
||||
family = "Berends", given = c("Matthijs", "S."), email = "m.s.berends@umcg.nl", comment = c(ORCID = "0000-0001-7620-1800")),
|
||||
person(role = c("aut", "ctb"),
|
||||
family = "Luz", given = c("Christian", "F."), email = "c.f.luz@umcg.nl", comment = c(ORCID = "0000-0001-5809-5995")),
|
||||
person(role = c("aut", "ths"),
|
||||
family = "Friedrich", given = c("Alexander", "W."), email = "alex.friedrich@umcg.nl", comment = c(ORCID = "0000-0003-4881-038X")),
|
||||
person(role = c("aut", "ths"),
|
||||
family = "Sinha", given = c("Bhanu", "N.", "M."), email = "b.sinha@umcg.nl", comment = c(ORCID = "0000-0003-1634-0010")),
|
||||
person(role = c("aut", "ths"),
|
||||
family = "Albers", given = c("Casper", "J."), email = "c.j.albers@rug.nl", comment = c(ORCID = "0000-0002-9213-6743")),
|
||||
person(role = c("aut", "ths"),
|
||||
family = "Glasner", given = "Corinna", email = "c.glasner@umcg.nl", comment = c(ORCID = "0000-0003-1241-1328")),
|
||||
person(role = "ctb",
|
||||
family = "Fonville", given = c("Judith", "M."), email = "j.fonville@pamm.nl"),
|
||||
person(role = "ctb",
|
||||
family = "Hassing", given = c("Erwin", "E.", "A."), email = "e.hassing@certe.nl"),
|
||||
person(role = "ctb",
|
||||
family = "Hazenberg", given = c("Eric", "H.", "L.", "C.", "M."), email = "e.hazenberg@jbz.nl"),
|
||||
person(role = "ctb",
|
||||
family = "Lenglet", given = "Annick", email = "annick.lenglet@amsterdam.msf.org"),
|
||||
person(role = "ctb",
|
||||
family = "Meijer", given = c("Bart", "C."), email = "b.meijerg@certe.nl"),
|
||||
person(role = "ctb",
|
||||
family = "Ny", given = "Sofia", email = "sofia.ny@folkhalsomyndigheten.se"),
|
||||
person(role = "ctb",
|
||||
family = "Souverein", given = "Dennis", email = "d.souvereing@streeklabhaarlem.nl"))
|
||||
Description: Functions to simplify the analysis and prediction of Antimicrobial
|
||||
Resistance (AMR) and to work with microbial and antimicrobial properties by
|
||||
using evidence-based methods, like those defined by Leclercq et al. (2013)
|
||||
<doi:10.1111/j.1469-0691.2011.03703.x> and the Clinical and Laboratory
|
||||
Standards Institute (2014) <isbn: 1-56238-899-1>.
|
||||
Depends:
|
||||
R (>= 3.0.0)
|
||||
Suggests:
|
||||
cleaner,
|
||||
dplyr,
|
||||
ggplot2,
|
||||
knitr,
|
||||
microbenchmark,
|
||||
rmarkdown,
|
||||
testthat,
|
||||
tidyr,
|
||||
utils
|
||||
VignetteBuilder: knitr,rmarkdown
|
||||
URL: https://msberends.github.io/AMR, https://github.com/msberends/AMR
|
||||
BugReports: https://github.com/msberends/AMR/issues
|
||||
License: GPL-2 | file LICENSE
|
||||
Encoding: UTF-8
|
||||
LazyData: true
|
||||
RoxygenNote: 7.1.1
|
||||
Roxygen: list(markdown = TRUE)
|
||||
@@ -1,248 +0,0 @@
|
||||
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
|
||||
@@ -1,231 +1,134 @@
|
||||
<!-- Generated by pkgdown: do not edit by hand -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>License • AMR (for R)</title>
|
||||
|
||||
<!-- favicons -->
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="apple-touch-icon.png" />
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="apple-touch-icon-120x120.png" />
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="apple-touch-icon-76x76.png" />
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="apple-touch-icon-60x60.png" />
|
||||
|
||||
<!-- jquery -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
|
||||
<!-- Bootstrap -->
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.4.0/flatly/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous" />
|
||||
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js" integrity="sha256-nuL8/2cJ5NDSSwnKD8VqreErSWHtnEP9E7AySL+1ev4=" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- bootstrap-toc -->
|
||||
<link rel="stylesheet" href="bootstrap-toc.css">
|
||||
<script src="bootstrap-toc.js"></script>
|
||||
|
||||
<!-- Font Awesome icons -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous" />
|
||||
|
||||
<!-- clipboard.js -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- headroom.js -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script>
|
||||
|
||||
<!-- pkgdown -->
|
||||
<link href="pkgdown.css" rel="stylesheet">
|
||||
<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://msberends.github.io/AMR/logo.svg" />
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- mathjax -->
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script>
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<!-- 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="16x16" href="favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png"><link rel="apple-touch-icon" type="image/png" sizes="180x180" href="apple-touch-icon.png"><link rel="apple-touch-icon" type="image/png" sizes="120x120" href="apple-touch-icon-120x120.png"><link rel="apple-touch-icon" type="image/png" sizes="76x76" href="apple-touch-icon-76x76.png"><link rel="apple-touch-icon" type="image/png" sizes="60x60" href="apple-touch-icon-60x60.png"><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.2.2/bootstrap.min.css" rel="stylesheet"><script src="deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="deps/Fira_Code-0.4.4/font.css" rel="stylesheet"><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous"><!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></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://msberends.github.io/AMR/logo.svg"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@msberends"><meta name="twitter:site" content="@msberends"><!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
<![endif]--></head><body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</small>
|
||||
|
||||
</head>
|
||||
|
||||
<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>
|
||||
|
||||
<body data-spy="scroll" data-target="#toc">
|
||||
<div class="container template-title-body">
|
||||
<header>
|
||||
<div class="navbar navbar-default navbar-fixed-top" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<span class="navbar-brand">
|
||||
<a class="navbar-link" href="index.html">AMR (for R)</a>
|
||||
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.3.0</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div id="navbar" class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li>
|
||||
<a href="index.html">
|
||||
<div id="navbar" class="collapse navbar-collapse ms-3">
|
||||
<ul class="navbar-nav me-auto"><li class="nav-item">
|
||||
<a class="nav-link" href="index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li>
|
||||
<a href="articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get properties of a microorganism
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="articles/benchmarks.html">
|
||||
<span class="fa fa-shipping-fast"></span>
|
||||
|
||||
Other: benchmarks
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<a href="reference/index.html">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="reference/index.html">
|
||||
<span class="fa fa-book-open"></span>
|
||||
|
||||
Manual
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="authors.html">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="authors.html">
|
||||
<span class="fa fa-users"></span>
|
||||
|
||||
Authors
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="news/index.html">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<a href="https://github.com/msberends/AMR">
|
||||
</ul><form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="search.json" id="search-input" placeholder="Search for" autocomplete="off"></form>
|
||||
|
||||
<ul class="navbar-nav"><li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab fa-github"></span>
|
||||
|
||||
Source Code
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="survey.html">
|
||||
<span class="fa fa-clipboard-list"></span>
|
||||
|
||||
Survey
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
</div><!--/.nav-collapse -->
|
||||
</div><!--/.container -->
|
||||
</div><!--/.navbar -->
|
||||
|
||||
|
||||
|
||||
</header>
|
||||
</ul></div>
|
||||
|
||||
|
||||
</div>
|
||||
</nav><div class="container template-title-body">
|
||||
<div class="row">
|
||||
<div class="contents col-md-9">
|
||||
<div class="page-header">
|
||||
<h1>License</h1>
|
||||
<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
|
||||
@@ -478,34 +381,22 @@ POSSIBILITY OF SUCH DAMAGES.
|
||||
END OF TERMS AND CONDITIONS
|
||||
</pre>
|
||||
|
||||
</div>
|
||||
</main></div>
|
||||
|
||||
<div class="col-md-3 hidden-xs hidden-sm" id="pkgdown-sidebar">
|
||||
<nav id="toc" data-toggle="toc" class="sticky-top">
|
||||
<h2 data-toc-skip>Contents</h2>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p><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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer>
|
||||
<div class="copyright">
|
||||
<p>Developed by <a href='https://www.rug.nl/staff/m.s.berends/'>Matthijs S. Berends</a>, <a href='https://www.rug.nl/staff/c.f.luz/'>Christian F. Luz</a>, <a href='https://www.rug.nl/staff/a.w.friedrich/'>Alexander W. Friedrich</a>, <a href='https://www.rug.nl/staff/b.sinha/'>Bhanu N. M. Sinha</a>, <a href='https://www.rug.nl/staff/c.j.albers/'>Casper J. Albers</a>, <a href='https://www.rug.nl/staff/c.glasner/'>Corinna Glasner</a>.</p>
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p><p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown">
|
||||
<p>Site built with <a href="https://pkgdown.r-lib.org/">pkgdown</a> 1.5.1.</p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
</footer></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
</body></html>
|
||||
|
||||
@@ -1,228 +0,0 @@
|
||||
# Generated by roxygen2: do not edit by hand
|
||||
|
||||
S3method("[",ab)
|
||||
S3method("[",disk)
|
||||
S3method("[",mic)
|
||||
S3method("[",mo)
|
||||
S3method("[<-",ab)
|
||||
S3method("[<-",disk)
|
||||
S3method("[<-",mic)
|
||||
S3method("[<-",mo)
|
||||
S3method("[<-",rsi)
|
||||
S3method("[[",ab)
|
||||
S3method("[[",disk)
|
||||
S3method("[[",mic)
|
||||
S3method("[[",mo)
|
||||
S3method("[[<-",ab)
|
||||
S3method("[[<-",disk)
|
||||
S3method("[[<-",mic)
|
||||
S3method("[[<-",mo)
|
||||
S3method("[[<-",rsi)
|
||||
S3method(as.data.frame,ab)
|
||||
S3method(as.data.frame,mo)
|
||||
S3method(as.double,mic)
|
||||
S3method(as.integer,mic)
|
||||
S3method(as.numeric,mic)
|
||||
S3method(as.rsi,data.frame)
|
||||
S3method(as.rsi,default)
|
||||
S3method(as.rsi,disk)
|
||||
S3method(as.rsi,mic)
|
||||
S3method(barplot,mic)
|
||||
S3method(barplot,rsi)
|
||||
S3method(c,ab)
|
||||
S3method(c,disk)
|
||||
S3method(c,mic)
|
||||
S3method(c,mo)
|
||||
S3method(c,rsi)
|
||||
S3method(droplevels,mic)
|
||||
S3method(droplevels,rsi)
|
||||
S3method(format,bug_drug_combinations)
|
||||
S3method(kurtosis,data.frame)
|
||||
S3method(kurtosis,default)
|
||||
S3method(kurtosis,matrix)
|
||||
S3method(plot,mic)
|
||||
S3method(plot,resistance_predict)
|
||||
S3method(plot,rsi)
|
||||
S3method(print,ab)
|
||||
S3method(print,bug_drug_combinations)
|
||||
S3method(print,catalogue_of_life_version)
|
||||
S3method(print,disk)
|
||||
S3method(print,mic)
|
||||
S3method(print,mo)
|
||||
S3method(print,mo_renamed)
|
||||
S3method(print,mo_uncertainties)
|
||||
S3method(print,rsi)
|
||||
S3method(skewness,data.frame)
|
||||
S3method(skewness,default)
|
||||
S3method(skewness,matrix)
|
||||
S3method(summary,mic)
|
||||
S3method(summary,mo)
|
||||
S3method(summary,rsi)
|
||||
export("%like%")
|
||||
export("%like_case%")
|
||||
export(ab_atc)
|
||||
export(ab_atc_group1)
|
||||
export(ab_atc_group2)
|
||||
export(ab_cid)
|
||||
export(ab_class)
|
||||
export(ab_ddd)
|
||||
export(ab_from_text)
|
||||
export(ab_group)
|
||||
export(ab_info)
|
||||
export(ab_loinc)
|
||||
export(ab_name)
|
||||
export(ab_property)
|
||||
export(ab_synonyms)
|
||||
export(ab_tradenames)
|
||||
export(ab_url)
|
||||
export(age)
|
||||
export(age_groups)
|
||||
export(aminoglycosides)
|
||||
export(anti_join_microorganisms)
|
||||
export(as.ab)
|
||||
export(as.disk)
|
||||
export(as.mic)
|
||||
export(as.mo)
|
||||
export(as.rsi)
|
||||
export(atc_online_ddd)
|
||||
export(atc_online_groups)
|
||||
export(atc_online_property)
|
||||
export(availability)
|
||||
export(brmo)
|
||||
export(bug_drug_combinations)
|
||||
export(carbapenems)
|
||||
export(catalogue_of_life_version)
|
||||
export(cephalosporins)
|
||||
export(cephalosporins_1st)
|
||||
export(cephalosporins_2nd)
|
||||
export(cephalosporins_3rd)
|
||||
export(cephalosporins_4th)
|
||||
export(cephalosporins_5th)
|
||||
export(count_I)
|
||||
export(count_IR)
|
||||
export(count_R)
|
||||
export(count_S)
|
||||
export(count_SI)
|
||||
export(count_all)
|
||||
export(count_df)
|
||||
export(count_resistant)
|
||||
export(count_susceptible)
|
||||
export(eucast_exceptional_phenotypes)
|
||||
export(eucast_rules)
|
||||
export(facet_rsi)
|
||||
export(filter_1st_cephalosporins)
|
||||
export(filter_2nd_cephalosporins)
|
||||
export(filter_3rd_cephalosporins)
|
||||
export(filter_4th_cephalosporins)
|
||||
export(filter_5th_cephalosporins)
|
||||
export(filter_ab_class)
|
||||
export(filter_aminoglycosides)
|
||||
export(filter_carbapenems)
|
||||
export(filter_cephalosporins)
|
||||
export(filter_first_isolate)
|
||||
export(filter_first_weighted_isolate)
|
||||
export(filter_fluoroquinolones)
|
||||
export(filter_glycopeptides)
|
||||
export(filter_macrolides)
|
||||
export(filter_penicillins)
|
||||
export(filter_tetracyclines)
|
||||
export(first_isolate)
|
||||
export(fluoroquinolones)
|
||||
export(full_join_microorganisms)
|
||||
export(g.test)
|
||||
export(geom_rsi)
|
||||
export(get_locale)
|
||||
export(get_mo_source)
|
||||
export(ggplot_pca)
|
||||
export(ggplot_rsi)
|
||||
export(ggplot_rsi_predict)
|
||||
export(glycopeptides)
|
||||
export(guess_ab_col)
|
||||
export(inner_join_microorganisms)
|
||||
export(is.ab)
|
||||
export(is.disk)
|
||||
export(is.mic)
|
||||
export(is.mo)
|
||||
export(is.rsi)
|
||||
export(is.rsi.eligible)
|
||||
export(key_antibiotics)
|
||||
export(key_antibiotics_equal)
|
||||
export(kurtosis)
|
||||
export(labels_rsi_count)
|
||||
export(left_join_microorganisms)
|
||||
export(like)
|
||||
export(macrolides)
|
||||
export(mdr_cmi2012)
|
||||
export(mdr_tb)
|
||||
export(mdro)
|
||||
export(mo_authors)
|
||||
export(mo_class)
|
||||
export(mo_domain)
|
||||
export(mo_failures)
|
||||
export(mo_family)
|
||||
export(mo_fullname)
|
||||
export(mo_genus)
|
||||
export(mo_gramstain)
|
||||
export(mo_info)
|
||||
export(mo_kingdom)
|
||||
export(mo_name)
|
||||
export(mo_order)
|
||||
export(mo_phylum)
|
||||
export(mo_property)
|
||||
export(mo_rank)
|
||||
export(mo_ref)
|
||||
export(mo_renamed)
|
||||
export(mo_shortname)
|
||||
export(mo_snomed)
|
||||
export(mo_species)
|
||||
export(mo_subspecies)
|
||||
export(mo_synonyms)
|
||||
export(mo_taxonomy)
|
||||
export(mo_type)
|
||||
export(mo_uncertainties)
|
||||
export(mo_url)
|
||||
export(mo_year)
|
||||
export(mrgn)
|
||||
export(n_rsi)
|
||||
export(p_symbol)
|
||||
export(pca)
|
||||
export(penicillins)
|
||||
export(portion_I)
|
||||
export(portion_IR)
|
||||
export(portion_R)
|
||||
export(portion_S)
|
||||
export(portion_SI)
|
||||
export(portion_df)
|
||||
export(proportion_I)
|
||||
export(proportion_IR)
|
||||
export(proportion_R)
|
||||
export(proportion_S)
|
||||
export(proportion_SI)
|
||||
export(proportion_df)
|
||||
export(resistance)
|
||||
export(resistance_predict)
|
||||
export(right_join_microorganisms)
|
||||
export(rsi_df)
|
||||
export(rsi_predict)
|
||||
export(scale_rsi_colours)
|
||||
export(scale_y_percent)
|
||||
export(semi_join_microorganisms)
|
||||
export(set_mo_source)
|
||||
export(skewness)
|
||||
export(susceptibility)
|
||||
export(tetracyclines)
|
||||
export(theme_rsi)
|
||||
importFrom(graphics,arrows)
|
||||
importFrom(graphics,axis)
|
||||
importFrom(graphics,barplot)
|
||||
importFrom(graphics,par)
|
||||
importFrom(graphics,points)
|
||||
importFrom(graphics,text)
|
||||
importFrom(stats,complete.cases)
|
||||
importFrom(stats,glm)
|
||||
importFrom(stats,lm)
|
||||
importFrom(stats,pchisq)
|
||||
importFrom(stats,prcomp)
|
||||
importFrom(stats,predict)
|
||||
importFrom(stats,qchisq)
|
||||
importFrom(stats,var)
|
||||
@@ -1,539 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
# functions from dplyr, will perhaps become poorman
|
||||
distinct <- function(.data, ..., .keep_all = FALSE) {
|
||||
check_is_dataframe(.data)
|
||||
if ("grouped_data" %in% class(.data)) {
|
||||
distinct.grouped_data(.data, ..., .keep_all = .keep_all)
|
||||
} else {
|
||||
distinct.default(.data, ..., .keep_all = .keep_all)
|
||||
}
|
||||
}
|
||||
distinct.default <- function(.data, ..., .keep_all = FALSE) {
|
||||
names <- rownames(.data)
|
||||
rownames(.data) <- NULL
|
||||
if (length(deparse_dots(...)) == 0) {
|
||||
selected <- .data
|
||||
} else {
|
||||
selected <- select(.data, ...)
|
||||
}
|
||||
rows <- as.integer(rownames(unique(selected)))
|
||||
if (isTRUE(.keep_all)) {
|
||||
res <- .data[rows, , drop = FALSE]
|
||||
} else {
|
||||
res <- selected[rows, , drop = FALSE]
|
||||
}
|
||||
rownames(res) <- names[rows]
|
||||
res
|
||||
}
|
||||
distinct.grouped_data <- function(.data, ..., .keep_all = FALSE) {
|
||||
apply_grouped_function(.data, "distinct", ..., .keep_all = .keep_all)
|
||||
}
|
||||
filter_join_worker <- function(x, y, by = NULL, type = c("anti", "semi")) {
|
||||
type <- match.arg(type, choices = c("anti", "semi"), several.ok = FALSE)
|
||||
if (is.null(by)) {
|
||||
by <- intersect(names(x), names(y))
|
||||
join_message(by)
|
||||
}
|
||||
rows <- interaction(x[, by]) %in% interaction(y[, by])
|
||||
if (type == "anti") rows <- !rows
|
||||
res <- x[rows, , drop = FALSE]
|
||||
rownames(res) <- NULL
|
||||
res
|
||||
}
|
||||
|
||||
# No export, no Rd
|
||||
addin_insert_in <- function() {
|
||||
import_fn("insertText", "rstudioapi")(" %in% ")
|
||||
}
|
||||
|
||||
# No export, no Rd
|
||||
addin_insert_like <- function() {
|
||||
import_fn("insertText", "rstudioapi")(" %like% ")
|
||||
}
|
||||
|
||||
check_dataset_integrity <- function() {
|
||||
# check if user overwrote our data sets in their global environment
|
||||
data_in_pkg <- data(package = "AMR", envir = asNamespace("AMR"))$results[, "Item", drop = TRUE]
|
||||
data_in_globalenv <- ls(envir = globalenv())
|
||||
overwritten <- data_in_pkg[data_in_pkg %in% data_in_globalenv]
|
||||
stop_if(length(overwritten) > 0,
|
||||
"the following data set is overwritten by your global environment and prevents the AMR package from working correctly:\n",
|
||||
paste0("'", overwritten, "'", collapse = ", "),
|
||||
".\nPlease rename your object before using this function.", call = FALSE)
|
||||
# check if other packages did not overwrite our data sets
|
||||
tryCatch({
|
||||
check_microorganisms <- all(c("mo", "fullname", "kingdom", "phylum",
|
||||
"class", "order", "family", "genus",
|
||||
"species", "subspecies", "rank",
|
||||
"species_id", "source", "ref", "prevalence") %in% colnames(microorganisms),
|
||||
na.rm = TRUE)
|
||||
check_antibiotics <- all(c("ab", "atc", "cid", "name", "group",
|
||||
"atc_group1", "atc_group2", "abbreviations",
|
||||
"synonyms", "oral_ddd", "oral_units",
|
||||
"iv_ddd", "iv_units", "loinc") %in% colnames(antibiotics),
|
||||
na.rm = TRUE)
|
||||
}, error = function(e)
|
||||
stop_('please use the command \'library("AMR")\' before using this function, to load the required reference data.', call = FALSE)
|
||||
)
|
||||
invisible(TRUE)
|
||||
}
|
||||
|
||||
search_type_in_df <- function(x, type) {
|
||||
# try to find columns based on type
|
||||
found <- NULL
|
||||
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
colnames(x) <- trimws(colnames(x))
|
||||
|
||||
# -- mo
|
||||
if (type == "mo") {
|
||||
if (any(sapply(x, is.mo))) {
|
||||
found <- sort(colnames(x)[sapply(x, is.mo)])[1]
|
||||
} else if ("mo" %in% colnames(x) &
|
||||
suppressWarnings(
|
||||
all(x$mo %in% c(NA,
|
||||
microorganisms$mo,
|
||||
microorganisms.translation$mo_old)))) {
|
||||
found <- "mo"
|
||||
} else if (any(colnames(x) %like% "^(mo|microorganism|organism|bacteria|ba[ck]terie)s?$")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "^(mo|microorganism|organism|bacteria|ba[ck]terie)s?$"])[1]
|
||||
} else if (any(colnames(x) %like% "^(microorganism|organism|bacteria|ba[ck]terie)")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "^(microorganism|organism|bacteria|ba[ck]terie)"])[1]
|
||||
} else if (any(colnames(x) %like% "species")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "species"])[1]
|
||||
}
|
||||
|
||||
}
|
||||
# -- key antibiotics
|
||||
if (type == "keyantibiotics") {
|
||||
if (any(colnames(x) %like% "^key.*(ab|antibiotics)")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "^key.*(ab|antibiotics)"])[1]
|
||||
}
|
||||
}
|
||||
# -- date
|
||||
if (type == "date") {
|
||||
if (any(colnames(x) %like% "^(specimen date|specimen_date|spec_date)")) {
|
||||
# WHONET support
|
||||
found <- sort(colnames(x)[colnames(x) %like% "^(specimen date|specimen_date|spec_date)"])[1]
|
||||
if (!any(class(pull(x, found)) %in% c("Date", "POSIXct"))) {
|
||||
stop(font_red(paste0("ERROR: Found column `", font_bold(found), "` to be used as input for `col_", type,
|
||||
"`, but this column contains no valid dates. Transform its values to valid dates first.")),
|
||||
call. = FALSE)
|
||||
}
|
||||
} else if (any(sapply(x, function(x) inherits(x, c("Date", "POSIXct"))))) {
|
||||
found <- sort(colnames(x)[sapply(x, function(x) inherits(x, c("Date", "POSIXct")))])[1]
|
||||
}
|
||||
}
|
||||
# -- patient id
|
||||
if (type == "patient_id") {
|
||||
if (any(colnames(x) %like% "^(identification |patient|patid)")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "^(identification |patient|patid)"])[1]
|
||||
}
|
||||
}
|
||||
# -- specimen
|
||||
if (type == "specimen") {
|
||||
if (any(colnames(x) %like% "(specimen type|spec_type)")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "(specimen type|spec_type)"])[1]
|
||||
} else if (any(colnames(x) %like% "^(specimen)")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "^(specimen)"])[1]
|
||||
}
|
||||
}
|
||||
# -- UTI (urinary tract infection)
|
||||
if (type == "uti") {
|
||||
if (any(colnames(x) == "uti")) {
|
||||
found <- colnames(x)[colnames(x) == "uti"][1]
|
||||
} else if (any(colnames(x) %like% "(urine|urinary)")) {
|
||||
found <- sort(colnames(x)[colnames(x) %like% "(urine|urinary)"])[1]
|
||||
}
|
||||
if (!is.null(found)) {
|
||||
# this column should contain logicals
|
||||
if (!is.logical(x[, found, drop = TRUE])) {
|
||||
message(font_red(paste0("NOTE: Column `", font_bold(found), "` found as input for `col_", type,
|
||||
"`, but this column does not contain 'logical' values (TRUE/FALSE) and was ignored.")))
|
||||
found <- NULL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!is.null(found)) {
|
||||
msg <- paste0("NOTE: Using column `", font_bold(found), "` as input for `col_", type, "`.")
|
||||
if (type %in% c("keyantibiotics", "specimen")) {
|
||||
msg <- paste(msg, "Use", font_bold(paste0("col_", type), "= FALSE"), "to prevent this.")
|
||||
}
|
||||
message(font_blue(msg))
|
||||
}
|
||||
found
|
||||
}
|
||||
|
||||
stop_ifnot_installed <- function(package) {
|
||||
# no "utils::installed.packages()" since it requires non-staged install since R 3.6.0
|
||||
# https://developer.r-project.org/Blog/public/2019/02/14/staged-install/index.html
|
||||
sapply(package, function(pkg)
|
||||
tryCatch(get(".packageName", envir = asNamespace(pkg)),
|
||||
error = function(e) {
|
||||
if (package == "rstudioapi") {
|
||||
stop("This function only works in RStudio.", call. = FALSE)
|
||||
} else if (pkg != "base") {
|
||||
stop("package '", pkg, "' required but not installed.",
|
||||
"\nTry to install it with: install.packages(\"", pkg, "\")",
|
||||
call. = FALSE)
|
||||
}
|
||||
}))
|
||||
return(invisible())
|
||||
}
|
||||
|
||||
import_fn <- function(name, pkg) {
|
||||
stop_ifnot_installed(pkg)
|
||||
tryCatch(
|
||||
get(name, envir = asNamespace(pkg)),
|
||||
error = function(e) stop_("an error occurred in import_fn() while using this function", call = FALSE))
|
||||
}
|
||||
|
||||
stop_ <- function(..., call = TRUE) {
|
||||
msg <- paste0(c(...), collapse = "")
|
||||
if (!isFALSE(call)) {
|
||||
if (isTRUE(call)) {
|
||||
call <- as.character(sys.call(-1)[1])
|
||||
} else {
|
||||
# so you can go back more than 1 call, as used in rsi_calc(), that now throws a reference to e.g. n_rsi()
|
||||
call <- as.character(sys.call(call)[1])
|
||||
}
|
||||
msg <- paste0("in ", call, "(): ", msg)
|
||||
}
|
||||
stop(msg, call. = FALSE)
|
||||
}
|
||||
|
||||
stop_if <- function(expr, ..., call = TRUE) {
|
||||
if (isTRUE(expr)) {
|
||||
if (isTRUE(call)) {
|
||||
call <- -1
|
||||
}
|
||||
if (!isFALSE(call)) {
|
||||
# since we're calling stop_(), which is another call
|
||||
call <- call - 1
|
||||
}
|
||||
stop_(..., call = call)
|
||||
}
|
||||
}
|
||||
|
||||
stop_ifnot <- function(expr, ..., call = TRUE) {
|
||||
if (!isTRUE(expr)) {
|
||||
if (isTRUE(call)) {
|
||||
call <- -1
|
||||
}
|
||||
if (!isFALSE(call)) {
|
||||
# since we're calling stop_(), which is another call
|
||||
call <- call - 1
|
||||
}
|
||||
stop_(..., call = call)
|
||||
}
|
||||
}
|
||||
|
||||
"%or%" <- function(x, y) {
|
||||
if (is.null(x) | is.null(y)) {
|
||||
if (is.null(x)) {
|
||||
return(y)
|
||||
} else {
|
||||
return(x)
|
||||
}
|
||||
}
|
||||
ifelse(!is.na(x),
|
||||
x,
|
||||
ifelse(!is.na(y), y, NA))
|
||||
}
|
||||
|
||||
class_integrity_check <- function(value, type, check_vector) {
|
||||
if (!all(value[!is.na(value)] %in% check_vector)) {
|
||||
warning(paste0("invalid ", type, ", NA generated"), call. = FALSE)
|
||||
value[!value %in% check_vector] <- NA
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
# transforms data set to data.frame with only ASCII values, to comply with CRAN policies
|
||||
dataset_UTF8_to_ASCII <- function(df) {
|
||||
trans <- function(vect) {
|
||||
iconv(vect, from = "UTF-8", to = "ASCII//TRANSLIT")
|
||||
}
|
||||
df <- as.data.frame(df, stringsAsFactors = FALSE)
|
||||
for (i in seq_len(NCOL(df))) {
|
||||
col <- df[, i]
|
||||
if (is.list(col)) {
|
||||
col <- lapply(col, function(j) trans(j))
|
||||
df[, i] <- list(col)
|
||||
} else {
|
||||
if (is.factor(col)) {
|
||||
levels(col) <- trans(levels(col))
|
||||
} else if (is.character(col)) {
|
||||
col <- trans(col)
|
||||
} else {
|
||||
col
|
||||
}
|
||||
df[, i] <- col
|
||||
}
|
||||
}
|
||||
df
|
||||
}
|
||||
|
||||
has_colour <- function() {
|
||||
# this is a base R version of crayon::has_color
|
||||
enabled <- getOption("crayon.enabled")
|
||||
if (!is.null(enabled)) {
|
||||
return(isTRUE(enabled))
|
||||
}
|
||||
rstudio_with_ansi_support <- function(x) {
|
||||
if (Sys.getenv("RSTUDIO", "") == "") {
|
||||
return(FALSE)
|
||||
}
|
||||
if ((cols <- Sys.getenv("RSTUDIO_CONSOLE_COLOR", "")) != "" && !is.na(as.numeric(cols))) {
|
||||
return(TRUE)
|
||||
}
|
||||
tryCatch(get("isAvailable", envir = asNamespace("rstudioapi"))(), error = function(e) return(FALSE)) &&
|
||||
tryCatch(get("hasFun", envir = asNamespace("rstudioapi"))("getConsoleHasColor"), error = function(e) return(FALSE))
|
||||
}
|
||||
if (rstudio_with_ansi_support() && sink.number() == 0) {
|
||||
return(TRUE)
|
||||
}
|
||||
if (!isatty(stdout())) {
|
||||
return(FALSE)
|
||||
}
|
||||
if (tolower(Sys.info()["sysname"]) == "windows") {
|
||||
if (Sys.getenv("ConEmuANSI") == "ON") {
|
||||
return(TRUE)
|
||||
}
|
||||
if (Sys.getenv("CMDER_ROOT") != "") {
|
||||
return(TRUE)
|
||||
}
|
||||
return(FALSE)
|
||||
}
|
||||
emacs_version <- function() {
|
||||
ver <- Sys.getenv("INSIDE_EMACS")
|
||||
if (ver == "") {
|
||||
return(NA_integer_)
|
||||
}
|
||||
ver <- gsub("'", "", ver)
|
||||
ver <- strsplit(ver, ",", fixed = TRUE)[[1]]
|
||||
ver <- strsplit(ver, ".", fixed = TRUE)[[1]]
|
||||
as.numeric(ver)
|
||||
}
|
||||
if ((Sys.getenv("EMACS") != "" || Sys.getenv("INSIDE_EMACS") != "") &&
|
||||
!is.na(emacs_version()[1]) && emacs_version()[1] >= 23) {
|
||||
return(TRUE)
|
||||
}
|
||||
if ("COLORTERM" %in% names(Sys.getenv())) {
|
||||
return(TRUE)
|
||||
}
|
||||
if (Sys.getenv("TERM") == "dumb") {
|
||||
return(FALSE)
|
||||
}
|
||||
grepl(pattern = "^screen|^xterm|^vt100|color|ansi|cygwin|linux",
|
||||
x = Sys.getenv("TERM"),
|
||||
ignore.case = TRUE,
|
||||
perl = TRUE)
|
||||
}
|
||||
|
||||
# the crayon colours
|
||||
try_colour <- function(..., before, after, collapse = " ") {
|
||||
txt <- paste0(unlist(list(...)), collapse = collapse)
|
||||
if (isTRUE(has_colour())) {
|
||||
if (is.null(collapse)) {
|
||||
paste0(before, txt, after, collapse = NULL)
|
||||
} else {
|
||||
paste0(before, txt, after, collapse = "")
|
||||
}
|
||||
} else {
|
||||
txt
|
||||
}
|
||||
}
|
||||
font_black <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[38;5;232m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_blue <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[34m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_green <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[32m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_magenta <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[35m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_red <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[31m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_silver <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[90m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_white <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[37m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_yellow <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[33m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_subtle <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[38;5;246m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_grey <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[38;5;249m", after = "\033[39m", collapse = collapse)
|
||||
}
|
||||
font_green_bg <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[42m", after = "\033[49m", collapse = collapse)
|
||||
}
|
||||
font_red_bg <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[41m", after = "\033[49m", collapse = collapse)
|
||||
}
|
||||
font_yellow_bg <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[43m", after = "\033[49m", collapse = collapse)
|
||||
}
|
||||
font_bold <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[1m", after = "\033[22m", collapse = collapse)
|
||||
}
|
||||
font_italic <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[3m", after = "\033[23m", collapse = collapse)
|
||||
}
|
||||
font_underline <- function(..., collapse = " ") {
|
||||
try_colour(..., before = "\033[4m", after = "\033[24m", collapse = collapse)
|
||||
}
|
||||
font_stripstyle <- function(x) {
|
||||
# from crayon:::ansi_regex
|
||||
gsub("(?:(?:\\x{001b}\\[)|\\x{009b})(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])|\\x{001b}[A-M]", "", x, perl = TRUE)
|
||||
}
|
||||
|
||||
progress_estimated <- function(n = 1, n_min = 0, ...) {
|
||||
if (!interactive() || n < n_min) {
|
||||
pb <- list()
|
||||
pb$tick <- function() {
|
||||
invisible()
|
||||
}
|
||||
pb$kill <- function() {
|
||||
invisible()
|
||||
}
|
||||
structure(pb, class = "txtProgressBar")
|
||||
} else if (n >= n_min) {
|
||||
pb <- utils::txtProgressBar(max = n, style = 3)
|
||||
pb$tick <- function() {
|
||||
pb$up(pb$getVal() + 1)
|
||||
}
|
||||
pb
|
||||
}
|
||||
}
|
||||
|
||||
# works exactly like round(), but rounds `round2(44.55, 1)` to 44.6 instead of 44.5
|
||||
# and adds decimal zeroes until `digits` is reached when force_zero = TRUE
|
||||
round2 <- function(x, digits = 0, force_zero = TRUE) {
|
||||
x <- as.double(x)
|
||||
# https://stackoverflow.com/a/12688836/4575331
|
||||
val <- (trunc((abs(x) * 10 ^ digits) + 0.5) / 10 ^ digits) * sign(x)
|
||||
if (digits > 0 & force_zero == TRUE) {
|
||||
values_trans <- val[val != as.integer(val) & !is.na(val)]
|
||||
val[val != as.integer(val) & !is.na(val)] <- paste0(values_trans,
|
||||
strrep("0",
|
||||
max(0,
|
||||
digits - nchar(
|
||||
format(
|
||||
as.double(
|
||||
gsub(".*[.](.*)$",
|
||||
"\\1",
|
||||
values_trans)),
|
||||
scientific = FALSE)))))
|
||||
}
|
||||
as.double(val)
|
||||
}
|
||||
|
||||
|
||||
# percentage from our other package: 'cleaner'
|
||||
percentage <- function(x, digits = NULL, ...) {
|
||||
|
||||
# getdecimalplaces() function
|
||||
getdecimalplaces <- function(x, minimum = 0, maximum = 3) {
|
||||
if (maximum < minimum) {
|
||||
maximum <- minimum
|
||||
}
|
||||
if (minimum > maximum) {
|
||||
minimum <- maximum
|
||||
}
|
||||
max_places <- max(unlist(lapply(strsplit(sub("0+$", "",
|
||||
as.character(x * 100)), ".", fixed = TRUE),
|
||||
function(y) ifelse(length(y) == 2, nchar(y[2]), 0))), na.rm = TRUE)
|
||||
max(min(max_places,
|
||||
maximum, na.rm = TRUE),
|
||||
minimum, na.rm = TRUE)
|
||||
}
|
||||
|
||||
# format_percentage() function
|
||||
format_percentage <- function(x, digits = NULL, ...) {
|
||||
if (is.null(digits)) {
|
||||
digits <- getdecimalplaces(x)
|
||||
}
|
||||
|
||||
# round right: percentage(0.4455) and format(as.percentage(0.4455), 1) should return "44.6%", not "44.5%"
|
||||
x_formatted <- format(round2(as.double(x), digits = digits + 2) * 100,
|
||||
scientific = FALSE,
|
||||
digits = digits,
|
||||
nsmall = digits,
|
||||
...)
|
||||
x_formatted <- paste0(x_formatted, "%")
|
||||
x_formatted[!grepl(pattern = "^[0-9.,e-]+$", x = x)] <- NA_character_
|
||||
x_formatted
|
||||
}
|
||||
|
||||
# the actual working part
|
||||
x <- as.double(x)
|
||||
if (is.null(digits)) {
|
||||
# max one digit if undefined
|
||||
digits <- getdecimalplaces(x, minimum = 0, maximum = 1)
|
||||
}
|
||||
format_percentage(structure(.Data = as.double(x),
|
||||
class = c("percentage", "numeric")),
|
||||
digits = digits, ...)
|
||||
}
|
||||
|
||||
# prevent dependency on package 'backports'
|
||||
# these functions were not available in previous versions of R (last checked: R 4.0.0)
|
||||
# see here for the full list: https://github.com/r-lib/backports
|
||||
strrep <- function(x, times) {
|
||||
x <- as.character(x)
|
||||
if (length(x) == 0L)
|
||||
return(x)
|
||||
unlist(.mapply(function(x, times) {
|
||||
if (is.na(x) || is.na(times))
|
||||
return(NA_character_)
|
||||
if (times <= 0L)
|
||||
return("")
|
||||
paste0(replicate(times, x), collapse = "")
|
||||
}, list(x = x, times = times), MoreArgs = list()), use.names = FALSE)
|
||||
}
|
||||
trimws <- function(x, which = c("both", "left", "right")) {
|
||||
which <- match.arg(which)
|
||||
mysub <- function(re, x) sub(re, "", x, perl = TRUE)
|
||||
if (which == "left")
|
||||
return(mysub("^[ \t\r\n]+", x))
|
||||
if (which == "right")
|
||||
return(mysub("[ \t\r\n]+$", x))
|
||||
mysub("[ \t\r\n]+$", mysub("^[ \t\r\n]+", x))
|
||||
}
|
||||
isFALSE <- function(x) {
|
||||
is.logical(x) && length(x) == 1L && !is.na(x) && !x
|
||||
}
|
||||
deparse1 <- function(expr, collapse = " ", width.cutoff = 500L, ...) {
|
||||
paste(deparse(expr, width.cutoff, ...), collapse = collapse)
|
||||
}
|
||||
@@ -1,775 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
# ------------------------------------------------
|
||||
# THIS FILE WAS CREATED AUTOMATICALLY!
|
||||
# Source file: data-raw/reproduction_of_poorman.R
|
||||
# ------------------------------------------------
|
||||
|
||||
# Poorman: a package to replace all dplyr functions with base R so we can lose dependency on dplyr.
|
||||
# These functions were downloaded from https://github.com/nathaneastwood/poorman,
|
||||
# from this commit: https://github.com/nathaneastwood/poorman/tree/7d76d77f8f7bc663bf30fb5a161abb49801afa17
|
||||
#
|
||||
# All code below was released under MIT license, that permits 'free of charge, to any person obtaining a
|
||||
# copy of the software and associated documentation files (the "Software"), to deal in the Software
|
||||
# without restriction, including without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
# is furnished to do so', given that a copyright notice is given in the software.
|
||||
#
|
||||
# Copyright notice as found on https://github.com/nathaneastwood/poorman/blob/master/LICENSE on 2 May 2020:
|
||||
# YEAR: 2020
|
||||
# COPYRIGHT HOLDER: Nathan Eastwood
|
||||
|
||||
arrange <- function(.data, ...) {
|
||||
check_is_dataframe(.data)
|
||||
if ("grouped_data" %in% class(.data)) {
|
||||
arrange.grouped_data(.data, ...)
|
||||
} else {
|
||||
arrange.default(.data, ...)
|
||||
}
|
||||
}
|
||||
|
||||
arrange.default <- function(.data, ...) {
|
||||
rows <- eval.parent(substitute(with(.data, order(...))))
|
||||
.data[rows, , drop = FALSE]
|
||||
}
|
||||
|
||||
arrange.grouped_data <- function(.data, ...) {
|
||||
apply_grouped_function(.data, "arrange", ...)
|
||||
}
|
||||
between <- function(x, left, right) {
|
||||
if (!is.null(attr(x, "class")) && !inherits(x, c("Date", "POSIXct"))) {
|
||||
warning("`between()` called on numeric vector with S3 class")
|
||||
}
|
||||
if (!is.double(x)) x <- as.numeric(x)
|
||||
x >= as.numeric(left) & x <= as.numeric(right)
|
||||
}
|
||||
count <- function(x, ..., wt = NULL, sort = FALSE, name = NULL) {
|
||||
groups <- get_groups(x)
|
||||
if (!missing(...)) x <- group_by(x, ..., .add = TRUE)
|
||||
wt <- deparse_var(wt)
|
||||
res <- do.call(tally, list(x, wt, sort, name))
|
||||
if (length(groups) > 0L) res <- do.call(group_by, list(res, as.name(groups)))
|
||||
res
|
||||
}
|
||||
|
||||
tally <- function(x, wt = NULL, sort = FALSE, name = NULL) {
|
||||
name <- check_name(x, name)
|
||||
wt <- deparse_var(wt)
|
||||
res <- do.call(summarise, set_names(list(x, as.name(tally_n(x, wt))), c(".data", name)))
|
||||
res <- ungroup(res)
|
||||
if (isTRUE(sort)) res <- do.call(arrange, list(res, call("desc", as.name(name))))
|
||||
rownames(res) <- NULL
|
||||
res
|
||||
}
|
||||
|
||||
add_count <- function(x, ..., wt = NULL, sort = FALSE, name = NULL) {
|
||||
name <- check_name(x, name)
|
||||
row_names <- rownames(x)
|
||||
wt <- deparse_var(wt)
|
||||
if (!missing(...)) x <- group_by(x, ..., .add = TRUE)
|
||||
res <- do.call(add_tally, list(x, wt, sort, name))
|
||||
res[row_names, ]
|
||||
}
|
||||
|
||||
add_tally <- function(x, wt = NULL, sort = FALSE, name = NULL) {
|
||||
wt <- deparse_var(wt)
|
||||
n <- tally_n(x, wt)
|
||||
name <- check_name(x, name)
|
||||
res <- do.call(mutate, set_names(list(x, as.name(n)), c(".data", name)))
|
||||
|
||||
if (isTRUE(sort)) {
|
||||
do.call(arrange, list(res, call("desc", as.name(name))))
|
||||
} else {
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
tally_n <- function(x, wt) {
|
||||
if (is.null(wt) && "n" %in% colnames(x)) {
|
||||
message("Using `n` as weighting variable")
|
||||
wt <- "n"
|
||||
}
|
||||
context$.data <- x
|
||||
on.exit(rm(list = ".data", envir = context))
|
||||
if (is.null(wt)) {
|
||||
"n()"
|
||||
} else {
|
||||
paste0("sum(", wt, ", na.rm = TRUE)")
|
||||
}
|
||||
}
|
||||
|
||||
check_name <- function(df, name) {
|
||||
if (is.null(name)) {
|
||||
if ("n" %in% colnames(df)) {
|
||||
stop(
|
||||
"Column 'n' is already present in output\n",
|
||||
"* Use `name = \"new_name\"` to pick a new name"
|
||||
)
|
||||
}
|
||||
return("n")
|
||||
}
|
||||
|
||||
if (!is.character(name) || length(name) != 1) {
|
||||
stop("`name` must be a single string")
|
||||
}
|
||||
|
||||
name
|
||||
}
|
||||
desc <- function(x) -xtfrm(x)
|
||||
select_env <- new.env()
|
||||
|
||||
peek_vars <- function() {
|
||||
get(".col_names", envir = select_env)
|
||||
}
|
||||
|
||||
context <- new.env()
|
||||
|
||||
n <- function() {
|
||||
do.call(nrow, list(quote(.data)), envir = context)
|
||||
}
|
||||
filter <- function(.data, ...) {
|
||||
check_is_dataframe(.data)
|
||||
if ("grouped_data" %in% class(.data)) {
|
||||
filter.grouped_data(.data, ...)
|
||||
} else {
|
||||
filter.default(.data, ...)
|
||||
}
|
||||
}
|
||||
|
||||
filter.default <- function(.data, ...) {
|
||||
conditions <- paste(deparse_dots(...), collapse = " & ")
|
||||
context$.data <- .data
|
||||
on.exit(rm(.data, envir = context))
|
||||
.data[do.call(with, list(.data, str2lang(unname(conditions)))), ]
|
||||
}
|
||||
|
||||
filter.grouped_data <- function(.data, ...) {
|
||||
rows <- rownames(.data)
|
||||
res <- apply_grouped_function(.data, "filter", ...)
|
||||
res[rows[rows %in% rownames(res)], ]
|
||||
}
|
||||
group_by <- function(.data, ..., .add = FALSE) {
|
||||
check_is_dataframe(.data)
|
||||
pre_groups <- get_groups(.data)
|
||||
groups <- deparse_dots(...)
|
||||
if (isTRUE(.add)) groups <- unique(c(pre_groups, groups))
|
||||
unknown <- !(groups %in% colnames(.data))
|
||||
if (any(unknown)) stop("Invalid groups: ", groups[unknown])
|
||||
structure(.data, class = c("grouped_data", class(.data)), groups = groups)
|
||||
}
|
||||
|
||||
ungroup <- function(x, ...) {
|
||||
check_is_dataframe(x)
|
||||
rm_groups <- deparse_dots(...)
|
||||
groups <- attr(x, "groups")
|
||||
if (length(rm_groups) == 0L) rm_groups <- groups
|
||||
attr(x, "groups") <- groups[!(groups %in% rm_groups)]
|
||||
if (length(attr(x, "groups")) == 0L) {
|
||||
attr(x, "groups") <- NULL
|
||||
class(x) <- class(x)[!(class(x) %in% "grouped_data")]
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
get_groups <- function(x) {
|
||||
attr(x, "groups", exact = TRUE)
|
||||
}
|
||||
|
||||
has_groups <- function(x) {
|
||||
groups <- get_groups(x)
|
||||
if (is.null(groups)) FALSE else TRUE
|
||||
}
|
||||
|
||||
set_groups <- function(x, groups) {
|
||||
attr(x, "groups") <- groups
|
||||
x
|
||||
}
|
||||
|
||||
apply_grouped_function <- function(.data, fn, ...) {
|
||||
groups <- get_groups(.data)
|
||||
grouped <- split_into_groups(.data, groups)
|
||||
res <- do.call(rbind, unname(lapply(grouped, fn, ...)))
|
||||
if (any(groups %in% colnames(res))) {
|
||||
class(res) <- c("grouped_data", class(res))
|
||||
attr(res, "groups") <- groups[groups %in% colnames(res)]
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
split_into_groups <- function(.data, groups) {
|
||||
class(.data) <- "data.frame"
|
||||
group_factors <- lapply(groups, function(x, .data) as.factor(.data[, x]), .data)
|
||||
res <- split(x = .data, f = group_factors)
|
||||
res
|
||||
}
|
||||
|
||||
print.grouped_data <- function(x, ..., digits = NULL, quote = FALSE, right = TRUE, row.names = TRUE, max = NULL) {
|
||||
class(x) <- "data.frame"
|
||||
print(x, ..., digits = digits, quote = quote, right = right, row.names = row.names, max = max)
|
||||
cat("\nGroups: ", paste(attr(x, "groups", exact = TRUE), collapse = ", "), "\n\n")
|
||||
}
|
||||
if_else <- function(condition, true, false, missing = NULL) {
|
||||
if (!is.logical(condition)) stop("`condition` must be a logical vector.")
|
||||
cls_true <- class(true)
|
||||
cls_false <- class(false)
|
||||
cls_missing <- class(missing)
|
||||
if (!identical(cls_true, cls_false)) {
|
||||
stop("The class of `true` <", class(true), "> is not the same as the class of `false` <", class(false), ">")
|
||||
}
|
||||
if (!is.null(missing) && !identical(cls_true, cls_missing)) {
|
||||
stop("`missing` must be a ", cls_true, " vector, not a ", cls_missing, " vector.")
|
||||
}
|
||||
res <- ifelse(condition, true, false)
|
||||
if (!is.null(missing)) res[is.na(res)] <- missing
|
||||
attributes(res) <- attributes(true)
|
||||
res
|
||||
}
|
||||
|
||||
inner_join <- function(x, y, by = NULL, suffix = c(".x", ".y")) {
|
||||
join_worker(x = x, y = y, by = by, suffix = suffix, sort = FALSE)
|
||||
}
|
||||
|
||||
left_join <- function(x, y, by = NULL, suffix = c(".x", ".y")) {
|
||||
join_worker(x = x, y = y, by = by, suffix = suffix, all.x = TRUE)
|
||||
}
|
||||
|
||||
right_join <- function(x, y, by = NULL, suffix = c(".x", ".y")) {
|
||||
join_worker(x = x, y = y, by = by, suffix = suffix, all.y = TRUE)
|
||||
}
|
||||
|
||||
full_join <- function(x, y, by = NULL, suffix = c(".x", ".y")) {
|
||||
join_worker(x = x, y = y, by = by, suffix = suffix, all = TRUE)
|
||||
}
|
||||
|
||||
join_worker <- function(x, y, by = NULL, suffix = c(".x", ".y"), ...) {
|
||||
x[, ".join_id"] <- seq_len(nrow(x))
|
||||
if (is.null(by)) {
|
||||
by <- intersect(names(x), names(y))
|
||||
join_message(by)
|
||||
merged <- merge(x = x, y = y, by = by, suffixes = suffix, ...)[, union(names(x), names(y))]
|
||||
} else if (is.null(names(by))) {
|
||||
merged <- merge(x = x, y = y, by = by, suffixes = suffix, ...)
|
||||
} else {
|
||||
merged <- merge(x = x, y = y, by.x = names(by), by.y = by, suffixes = suffix, ...)
|
||||
}
|
||||
merged <- merged[order(merged[, ".join_id"]), colnames(merged) != ".join_id"]
|
||||
rownames(merged) <- NULL
|
||||
merged
|
||||
}
|
||||
|
||||
join_message <- function(by) {
|
||||
if (length(by) > 1L) {
|
||||
message("Joining, by = c(\"", paste0(by, collapse = "\", \""), "\")\n", sep = "")
|
||||
} else {
|
||||
message("Joining, by = \"", by, "\"\n", sep = "")
|
||||
}
|
||||
}
|
||||
|
||||
anti_join <- function(x, y, by = NULL) {
|
||||
filter_join_worker(x, y, by, type = "anti")
|
||||
}
|
||||
|
||||
semi_join <- function(x, y, by = NULL) {
|
||||
filter_join_worker(x, y, by, type = "semi")
|
||||
}
|
||||
|
||||
# filter_join_worker <- function(x, y, by = NULL, type = c("anti", "semi")) {
|
||||
# type <- match.arg(type, choices = c("anti", "semi"), several.ok = FALSE)
|
||||
# if (is.null(by)) {
|
||||
# by <- intersect(names(x), names(y))
|
||||
# join_message(by)
|
||||
# }
|
||||
# rows <- interaction(x[, by]) %in% interaction(y[, by])
|
||||
# if (type == "anti") rows <- !rows
|
||||
# res <- x[rows, ]
|
||||
# rownames(res) <- NULL
|
||||
# res
|
||||
# }
|
||||
lag <- function (x, n = 1L, default = NA) {
|
||||
if (inherits(x, "ts")) stop("`x` must be a vector, not a `ts` object, do you want `stats::lag()`?")
|
||||
if (length(n) != 1L || !is.numeric(n) || n < 0L) stop("`n` must be a nonnegative integer scalar")
|
||||
if (n == 0L) return(x)
|
||||
tryCatch(
|
||||
storage.mode(default) <- typeof(x),
|
||||
warning = function(w) {
|
||||
stop("Cannot convert `default` <", typeof(default), "> to `x` <", typeof(x), ">")
|
||||
}
|
||||
)
|
||||
xlen <- length(x)
|
||||
n <- pmin(n, xlen)
|
||||
res <- c(rep(default, n), x[seq_len(xlen - n)])
|
||||
attributes(res) <- attributes(x)
|
||||
res
|
||||
}
|
||||
|
||||
lead <- function (x, n = 1L, default = NA) {
|
||||
if (length(n) != 1L || !is.numeric(n) || n < 0L) stop("n must be a nonnegative integer scalar")
|
||||
if (n == 0L) return(x)
|
||||
tryCatch(
|
||||
storage.mode(default) <- typeof(x),
|
||||
warning = function(w) {
|
||||
stop("Cannot convert `default` <", typeof(default), "> to `x` <", typeof(x), ">")
|
||||
}
|
||||
)
|
||||
xlen <- length(x)
|
||||
n <- pmin(n, xlen)
|
||||
res <- c(x[-seq_len(n)], rep(default, n))
|
||||
attributes(res) <- attributes(x)
|
||||
res
|
||||
}
|
||||
mutate <- function(.data, ...) {
|
||||
check_is_dataframe(.data)
|
||||
if ("grouped_data" %in% class(.data)) {
|
||||
mutate.grouped_data(.data, ...)
|
||||
} else {
|
||||
mutate.default(.data, ...)
|
||||
}
|
||||
}
|
||||
|
||||
mutate.default <- function(.data, ...) {
|
||||
conditions <- deparse_dots(...)
|
||||
cond_names <- names(conditions)
|
||||
unnamed <- which(nchar(cond_names) == 0L)
|
||||
if (is.null(cond_names)) {
|
||||
names(conditions) <- conditions
|
||||
} else if (length(unnamed) > 0L) {
|
||||
names(conditions)[unnamed] <- conditions[unnamed]
|
||||
}
|
||||
not_matched <- names(conditions)[!names(conditions) %in% names(.data)]
|
||||
.data[, not_matched] <- NA
|
||||
context$.data <- .data
|
||||
on.exit(rm(.data, envir = context))
|
||||
for (i in seq_along(conditions)) {
|
||||
.data[, names(conditions)[i]] <- do.call(with, list(.data, str2lang(unname(conditions)[i])))
|
||||
}
|
||||
.data
|
||||
}
|
||||
|
||||
mutate.grouped_data <- function(.data, ...) {
|
||||
rows <- rownames(.data)
|
||||
res <- apply_grouped_function(.data, "mutate", ...)
|
||||
res[rows, ]
|
||||
}
|
||||
n_distinct <- function(..., na.rm = FALSE) {
|
||||
res <- c(...)
|
||||
if (is.list(res)) return(nrow(unique(as.data.frame(res, stringsAsFactors = FALSE))))
|
||||
if (isTRUE(na.rm)) res <- res[!is.na(res)]
|
||||
length(unique(res))
|
||||
}
|
||||
`%>%` <- function(lhs, rhs) {
|
||||
lhs <- substitute(lhs)
|
||||
rhs <- substitute(rhs)
|
||||
eval(as.call(c(rhs[[1L]], lhs, as.list(rhs[-1L]))), envir = parent.frame())
|
||||
}
|
||||
pull <- function(.data, var = -1) {
|
||||
var_deparse <- deparse_var(var)
|
||||
col_names <- colnames(.data)
|
||||
if (!(var_deparse %in% col_names) & grepl("^[[:digit:]]+L|[[:digit:]]", var_deparse)) {
|
||||
var <- as.integer(gsub("L", "", var_deparse))
|
||||
var <- if_else(var < 1L, rev(col_names)[abs(var)], col_names[var])
|
||||
} else if (var_deparse %in% col_names) {
|
||||
var <- var_deparse
|
||||
}
|
||||
.data[, var]
|
||||
}
|
||||
relocate <- function(.data, ..., .before = NULL, .after = NULL) {
|
||||
check_is_dataframe(.data)
|
||||
data_names <- colnames(.data)
|
||||
col_pos <- select_positions(.data, ...)
|
||||
|
||||
.before <- deparse_var(.before)
|
||||
.after <- deparse_var(.after)
|
||||
has_before <- !is.null(.before)
|
||||
has_after <- !is.null(.after)
|
||||
|
||||
if (has_before && has_after) {
|
||||
stop("You must supply only one of `.before` and `.after`")
|
||||
} else if (has_before) {
|
||||
where <- min(match(.before, data_names))
|
||||
col_pos <- c(setdiff(col_pos, where), where)
|
||||
} else if (has_after) {
|
||||
where <- max(match(.after, data_names))
|
||||
col_pos <- c(where, setdiff(col_pos, where))
|
||||
} else {
|
||||
where <- 1L
|
||||
col_pos <- union(col_pos, where)
|
||||
}
|
||||
lhs <- setdiff(seq(1L, where - 1L), col_pos)
|
||||
rhs <- setdiff(seq(where + 1L, ncol(.data)), col_pos)
|
||||
col_pos <- unique(c(lhs, col_pos, rhs))
|
||||
col_pos <- col_pos[col_pos <= length(data_names)]
|
||||
|
||||
res <- .data[col_pos]
|
||||
if (has_groups(.data)) res <- set_groups(res, get_groups(.data))
|
||||
res
|
||||
}
|
||||
rename <- function(.data, ...) {
|
||||
check_is_dataframe(.data)
|
||||
new_names <- names(deparse_dots(...))
|
||||
if (length(new_names) == 0L) {
|
||||
warning("You didn't give any new names")
|
||||
return(.data)
|
||||
}
|
||||
col_pos <- select_positions(.data, ...)
|
||||
old_names <- colnames(.data)[col_pos]
|
||||
new_names_zero <- nchar(new_names) == 0L
|
||||
if (any(new_names_zero)) {
|
||||
warning("You didn't provide new names for: ", paste0("`", old_names[new_names_zero], collapse = ", "), "`")
|
||||
new_names[new_names_zero] <- old_names[new_names_zero]
|
||||
}
|
||||
colnames(.data)[col_pos] <- new_names
|
||||
.data
|
||||
}
|
||||
rownames_to_column <- function(.data, var = "rowname") {
|
||||
check_is_dataframe(.data)
|
||||
col_names <- colnames(.data)
|
||||
if (var %in% col_names) stop("Column `", var, "` already exists in `.data`")
|
||||
.data[, var] <- rownames(.data)
|
||||
rownames(.data) <- NULL
|
||||
.data[, c(var, setdiff(col_names, var))]
|
||||
}
|
||||
|
||||
select <- function(.data, ...) {
|
||||
map <- names(deparse_dots(...))
|
||||
col_pos <- select_positions(.data, ..., group_pos = TRUE)
|
||||
res <- .data[, col_pos, drop = FALSE]
|
||||
to_map <- nchar(map) > 0L
|
||||
colnames(res)[to_map] <- map[to_map]
|
||||
if (has_groups(.data)) res <- set_groups(res, get_groups(.data))
|
||||
res
|
||||
}
|
||||
starts_with <- function(match, ignore.case = TRUE, vars = peek_vars()) {
|
||||
grep(pattern = paste0("^", paste0(match, collapse = "|^")), x = vars, ignore.case = ignore.case)
|
||||
}
|
||||
|
||||
ends_with <- function(match, ignore.case = TRUE, vars = peek_vars()) {
|
||||
grep(pattern = paste0(paste0(match, collapse = "$|"), "$"), x = vars, ignore.case = ignore.case)
|
||||
}
|
||||
|
||||
contains <- function(match, ignore.case = TRUE, vars = peek_vars()) {
|
||||
matches <- lapply(
|
||||
match,
|
||||
function(x) {
|
||||
if (isTRUE(ignore.case)) {
|
||||
match_u <- toupper(x)
|
||||
match_l <- tolower(x)
|
||||
pos_u <- grep(pattern = match_u, x = toupper(vars), fixed = TRUE)
|
||||
pos_l <- grep(pattern = match_l, x = tolower(vars), fixed = TRUE)
|
||||
unique(c(pos_l, pos_u))
|
||||
} else {
|
||||
grep(pattern = x, x = vars, fixed = TRUE)
|
||||
}
|
||||
}
|
||||
)
|
||||
unique(matches)
|
||||
}
|
||||
|
||||
matches <- function(match, ignore.case = TRUE, perl = FALSE, vars = peek_vars()) {
|
||||
grep(pattern = match, x = vars, ignore.case = ignore.case, perl = perl)
|
||||
}
|
||||
|
||||
num_range <- function(prefix, range, width = NULL, vars = peek_vars()) {
|
||||
if (!is.null(width)) {
|
||||
range <- sprintf(paste0("%0", width, "d"), range)
|
||||
}
|
||||
find <- paste0(prefix, range)
|
||||
if (any(duplicated(vars))) {
|
||||
stop("Column names must be unique")
|
||||
} else {
|
||||
x <- match(find, vars)
|
||||
x[!is.na(x)]
|
||||
}
|
||||
}
|
||||
|
||||
all_of <- function(x, vars = peek_vars()) {
|
||||
x_ <- !x %in% vars
|
||||
if (any(x_)) {
|
||||
which_x_ <- which(x_)
|
||||
if (length(which_x_) == 1L) {
|
||||
stop("The column ", x[which_x_], " does not exist.")
|
||||
} else {
|
||||
stop("The columns ", paste(x[which_x_], collapse = ", "), " do not exist.")
|
||||
}
|
||||
} else {
|
||||
which(vars %in% x)
|
||||
}
|
||||
}
|
||||
|
||||
any_of <- function(x, vars = peek_vars()) {
|
||||
which(vars %in% x)
|
||||
}
|
||||
|
||||
everything <- function(vars = peek_vars()) {
|
||||
seq_along(vars)
|
||||
}
|
||||
|
||||
last_col <- function(offset = 0L, vars = peek_vars()) {
|
||||
if (!is_wholenumber(offset)) stop("`offset` must be an integer")
|
||||
n <- length(vars)
|
||||
if (offset && n <= offset) {
|
||||
stop("`offset` must be smaller than the number of `vars`")
|
||||
} else if (n == 0) {
|
||||
stop("Can't select last column when `vars` is empty")
|
||||
} else {
|
||||
n - offset
|
||||
}
|
||||
}
|
||||
select_positions <- function(.data, ..., group_pos = FALSE) {
|
||||
cols <- eval(substitute(alist(...)))
|
||||
data_names <- colnames(.data)
|
||||
select_env$.col_names <- data_names
|
||||
on.exit(rm(list = ".col_names", envir = select_env))
|
||||
exec_env <- parent.frame(2L)
|
||||
pos <- unlist(lapply(cols, eval_expr, exec_env = exec_env))
|
||||
if (isTRUE(group_pos)) {
|
||||
groups <- get_groups(.data)
|
||||
missing_groups <- !(groups %in% cols)
|
||||
if (any(missing_groups)) {
|
||||
message("Adding missing grouping variables: `", paste(groups[missing_groups], collapse = "`, `"), "`")
|
||||
pos <- c(match(groups[missing_groups], data_names), pos)
|
||||
}
|
||||
}
|
||||
unique(pos)
|
||||
}
|
||||
|
||||
eval_expr <- function(x, exec_env) {
|
||||
type <- typeof(x)
|
||||
switch(
|
||||
type,
|
||||
"integer" = x,
|
||||
"double" = as.integer(x),
|
||||
"character" = select_char(x),
|
||||
"symbol" = select_symbol(x, exec_env = exec_env),
|
||||
"language" = eval_call(x),
|
||||
stop("Expressions of type <", typeof(x), "> cannot be evaluated for use when subsetting.")
|
||||
)
|
||||
}
|
||||
|
||||
select_char <- function(expr) {
|
||||
pos <- match(expr, select_env$.col_names)
|
||||
if (is.na(pos)) stop("Column `", expr, "` does not exist")
|
||||
pos
|
||||
}
|
||||
|
||||
select_symbol <- function(expr, exec_env) {
|
||||
res <- try(select_char(as.character(expr)), silent = TRUE)
|
||||
if (inherits(res, "try-error")) {
|
||||
res <- tryCatch(
|
||||
select_char(eval(expr, envir = exec_env)),
|
||||
error = function(e) stop("Column ", expr, " does not exist.")
|
||||
)
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
eval_call <- function(x) {
|
||||
type <- as.character(x[[1]])
|
||||
switch(
|
||||
type,
|
||||
`:` = select_seq(x),
|
||||
`!` = select_negate(x),
|
||||
`-` = select_minus(x),
|
||||
`c` = select_c(x),
|
||||
`(` = select_bracket(x),
|
||||
select_context(x)
|
||||
)
|
||||
}
|
||||
|
||||
select_seq <- function(expr) {
|
||||
x <- eval_expr(expr[[2]])
|
||||
y <- eval_expr(expr[[3]])
|
||||
x:y
|
||||
}
|
||||
|
||||
select_negate <- function(expr) {
|
||||
x <- if (is_negated_colon(expr)) {
|
||||
expr <- call(":", expr[[2]][[2]], expr[[2]][[3]][[2]])
|
||||
eval_expr(expr)
|
||||
} else {
|
||||
eval_expr(expr[[2]])
|
||||
}
|
||||
x * -1L
|
||||
}
|
||||
|
||||
is_negated_colon <- function(expr) {
|
||||
expr[[1]] == "!" && length(expr[[2]]) > 1L && expr[[2]][[1]] == ":" && expr[[2]][[3]][[1]] == "!"
|
||||
}
|
||||
|
||||
select_minus <- function(expr) {
|
||||
x <- eval_expr(expr[[2]])
|
||||
x * -1L
|
||||
}
|
||||
|
||||
select_c <- function(expr) {
|
||||
lst_expr <- as.list(expr)
|
||||
lst_expr[[1]] <- NULL
|
||||
unlist(lapply(lst_expr, eval_expr))
|
||||
}
|
||||
|
||||
select_bracket <- function(expr) {
|
||||
eval_expr(expr[[2]])
|
||||
}
|
||||
|
||||
select_context <- function(expr) {
|
||||
eval(expr, envir = context$.data)
|
||||
}
|
||||
slice <- function(.data, ...) {
|
||||
check_is_dataframe(.data)
|
||||
if ("grouped_data" %in% class(.data)) {
|
||||
slice.grouped_data(.data, ...)
|
||||
} else {
|
||||
slice.default(.data, ...)
|
||||
}
|
||||
}
|
||||
|
||||
slice.default <- function(.data, ...) {
|
||||
rows <- c(...)
|
||||
stopifnot(is.numeric(rows) | is.integer(rows))
|
||||
if (all(rows > 0L)) rows <- rows[rows <= nrow(.data)]
|
||||
.data[rows, ]
|
||||
}
|
||||
|
||||
slice.grouped_data <- function(.data, ...) {
|
||||
apply_grouped_function(.data, "slice", ...)
|
||||
}
|
||||
summarise <- function(.data, ...) {
|
||||
check_is_dataframe(.data)
|
||||
if ("grouped_data" %in% class(.data)) {
|
||||
summarise.grouped_data(.data, ...)
|
||||
} else {
|
||||
summarise.default(.data, ...)
|
||||
}
|
||||
}
|
||||
|
||||
summarise.default <- function(.data, ...) {
|
||||
fns <- vapply(substitute(...()), deparse, NA_character_)
|
||||
context$.data <- .data
|
||||
on.exit(rm(.data, envir = context))
|
||||
if (has_groups(.data)) {
|
||||
group <- unique(.data[, get_groups(.data), drop = FALSE])
|
||||
if (nrow(group) == 0L) return(NULL)
|
||||
}
|
||||
res <- lapply(fns, function(x) do.call(with, list(.data, str2lang(x))))
|
||||
res <- as.data.frame(res)
|
||||
fn_names <- names(fns)
|
||||
colnames(res) <- if (is.null(fn_names)) fns else fn_names
|
||||
if (has_groups(.data)) res <- cbind(group, res)
|
||||
res
|
||||
}
|
||||
|
||||
summarise.grouped_data <- function(.data, ...) {
|
||||
groups <- get_groups(.data)
|
||||
res <- apply_grouped_function(.data, "summarise", ...)
|
||||
res <- res[do.call(order, lapply(groups, function(x) res[, x])), ]
|
||||
rownames(res) <- NULL
|
||||
res
|
||||
}
|
||||
|
||||
summarize <- summarise
|
||||
summarize.default <- summarise.default
|
||||
summarize.grouped_data <- summarise.grouped_data
|
||||
transmute <- function(.data, ...) {
|
||||
check_is_dataframe(.data)
|
||||
if ("grouped_data" %in% class(.data)) {
|
||||
transmute.grouped_data(.data, ...)
|
||||
} else {
|
||||
transmute.default(.data, ...)
|
||||
}
|
||||
}
|
||||
|
||||
transmute.default <- function(.data, ...) {
|
||||
conditions <- deparse_dots(...)
|
||||
mutated <- mutate(.data, ...)
|
||||
mutated[, names(conditions), drop = FALSE]
|
||||
}
|
||||
|
||||
transmute.grouped_data <- function(.data, ...) {
|
||||
rows <- rownames(.data)
|
||||
res <- apply_grouped_function(.data, "transmute", ...)
|
||||
res[rows, ]
|
||||
}
|
||||
deparse_dots <- function(...) {
|
||||
vapply(substitute(...()), deparse, NA_character_)
|
||||
}
|
||||
|
||||
deparse_var <- function(var) {
|
||||
sub_var <- eval(substitute(substitute(var)), parent.frame())
|
||||
if (is.symbol(sub_var)) var <- as.character(sub_var)
|
||||
var
|
||||
}
|
||||
|
||||
check_is_dataframe <- function(.data) {
|
||||
parent_fn <- all.names(sys.call(-1L), max.names = 1L)
|
||||
if (!is.data.frame(.data)) stop(parent_fn, " must be given a data.frame")
|
||||
invisible()
|
||||
}
|
||||
|
||||
is_wholenumber <- function(x) {
|
||||
x %% 1L == 0L
|
||||
}
|
||||
|
||||
set_names <- function(object = nm, nm) {
|
||||
names(object) <- nm
|
||||
object
|
||||
}
|
||||
|
||||
cume_dist <- function(x) {
|
||||
rank(x, ties.method = "max", na.last = "keep") / sum(!is.na(x))
|
||||
}
|
||||
|
||||
dense_rank <- function(x) {
|
||||
match(x, sort(unique(x)))
|
||||
}
|
||||
|
||||
min_rank <- function(x) {
|
||||
rank(x, ties.method = "min", na.last = "keep")
|
||||
}
|
||||
|
||||
ntile <- function (x = row_number(), n) {
|
||||
if (!missing(x)) x <- row_number(x)
|
||||
len <- length(x) - sum(is.na(x))
|
||||
n <- as.integer(floor(n))
|
||||
if (len == 0L) {
|
||||
rep(NA_integer_, length(x))
|
||||
} else {
|
||||
n_larger <- as.integer(len %% n)
|
||||
n_smaller <- as.integer(n - n_larger)
|
||||
size <- len / n
|
||||
larger_size <- as.integer(ceiling(size))
|
||||
smaller_size <- as.integer(floor(size))
|
||||
larger_threshold <- larger_size * n_larger
|
||||
bins <- if_else(
|
||||
x <= larger_threshold,
|
||||
(x + (larger_size - 1L)) / larger_size,
|
||||
(x + (-larger_threshold + smaller_size - 1L)) / smaller_size + n_larger
|
||||
)
|
||||
as.integer(floor(bins))
|
||||
}
|
||||
}
|
||||
|
||||
percent_rank <- function(x) {
|
||||
(min_rank(x) - 1) / (sum(!is.na(x)) - 1)
|
||||
}
|
||||
|
||||
row_number <- function(x) {
|
||||
if (missing(x)) seq_len(n()) else rank(x, ties.method = "first", na.last = "keep")
|
||||
}
|
||||
@@ -1,526 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Transform to antibiotic ID
|
||||
#'
|
||||
#' Use this function to determine the antibiotic code of one or more antibiotics. The data set [antibiotics] will be searched for abbreviations, official names and synonyms (brand names).
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param x character vector to determine to antibiotic ID
|
||||
#' @param flag_multiple_results logical to indicate whether a note should be printed to the console that probably more than one antibiotic code or name can be retrieved from a single input value.
|
||||
#' @param ... arguments passed on to internal functions
|
||||
#' @rdname as.ab
|
||||
#' @inheritSection WHOCC WHOCC
|
||||
#' @details All entries in the [antibiotics] data set have three different identifiers: a human readable EARS-Net code (column `ab`, used by ECDC and WHONET), an ATC code (column `atc`, used by WHO), and a CID code (column `cid`, Compound ID, used by PubChem). The data set contains more than 5,000 official brand names from many different countries, as found in PubChem.
|
||||
#'
|
||||
#' All these properties will be searched for the user input. The [as.ab()] can correct for different forms of misspelling:
|
||||
#'
|
||||
#' * Wrong spelling of drug names (like "tobramicin" or "gentamycin"), which corrects for most audible similarities such as f/ph, x/ks, c/z/s, t/th, etc.
|
||||
#' * Too few or too many vowels or consonants
|
||||
#' * Switching two characters (like "mreopenem", often the case in clinical data, when doctors typed too fast)
|
||||
#' * Digitalised paper records, leaving artefacts like 0/o/O (zero and O's), B/8, n/r, etc.
|
||||
#'
|
||||
#' Use the [ab_property()] functions to get properties based on the returned antibiotic ID, see Examples.
|
||||
#'
|
||||
#' @section Source:
|
||||
#' World Health Organization (WHO) Collaborating Centre for Drug Statistics Methodology: \url{https://www.whocc.no/atc_ddd_index/}
|
||||
#'
|
||||
#' WHONET 2019 software: \url{http://www.whonet.org/software.html}
|
||||
#'
|
||||
#' European Commission Public Health PHARMACEUTICALS - COMMUNITY REGISTER: \url{http://ec.europa.eu/health/documents/community-register/html/atc.htm}
|
||||
#' @aliases ab
|
||||
#' @return Character (vector) with class [`ab`]. Unknown values will return `NA`.
|
||||
#' @seealso
|
||||
#' * [antibiotics] for the dataframe that is being used to determine ATCs
|
||||
#' * [ab_from_text()] for a function to retrieve antimicrobial drugs from clinical text (from health care records)
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
#' @examples
|
||||
#' # these examples all return "ERY", the ID of erythromycin:
|
||||
#' as.ab("J01FA01")
|
||||
#' as.ab("J 01 FA 01")
|
||||
#' as.ab("Erythromycin")
|
||||
#' as.ab("eryt")
|
||||
#' as.ab(" eryt 123")
|
||||
#' as.ab("ERYT")
|
||||
#' as.ab("ERY")
|
||||
#' as.ab("eritromicine") # spelled wrong, yet works
|
||||
#' as.ab("Erythrocin") # trade name
|
||||
#' as.ab("Romycin") # trade name
|
||||
#'
|
||||
#' # spelling from different languages and dyslexia are no problem
|
||||
#' ab_atc("ceftriaxon")
|
||||
#' ab_atc("cephtriaxone") # small spelling error
|
||||
#' ab_atc("cephthriaxone") # or a bit more severe
|
||||
#' ab_atc("seephthriaaksone") # and even this works
|
||||
#'
|
||||
#' # use ab_* functions to get a specific properties (see ?ab_property);
|
||||
#' # they use as.ab() internally:
|
||||
#' ab_name("J01FA01") # "Erythromycin"
|
||||
#' ab_name("eryt") # "Erythromycin"
|
||||
as.ab <- function(x, flag_multiple_results = TRUE, ...) {
|
||||
|
||||
check_dataset_integrity()
|
||||
|
||||
if (is.ab(x)) {
|
||||
return(x)
|
||||
}
|
||||
|
||||
initial_search <- is.null(list(...)$initial_search)
|
||||
already_regex <- isTRUE(list(...)$already_regex)
|
||||
|
||||
if (all(toupper(x) %in% antibiotics$ab)) {
|
||||
# valid AB code, but not yet right class
|
||||
return(structure(.Data = toupper(x),
|
||||
class = c("ab", "character")))
|
||||
}
|
||||
|
||||
x_bak <- x
|
||||
x <- toupper(x)
|
||||
# remove diacritics
|
||||
x <- iconv(x, from = "UTF-8", to = "ASCII//TRANSLIT")
|
||||
x <- gsub('"', "", x, fixed = TRUE)
|
||||
x_bak_clean <- x
|
||||
if (already_regex == FALSE) {
|
||||
# remove suffices
|
||||
x_bak_clean <- gsub("_(MIC|RSI|DIS[CK])$", "", x_bak_clean)
|
||||
# remove disk concentrations, like LVX_NM -> LVX
|
||||
x_bak_clean <- gsub("_[A-Z]{2}[0-9_.]{0,3}$", "", x_bak_clean)
|
||||
# remove part between brackets if that's followed by another string
|
||||
x_bak_clean <- gsub("(.*)+ [(].*[)]", "\\1", x_bak_clean)
|
||||
# keep only max 1 space
|
||||
x_bak_clean <- trimws(gsub(" +", " ", x_bak_clean))
|
||||
# non-character, space or number should be a slash
|
||||
x_bak_clean <- gsub("[^A-Z0-9 -]", "/", x_bak_clean)
|
||||
# spaces around non-characters must be removed: amox + clav -> amox/clav
|
||||
x_bak_clean <- gsub("(.*[A-Z0-9]) ([^A-Z0-9].*)", "\\1\\2", x_bak_clean)
|
||||
x_bak_clean <- gsub("(.*[^A-Z0-9]) ([A-Z0-9].*)", "\\1\\2", x_bak_clean)
|
||||
# remove hyphen after a starting "co"
|
||||
x_bak_clean <- gsub("^CO-", "CO", x_bak_clean)
|
||||
# replace text 'and' with a slash
|
||||
x_bak_clean <- gsub(" AND ", "/", x_bak_clean)
|
||||
}
|
||||
|
||||
x <- unique(x_bak_clean)
|
||||
x_new <- rep(NA_character_, length(x))
|
||||
x_unknown <- character(0)
|
||||
|
||||
note_if_more_than_one_found <- function(found, index, from_text) {
|
||||
if (initial_search == TRUE & isTRUE(length(from_text) > 1)) {
|
||||
message(font_blue(paste0("NOTE: more than one result was found for item ", index, ": ",
|
||||
paste0(ab_name(from_text, tolower = TRUE, initial_search = FALSE), collapse = ", "))))
|
||||
}
|
||||
found[1L]
|
||||
}
|
||||
|
||||
if (initial_search == TRUE) {
|
||||
progress <- progress_estimated(n = length(x), n_min = 25) # start if n >= 25
|
||||
on.exit(close(progress))
|
||||
}
|
||||
|
||||
for (i in seq_len(length(x))) {
|
||||
if (initial_search == TRUE) {
|
||||
progress$tick()
|
||||
}
|
||||
|
||||
if (is.na(x[i]) | is.null(x[i])) {
|
||||
next
|
||||
}
|
||||
if (identical(x[i], "") |
|
||||
# no short names:
|
||||
nchar(x[i]) <= 2 |
|
||||
# prevent "bacteria" from coercing to TMP, since Bacterial is a brand name of it:
|
||||
identical(tolower(x[i]), "bacteria")) {
|
||||
x_unknown <- c(x_unknown, x_bak[x[i] == x_bak_clean][1])
|
||||
next
|
||||
}
|
||||
|
||||
if (isTRUE(flag_multiple_results) & x[i] %like% "[ ]") {
|
||||
from_text <- suppressWarnings(ab_from_text(x[i], initial_search = FALSE, translate_ab = FALSE)[[1]])
|
||||
} else {
|
||||
from_text <- character(0)
|
||||
}
|
||||
|
||||
# exact AB code
|
||||
found <- antibiotics[which(antibiotics$ab == x[i]), ]$ab
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# exact ATC code
|
||||
found <- antibiotics[which(antibiotics$atc == x[i]), ]$ab
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# exact CID code
|
||||
found <- antibiotics[which(antibiotics$cid == x[i]), ]$ab
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# exact name
|
||||
found <- antibiotics[which(toupper(antibiotics$name) == x[i]), ]$ab
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# exact LOINC code
|
||||
loinc_found <- unlist(lapply(antibiotics$loinc,
|
||||
function(s) x[i] %in% s))
|
||||
found <- antibiotics$ab[loinc_found == TRUE]
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# exact synonym
|
||||
synonym_found <- unlist(lapply(antibiotics$synonyms,
|
||||
function(s) x[i] %in% toupper(s)))
|
||||
found <- antibiotics$ab[synonym_found == TRUE]
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# exact abbreviation
|
||||
abbr_found <- unlist(lapply(antibiotics$abbreviations,
|
||||
function(a) x[i] %in% toupper(a)))
|
||||
found <- antibiotics$ab[abbr_found == TRUE]
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# allow characters that resemble others, but only continue when having more than 3 characters
|
||||
if (nchar(x[i]) <= 3) {
|
||||
x_unknown <- c(x_unknown, x_bak[x[i] == x_bak_clean][1])
|
||||
next
|
||||
}
|
||||
x_spelling <- x[i]
|
||||
if (already_regex == FALSE) {
|
||||
x_spelling <- gsub("[IY]+", "[IY]+", x_spelling)
|
||||
x_spelling <- gsub("(C|K|Q|QU|S|Z|X|KS)+", "(C|K|Q|QU|S|Z|X|KS)+", x_spelling)
|
||||
x_spelling <- gsub("(PH|F|V)+", "(PH|F|V)+", x_spelling)
|
||||
x_spelling <- gsub("(TH|T)+", "(TH|T)+", x_spelling)
|
||||
x_spelling <- gsub("A+", "A+", x_spelling)
|
||||
x_spelling <- gsub("E+", "E+", x_spelling)
|
||||
x_spelling <- gsub("O+", "O+", x_spelling)
|
||||
# allow any ending of -in/-ine and -im/-ime
|
||||
x_spelling <- gsub("(\\[IY\\]\\+(N|M)|\\[IY\\]\\+(N|M)E\\+)$", "[IY]+(N|M)E*", x_spelling)
|
||||
# allow any ending of -ol/-ole
|
||||
x_spelling <- gsub("(O\\+L|O\\+LE\\+)$", "O+LE*", x_spelling)
|
||||
# allow any ending of -on/-one
|
||||
x_spelling <- gsub("(O\\+N|O\\+NE\\+)$", "O+NE*", x_spelling)
|
||||
# replace multiple same characters to single one with '+', like "ll" -> "l+"
|
||||
x_spelling <- gsub("(.)\\1+", "\\1+", x_spelling)
|
||||
# replace spaces and slashes with a possibility on both
|
||||
x_spelling <- gsub("[ /]", "( .*|.*/)", x_spelling)
|
||||
# correct for digital reading text (OCR)
|
||||
x_spelling <- gsub("[NRD8B]", "[NRD8B]", x_spelling)
|
||||
x_spelling <- gsub("(O|0)", "(O|0)+", x_spelling)
|
||||
x_spelling <- gsub("++", "+", x_spelling, fixed = TRUE)
|
||||
}
|
||||
|
||||
# try if name starts with it
|
||||
found <- antibiotics[which(antibiotics$name %like% paste0("^", x_spelling)), ]$ab
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
# try if name ends with it
|
||||
found <- antibiotics[which(antibiotics$name %like% paste0(x_spelling, "$")), ]$ab
|
||||
if (nchar(x[i]) >= 4 & length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# and try if any synonym starts with it
|
||||
synonym_found <- unlist(lapply(antibiotics$synonyms,
|
||||
function(s) any(s %like% paste0("^", x_spelling))))
|
||||
found <- antibiotics$ab[synonym_found == TRUE]
|
||||
if (length(found) > 0) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# INITIAL SEARCH - More uncertain results ----
|
||||
|
||||
if (initial_search == TRUE) {
|
||||
# only run on first try
|
||||
|
||||
# try by removing all spaces
|
||||
if (x[i] %like% " ") {
|
||||
found <- suppressWarnings(as.ab(gsub(" +", "", x[i]), initial_search = FALSE))
|
||||
if (length(found) > 0 & !is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
# try by removing all spaces and numbers
|
||||
if (x[i] %like% " " | x[i] %like% "[0-9]") {
|
||||
found <- suppressWarnings(as.ab(gsub("[ 0-9]", "", x[i]), initial_search = FALSE))
|
||||
if (length(found) > 0 & !is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
# transform back from other languages and try again
|
||||
x_translated <- paste(lapply(strsplit(x[i], "[^A-Z0-9 ]"),
|
||||
function(y) {
|
||||
for (i in seq_len(length(y))) {
|
||||
y[i] <- ifelse(tolower(y[i]) %in% tolower(translations_file$replacement),
|
||||
translations_file[which(tolower(translations_file$replacement) == tolower(y[i]) &
|
||||
!isFALSE(translations_file$fixed)), "pattern"],
|
||||
y[i])
|
||||
}
|
||||
y
|
||||
})[[1]],
|
||||
collapse = "/")
|
||||
x_translated_guess <- suppressWarnings(as.ab(x_translated, initial_search = FALSE))
|
||||
if (!is.na(x_translated_guess)) {
|
||||
x_new[i] <- x_translated_guess
|
||||
next
|
||||
}
|
||||
|
||||
# now also try to coerce brandname combinations like "Amoxy/clavulanic acid"
|
||||
x_translated <- paste(lapply(strsplit(x_translated, "[^A-Z0-9 ]"),
|
||||
function(y) {
|
||||
for (i in seq_len(length(y))) {
|
||||
y_name <- suppressWarnings(ab_name(y[i], language = NULL, initial_search = FALSE))
|
||||
y[i] <- ifelse(!is.na(y_name),
|
||||
y_name,
|
||||
y[i])
|
||||
}
|
||||
y
|
||||
})[[1]],
|
||||
collapse = "/")
|
||||
x_translated_guess <- suppressWarnings(as.ab(x_translated, initial_search = FALSE))
|
||||
if (!is.na(x_translated_guess)) {
|
||||
x_new[i] <- x_translated_guess
|
||||
next
|
||||
}
|
||||
|
||||
# try by removing all trailing capitals
|
||||
if (x[i] %like_case% "[a-z]+[A-Z]+$") {
|
||||
found <- suppressWarnings(as.ab(gsub("[A-Z]+$", "", x[i]), initial_search = FALSE))
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
# keep only letters
|
||||
found <- suppressWarnings(as.ab(gsub("[^A-Z]", "", x[i]), initial_search = FALSE))
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# try from a bigger text, like from a health care record, see ?ab_from_text
|
||||
# already calculated above if flag_multiple_results = TRUE
|
||||
if (isTRUE(flag_multiple_results)) {
|
||||
found <- from_text[1L]
|
||||
} else {
|
||||
found <- suppressWarnings(ab_from_text(x[i], initial_search = FALSE, translate_ab = FALSE)[[1]][1L])
|
||||
}
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# first 5 except for cephalosporins, then first 7 (those cephalosporins all start quite the same!)
|
||||
found <- suppressWarnings(as.ab(substr(x[i], 1, 5), initial_search = FALSE))
|
||||
if (!is.na(found) && !ab_group(found, initial_search = FALSE) %like% "cephalosporins") {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
found <- suppressWarnings(as.ab(substr(x[i], 1, 7), initial_search = FALSE))
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# make all consonants facultative
|
||||
search_str <- gsub("([BCDFGHJKLMNPQRSTVWXZ])", "\\1*", x[i])
|
||||
found <- suppressWarnings(as.ab(search_str, initial_search = FALSE, already_regex = TRUE))
|
||||
# keep at least 4 normal characters
|
||||
if (nchar(gsub(".\\*", "", search_str)) < 4) {
|
||||
found <- NA
|
||||
}
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# make all vowels facultative
|
||||
search_str <- gsub("([AEIOUY])", "\\1*", x[i])
|
||||
found <- suppressWarnings(as.ab(search_str, initial_search = FALSE, already_regex = TRUE))
|
||||
# keep at least 5 normal characters
|
||||
if (nchar(gsub(".\\*", "", search_str)) < 5) {
|
||||
found <- NA
|
||||
}
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# allow misspelling of vowels
|
||||
x_spelling <- gsub("A+", "[AEIOU]+", x_spelling, fixed = TRUE)
|
||||
x_spelling <- gsub("E+", "[AEIOU]+", x_spelling, fixed = TRUE)
|
||||
x_spelling <- gsub("I+", "[AEIOU]+", x_spelling, fixed = TRUE)
|
||||
x_spelling <- gsub("O+", "[AEIOU]+", x_spelling, fixed = TRUE)
|
||||
x_spelling <- gsub("U+", "[AEIOU]+", x_spelling, fixed = TRUE)
|
||||
found <- suppressWarnings(as.ab(x_spelling, initial_search = FALSE, already_regex = TRUE))
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- note_if_more_than_one_found(found, i, from_text)
|
||||
next
|
||||
}
|
||||
|
||||
# try with switched character, like "mreopenem"
|
||||
for (j in seq_len(nchar(x[i]))) {
|
||||
x_switched <- paste0(
|
||||
# beginning part:
|
||||
substr(x[i], 1, j - 1),
|
||||
# here is the switching of 2 characters:
|
||||
substr(x[i], j + 1, j + 1),
|
||||
substr(x[i], j, j),
|
||||
# ending part:
|
||||
substr(x[i], j + 2, nchar(x[i])))
|
||||
found <- suppressWarnings(as.ab(x_switched, initial_search = FALSE))
|
||||
if (!is.na(found)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!is.na(found)) {
|
||||
x_new[i] <- found[1L]
|
||||
next
|
||||
}
|
||||
|
||||
} # end of initial_search = TRUE
|
||||
|
||||
# not found
|
||||
x_unknown <- c(x_unknown, x_bak[x[i] == x_bak_clean][1])
|
||||
}
|
||||
|
||||
if (initial_search == TRUE) {
|
||||
close(progress)
|
||||
}
|
||||
|
||||
# take failed ATC codes apart from rest
|
||||
x_unknown_ATCs <- x_unknown[x_unknown %like% "[A-Z][0-9][0-9][A-Z][A-Z][0-9][0-9]"]
|
||||
x_unknown <- x_unknown[!x_unknown %in% x_unknown_ATCs]
|
||||
if (length(x_unknown_ATCs) > 0) {
|
||||
warning("These ATC codes are not (yet) in the antibiotics data set: ",
|
||||
paste('"', sort(unique(x_unknown_ATCs)), '"', sep = "", collapse = ", "),
|
||||
".",
|
||||
call. = FALSE)
|
||||
}
|
||||
|
||||
if (length(x_unknown) > 0) {
|
||||
warning("These values could not be coerced to a valid antimicrobial ID: ",
|
||||
paste('"', sort(unique(x_unknown)), '"', sep = "", collapse = ", "),
|
||||
".",
|
||||
call. = FALSE)
|
||||
}
|
||||
|
||||
x_result <- data.frame(x = x_bak_clean, stringsAsFactors = FALSE) %>%
|
||||
left_join(data.frame(x = x, x_new = x_new, stringsAsFactors = FALSE), by = "x") %>%
|
||||
pull(x_new)
|
||||
|
||||
if (length(x_result) == 0) {
|
||||
x_result <- NA_character_
|
||||
}
|
||||
|
||||
structure(.Data = x_result,
|
||||
class = c("ab", "character"))
|
||||
}
|
||||
|
||||
#' @rdname as.ab
|
||||
#' @export
|
||||
is.ab <- function(x) {
|
||||
inherits(x, "ab")
|
||||
}
|
||||
|
||||
#' @method print ab
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.ab <- function(x, ...) {
|
||||
cat("Class <ab>\n")
|
||||
print(as.character(x), quote = FALSE)
|
||||
}
|
||||
|
||||
#' @method as.data.frame ab
|
||||
#' @export
|
||||
#' @noRd
|
||||
as.data.frame.ab <- function(x, ...) {
|
||||
nm <- deparse1(substitute(x))
|
||||
if (!"nm" %in% names(list(...))) {
|
||||
as.data.frame.vector(as.ab(x), ..., nm = nm)
|
||||
} else {
|
||||
as.data.frame.vector(as.ab(x), ...)
|
||||
}
|
||||
}
|
||||
#' @method [ ab
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[.ab" <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
#' @method [[ ab
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[.ab" <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
#' @method [<- ab
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[<-.ab" <- function(i, j, ..., value) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
class_integrity_check(y, "antimicrobial code", antibiotics$ab)
|
||||
}
|
||||
#' @method [[<- ab
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[<-.ab" <- function(i, j, ..., value) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
class_integrity_check(y, "antimicrobial code", antibiotics$ab)
|
||||
}
|
||||
#' @method c ab
|
||||
#' @export
|
||||
#' @noRd
|
||||
c.ab <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
class_integrity_check(y, "antimicrobial code", antibiotics$ab)
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Antibiotic class selectors
|
||||
#'
|
||||
#' Use these selection helpers inside any function that allows [Tidyverse selections](https://tidyselect.r-lib.org/reference/language.html), like `dplyr::select()` or `tidyr::pivot_longer()`. They help to select the columns of antibiotics that are of a specific antibiotic class, without the need to define the columns or antibiotic abbreviations.
|
||||
#' @inheritParams filter_ab_class
|
||||
#' @details All columns will be searched for known antibiotic names, abbreviations, brand names and codes (ATC, EARS-Net, WHO, etc.). This means that a selector like e.g. [aminoglycosides()] will pick up column names like 'gen', 'genta', 'J01GB03', 'tobra', 'Tobracin', etc.
|
||||
#'
|
||||
#' These functions only work if the `tidyselect` package is installed, that comes with the `dplyr` package. An error will be thrown if `tidyselect` package is not installed, or if the functions are used outside a function that allows Tidyverse selections like `select()` or `pivot_longer()`.
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @seealso [filter_ab_class()] for the `filter()` equivalent.
|
||||
#' @name antibiotic_class_selectors
|
||||
#' @export
|
||||
#' @examples
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#'
|
||||
#' # this will select columns 'IPM' (imipenem) and 'MEM' (meropenem):
|
||||
#' example_isolates %>%
|
||||
#' select(carbapenems())
|
||||
#'
|
||||
#' # this will select columns 'mo', 'AMK', 'GEN', 'KAN' and 'TOB':
|
||||
#' example_isolates %>%
|
||||
#' select(mo, aminoglycosides())
|
||||
#'
|
||||
#' # this will select columns 'mo' and all antimycobacterial drugs ('RIF'):
|
||||
#' example_isolates %>%
|
||||
#' select(mo, ab_class("mycobact"))
|
||||
#'
|
||||
#'
|
||||
#' # get bug/drug combinations for only macrolides in Gram-positives:
|
||||
#' example_isolates %>%
|
||||
#' filter(mo_gramstain(mo) %like% "pos") %>%
|
||||
#' select(mo, macrolides()) %>%
|
||||
#' bug_drug_combinations() %>%
|
||||
#' format()
|
||||
#'
|
||||
#'
|
||||
#' data.frame(irrelevant = "value",
|
||||
#' J01CA01 = "S") %>% # ATC code of ampicillin
|
||||
#' select(penicillins()) # so the 'J01CA01' column is selected
|
||||
#'
|
||||
#' }
|
||||
ab_class <- function(ab_class) {
|
||||
ab_selector(ab_class, function_name = "ab_class")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
aminoglycosides <- function() {
|
||||
ab_selector("aminoglycoside", function_name = "aminoglycosides")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
carbapenems <- function() {
|
||||
ab_selector("carbapenem", function_name = "carbapenems")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
cephalosporins <- function() {
|
||||
ab_selector("cephalosporin", function_name = "cephalosporins")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
cephalosporins_1st <- function() {
|
||||
ab_selector("cephalosporins.*1", function_name = "cephalosporins_1st")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
cephalosporins_2nd <- function() {
|
||||
ab_selector("cephalosporins.*2", function_name = "cephalosporins_2nd")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
cephalosporins_3rd <- function() {
|
||||
ab_selector("cephalosporins.*3", function_name = "cephalosporins_3rd")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
cephalosporins_4th <- function() {
|
||||
ab_selector("cephalosporins.*4", function_name = "cephalosporins_4th")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
cephalosporins_5th <- function() {
|
||||
ab_selector("cephalosporins.*5", function_name = "cephalosporins_5th")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
fluoroquinolones <- function() {
|
||||
ab_selector("fluoroquinolone", function_name = "fluoroquinolones")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
glycopeptides <- function() {
|
||||
ab_selector("glycopeptide", function_name = "glycopeptides")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
macrolides <- function() {
|
||||
ab_selector("macrolide", function_name = "macrolides")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
penicillins <- function() {
|
||||
ab_selector("penicillin", function_name = "penicillins")
|
||||
}
|
||||
|
||||
#' @rdname antibiotic_class_selectors
|
||||
#' @export
|
||||
tetracyclines <- function() {
|
||||
ab_selector("tetracycline", function_name = "tetracyclines")
|
||||
}
|
||||
|
||||
ab_selector <- function(ab_class, function_name) {
|
||||
peek_vars_tidyselect <- import_fn("peek_vars", "tidyselect")
|
||||
vars_vct <- peek_vars_tidyselect(fn = function_name)
|
||||
vars_df <- data.frame(as.list(vars_vct))[0, , drop = FALSE]
|
||||
colnames(vars_df) <- vars_vct
|
||||
ab_in_data <- suppressMessages(get_column_abx(vars_df))
|
||||
|
||||
if (length(ab_in_data) == 0) {
|
||||
message(font_blue("NOTE: no antimicrobial agents found."))
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
ab_reference <- subset(antibiotics,
|
||||
group %like% ab_class |
|
||||
atc_group1 %like% ab_class |
|
||||
atc_group2 %like% ab_class)
|
||||
ab_group <- find_ab_group(ab_class)
|
||||
if (ab_group == "") {
|
||||
ab_group <- paste0("'", ab_class, "'")
|
||||
examples <- ""
|
||||
} else {
|
||||
examples <- paste0(" (such as ", find_ab_names(ab_class, 2), ")")
|
||||
}
|
||||
# get the columns with a group names in the chosen ab class
|
||||
agents <- ab_in_data[names(ab_in_data) %in% ab_reference$ab]
|
||||
if (length(agents) == 0) {
|
||||
message(font_blue(paste0("NOTE: No antimicrobial agents of class ", ab_group,
|
||||
" found", examples, ".")))
|
||||
} else {
|
||||
message(font_blue(paste0("Selecting ", ab_group, ": ",
|
||||
paste(paste0("`", font_bold(agents, collapse = NULL),
|
||||
"` (", ab_name(names(agents), tolower = TRUE, language = NULL), ")"),
|
||||
collapse = ", "))))
|
||||
}
|
||||
unname(agents)
|
||||
}
|
||||
@@ -1,207 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Retrieve antimicrobial drug names and doses from clinical text
|
||||
#'
|
||||
#' Use this function on e.g. clinical texts from health care records. It returns a [list] with all antimicrobial drugs, doses and forms of administration found in the texts.
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param text text to analyse
|
||||
#' @param type type of property to search for, either `"drug"`, `"dose"` or `"administration"`, see *Examples*
|
||||
#' @param collapse character to pass on to `paste(..., collapse = ...)` to only return one character per element of `text`, see *Examples*
|
||||
#' @param translate_ab if `type = "drug"`: a column name of the [antibiotics] data set to translate the antibiotic abbreviations to, using [ab_property()]. Defaults to `FALSE`. Using `TRUE` is equal to using "name".
|
||||
#' @param thorough_search logical to indicate whether the input must be extensively searched for misspelling and other faulty input values. Setting this to `TRUE` will take considerably more time than when using `FALSE`. At default, it will turn `TRUE` when all input elements contain a maximum of three words.
|
||||
#' @param ... parameters passed on to [as.ab()]
|
||||
#' @details This function is also internally used by [as.ab()], although it then only searches for the first drug name and will throw a note if more drug names could have been returned.
|
||||
#'
|
||||
#' ## Parameter `type`
|
||||
#' At default, the function will search for antimicrobial drug names. All text elements will be searched for official names, ATC codes and brand names. As it uses [as.ab()] internally, it will correct for misspelling.
|
||||
#'
|
||||
#' With `type = "dose"` (or similar, like "dosing", "doses"), all text elements will be searched for numeric values that are higher than 100 and do not resemble years. The output will be numeric. It supports any unit (g, mg, IE, etc.) and multiple values in one clinical text, see *Examples*.
|
||||
#'
|
||||
#' With `type = "administration"` (or abbreviations, like "admin", "adm"), all text elements will be searched for a form of drug administration. It supports the following forms (including common abbreviations): buccal, implant, inhalation, instillation, intravenous, nasal, oral, parenteral, rectal, sublingual, transdermal and vaginal. Abbreviations for oral (such as 'po', 'per os') will become "oral", all values for intravenous (such as 'iv', 'intraven') will become "iv". It supports multiple values in one clinical text, see *Examples*.
|
||||
#'
|
||||
#' ## Parameter `collapse`
|
||||
#' Without using `collapse`, this function will return a [list]. This can be convenient to use e.g. inside a `mutate()`):\cr
|
||||
#' `df %>% mutate(abx = ab_from_text(clinical_text))`
|
||||
#'
|
||||
#' The returned AB codes can be transformed to official names, groups, etc. with all [ab_property()] functions like [ab_name()] and [ab_group()], or by using the `translate_ab` parameter.
|
||||
#'
|
||||
#' With using `collapse`, this function will return a [character]:\cr
|
||||
#' `df %>% mutate(abx = ab_from_text(clinical_text, collapse = "|"))`
|
||||
#' @export
|
||||
#' @return A [list], or a [character] if `collapse` is not `NULL`
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' # mind the bad spelling of amoxicillin in this line,
|
||||
#' # straight from a true health care record:
|
||||
#' ab_from_text("28/03/2020 regular amoxicilliin 500mg po tds")
|
||||
#'
|
||||
#' ab_from_text("500 mg amoxi po and 400mg cipro iv")
|
||||
#' ab_from_text("500 mg amoxi po and 400mg cipro iv", type = "dose")
|
||||
#' ab_from_text("500 mg amoxi po and 400mg cipro iv", type = "admin")
|
||||
#'
|
||||
#' ab_from_text("500 mg amoxi po and 400mg cipro iv", collapse = ", ")
|
||||
#'
|
||||
#' # if you want to know which antibiotic groups were administered, do e.g.:
|
||||
#' abx <- ab_from_text("500 mg amoxi po and 400mg cipro iv")
|
||||
#' ab_group(abx[[1]])
|
||||
#'
|
||||
#' if (require("dplyr")) {
|
||||
#' tibble(clinical_text = c("given 400mg cipro and 500 mg amox",
|
||||
#' "started on doxy iv today")) %>%
|
||||
#' mutate(abx_codes = ab_from_text(clinical_text),
|
||||
#' abx_doses = ab_from_text(clinical_text, type = "doses"),
|
||||
#' abx_admin = ab_from_text(clinical_text, type = "admin"),
|
||||
#' abx_coll = ab_from_text(clinical_text, collapse = "|"),
|
||||
#' abx_coll_names = ab_from_text(clinical_text,
|
||||
#' collapse = "|",
|
||||
#' translate_ab = "name"),
|
||||
#' abx_coll_doses = ab_from_text(clinical_text,
|
||||
#' type = "doses",
|
||||
#' collapse = "|"),
|
||||
#' abx_coll_admin = ab_from_text(clinical_text,
|
||||
#' type = "admin",
|
||||
#' collapse = "|"))
|
||||
#'
|
||||
#' }
|
||||
ab_from_text <- function(text,
|
||||
type = c("drug", "dose", "administration"),
|
||||
collapse = NULL,
|
||||
translate_ab = FALSE,
|
||||
thorough_search = NULL,
|
||||
...) {
|
||||
|
||||
if (missing(type)) {
|
||||
type <- type[1L]
|
||||
}
|
||||
type <- tolower(trimws(type))
|
||||
stop_if(length(type) != 1, "`type` must be of length 1")
|
||||
|
||||
text <- tolower(as.character(text))
|
||||
text_split_all <- strsplit(text, "[ ;.,:\\|]")
|
||||
progress <- progress_estimated(n = length(text_split_all), n_min = 5)
|
||||
on.exit(close(progress))
|
||||
|
||||
if (type %like% "(drug|ab|anti)") {
|
||||
|
||||
translate_ab <- get_translate_ab(translate_ab)
|
||||
|
||||
if (isTRUE(thorough_search) |
|
||||
(isTRUE(is.null(thorough_search)) & max(sapply(text_split_all, length), na.rm = TRUE) <= 3)) {
|
||||
text_split_all <- text_split_all[nchar(text_split_all) >= 4 & grepl("[a-z]+", text_split_all)]
|
||||
result <- lapply(text_split_all, function(text_split) {
|
||||
progress$tick()
|
||||
suppressWarnings(
|
||||
out <- as.ab(text_split, ...)
|
||||
)
|
||||
})
|
||||
|
||||
} else {
|
||||
# no thorough search
|
||||
abbr <- unlist(antibiotics$abbreviations)
|
||||
abbr <- abbr[nchar(abbr) >= 4]
|
||||
names_atc <- substr(c(antibiotics$name, antibiotics$atc), 1, 5)
|
||||
synonyms <- unlist(antibiotics$synonyms)
|
||||
synonyms <- synonyms[nchar(synonyms) >= 4]
|
||||
# regular expression must not be too long, so split synonyms in two:
|
||||
synonyms_part1 <- synonyms[seq_len(0.5 * length(synonyms))]
|
||||
synonyms_part2 <- synonyms[!synonyms %in% synonyms_part1]
|
||||
to_regex <- function(x) {
|
||||
paste0("^(",
|
||||
paste0(unique(gsub("[^a-z0-9]+", "", sort(tolower(x)))), collapse = "|"),
|
||||
").*")
|
||||
}
|
||||
result <- lapply(text_split_all, function(text_split) {
|
||||
progress$tick()
|
||||
suppressWarnings(
|
||||
out <- as.ab(unique(c(text_split[text_split %like_case% to_regex(abbr)],
|
||||
text_split[text_split %like_case% to_regex(names_atc)],
|
||||
text_split[text_split %like_case% to_regex(synonyms_part1)],
|
||||
text_split[text_split %like_case% to_regex(synonyms_part2)])
|
||||
),
|
||||
...)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
close(progress)
|
||||
|
||||
result <- lapply(result, function(out) {
|
||||
out <- out[!is.na(out)]
|
||||
if (length(out) == 0) {
|
||||
as.ab(NA)
|
||||
} else {
|
||||
if (!isFALSE(translate_ab)) {
|
||||
out <- ab_property(out, property = translate_ab, initial_search = FALSE)
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
} else if (type %like% "dos") {
|
||||
text_split_all <- strsplit(text, " ")
|
||||
result <- lapply(text_split_all, function(text_split) {
|
||||
text_split <- text_split[text_split %like% "^[0-9]{2,}(/[0-9]+)?[a-z]*$"]
|
||||
# only left part of "/", like 500 in "500/125"
|
||||
text_split <- gsub("/.*", "", text_split)
|
||||
text_split <- gsub(",", ".", text_split, fixed = TRUE) # foreign system using comma as decimal sep
|
||||
text_split <- as.double(gsub("[^0-9.]", "", text_split))
|
||||
# minimal 100 units/mg and no years that unlikely doses
|
||||
text_split <- text_split[text_split >= 100 & !text_split %in% c(1951:1999, 2001:2049)]
|
||||
|
||||
if (length(text_split) > 0) {
|
||||
text_split
|
||||
} else {
|
||||
NA_real_
|
||||
}
|
||||
})
|
||||
|
||||
} else if (type %like% "adm") {
|
||||
result <- lapply(text_split_all, function(text_split) {
|
||||
text_split <- text_split[text_split %like% "(^iv$|intraven|^po$|per os|oral|implant|inhal|instill|nasal|paren|rectal|sublingual|buccal|trans.*dermal|vaginal)"]
|
||||
if (length(text_split) > 0) {
|
||||
text_split <- gsub("(^po$|.*per os.*)", "oral", text_split)
|
||||
text_split <- gsub("(^iv$|.*intraven.*)", "iv", text_split)
|
||||
text_split
|
||||
} else {
|
||||
NA_character_
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
stop_("`type` must be either 'drug', 'dose' or 'administration'")
|
||||
}
|
||||
|
||||
# collapse text if needed
|
||||
if (!is.null(collapse)) {
|
||||
result <- sapply(result, function(x) {
|
||||
if (length(x) == 1 & all(is.na(x))) {
|
||||
NA_character_
|
||||
} else {
|
||||
paste0(x, collapse = collapse)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
result
|
||||
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Property of an antibiotic
|
||||
#'
|
||||
#' Use these functions to return a specific property of an antibiotic from the [antibiotics] data set. All input values will be evaluated internally with [as.ab()].
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x any (vector of) text that can be coerced to a valid antibiotic code with [as.ab()]
|
||||
#' @param tolower logical to indicate whether the first character of every output should be transformed to a lower case character. This will lead to e.g. "polymyxin B" and not "polymyxin b".
|
||||
#' @param property one of the column names of one of the [antibiotics] data set
|
||||
#' @param language language of the returned text, defaults to system language (see [get_locale()]) and can also be set with `getOption("AMR_locale")`. Use `language = NULL` or `language = ""` to prevent translation.
|
||||
#' @param administration way of administration, either `"oral"` or `"iv"`
|
||||
#' @param units a logical to indicate whether the units instead of the DDDs itself must be returned, see Examples
|
||||
#' @param open browse the URL using [utils::browseURL()]
|
||||
#' @param ... other parameters passed on to [as.ab()]
|
||||
#' @details All output will be [translate]d where possible.
|
||||
#'
|
||||
#' The function [ab_url()] will return the direct URL to the official WHO website. A warning will be returned if the required ATC code is not available.
|
||||
#' @inheritSection as.ab Source
|
||||
#' @rdname ab_property
|
||||
#' @name ab_property
|
||||
#' @return
|
||||
#' - An [`integer`] in case of [ab_cid()]
|
||||
#' - A named [`list`] in case of [ab_info()] and multiple [ab_synonyms()]/[ab_tradenames()]
|
||||
#' - A [`double`] in case of [ab_ddd()]
|
||||
#' - A [`character`] in all other cases
|
||||
#' @export
|
||||
#' @seealso [antibiotics]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' # all properties:
|
||||
#' ab_name("AMX") # "Amoxicillin"
|
||||
#' ab_atc("AMX") # J01CA04 (ATC code from the WHO)
|
||||
#' ab_cid("AMX") # 33613 (Compound ID from PubChem)
|
||||
#' ab_synonyms("AMX") # a list with brand names of amoxicillin
|
||||
#' ab_tradenames("AMX") # same
|
||||
#' ab_group("AMX") # "Beta-lactams/penicillins"
|
||||
#' ab_atc_group1("AMX") # "Beta-lactam antibacterials, penicillins"
|
||||
#' ab_atc_group2("AMX") # "Penicillins with extended spectrum"
|
||||
#' ab_url("AMX") # link to the official WHO page
|
||||
#'
|
||||
#' # smart lowercase tranformation
|
||||
#' ab_name(x = c("AMC", "PLB")) # "Amoxicillin/clavulanic acid" "Polymyxin B"
|
||||
#' ab_name(x = c("AMC", "PLB"),
|
||||
#' tolower = TRUE) # "amoxicillin/clavulanic acid" "polymyxin B"
|
||||
#'
|
||||
#' # defined daily doses (DDD)
|
||||
#' ab_ddd("AMX", "oral") # 1
|
||||
#' ab_ddd("AMX", "oral", units = TRUE) # "g"
|
||||
#' ab_ddd("AMX", "iv") # 1
|
||||
#' ab_ddd("AMX", "iv", units = TRUE) # "g"
|
||||
#'
|
||||
#' ab_info("AMX") # all properties as a list
|
||||
#'
|
||||
#' # all ab_* functions use as.ab() internally, so you can go from 'any' to 'any':
|
||||
#' ab_atc("AMP") # ATC code of AMP (ampicillin)
|
||||
#' ab_group("J01CA01") # Drug group of ampicillins ATC code
|
||||
#' ab_loinc("ampicillin") # LOINC codes of ampicillin
|
||||
#' ab_name("21066-6") # "Ampicillin" (using LOINC)
|
||||
#' ab_name(6249) # "Ampicillin" (using CID)
|
||||
#' ab_name("J01CA01") # "Ampicillin" (using ATC)
|
||||
#'
|
||||
#' # spelling from different languages and dyslexia are no problem
|
||||
#' ab_atc("ceftriaxon")
|
||||
#' ab_atc("cephtriaxone")
|
||||
#' ab_atc("cephthriaxone")
|
||||
#' ab_atc("seephthriaaksone")
|
||||
ab_name <- function(x, language = get_locale(), tolower = FALSE, ...) {
|
||||
x <- translate_AMR(ab_validate(x = x, property = "name", ...), language = language)
|
||||
if (tolower == TRUE) {
|
||||
# use perl to only transform the first character
|
||||
# as we want "polymyxin B", not "polymyxin b"
|
||||
x <- gsub("^([A-Z])", "\\L\\1", x, perl = TRUE)
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @aliases ATC
|
||||
#' @export
|
||||
ab_atc <- function(x, ...) {
|
||||
ab_validate(x = x, property = "atc", ...)
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_cid <- function(x, ...) {
|
||||
ab_validate(x = x, property = "cid", ...)
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_synonyms <- function(x, ...) {
|
||||
syns <- ab_validate(x = x, property = "synonyms", ...)
|
||||
names(syns) <- x
|
||||
if (length(syns) == 1) {
|
||||
unname(unlist(syns))
|
||||
} else {
|
||||
syns
|
||||
}
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_tradenames <- function(x, ...) {
|
||||
ab_synonyms(x, ...)
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_group <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(ab_validate(x = x, property = "group", ...), language = language)
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_atc_group1 <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(ab_validate(x = x, property = "atc_group1", ...), language = language)
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_atc_group2 <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(ab_validate(x = x, property = "atc_group2", ...), language = language)
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_loinc <- function(x, ...) {
|
||||
loincs <- ab_validate(x = x, property = "loinc", ...)
|
||||
names(loincs) <- x
|
||||
if (length(loincs) == 1) {
|
||||
unname(unlist(loincs))
|
||||
} else {
|
||||
loincs
|
||||
}
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_ddd <- function(x, administration = "oral", units = FALSE, ...) {
|
||||
stop_ifnot(administration %in% c("oral", "iv"), "`administration` must be 'oral' or 'iv'")
|
||||
ddd_prop <- administration
|
||||
if (units == TRUE) {
|
||||
ddd_prop <- paste0(ddd_prop, "_units")
|
||||
} else {
|
||||
ddd_prop <- paste0(ddd_prop, "_ddd")
|
||||
}
|
||||
ab_validate(x = x, property = ddd_prop, ...)
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_info <- function(x, language = get_locale(), ...) {
|
||||
x <- as.ab(x, ...)
|
||||
base::list(ab = as.character(x),
|
||||
atc = ab_atc(x),
|
||||
cid = ab_cid(x),
|
||||
name = ab_name(x, language = language),
|
||||
group = ab_group(x, language = language),
|
||||
atc_group1 = ab_atc_group1(x, language = language),
|
||||
atc_group2 = ab_atc_group2(x, language = language),
|
||||
tradenames = ab_tradenames(x),
|
||||
ddd = list(oral = list(amount = ab_ddd(x, administration = "oral", units = FALSE),
|
||||
units = ab_ddd(x, administration = "oral", units = TRUE)),
|
||||
iv = list(amount = ab_ddd(x, administration = "iv", units = FALSE),
|
||||
units = ab_ddd(x, administration = "iv", units = TRUE))))
|
||||
}
|
||||
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_url <- function(x, open = FALSE, ...) {
|
||||
ab <- as.ab(x = x, ... = ...)
|
||||
u <- paste0("https://www.whocc.no/atc_ddd_index/?code=", ab_atc(ab), "&showdescription=no")
|
||||
u[is.na(ab_atc(ab))] <- NA_character_
|
||||
names(u) <- ab_name(ab)
|
||||
|
||||
NAs <- ab_name(ab, tolower = TRUE, language = NULL)[!is.na(ab) & is.na(ab_atc(ab))]
|
||||
if (length(NAs) > 0) {
|
||||
warning("No ATC code available for ", paste0(NAs, collapse = ", "), ".")
|
||||
}
|
||||
|
||||
if (open == TRUE) {
|
||||
if (length(u) > 1 & !is.na(u[1L])) {
|
||||
warning("only the first URL will be opened, as `browseURL()` only suports one string.")
|
||||
}
|
||||
if (!is.na(u[1L])) {
|
||||
utils::browseURL(u[1L])
|
||||
}
|
||||
}
|
||||
u
|
||||
}
|
||||
|
||||
#' @rdname ab_property
|
||||
#' @export
|
||||
ab_property <- function(x, property = "name", language = get_locale(), ...) {
|
||||
stop_if(length(property) != 1L, "'property' must be of length 1.")
|
||||
stop_ifnot(property %in% colnames(antibiotics),
|
||||
"invalid property: '", property, "' - use a column name of the `antibiotics` data set")
|
||||
|
||||
translate_AMR(ab_validate(x = x, property = property, ...), language = language)
|
||||
}
|
||||
|
||||
ab_validate <- function(x, property, ...) {
|
||||
|
||||
check_dataset_integrity()
|
||||
|
||||
# try to catch an error when inputting an invalid parameter
|
||||
# so the 'call.' can be set to FALSE
|
||||
tryCatch(x[1L] %in% antibiotics[1, property],
|
||||
error = function(e) stop(e$message, call. = FALSE))
|
||||
x_bak <- x
|
||||
if (!all(x %in% antibiotics[, property])) {
|
||||
x <- data.frame(ab = as.ab(x, ...), stringsAsFactors = FALSE) %>%
|
||||
left_join(antibiotics, by = "ab") %>%
|
||||
pull(property)
|
||||
}
|
||||
if (property == "ab") {
|
||||
return(structure(x, class = property))
|
||||
} else if (property == "cid") {
|
||||
return(as.integer(x))
|
||||
} else if (property %like% "ddd") {
|
||||
return(as.double(x))
|
||||
} else {
|
||||
x[is.na(x) & !is.na(x_bak)] <- NA
|
||||
return(x)
|
||||
}
|
||||
}
|
||||
@@ -1,185 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Age in years of individuals
|
||||
#'
|
||||
#' Calculates age in years based on a reference date, which is the sytem date at default.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x date(s), will be coerced with [as.POSIXlt()]
|
||||
#' @param reference reference date(s) (defaults to today), will be coerced with [as.POSIXlt()] and cannot be lower than `x`
|
||||
#' @param exact a logical to indicate whether age calculation should be exact, i.e. with decimals. It divides the number of days of [year-to-date](https://en.wikipedia.org/wiki/Year-to-date) (YTD) of `x` by the number of days in the year of `reference` (either 365 or 366).
|
||||
#' @param na.rm a logical to indicate whether missing values should be removed
|
||||
#' @return An [integer] (no decimals) if `exact = FALSE`, a [double] (with decimals) otherwise
|
||||
#' @seealso To split ages into groups, use the [age_groups()] function.
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
#' @examples
|
||||
#' # 10 random birth dates
|
||||
#' df <- data.frame(birth_date = Sys.Date() - runif(10) * 25000)
|
||||
#' # add ages
|
||||
#' df$age <- age(df$birth_date)
|
||||
#' # add exact ages
|
||||
#' df$age_exact <- age(df$birth_date, exact = TRUE)
|
||||
#'
|
||||
#' df
|
||||
age <- function(x, reference = Sys.Date(), exact = FALSE, na.rm = FALSE) {
|
||||
if (length(x) != length(reference)) {
|
||||
stop_if(length(reference) != 1, "`x` and `reference` must be of same length, or `reference` must be of length 1.")
|
||||
reference <- rep(reference, length(x))
|
||||
}
|
||||
x <- as.POSIXlt(x)
|
||||
reference <- as.POSIXlt(reference)
|
||||
|
||||
# from https://stackoverflow.com/a/25450756/4575331
|
||||
years_gap <- reference$year - x$year
|
||||
ages <- ifelse(reference$mon < x$mon | (reference$mon == x$mon & reference$mday < x$mday),
|
||||
as.integer(years_gap - 1),
|
||||
as.integer(years_gap))
|
||||
|
||||
# add decimals
|
||||
if (exact == TRUE) {
|
||||
# get dates of `x` when `x` would have the year of `reference`
|
||||
x_in_reference_year <- as.POSIXlt(paste0(format(reference, "%Y"), format(x, "-%m-%d")))
|
||||
# get differences in days
|
||||
n_days_x_rest <- as.double(difftime(reference, x_in_reference_year, units = "days"))
|
||||
# get numbers of days the years of `reference` has for a reliable denominator
|
||||
n_days_reference_year <- as.POSIXlt(paste0(format(reference, "%Y"), "-12-31"))$yday + 1
|
||||
# add decimal parts of year
|
||||
mod <- n_days_x_rest / n_days_reference_year
|
||||
# negative mods are cases where `x_in_reference_year` > `reference` - so 'add' a year
|
||||
mod[mod < 0] <- 1 + mod[mod < 0]
|
||||
# and finally add to ages
|
||||
ages <- ages + mod
|
||||
}
|
||||
|
||||
if (any(ages < 0, na.rm = TRUE)) {
|
||||
ages[ages < 0] <- NA
|
||||
warning("NAs introduced for ages below 0.")
|
||||
}
|
||||
if (any(ages > 120, na.rm = TRUE)) {
|
||||
warning("Some ages are above 120.")
|
||||
}
|
||||
|
||||
if (isTRUE(na.rm)) {
|
||||
ages <- ages[!is.na(ages)]
|
||||
}
|
||||
|
||||
ages
|
||||
}
|
||||
|
||||
#' Split ages into age groups
|
||||
#'
|
||||
#' Split ages into age groups defined by the `split` parameter. This allows for easier demographic (antimicrobial resistance) analysis.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x age, e.g. calculated with [age()]
|
||||
#' @param split_at values to split `x` at, defaults to age groups 0-11, 12-24, 25-54, 55-74 and 75+. See Details.
|
||||
#' @param na.rm a [logical] to indicate whether missing values should be removed
|
||||
#' @details To split ages, the input for the `split_at` parameter can be:
|
||||
#'
|
||||
#' * A numeric vector. A vector of e.g. `c(10, 20)` will split on 0-9, 10-19 and 20+. A value of only `50` will split on 0-49 and 50+.
|
||||
#' The default is to split on young children (0-11), youth (12-24), young adults (25-54), middle-aged adults (55-74) and elderly (75+).
|
||||
#' * A character:
|
||||
#' - `"children"` or `"kids"`, equivalent of: `c(0, 1, 2, 4, 6, 13, 18)`. This will split on 0, 1, 2-3, 4-5, 6-12, 13-17 and 18+.
|
||||
#' - `"elderly"` or `"seniors"`, equivalent of: `c(65, 75, 85)`. This will split on 0-64, 65-74, 75-84, 85+.
|
||||
#' - `"fives"`, equivalent of: `1:20 * 5`. This will split on 0-4, 5-9, 10-14, ..., 90-94, 95-99, 100+.
|
||||
#' - `"tens"`, equivalent of: `1:10 * 10`. This will split on 0-9, 10-19, 20-29, ..., 80-89, 90-99, 100+.
|
||||
#' @return Ordered [factor]
|
||||
#' @seealso To determine ages, based on one or more reference dates, use the [age()] function.
|
||||
#' @export
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' ages <- c(3, 8, 16, 54, 31, 76, 101, 43, 21)
|
||||
#'
|
||||
#' # split into 0-49 and 50+
|
||||
#' age_groups(ages, 50)
|
||||
#'
|
||||
#' # split into 0-19, 20-49 and 50+
|
||||
#' age_groups(ages, c(20, 50))
|
||||
#'
|
||||
#' # split into groups of ten years
|
||||
#' age_groups(ages, 1:10 * 10)
|
||||
#' age_groups(ages, split_at = "tens")
|
||||
#'
|
||||
#' # split into groups of five years
|
||||
#' age_groups(ages, 1:20 * 5)
|
||||
#' age_groups(ages, split_at = "fives")
|
||||
#'
|
||||
#' # split specifically for children
|
||||
#' age_groups(ages, "children")
|
||||
#' # same:
|
||||
#' age_groups(ages, c(1, 2, 4, 6, 13, 17))
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' # resistance of ciprofloxacine per age group
|
||||
#' library(dplyr)
|
||||
#' example_isolates %>%
|
||||
#' filter_first_isolate() %>%
|
||||
#' filter(mo == as.mo("E. coli")) %>%
|
||||
#' group_by(age_group = age_groups(age)) %>%
|
||||
#' select(age_group, CIP) %>%
|
||||
#' ggplot_rsi(x = "age_group")
|
||||
#' }
|
||||
age_groups <- function(x, split_at = c(12, 25, 55, 75), na.rm = FALSE) {
|
||||
stop_ifnot(is.numeric(x), "`x` must be numeric, not ", paste0(class(x), collapse = "/"))
|
||||
if (any(x < 0, na.rm = TRUE)) {
|
||||
x[x < 0] <- NA
|
||||
warning("NAs introduced for ages below 0.")
|
||||
}
|
||||
if (is.character(split_at)) {
|
||||
split_at <- split_at[1L]
|
||||
if (split_at %like% "^(child|kid|junior)") {
|
||||
split_at <- c(0, 1, 2, 4, 6, 13, 18)
|
||||
} else if (split_at %like% "^(elder|senior)") {
|
||||
split_at <- c(65, 75, 85)
|
||||
} else if (split_at %like% "^five") {
|
||||
split_at <- 1:20 * 5
|
||||
} else if (split_at %like% "^ten") {
|
||||
split_at <- 1:10 * 10
|
||||
}
|
||||
}
|
||||
split_at <- sort(unique(as.integer(split_at)))
|
||||
if (!split_at[1] == 0) {
|
||||
# add base number 0
|
||||
split_at <- c(0, split_at)
|
||||
}
|
||||
split_at <- split_at[!is.na(split_at)]
|
||||
stop_if(length(split_at) == 1, "invalid value for `split_at`") # only 0 is available
|
||||
|
||||
# turn input values to 'split_at' indices
|
||||
y <- x
|
||||
labs <- split_at
|
||||
for (i in seq_len(length(split_at))) {
|
||||
y[x >= split_at[i]] <- i
|
||||
# create labels
|
||||
labs[i - 1] <- paste0(unique(c(split_at[i - 1], split_at[i] - 1)), collapse = "-")
|
||||
}
|
||||
|
||||
# last category
|
||||
labs[length(labs)] <- paste0(split_at[length(split_at)], "+")
|
||||
|
||||
agegroups <- factor(labs[y], levels = labs, ordered = TRUE)
|
||||
|
||||
if (isTRUE(na.rm)) {
|
||||
agegroups <- agegroups[!is.na(agegroups)]
|
||||
}
|
||||
|
||||
agegroups
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' The `AMR` Package
|
||||
#'
|
||||
#' Welcome to the `AMR` package.
|
||||
#' @details
|
||||
#' `AMR` is a free, open-source and independent R package to simplify the analysis and prediction of Antimicrobial Resistance (AMR) and to work with microbial and antimicrobial data and properties, by using evidence-based methods. Our aim is to provide a standard for clean and reproducible antimicrobial resistance data analysis, that can therefore empower epidemiological analyses to continuously enable surveillance and treatment evaluation in any setting.
|
||||
#'
|
||||
#' After installing this package, R knows ~70,000 distinct microbial species and all ~550 antibiotic, antimycotic and antiviral drugs by name and code (including ATC, EARS-NET, LOINC and SNOMED CT), and knows all about valid R/SI and MIC values. It supports any data format, including WHONET/EARS-Net data.
|
||||
#'
|
||||
#' This package is fully independent of any other R package and works on Windows, macOS and Linux with all versions of R since R-3.0.0 (April 2013). It was designed to work in any setting, including those with very limited resources. It was created for both routine data analysis and academic research at the Faculty of Medical Sciences of the University of Groningen, in collaboration with non-profit organisations Certe Medical Diagnostics and Advice and University Medical Center Groningen. This R package is actively maintained and free software; you can freely use and distribute it for both personal and commercial (but not patent) purposes under the terms of the GNU General Public License version 2.0 (GPL-2), as published by the Free Software Foundation.
|
||||
#'
|
||||
#' This package can be used for:
|
||||
#' - Reference for the taxonomy of microorganisms, since the package contains all microbial (sub)species from the Catalogue of Life and List of Prokaryotic names with Standing in Nomenclature
|
||||
#' - Interpreting raw MIC and disk diffusion values, based on the latest CLSI or EUCAST guidelines
|
||||
#' - Retrieving antimicrobial drug names, doses and forms of administration from clinical health care records
|
||||
#' - Determining first isolates to be used for AMR analysis
|
||||
#' - Calculating antimicrobial resistance
|
||||
#' - Determining multi-drug resistance (MDR) / multi-drug resistant organisms (MDRO)
|
||||
#' - Calculating (empirical) susceptibility of both mono therapy and combination therapies
|
||||
#' - Predicting future antimicrobial resistance using regression models
|
||||
#' - Getting properties for any microorganism (like Gram stain, species, genus or family)
|
||||
#' - Getting properties for any antibiotic (like name, code of EARS-Net/ATC/LOINC/PubChem, defined daily dose or trade name)
|
||||
#' - Plotting antimicrobial resistance
|
||||
#' - Applying EUCAST expert rules
|
||||
#' - Getting SNOMED codes of a microorganism, or getting properties of a microorganism based on a SNOMED code
|
||||
#' - Getting LOINC codes of an antibiotic, or getting properties of an antibiotic based on a LOINC code
|
||||
#' - Machine reading the EUCAST and CLSI guidelines from 2011-2020 to translate MIC values and disk diffusion diameters to R/SI
|
||||
#' - Principal component analysis for AMR
|
||||
#'
|
||||
#' @section Read more on our website!:
|
||||
#' On our website <https://msberends.github.io/AMR> you can find [a comprehensive tutorial](https://msberends.github.io/AMR/articles/AMR.html) about how to conduct AMR analysis, the [complete documentation of all functions](https://msberends.github.io/AMR/reference) (which reads a lot easier than here in R) and [an example analysis using WHONET data](https://msberends.github.io/AMR/articles/WHONET.html). As we would like to better understand the backgrounds and needs of our users, please [participate in our survey](https://msberends.github.io/AMR/survey.html)!
|
||||
#' @section Contact Us:
|
||||
#' For suggestions, comments or questions, please contact us at:
|
||||
#'
|
||||
#' Matthijs S. Berends \cr
|
||||
#' m.s.berends \[at\] umcg \[dot\] nl \cr
|
||||
#' University of Groningen
|
||||
#' Department of Medical Microbiology
|
||||
#' University Medical Center Groningen \cr
|
||||
#' Post Office Box 30001 \cr
|
||||
#' 9700 RB Groningen \cr
|
||||
#' The Netherlands
|
||||
#'
|
||||
#' If you have found a bug, please file a new issue at: \cr
|
||||
#' <https://github.com/msberends/AMR/issues>
|
||||
#' @name AMR
|
||||
#' @rdname AMR
|
||||
NULL
|
||||
@@ -1,200 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Get ATC properties from WHOCC website
|
||||
#'
|
||||
#' @inheritSection lifecycle Questioning lifecycle
|
||||
#' @description Gets data from the WHO to determine properties of an ATC (e.g. an antibiotic) like name, defined daily dose (DDD) or standard unit.
|
||||
#'
|
||||
#' **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 `"ATC"`, `"Name"`, `"DDD"`, `"U"` (`"unit"`), `"Adm.R"`, `"Note"` and `groups`. For this last option, all hierarchical groups of an ATC code will be returned, see Examples.
|
||||
#' @param administration type of administration when using `property = "Adm.R"`, see Details
|
||||
#' @param url url of website of the WHO. The sign `%s` can be used as a placeholder for ATC codes.
|
||||
#' @param ... parameters to pass on to `atc_property`
|
||||
#' @details
|
||||
#' Options for parameter `administration`:
|
||||
#'
|
||||
#' - `"Implant"` = Implant
|
||||
#' - `"Inhal"` = Inhalation
|
||||
#' - `"Instill"` = Instillation
|
||||
#' - `"N"` = nasal
|
||||
#' - `"O"` = oral
|
||||
#' - `"P"` = parenteral
|
||||
#' - `"R"` = rectal
|
||||
#' - `"SL"` = sublingual/buccal
|
||||
#' - `"TD"` = transdermal
|
||||
#' - `"V"` = vaginal
|
||||
#'
|
||||
#' Abbreviations of return values when using `property = "U"` (unit):
|
||||
#'
|
||||
#' - `"g"` = gram
|
||||
#' - `"mg"` = milligram
|
||||
#' - `"mcg"`` = microgram
|
||||
#' - `"U"` = unit
|
||||
#' - `"TU"` = thousand units
|
||||
#' - `"MU"` = million units
|
||||
#' - `"mmol"` = millimole
|
||||
#' - `"ml"` = milliliter (e.g. eyedrops)
|
||||
#' @export
|
||||
#' @rdname atc_online
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @source <https://www.whocc.no/atc_ddd_alterations__cumulative/ddd_alterations/abbrevations/>
|
||||
#' @examples
|
||||
#' \dontrun{
|
||||
#' # oral DDD (Defined Daily Dose) of amoxicillin
|
||||
#' atc_online_property("J01CA04", "DDD", "O")
|
||||
#' # parenteral DDD (Defined Daily Dose) of amoxicillin
|
||||
#' atc_online_property("J01CA04", "DDD", "P")
|
||||
#'
|
||||
#' atc_online_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_online_property <- function(atc_code,
|
||||
property,
|
||||
administration = "O",
|
||||
url = "https://www.whocc.no/atc_ddd_index/?code=%s&showdescription=no") {
|
||||
|
||||
has_internet <- import_fn("has_internet", "curl")
|
||||
html_attr <- import_fn("html_attr", "rvest")
|
||||
html_children <- import_fn("html_children", "rvest")
|
||||
html_node <- import_fn("html_node", "rvest")
|
||||
html_nodes <- import_fn("html_nodes", "rvest")
|
||||
html_table <- import_fn("html_table", "rvest")
|
||||
html_text <- import_fn("html_text", "rvest")
|
||||
read_html <- import_fn("read_html", "xml2")
|
||||
|
||||
check_dataset_integrity()
|
||||
|
||||
if (!all(atc_code %in% antibiotics)) {
|
||||
atc_code <- as.character(ab_atc(atc_code))
|
||||
}
|
||||
|
||||
if (!has_internet()) {
|
||||
message("There appears to be no internet connection.")
|
||||
return(rep(NA, length(atc_code)))
|
||||
}
|
||||
|
||||
stop_if(length(property) != 1L, "`property` must be of length 1")
|
||||
stop_if(length(administration) != 1L, "`administration` must be of length 1")
|
||||
|
||||
# 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)
|
||||
|
||||
stop_ifnot(property %in% valid_properties,
|
||||
"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), 3)
|
||||
on.exit(close(progress))
|
||||
|
||||
for (i in seq_len(length(atc_code))) {
|
||||
|
||||
progress$tick()
|
||||
|
||||
atc_url <- sub("%s", atc_code[i], url, fixed = TRUE)
|
||||
|
||||
if (property == "groups") {
|
||||
tbl <- read_html(atc_url) %>%
|
||||
html_node("#content") %>%
|
||||
html_children() %>%
|
||||
html_node("a")
|
||||
|
||||
# get URLS of items
|
||||
hrefs <- tbl %>% html_attr("href")
|
||||
# get text of items
|
||||
texts <- tbl %>% 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[seq_len(length(texts)) - 1]
|
||||
returnvalue <- c(list(texts), returnvalue)
|
||||
|
||||
} else {
|
||||
tbl <- read_html(atc_url) %>%
|
||||
html_nodes("table") %>%
|
||||
html_table(header = TRUE) %>%
|
||||
as.data.frame(stringsAsFactors = FALSE)
|
||||
|
||||
# case insensitive column names
|
||||
colnames(tbl) <- gsub("^atc.*", "atc", tolower(colnames(tbl)))
|
||||
|
||||
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 seq_len(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_online
|
||||
#' @export
|
||||
atc_online_groups <- function(atc_code, ...) {
|
||||
atc_online_property(atc_code = atc_code, property = "groups", ...)
|
||||
}
|
||||
|
||||
#' @rdname atc_online
|
||||
#' @export
|
||||
atc_online_ddd <- function(atc_code, ...) {
|
||||
atc_online_property(atc_code = atc_code, property = "ddd", ...)
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Check availability of columns
|
||||
#'
|
||||
#' Easy check for data availability of all columns in a data set. This makes it easy to get an idea of which antimicrobial combinations can be used for calculation with e.g. [susceptibility()] and [resistance()].
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param tbl a [`data.frame`] or [`list`]
|
||||
#' @param width number of characters to present the visual availability, defaults to filling the width of the console
|
||||
#' @details The function returns a [`data.frame`] with columns `"resistant"` and `"visual_resistance"`. The values in that columns are calculated with [resistance()].
|
||||
#' @return [`data.frame`] with column names of `tbl` as row names
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
#' @examples
|
||||
#' availability(example_isolates)
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' example_isolates %>% availability()
|
||||
#'
|
||||
#' example_isolates %>%
|
||||
#' select_if(is.rsi) %>%
|
||||
#' availability()
|
||||
#'
|
||||
#' example_isolates %>%
|
||||
#' filter(mo == as.mo("E. coli")) %>%
|
||||
#' select_if(is.rsi) %>%
|
||||
#' availability()
|
||||
#' }
|
||||
availability <- function(tbl, width = NULL) {
|
||||
stop_ifnot(is.data.frame(tbl), "`tbl` must be a data.frame")
|
||||
x <- base::sapply(tbl, function(x) {
|
||||
1 - base::sum(base::is.na(x)) / base::length(x)
|
||||
})
|
||||
n <- base::sapply(tbl, function(x) base::length(x[!base::is.na(x)]))
|
||||
R <- base::sapply(tbl, function(x) base::ifelse(is.rsi(x), resistance(x, minimum = 0), NA))
|
||||
R_print <- character(length(R))
|
||||
R_print[!is.na(R)] <- percentage(R[!is.na(R)])
|
||||
R_print[is.na(R)] <- ""
|
||||
|
||||
if (is.null(width)) {
|
||||
width <- options()$width -
|
||||
(max(nchar(colnames(tbl))) +
|
||||
# count col
|
||||
8 +
|
||||
# available % column
|
||||
10 +
|
||||
# resistant % column
|
||||
10 +
|
||||
# extra margin
|
||||
5)
|
||||
width <- width / 2
|
||||
}
|
||||
|
||||
if (length(R[is.na(R)]) == ncol(tbl)) {
|
||||
width <- width * 2 + 10
|
||||
}
|
||||
|
||||
x_chars_R <- strrep("#", round(width * R, digits = 2))
|
||||
x_chars_SI <- strrep("-", width - nchar(x_chars_R))
|
||||
vis_resistance <- paste0("|", x_chars_R, x_chars_SI, "|")
|
||||
vis_resistance[is.na(R)] <- ""
|
||||
|
||||
x_chars <- strrep("#", round(x, digits = 2) / (1 / width))
|
||||
x_chars_empty <- strrep("-", width - nchar(x_chars))
|
||||
|
||||
df <- data.frame(count = n,
|
||||
available = percentage(x),
|
||||
visual_availabilty = paste0("|", x_chars, x_chars_empty, "|"),
|
||||
resistant = R_print,
|
||||
visual_resistance = vis_resistance)
|
||||
if (length(R[is.na(R)]) == ncol(tbl)) {
|
||||
df[, 1:3]
|
||||
} else {
|
||||
df
|
||||
}
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Determine bug-drug combinations
|
||||
#'
|
||||
#' Determine antimicrobial resistance (AMR) of all bug-drug combinations in your data set where at least 30 (default) isolates are available per species. Use [format()] on the result to prettify it to a publicable/printable format, see Examples.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @inheritParams eucast_rules
|
||||
#' @param combine_IR logical to indicate whether values R and I should be summed
|
||||
#' @param add_ab_group logical to indicate where the group of the antimicrobials must be included as a first column
|
||||
#' @param remove_intrinsic_resistant logical to indicate that rows with 100% resistance for all tested antimicrobials must be removed from the table
|
||||
#' @param FUN the function to call on the `mo` column to transform the microorganism IDs, defaults to [mo_shortname()]
|
||||
#' @param translate_ab a character of length 1 containing column names of the [antibiotics] data set
|
||||
#' @param ... arguments passed on to `FUN`
|
||||
#' @inheritParams rsi_df
|
||||
#' @inheritParams base::formatC
|
||||
#' @details The function [format()] calculates the resistance per bug-drug combination. Use `combine_IR = FALSE` (default) to test R vs. S+I and `combine_IR = TRUE` to test R+I vs. S.
|
||||
#'
|
||||
#' The language of the output can be overwritten with `options(AMR_locale)`, please see [translate].
|
||||
#' @export
|
||||
#' @rdname bug_drug_combinations
|
||||
#' @return The function [bug_drug_combinations()] returns a [`data.frame`] with columns "mo", "ab", "S", "I", "R" and "total".
|
||||
#' @source \strong{M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 4th Edition}, 2014, *Clinical and Laboratory Standards Institute (CLSI)*. <https://clsi.org/standards/products/microbiology/documents/m39/>.
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' \donttest{
|
||||
#' x <- bug_drug_combinations(example_isolates)
|
||||
#' x
|
||||
#' format(x, translate_ab = "name (atc)")
|
||||
#'
|
||||
#' # Use FUN to change to transformation of microorganism codes
|
||||
#' x <- bug_drug_combinations(example_isolates,
|
||||
#' FUN = mo_gramstain)
|
||||
#'
|
||||
#' x <- bug_drug_combinations(example_isolates,
|
||||
#' FUN = function(x) ifelse(x == "B_ESCHR_COLI",
|
||||
#' "E. coli",
|
||||
#' "Others"))
|
||||
#' }
|
||||
bug_drug_combinations <- function(x,
|
||||
col_mo = NULL,
|
||||
FUN = mo_shortname,
|
||||
...) {
|
||||
stop_ifnot(is.data.frame(x), "`x` must be a data frame")
|
||||
stop_ifnot(any(sapply(x, is.rsi), na.rm = TRUE), "No columns with class <rsi> found. See ?as.rsi.")
|
||||
|
||||
# try to find columns based on type
|
||||
# -- mo
|
||||
if (is.null(col_mo)) {
|
||||
col_mo <- search_type_in_df(x = x, type = "mo")
|
||||
}
|
||||
stop_if(is.null(col_mo), "`col_mo` must be set")
|
||||
|
||||
x_class <- class(x)
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
x[, col_mo] <- FUN(x[, col_mo, drop = TRUE])
|
||||
x <- x[, c(col_mo, names(which(sapply(x, is.rsi)))), drop = FALSE]
|
||||
|
||||
unique_mo <- sort(unique(x[, col_mo, drop = TRUE]))
|
||||
|
||||
out <- data.frame(
|
||||
mo = character(0),
|
||||
ab = character(0),
|
||||
S = integer(0),
|
||||
I = integer(0),
|
||||
R = integer(0),
|
||||
total = integer(0))
|
||||
|
||||
for (i in seq_len(length(unique_mo))) {
|
||||
# filter on MO group and only select R/SI columns
|
||||
x_mo_filter <- x[which(x[, col_mo, drop = TRUE] == unique_mo[i]), names(which(sapply(x, is.rsi))), drop = FALSE]
|
||||
# turn and merge everything
|
||||
pivot <- lapply(x_mo_filter, function(x) {
|
||||
m <- as.matrix(table(x))
|
||||
data.frame(S = m["S", ], I = m["I", ], R = m["R", ], stringsAsFactors = FALSE)
|
||||
})
|
||||
merged <- do.call(rbind, pivot)
|
||||
out_group <- data.frame(mo = unique_mo[i],
|
||||
ab = rownames(merged),
|
||||
S = merged$S,
|
||||
I = merged$I,
|
||||
R = merged$R,
|
||||
total = merged$S + merged$I + merged$R)
|
||||
out <- rbind(out, out_group)
|
||||
}
|
||||
|
||||
structure(.Data = out, class = c("bug_drug_combinations", x_class))
|
||||
}
|
||||
|
||||
#' @method format bug_drug_combinations
|
||||
#' @export
|
||||
#' @rdname bug_drug_combinations
|
||||
format.bug_drug_combinations <- function(x,
|
||||
translate_ab = "name (ab, atc)",
|
||||
language = get_locale(),
|
||||
minimum = 30,
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE,
|
||||
add_ab_group = TRUE,
|
||||
remove_intrinsic_resistant = FALSE,
|
||||
decimal.mark = getOption("OutDec"),
|
||||
big.mark = ifelse(decimal.mark == ",", ".", ","),
|
||||
...) {
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
x <- subset(x, total >= minimum)
|
||||
|
||||
if (remove_intrinsic_resistant == TRUE) {
|
||||
x <- subset(x, R != total)
|
||||
}
|
||||
if (combine_SI == TRUE | combine_IR == FALSE) {
|
||||
x$isolates <- x$R
|
||||
} else {
|
||||
x$isolates <- x$R + x$I
|
||||
}
|
||||
|
||||
give_ab_name <- function(ab, format, language) {
|
||||
format <- tolower(format)
|
||||
ab_txt <- rep(format, length(ab))
|
||||
for (i in seq_len(length(ab_txt))) {
|
||||
ab_txt[i] <- gsub("ab", as.character(as.ab(ab[i])), ab_txt[i])
|
||||
ab_txt[i] <- gsub("cid", ab_cid(ab[i]), ab_txt[i])
|
||||
ab_txt[i] <- gsub("group", ab_group(ab[i], language = language), ab_txt[i])
|
||||
ab_txt[i] <- gsub("atc_group1", ab_atc_group1(ab[i], language = language), ab_txt[i])
|
||||
ab_txt[i] <- gsub("atc_group2", ab_atc_group2(ab[i], language = language), ab_txt[i])
|
||||
ab_txt[i] <- gsub("atc", ab_atc(ab[i]), ab_txt[i])
|
||||
ab_txt[i] <- gsub("name", ab_name(ab[i], language = language), ab_txt[i])
|
||||
ab_txt[i]
|
||||
}
|
||||
ab_txt
|
||||
}
|
||||
|
||||
remove_NAs <- function(.data) {
|
||||
cols <- colnames(.data)
|
||||
.data <- as.data.frame(sapply(.data, function(x) ifelse(is.na(x), "", x), simplify = FALSE))
|
||||
colnames(.data) <- cols
|
||||
.data
|
||||
}
|
||||
|
||||
create_var <- function(.data, ...) {
|
||||
dots <- list(...)
|
||||
for (i in seq_len(length(dots))) {
|
||||
.data[, names(dots)[i]] <- dots[[i]]
|
||||
}
|
||||
.data
|
||||
}
|
||||
|
||||
y <- x %>%
|
||||
create_var(ab = as.ab(x$ab),
|
||||
ab_txt = give_ab_name(ab = x$ab, format = translate_ab, language = language)) %>%
|
||||
group_by(ab, ab_txt, mo) %>%
|
||||
summarise(isolates = sum(isolates, na.rm = TRUE),
|
||||
total = sum(total, na.rm = TRUE)) %>%
|
||||
ungroup()
|
||||
|
||||
y <- y %>%
|
||||
create_var(txt = paste0(percentage(y$isolates / y$total, decimal.mark = decimal.mark, big.mark = big.mark),
|
||||
" (", trimws(format(y$isolates, big.mark = big.mark)), "/",
|
||||
trimws(format(y$total, big.mark = big.mark)), ")")) %>%
|
||||
select(ab, ab_txt, mo, txt) %>%
|
||||
arrange(mo)
|
||||
|
||||
# replace tidyr::pivot_wider() from here
|
||||
for (i in unique(y$mo)) {
|
||||
mo_group <- y[which(y$mo == i), c("ab", "txt")]
|
||||
colnames(mo_group) <- c("ab", i)
|
||||
rownames(mo_group) <- NULL
|
||||
y <- y %>%
|
||||
left_join(mo_group, by = "ab")
|
||||
}
|
||||
y <- y %>%
|
||||
distinct(ab, .keep_all = TRUE) %>%
|
||||
select(-mo, -txt) %>%
|
||||
# replace tidyr::pivot_wider() until here
|
||||
remove_NAs()
|
||||
|
||||
select_ab_vars <- function(.data) {
|
||||
.data[, c("ab_group", "ab_txt", colnames(.data)[!colnames(.data) %in% c("ab_group", "ab_txt", "ab")])]
|
||||
}
|
||||
|
||||
y <- y %>%
|
||||
create_var(ab_group = ab_group(y$ab, language = language)) %>%
|
||||
select_ab_vars() %>%
|
||||
arrange(ab_group, ab_txt)
|
||||
y <- y %>%
|
||||
create_var(ab_group = ifelse(y$ab_group != lag(y$ab_group) | is.na(lag(y$ab_group)), y$ab_group, ""))
|
||||
|
||||
if (add_ab_group == FALSE) {
|
||||
y <- y %>%
|
||||
select(-ab_group) %>%
|
||||
rename("Drug" = ab_txt)
|
||||
colnames(y)[1] <- translate_AMR(colnames(y)[1], language = get_locale(), only_unknown = FALSE)
|
||||
} else {
|
||||
y <- y %>% rename("Group" = ab_group,
|
||||
"Drug" = ab_txt)
|
||||
colnames(y)[1:2] <- translate_AMR(colnames(y)[1:2], language = get_locale(), only_unknown = FALSE)
|
||||
}
|
||||
|
||||
rownames(y) <- NULL
|
||||
y
|
||||
}
|
||||
|
||||
#' @method print bug_drug_combinations
|
||||
#' @export
|
||||
print.bug_drug_combinations <- function(x, ...) {
|
||||
x_class <- class(x)
|
||||
print(structure(x, class = x_class[x_class != "bug_drug_combinations"]),
|
||||
...)
|
||||
message(font_blue("NOTE: Use 'format()' on this result to get a publishable/printable format."))
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' The Catalogue of Life
|
||||
#'
|
||||
#' This package contains the complete taxonomic tree of almost all microorganisms from the authoritative and comprehensive Catalogue of Life.
|
||||
#' @section Catalogue of Life:
|
||||
#' \if{html}{\figure{logo_col.png}{options: height=40px style=margin-bottom:5px} \cr}
|
||||
#' This package contains the complete taxonomic tree of almost all microorganisms (~70,000 species) from the authoritative and comprehensive Catalogue of Life (<http://www.catalogueoflife.org>). The Catalogue of Life is the most comprehensive and authoritative global index of species currently available.
|
||||
#'
|
||||
#' [Click here][catalogue_of_life] for more information about the included taxa. Check which version of the Catalogue of Life was included in this package with [catalogue_of_life_version()].
|
||||
#' @section Included taxa:
|
||||
#' Included are:
|
||||
#' - All ~61,000 (sub)species from the kingdoms of Archaea, Bacteria, Chromista and Protozoa
|
||||
#' - All ~8,500 (sub)species from these orders of the kingdom of Fungi: Eurotiales, Microascales, Mucorales, Onygenales, Pneumocystales, Saccharomycetales, Schizosaccharomycetales and Tremellales. The kingdom of Fungi is a very large taxon with almost 300,000 different (sub)species, of which most are not microbial (but rather macroscopic, like mushrooms). Because of this, not all fungi fit the scope of this package and including everything would tremendously slow down our algorithms too. By only including the aforementioned taxonomic orders, the most relevant fungi are covered (like all species of *Aspergillus*, *Candida*, *Cryptococcus*, *Histplasma*, *Pneumocystis*, *Saccharomyces* and *Trichophyton*).
|
||||
#' - All ~150 (sub)species from ~100 other relevant genera from the kingdom of Animalia (like *Strongyloides* and *Taenia*)
|
||||
#' - All ~23,000 previously accepted names of all included (sub)species (these were taxonomically renamed)
|
||||
#' - The complete taxonomic tree of all included (sub)species: from kingdom to subspecies
|
||||
#' - The responsible author(s) and year of scientific publication
|
||||
#'
|
||||
#' The Catalogue of Life (<http://www.catalogueoflife.org>) is the most comprehensive and authoritative global index of species currently available. It holds essential information on the names, relationships and distributions of over 1.9 million species. The Catalogue of Life is used to support the major biodiversity and conservation information services such as the Global Biodiversity Information Facility (GBIF), Encyclopedia of Life (EoL) and the International Union for Conservation of Nature Red List. It is recognised by the Convention on Biological Diversity as a significant component of the Global Taxonomy Initiative and a contribution to Target 1 of the Global Strategy for Plant Conservation.
|
||||
#'
|
||||
#' The syntax used to transform the original data to a cleansed R format, can be found here: <https://github.com/msberends/AMR/blob/master/data-raw/reproduction_of_microorganisms.R>.
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @name catalogue_of_life
|
||||
#' @rdname catalogue_of_life
|
||||
#' @seealso Data set [microorganisms] for the actual data. \cr
|
||||
#' Function [as.mo()] to use the data for intelligent determination of microorganisms.
|
||||
#' @examples
|
||||
#' # Get version info of included data set
|
||||
#' catalogue_of_life_version()
|
||||
#'
|
||||
#'
|
||||
#' # Get a note when a species was renamed
|
||||
#' mo_shortname("Chlamydophila psittaci")
|
||||
#' # Note: 'Chlamydophila psittaci' (Everett et al., 1999) was renamed back to
|
||||
#' # 'Chlamydia psittaci' (Page, 1968)
|
||||
#' # [1] "C. psittaci"
|
||||
#'
|
||||
#' # Get any property from the entire taxonomic tree for all included species
|
||||
#' mo_class("E. coli")
|
||||
#' # [1] "Gammaproteobacteria"
|
||||
#'
|
||||
#' mo_family("E. coli")
|
||||
#' # [1] "Enterobacteriaceae"
|
||||
#'
|
||||
#' mo_gramstain("E. coli") # based on kingdom and phylum, see ?mo_gramstain
|
||||
#' # [1] "Gram negative"
|
||||
#'
|
||||
#' mo_ref("E. coli")
|
||||
#' # [1] "Castellani et al., 1919"
|
||||
#'
|
||||
#' # Do not get mistaken - this package is about microorganisms
|
||||
#' mo_kingdom("C. elegans")
|
||||
#' # [1] "Fungi" # Fungi?!
|
||||
#' mo_name("C. elegans")
|
||||
#' # [1] "Cladosporium elegans" # Because a microorganism was found
|
||||
NULL
|
||||
|
||||
#' Version info of included Catalogue of Life
|
||||
#'
|
||||
#' This function returns information about the included data from the Catalogue of Life.
|
||||
#' @seealso [microorganisms]
|
||||
#' @details For DSMZ, see [microorganisms].
|
||||
#' @return a [`list`], which prints in pretty format
|
||||
#' @inheritSection catalogue_of_life Catalogue of Life
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
catalogue_of_life_version <- function() {
|
||||
|
||||
check_dataset_integrity()
|
||||
|
||||
# see the `catalogue_of_life` list in R/data.R
|
||||
lst <- list(catalogue_of_life =
|
||||
list(version = gsub("{year}", catalogue_of_life$year, catalogue_of_life$version, fixed = TRUE),
|
||||
url = gsub("{year}", catalogue_of_life$year, catalogue_of_life$url_CoL, fixed = TRUE),
|
||||
n = nrow(filter(microorganisms, source == "CoL"))),
|
||||
deutsche_sammlung_von_mikroorganismen_und_zellkulturen =
|
||||
list(version = "Prokaryotic Nomenclature Up-to-Date from DSMZ",
|
||||
url = catalogue_of_life$url_DSMZ,
|
||||
yearmonth = catalogue_of_life$yearmonth_DSMZ,
|
||||
n = nrow(filter(microorganisms, source == "DSMZ"))),
|
||||
total_included =
|
||||
list(
|
||||
n_total_species = nrow(microorganisms),
|
||||
n_total_synonyms = nrow(microorganisms.old)))
|
||||
|
||||
structure(.Data = lst,
|
||||
class = c("catalogue_of_life_version", "list"))
|
||||
}
|
||||
|
||||
#' @method print catalogue_of_life_version
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.catalogue_of_life_version <- function(x, ...) {
|
||||
lst <- x
|
||||
cat(paste0(font_bold("Included in this AMR package are:\n\n"),
|
||||
font_underline(lst$catalogue_of_life$version), "\n",
|
||||
" Available at: ", lst$catalogue_of_life$url, "\n",
|
||||
" Number of included species: ", format(lst$catalogue_of_life$n, big.mark = ","), "\n",
|
||||
font_underline(paste0(lst$deutsche_sammlung_von_mikroorganismen_und_zellkulturen$version, " (",
|
||||
lst$deutsche_sammlung_von_mikroorganismen_und_zellkulturen$yearmonth, ")")), "\n",
|
||||
" Available at: ", lst$deutsche_sammlung_von_mikroorganismen_und_zellkulturen$url, "\n",
|
||||
" Number of included species: ", format(lst$deutsche_sammlung_von_mikroorganismen_und_zellkulturen$n, big.mark = ","), "\n\n",
|
||||
"=> Total number of species included: ", format(lst$total_included$n_total_species, big.mark = ","), "\n",
|
||||
"=> Total number of synonyms included: ", format(lst$total_included$n_total_synonyms, big.mark = ","), "\n\n",
|
||||
"See for more info ?microorganisms and ?catalogue_of_life.\n"))
|
||||
}
|
||||
@@ -1,196 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Count available isolates
|
||||
#'
|
||||
#' @description These functions can be used to count resistant/susceptible microbial isolates. All functions support quasiquotation with pipes, can be used in `summarise()` from the `dplyr` package and also support grouped variables, please see *Examples*.
|
||||
#'
|
||||
#' [count_resistant()] should be used to count resistant isolates, [count_susceptible()] should be used to count susceptible isolates.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param ... one or more vectors (or columns) with antibiotic interpretations. They will be transformed internally with [as.rsi()] if needed.
|
||||
#' @inheritParams proportion
|
||||
#' @inheritSection as.rsi Interpretation of R and S/I
|
||||
#' @details These functions are meant to count isolates. Use the [resistance()]/[susceptibility()] functions to calculate microbial resistance/susceptibility.
|
||||
#'
|
||||
#' The function [count_resistant()] is equal to the function [count_R()]. The function [count_susceptible()] is equal to the function [count_SI()].
|
||||
#'
|
||||
#' The function [n_rsi()] is an alias of [count_all()]. They can be used to count all available isolates, i.e. where all input antibiotics have an available result (S, I or R). Their use is equal to `n_distinct()`. Their function is equal to `count_susceptible(...) + count_resistant(...)`.
|
||||
#'
|
||||
#' The function [count_df()] takes any variable from `data` that has an [`rsi`] class (created with [as.rsi()]) and counts the number of S's, I's and R's. It also supports grouped variables. The function [rsi_df()] works exactly like [count_df()], but adds the percentage of S, I and R.
|
||||
#' @inheritSection proportion Combination therapy
|
||||
#' @seealso [`proportion_*`][proportion] to calculate microbial resistance and susceptibility.
|
||||
#' @return An [`integer`]
|
||||
#' @rdname count
|
||||
#' @name count
|
||||
#' @export
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' # example_isolates is a data set available in the AMR package.
|
||||
#' ?example_isolates
|
||||
#'
|
||||
#' count_resistant(example_isolates$AMX) # counts "R"
|
||||
#' count_susceptible(example_isolates$AMX) # counts "S" and "I"
|
||||
#' count_all(example_isolates$AMX) # counts "S", "I" and "R"
|
||||
#'
|
||||
#' # be more specific
|
||||
#' count_S(example_isolates$AMX)
|
||||
#' count_SI(example_isolates$AMX)
|
||||
#' count_I(example_isolates$AMX)
|
||||
#' count_IR(example_isolates$AMX)
|
||||
#' count_R(example_isolates$AMX)
|
||||
#'
|
||||
#' # Count all available isolates
|
||||
#' count_all(example_isolates$AMX)
|
||||
#' n_rsi(example_isolates$AMX)
|
||||
#'
|
||||
#' # n_rsi() is an alias of count_all().
|
||||
#' # Since it counts all available isolates, you can
|
||||
#' # calculate back to count e.g. susceptible isolates.
|
||||
#' # These results are the same:
|
||||
#' count_susceptible(example_isolates$AMX)
|
||||
#' susceptibility(example_isolates$AMX) * n_rsi(example_isolates$AMX)
|
||||
#'
|
||||
#'
|
||||
#' if (require("dplyr")) {
|
||||
#' example_isolates %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' summarise(R = count_R(CIP),
|
||||
#' I = count_I(CIP),
|
||||
#' S = count_S(CIP),
|
||||
#' n1 = count_all(CIP), # the actual total; sum of all three
|
||||
#' n2 = n_rsi(CIP), # same - analogous to n_distinct
|
||||
#' total = n()) # NOT the number of tested isolates!
|
||||
#'
|
||||
#' # Count co-resistance between amoxicillin/clav acid and gentamicin,
|
||||
#' # so we can see that combination therapy does a lot more than mono therapy.
|
||||
#' # Please mind that `susceptibility()` calculates percentages right away instead.
|
||||
#' example_isolates %>% count_susceptible(AMC) # 1433
|
||||
#' example_isolates %>% count_all(AMC) # 1879
|
||||
#'
|
||||
#' example_isolates %>% count_susceptible(GEN) # 1399
|
||||
#' example_isolates %>% count_all(GEN) # 1855
|
||||
#'
|
||||
#' example_isolates %>% count_susceptible(AMC, GEN) # 1764
|
||||
#' example_isolates %>% count_all(AMC, GEN) # 1936
|
||||
#'
|
||||
#' # Get number of S+I vs. R immediately of selected columns
|
||||
#' example_isolates %>%
|
||||
#' select(AMX, CIP) %>%
|
||||
#' count_df(translate = FALSE)
|
||||
#'
|
||||
#' # It also supports grouping variables
|
||||
#' example_isolates %>%
|
||||
#' select(hospital_id, AMX, CIP) %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' count_df(translate = FALSE)
|
||||
#' }
|
||||
count_resistant <- function(..., only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = "R",
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_susceptible <- function(..., only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = c("S", "I"),
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_R <- function(..., only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = "R",
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_IR <- function(..., only_all_tested = FALSE) {
|
||||
warning("Using 'count_IR' is discouraged; use 'count_resistant()' instead to not consider \"I\" being resistant.", call. = FALSE)
|
||||
rsi_calc(...,
|
||||
ab_result = c("I", "R"),
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_I <- function(..., only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = "I",
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_SI <- function(..., only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = c("S", "I"),
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_S <- function(..., only_all_tested = FALSE) {
|
||||
warning("Using 'count_S' is discouraged; use 'count_susceptible()' instead to also consider \"I\" being susceptible.", call. = FALSE)
|
||||
rsi_calc(...,
|
||||
ab_result = "S",
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_all <- function(..., only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = c("S", "I", "R"),
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
n_rsi <- count_all
|
||||
|
||||
#' @rdname count
|
||||
#' @export
|
||||
count_df <- function(data,
|
||||
translate_ab = "name",
|
||||
language = get_locale(),
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE) {
|
||||
|
||||
rsi_calc_df(type = "count",
|
||||
data = data,
|
||||
translate_ab = translate_ab,
|
||||
language = language,
|
||||
combine_SI = combine_SI,
|
||||
combine_IR = combine_IR,
|
||||
combine_SI_missing = missing(combine_SI))
|
||||
}
|
||||
@@ -1,238 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Data sets with `r format(nrow(antibiotics) + nrow(antivirals), big.mark = ",")` antimicrobials
|
||||
#'
|
||||
#' Two data sets containing all antibiotics/antimycotics and antivirals. Use [as.ab()] or one of the [ab_property()] functions to retrieve values from the [antibiotics] data set. Three identifiers are included in this data set: an antibiotic ID (`ab`, primarily used in this package) as defined by WHONET/EARS-Net, an ATC code (`atc`) as defined by the WHO, and a Compound ID (`cid`) as found in PubChem. Other properties in this data set are derived from one or more of these codes.
|
||||
#' @format
|
||||
#' ### For the [antibiotics] data set: a [`data.frame`] with `r nrow(antibiotics)` observations and `r ncol(antibiotics)` variables:
|
||||
#' - `ab`\cr Antibiotic ID as used in this package (like `AMC`), using the official EARS-Net (European Antimicrobial Resistance Surveillance Network) codes where available
|
||||
#' - `atc`\cr ATC code (Anatomical Therapeutic Chemical) as defined by the WHOCC, like `J01CR02`
|
||||
#' - `cid`\cr Compound ID as found in PubChem
|
||||
#' - `name`\cr Official name as used by WHONET/EARS-Net or the WHO
|
||||
#' - `group`\cr A short and concise group name, based on WHONET and WHOCC definitions
|
||||
#' - `atc_group1`\cr Official pharmacological subgroup (3rd level ATC code) as defined by the WHOCC, like `"Macrolides, lincosamides and streptogramins"`
|
||||
#' - `atc_group2`\cr Official chemical subgroup (4th level ATC code) as defined by the WHOCC, like `"Macrolides"`
|
||||
#' - `abbr`\cr List of abbreviations as used in many countries, also for antibiotic susceptibility testing (AST)
|
||||
#' - `synonyms`\cr Synonyms (often trade names) of a drug, as found in PubChem based on their compound ID
|
||||
#' - `oral_ddd`\cr Defined Daily Dose (DDD), oral treatment
|
||||
#' - `oral_units`\cr Units of `oral_ddd`
|
||||
#' - `iv_ddd`\cr Defined Daily Dose (DDD), parenteral treatment
|
||||
#' - `iv_units`\cr Units of `iv_ddd`
|
||||
#' - `loinc`\cr All LOINC codes (Logical Observation Identifiers Names and Codes) associated with the name of the antimicrobial agent. Use [ab_loinc()] to retrieve them quickly, see [ab_property()].
|
||||
#'
|
||||
#' ### For the [antivirals] data set: a [`data.frame`] with `r nrow(antivirals)` observations and `r ncol(antivirals)` variables:
|
||||
#' - `atc`\cr ATC code (Anatomical Therapeutic Chemical) as defined by the WHOCC
|
||||
#' - `cid`\cr Compound ID as found in PubChem
|
||||
#' - `name`\cr Official name as used by WHONET/EARS-Net or the WHO
|
||||
#' - `atc_group`\cr Official pharmacological subgroup (3rd level ATC code) as defined by the WHOCC
|
||||
#' - `synonyms`\cr Synonyms (often trade names) of a drug, as found in PubChem based on their compound ID
|
||||
#' - `oral_ddd`\cr Defined Daily Dose (DDD), oral treatment
|
||||
#' - `oral_units`\cr Units of `oral_ddd`
|
||||
#' - `iv_ddd`\cr Defined Daily Dose (DDD), parenteral treatment
|
||||
#' - `iv_units`\cr Units of `iv_ddd`
|
||||
#' @details Properties that are based on an ATC code are only available when an ATC is available. These properties are: `atc_group1`, `atc_group2`, `oral_ddd`, `oral_units`, `iv_ddd` and `iv_units`.
|
||||
#'
|
||||
#' Synonyms (i.e. trade names) are derived from the Compound ID (`cid`) and consequently only available where a CID is available.
|
||||
#'
|
||||
#' ### Direct download
|
||||
#' These data sets are available as 'flat files' for use even without R - you can find the files here:
|
||||
#'
|
||||
#' * <https://github.com/msberends/AMR/raw/master/data-raw/antibiotics.txt>
|
||||
#' * <https://github.com/msberends/AMR/raw/master/data-raw/antivirals.txt>
|
||||
#'
|
||||
#' Files in R format (with preserved data structure) can be found here:
|
||||
#'
|
||||
#' * <https://github.com/msberends/AMR/raw/master/data/antibiotics.rda>
|
||||
#' * <https://github.com/msberends/AMR/raw/master/data/antivirals.rda>
|
||||
#' @source World Health Organization (WHO) Collaborating Centre for Drug Statistics Methodology (WHOCC): <https://www.whocc.no/atc_ddd_index/>
|
||||
#'
|
||||
#' WHONET 2019 software: <http://www.whonet.org/software.html>
|
||||
#'
|
||||
#' European Commission Public Health PHARMACEUTICALS - COMMUNITY REGISTER: <http://ec.europa.eu/health/documents/community-register/html/atc.htm>
|
||||
#' @inheritSection WHOCC WHOCC
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @seealso [microorganisms]
|
||||
"antibiotics"
|
||||
|
||||
#' @rdname antibiotics
|
||||
"antivirals"
|
||||
|
||||
#' Data set with `r format(nrow(microorganisms), big.mark = ",")` microorganisms
|
||||
#'
|
||||
#' A data set containing the microbial taxonomy of six kingdoms from the Catalogue of Life. MO codes can be looked up using [as.mo()].
|
||||
#' @inheritSection catalogue_of_life Catalogue of Life
|
||||
#' @format A [`data.frame`] with `r format(nrow(microorganisms), big.mark = ",")` observations and `r ncol(microorganisms)` variables:
|
||||
#' - `mo`\cr ID of microorganism as used by this package
|
||||
#' - `fullname`\cr Full name, like `"Escherichia coli"`
|
||||
#' - `kingdom`, `phylum`, `class`, `order`, `family`, `genus`, `species`, `subspecies`\cr Taxonomic rank of the microorganism
|
||||
#' - `rank`\cr Text of the taxonomic rank of the microorganism, like `"species"` or `"genus"`
|
||||
#' - `ref`\cr Author(s) and year of concerning scientific publication
|
||||
#' - `species_id`\cr ID of the species as used by the Catalogue of Life
|
||||
#' - `source`\cr Either "CoL", "DSMZ" (see Source) or "manually added"
|
||||
#' - `prevalence`\cr Prevalence of the microorganism, see [as.mo()]
|
||||
#' - `snomed`\cr SNOMED code of the microorganism. Use [mo_snomed()] to retrieve it quickly, see [mo_property()].
|
||||
#' @details Manually added were:
|
||||
#' - 11 entries of *Streptococcus* (beta-haemolytic: groups A, B, C, D, F, G, H, K and unspecified; other: viridans, milleri)
|
||||
#' - 2 entries of *Staphylococcus* (coagulase-negative (CoNS) and coagulase-positive (CoPS))
|
||||
#' - 3 entries of *Trichomonas* (*Trichomonas vaginalis*, and its family and genus)
|
||||
#' - 1 entry of *Candida* (*Candida krusei*), that is not (yet) in the Catalogue of Life
|
||||
#' - 1 entry of *Blastocystis* (*Blastocystis hominis*), although it officially does not exist (Noel *et al.* 2005, PMID 15634993)
|
||||
#' - 5 other 'undefined' entries (unknown, unknown Gram negatives, unknown Gram positives, unknown yeast and unknown fungus)
|
||||
#' - 6 families under the Enterobacterales order, according to Adeolu *et al.* (2016, PMID 27620848), that are not (yet) in the Catalogue of Life
|
||||
#' - `r format(nrow(filter(microorganisms, source == "DSMZ")), big.mark = ",")` species from the DSMZ (Deutsche Sammlung von Mikroorganismen und Zellkulturen) since the DSMZ contain the latest taxonomic information based on recent publications
|
||||
#'
|
||||
#' ### Direct download
|
||||
#' This data set is available as 'flat file' for use even without R - you can find the file here:
|
||||
#'
|
||||
#' * <https://github.com/msberends/AMR/raw/master/data-raw/microorganisms.txt>
|
||||
#'
|
||||
#' The file in R format (with preserved data structure) can be found here:
|
||||
#'
|
||||
#' * <https://github.com/msberends/AMR/raw/master/data/microorganisms.rda>
|
||||
#' @section About the records from DSMZ (see source):
|
||||
#' Names of prokaryotes are defined as being validly published by the International Code of Nomenclature of Bacteria. Validly published are all names which are included in the Approved Lists of Bacterial Names and the names subsequently published in the International Journal of Systematic Bacteriology (IJSB) and, from January 2000, in the International Journal of Systematic and Evolutionary Microbiology (IJSEM) as original articles or in the validation lists.
|
||||
#' *(from <https://www.dsmz.de/services/online-tools/prokaryotic-nomenclature-up-to-date/complete-list-readme>)*
|
||||
#'
|
||||
#' In February 2020, the DSMZ records were merged with the List of Prokaryotic names with Standing in Nomenclature (LPSN).
|
||||
#' @source Catalogue of Life: Annual Checklist (public online taxonomic database), <http://www.catalogueoflife.org> (check included annual version with [catalogue_of_life_version()]).
|
||||
#'
|
||||
#' Parte, A.C. (2018). LPSN — List of Prokaryotic names with Standing in Nomenclature (bacterio.net), 20 years on. International Journal of Systematic and Evolutionary Microbiology, 68, 1825-1829; doi: 10.1099/ijsem.0.002786
|
||||
#'
|
||||
#' Leibniz Institute DSMZ-German Collection of Microorganisms and Cell Cultures, Germany, Prokaryotic Nomenclature Up-to-Date, <https://www.dsmz.de/services/online-tools/prokaryotic-nomenclature-up-to-date> and <https://lpsn.dsmz.de> (check included version with [catalogue_of_life_version()]).
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @seealso [as.mo()], [mo_property()], [microorganisms.codes]
|
||||
"microorganisms"
|
||||
|
||||
catalogue_of_life <- list(
|
||||
year = 2019,
|
||||
version = "Catalogue of Life: {year} Annual Checklist",
|
||||
url_CoL = "http://www.catalogueoflife.org/col/",
|
||||
url_DSMZ = "https://lpsn.dsmz.de",
|
||||
yearmonth_DSMZ = "May 2020"
|
||||
)
|
||||
|
||||
#' Data set with previously accepted taxonomic names
|
||||
#'
|
||||
#' A data set containing old (previously valid or accepted) taxonomic names according to the Catalogue of Life. This data set is used internally by [as.mo()].
|
||||
#' @inheritSection catalogue_of_life Catalogue of Life
|
||||
#' @format A [`data.frame`] with `r format(nrow(microorganisms.old), big.mark = ",")` observations and `r ncol(microorganisms.old)` variables:
|
||||
#' - `fullname`\cr Old full taxonomic name of the microorganism
|
||||
#' - `fullname_new`\cr New full taxonomic name of the microorganism
|
||||
#' - `ref`\cr Author(s) and year of concerning scientific publication
|
||||
#' - `prevalence`\cr Prevalence of the microorganism, see [as.mo()]
|
||||
#' @source Catalogue of Life: Annual Checklist (public online taxonomic database), <http://www.catalogueoflife.org> (check included annual version with [catalogue_of_life_version()]).
|
||||
#'
|
||||
#' Parte, A.C. (2018). LPSN — List of Prokaryotic names with Standing in Nomenclature (bacterio.net), 20 years on. International Journal of Systematic and Evolutionary Microbiology, 68, 1825-1829; doi: 10.1099/ijsem.0.002786
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @seealso [as.mo()] [mo_property()] [microorganisms]
|
||||
"microorganisms.old"
|
||||
|
||||
#' Translation table with `r format(nrow(microorganisms.codes), big.mark = ",")` common microorganism codes
|
||||
#'
|
||||
#' A data set containing commonly used codes for microorganisms, from laboratory systems and WHONET. Define your own with [set_mo_source()]. They will all be searched when using [as.mo()] and consequently all the [`mo_*`][mo_property()] functions.
|
||||
#' @format A [`data.frame`] with `r format(nrow(microorganisms.codes), big.mark = ",")` observations and `r ncol(microorganisms.codes)` variables:
|
||||
#' - `code`\cr Commonly used code of a microorganism
|
||||
#' - `mo`\cr ID of the microorganism in the [microorganisms] data set
|
||||
#' @inheritSection catalogue_of_life Catalogue of Life
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @seealso [as.mo()] [microorganisms]
|
||||
"microorganisms.codes"
|
||||
|
||||
#' Data set with `r format(nrow(example_isolates), big.mark = ",")` example isolates
|
||||
#'
|
||||
#' A data set containing `r format(nrow(example_isolates), big.mark = ",")` microbial isolates with their full antibiograms. The data set reflects reality and can be used to practice AMR analysis. For examples, please read [the tutorial on our website](https://msberends.github.io/AMR/articles/AMR.html).
|
||||
#' @format A [`data.frame`] with `r format(nrow(example_isolates), big.mark = ",")` observations and `r ncol(example_isolates)` variables:
|
||||
#' - `date`\cr date of receipt at the laboratory
|
||||
#' - `hospital_id`\cr ID of the hospital, from A to D
|
||||
#' - `ward_icu`\cr logical to determine if ward is an intensive care unit
|
||||
#' - `ward_clinical`\cr logical to determine if ward is a regular clinical ward
|
||||
#' - `ward_outpatient`\cr logical to determine if ward is an outpatient clinic
|
||||
#' - `age`\cr age of the patient
|
||||
#' - `gender`\cr gender of the patient
|
||||
#' - `patient_id`\cr ID of the patient
|
||||
#' - `mo`\cr ID of microorganism created with [as.mo()], see also [microorganisms]
|
||||
#' - `PEN:RIF`\cr `r sum(sapply(example_isolates, is.rsi))` different antibiotics with class [`rsi`] (see [as.rsi()]); these column names occur in the [antibiotics] data set and can be translated with [ab_name()]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
"example_isolates"
|
||||
|
||||
#' Data set with unclean data
|
||||
#'
|
||||
#' A data set containing `r format(nrow(example_isolates_unclean), big.mark = ",")` microbial isolates that are not cleaned up and consequently not ready for AMR analysis. This data set can be used for practice.
|
||||
#' @format A [`data.frame`] with `r format(nrow(example_isolates_unclean), big.mark = ",")` observations and `r ncol(example_isolates_unclean)` variables:
|
||||
#' - `patient_id`\cr ID of the patient
|
||||
#' - `date`\cr date of receipt at the laboratory
|
||||
#' - `hospital`\cr ID of the hospital, from A to C
|
||||
#' - `bacteria`\cr info about microorganism that can be transformed with [as.mo()], see also [microorganisms]
|
||||
#' - `AMX:GEN`\cr 4 different antibiotics that have to be transformed with [as.rsi()]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
"example_isolates_unclean"
|
||||
|
||||
#' Data set with `r format(nrow(WHONET), big.mark = ",")` isolates - WHONET example
|
||||
#'
|
||||
#' This example data set has the exact same structure as an export file from WHONET. Such files can be used with this package, as this example data set shows. The data itself was based on our [example_isolates] data set.
|
||||
#' @format A [`data.frame`] with `r format(nrow(WHONET), big.mark = ",")` observations and `r ncol(WHONET)` variables:
|
||||
#' - `Identification number`\cr ID of the sample
|
||||
#' - `Specimen number`\cr ID of the specimen
|
||||
#' - `Organism`\cr Name of the microorganism. Before analysis, you should transform this to a valid microbial class, using [as.mo()].
|
||||
#' - `Country`\cr Country of origin
|
||||
#' - `Laboratory`\cr Name of laboratory
|
||||
#' - `Last name`\cr Last name of patient
|
||||
#' - `First name`\cr Initial of patient
|
||||
#' - `Sex`\cr Gender of patient
|
||||
#' - `Age`\cr Age of patient
|
||||
#' - `Age category`\cr Age group, can also be looked up using [age_groups()]
|
||||
#' - `Date of admission`\cr Date of hospital admission
|
||||
#' - `Specimen date`\cr Date when specimen was received at laboratory
|
||||
#' - `Specimen type`\cr Specimen type or group
|
||||
#' - `Specimen type (Numeric)`\cr Translation of `"Specimen type"`
|
||||
#' - `Reason`\cr Reason of request with Differential Diagnosis
|
||||
#' - `Isolate number`\cr ID of isolate
|
||||
#' - `Organism type`\cr Type of microorganism, can also be looked up using [mo_type()]
|
||||
#' - `Serotype`\cr Serotype of microorganism
|
||||
#' - `Beta-lactamase`\cr Microorganism produces beta-lactamase?
|
||||
#' - `ESBL`\cr Microorganism produces extended spectrum beta-lactamase?
|
||||
#' - `Carbapenemase`\cr Microorganism produces carbapenemase?
|
||||
#' - `MRSA screening test`\cr Microorganism is possible MRSA?
|
||||
#' - `Inducible clindamycin resistance`\cr Clindamycin can be induced?
|
||||
#' - `Comment`\cr Other comments
|
||||
#' - `Date of data entry`\cr Date this data was entered in WHONET
|
||||
#' - `AMP_ND10:CIP_EE`\cr `r sum(sapply(WHONET, is.rsi))` different antibiotics. You can lookup the abbreviations in the [antibiotics] data set, or use e.g. [`ab_name("AMP")`][ab_name()] to get the official name immediately. Before analysis, you should transform this to a valid antibiotic class, using [as.rsi()].
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
"WHONET"
|
||||
|
||||
#' Data set for R/SI interpretation
|
||||
#'
|
||||
#' Data set to interpret MIC and disk diffusion to R/SI values. Included guidelines are CLSI (2011-2019) and EUCAST (2011-2020). Use [as.rsi()] to transform MICs or disks measurements to R/SI values.
|
||||
#' @format A [`data.frame`] with `r format(nrow(rsi_translation), big.mark = ",")` observations and `r ncol(rsi_translation)` variables:
|
||||
#' - `guideline`\cr Name of the guideline
|
||||
#' - `method`\cr Either "MIC" or "DISK"
|
||||
#' - `site`\cr Body site, e.g. "Oral" or "Respiratory"
|
||||
#' - `mo`\cr Microbial ID, see [as.mo()]
|
||||
#' - `ab`\cr Antibiotic ID, see [as.ab()]
|
||||
#' - `ref_tbl`\cr Info about where the guideline rule can be found
|
||||
#' - `disk_dose`\cr Dose of the used disk diffusion method
|
||||
#' - `breakpoint_S`\cr Lowest MIC value or highest number of millimetres that leads to "S"
|
||||
#' - `breakpoint_R`\cr Highest MIC value or lowest number of millimetres that leads to "R"
|
||||
#' - `uti`\cr A logical value (`TRUE`/`FALSE`) to indicate whether the rule applies to a urinary tract infection (UTI)
|
||||
#' @details The repository of this `AMR` package contains a file comprising this exact data set: <https://github.com/msberends/AMR/blob/master/data-raw/rsi_translation.txt>. This file **allows for machine reading EUCAST and CLSI guidelines**, which is almost impossible with the Excel and PDF files distributed by EUCAST and CLSI. The file is updated automatically.
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
"rsi_translation"
|
||||
@@ -1,69 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Deprecated functions
|
||||
#'
|
||||
#' These functions are so-called '[Deprecated]'. They will be removed in a future release. Using the functions will give a warning with the name of the function it has been replaced by (if there is one).
|
||||
#' @inheritSection lifecycle Retired lifecycle
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
#' @keywords internal
|
||||
#' @name AMR-deprecated
|
||||
#' @export
|
||||
portion_R <- function(...) {
|
||||
.Deprecated("resistance()", package = "AMR")
|
||||
proportion_R(...)
|
||||
}
|
||||
|
||||
#' @rdname AMR-deprecated
|
||||
#' @export
|
||||
portion_IR <- function(...) {
|
||||
.Deprecated("proportion_IR()", package = "AMR")
|
||||
proportion_IR(...)
|
||||
}
|
||||
|
||||
#' @rdname AMR-deprecated
|
||||
#' @export
|
||||
portion_I <- function(...) {
|
||||
.Deprecated("proportion_I()", package = "AMR")
|
||||
proportion_I(...)
|
||||
}
|
||||
|
||||
#' @rdname AMR-deprecated
|
||||
#' @export
|
||||
portion_SI <- function(...) {
|
||||
.Deprecated("susceptibility()", package = "AMR")
|
||||
proportion_SI(...)
|
||||
}
|
||||
|
||||
#' @rdname AMR-deprecated
|
||||
#' @export
|
||||
portion_S <- function(...) {
|
||||
.Deprecated("proportion_S()", package = "AMR")
|
||||
proportion_S(...)
|
||||
}
|
||||
|
||||
#' @rdname AMR-deprecated
|
||||
#' @export
|
||||
portion_df <- function(...) {
|
||||
.Deprecated("proportion_df()", package = "AMR")
|
||||
proportion_df(...)
|
||||
}
|
||||
@@ -1,148 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Class 'disk'
|
||||
#'
|
||||
#' This transforms a vector to a new class [`disk`], which is a growth zone size (around an antibiotic disk) in millimetres between 6 and 50.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @rdname as.disk
|
||||
#' @param x vector
|
||||
#' @param na.rm a logical indicating whether missing values should be removed
|
||||
#' @details Interpret disk values as RSI values with [as.rsi()]. It supports guidelines from EUCAST and CLSI.
|
||||
#' @return An [`integer`] with additional new class [`disk`]
|
||||
#' @aliases disk
|
||||
#' @export
|
||||
#' @seealso [as.rsi()]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' \dontrun{
|
||||
#' # transform existing disk zones to the `disk` class
|
||||
#' library(dplyr)
|
||||
#' df <- data.frame(microorganism = "E. coli",
|
||||
#' AMP = 20,
|
||||
#' CIP = 14,
|
||||
#' GEN = 18,
|
||||
#' TOB = 16)
|
||||
#' df <- df %>% mutate_at(vars(AMP:TOB), as.disk)
|
||||
#' df
|
||||
#'
|
||||
#' # interpret disk values, see ?as.rsi
|
||||
#' as.rsi(x = as.disk(18),
|
||||
#' mo = "Strep pneu", # `mo` will be coerced with as.mo()
|
||||
#' ab = "ampicillin", # and `ab` with as.ab()
|
||||
#' guideline = "EUCAST")
|
||||
#'
|
||||
#' as.rsi(df)
|
||||
#' }
|
||||
as.disk <- function(x, na.rm = FALSE) {
|
||||
if (!is.disk(x)) {
|
||||
x <- x %>% unlist()
|
||||
if (na.rm == TRUE) {
|
||||
x <- x[!is.na(x)]
|
||||
}
|
||||
x.bak <- x
|
||||
|
||||
na_before <- length(x[is.na(x)])
|
||||
|
||||
# force it to be integer
|
||||
x <- suppressWarnings(as.integer(x))
|
||||
|
||||
# disks can never be less than 6 mm (size of smallest disk) or more than 50 mm
|
||||
x[x < 6 | x > 50] <- NA_integer_
|
||||
na_after <- length(x[is.na(x)])
|
||||
|
||||
if (na_before != na_after) {
|
||||
list_missing <- x.bak[is.na(x) & !is.na(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 disk zones: ",
|
||||
list_missing, call. = FALSE)
|
||||
}
|
||||
}
|
||||
structure(as.integer(x),
|
||||
class = c("disk", "integer"))
|
||||
}
|
||||
|
||||
all_valid_disks <- function(x) {
|
||||
x_disk <- suppressWarnings(as.disk(x[!is.na(x)]))
|
||||
!any(is.na(x_disk)) & !all(is.na(x))
|
||||
}
|
||||
|
||||
#' @rdname as.disk
|
||||
#' @export
|
||||
is.disk <- function(x) {
|
||||
inherits(x, "disk")
|
||||
}
|
||||
|
||||
#' @method print disk
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.disk <- function(x, ...) {
|
||||
cat("Class <disk>\n")
|
||||
print(as.integer(x), quote = FALSE)
|
||||
}
|
||||
|
||||
#' @method [ disk
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[.disk" <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
#' @method [[ disk
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[.disk" <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
#' @method [<- disk
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[<-.disk" <- function(i, j, ..., value) {
|
||||
value <- as.disk(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
y
|
||||
}
|
||||
#' @method [[<- disk
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[<-.disk" <- function(i, j, ..., value) {
|
||||
value <- as.disk(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
y
|
||||
}
|
||||
#' @method c disk
|
||||
#' @export
|
||||
#' @noRd
|
||||
c.disk <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
y <- as.disk(y)
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
@@ -1,922 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
# global variables
|
||||
EUCAST_VERSION_BREAKPOINTS <- "10.0, 2020"
|
||||
EUCAST_VERSION_EXPERT_RULES <- "3.1, 2016"
|
||||
|
||||
#' Apply EUCAST rules
|
||||
#'
|
||||
#' @description
|
||||
#' Apply susceptibility rules as defined by the European Committee on Antimicrobial Susceptibility Testing (EUCAST, <http://eucast.org>), see *Source*. This includes (1) expert rules and intrinsic resistance and (2) inferred resistance as defined in their breakpoint tables.
|
||||
#'
|
||||
#' To improve the interpretation of the antibiogram before EUCAST rules are applied, some non-EUCAST rules are applied at default, see Details.
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param x data with antibiotic columns, like e.g. `AMX` and `AMC`
|
||||
#' @param info print progress
|
||||
#' @param rules a character vector that specifies which rules should be applied. Must be one or more of `"breakpoints"`, `"expert"`, `"other"`, `"all"`, and defaults to `c("breakpoints", "expert")`. The default value can be set to another value using e.g. `options(AMR.eucast_rules = "all")`.
|
||||
#' @param verbose a logical to turn Verbose mode on and off (default is off). In Verbose mode, the function does not apply rules to the data, but instead returns a data set in logbook form with extensive info about which rows and columns would be effected and in which way.
|
||||
#' @param ... column name of an antibiotic, please see section *Antibiotics* below
|
||||
#' @inheritParams first_isolate
|
||||
#' @details
|
||||
#' **Note:** This function does not translate MIC values to RSI values. Use [as.rsi()] for that. \cr
|
||||
#' **Note:** When ampicillin (AMP, J01CA01) is not available but amoxicillin (AMX, J01CA04) is, the latter will be used for all rules where there is a dependency on ampicillin. These drugs are interchangeable when it comes to expression of antimicrobial resistance.
|
||||
#'
|
||||
#' Before further processing, some non-EUCAST rules can be applied to improve the efficacy of the EUCAST rules. These non-EUCAST rules, that are then applied to all isolates, are:
|
||||
#' - Inherit amoxicillin (AMX) from ampicillin (AMP), where amoxicillin (AMX) is unavailable;
|
||||
#' - Inherit ampicillin (AMP) from amoxicillin (AMX), where ampicillin (AMP) is unavailable;
|
||||
#' - Set amoxicillin (AMX) = R where amoxicillin/clavulanic acid (AMC) = R;
|
||||
#' - Set piperacillin (PIP) = R where piperacillin/tazobactam (TZP) = R;
|
||||
#' - Set trimethoprim (TMP) = R where trimethoprim/sulfamethoxazole (SXT) = R;
|
||||
#' - Set amoxicillin/clavulanic acid (AMC) = S where amoxicillin (AMX) = S;
|
||||
#' - Set piperacillin/tazobactam (TZP) = S where piperacillin (PIP) = S;
|
||||
#' - Set trimethoprim/sulfamethoxazole (SXT) = S where trimethoprim (TMP) = S.
|
||||
#'
|
||||
#' These rules are not applied at default, since they are not approved by EUCAST. To use these rules, please use `eucast_rules(..., rules = "all")`, or set the default behaviour of the `[eucast_rules()]` function with `options(AMR.eucast_rules = "all")` (or any other valid input value(s) to the `rules` parameter).
|
||||
#'
|
||||
#' The file containing all EUCAST rules is located here: <https://github.com/msberends/AMR/blob/master/data-raw/eucast_rules.tsv>.
|
||||
#'
|
||||
#' @section Antibiotics:
|
||||
#' To define antibiotics column names, leave as it is to determine it automatically with [guess_ab_col()] or input a text (case-insensitive), or use `NULL` to skip a column (e.g. `TIC = NULL` to skip ticarcillin). Manually defined but non-existing columns will be skipped with a warning.
|
||||
#'
|
||||
#' The following antibiotics are used for the functions [eucast_rules()] and [mdro()]. These are shown below in the format '**antimicrobial ID**: name ([ATC code](https://www.whocc.no/atc/structure_and_principles/))', sorted by name:
|
||||
#'
|
||||
#' **AMK**: amikacin ([J01GB06](https://www.whocc.no/atc_ddd_index/?code=J01GB06)),
|
||||
#' **AMX**: amoxicillin ([J01CA04](https://www.whocc.no/atc_ddd_index/?code=J01CA04)),
|
||||
#' **AMC**: amoxicillin/clavulanic acid ([J01CR02](https://www.whocc.no/atc_ddd_index/?code=J01CR02)),
|
||||
#' **AMP**: ampicillin ([J01CA01](https://www.whocc.no/atc_ddd_index/?code=J01CA01)),
|
||||
#' **SAM**: ampicillin/sulbactam ([J01CR01](https://www.whocc.no/atc_ddd_index/?code=J01CR01)),
|
||||
#' **AZM**: azithromycin ([J01FA10](https://www.whocc.no/atc_ddd_index/?code=J01FA10)),
|
||||
#' **AZL**: azlocillin ([J01CA09](https://www.whocc.no/atc_ddd_index/?code=J01CA09)),
|
||||
#' **ATM**: aztreonam ([J01DF01](https://www.whocc.no/atc_ddd_index/?code=J01DF01)),
|
||||
#' **CAP**: capreomycin ([J04AB30](https://www.whocc.no/atc_ddd_index/?code=J04AB30)),
|
||||
#' **RID**: cefaloridine ([J01DB02](https://www.whocc.no/atc_ddd_index/?code=J01DB02)),
|
||||
#' **CZO**: cefazolin ([J01DB04](https://www.whocc.no/atc_ddd_index/?code=J01DB04)),
|
||||
#' **FEP**: cefepime ([J01DE01](https://www.whocc.no/atc_ddd_index/?code=J01DE01)),
|
||||
#' **CTX**: cefotaxime ([J01DD01](https://www.whocc.no/atc_ddd_index/?code=J01DD01)),
|
||||
#' **CTT**: cefotetan ([J01DC05](https://www.whocc.no/atc_ddd_index/?code=J01DC05)),
|
||||
#' **FOX**: cefoxitin ([J01DC01](https://www.whocc.no/atc_ddd_index/?code=J01DC01)),
|
||||
#' **CPT**: ceftaroline ([J01DI02](https://www.whocc.no/atc_ddd_index/?code=J01DI02)),
|
||||
#' **CAZ**: ceftazidime ([J01DD02](https://www.whocc.no/atc_ddd_index/?code=J01DD02)),
|
||||
#' **CRO**: ceftriaxone ([J01DD04](https://www.whocc.no/atc_ddd_index/?code=J01DD04)),
|
||||
#' **CXM**: cefuroxime ([J01DC02](https://www.whocc.no/atc_ddd_index/?code=J01DC02)),
|
||||
#' **CED**: cephradine ([J01DB09](https://www.whocc.no/atc_ddd_index/?code=J01DB09)),
|
||||
#' **CHL**: chloramphenicol ([J01BA01](https://www.whocc.no/atc_ddd_index/?code=J01BA01)),
|
||||
#' **CIP**: ciprofloxacin ([J01MA02](https://www.whocc.no/atc_ddd_index/?code=J01MA02)),
|
||||
#' **CLR**: clarithromycin ([J01FA09](https://www.whocc.no/atc_ddd_index/?code=J01FA09)),
|
||||
#' **CLI**: clindamycin ([J01FF01](https://www.whocc.no/atc_ddd_index/?code=J01FF01)),
|
||||
#' **COL**: colistin ([J01XB01](https://www.whocc.no/atc_ddd_index/?code=J01XB01)),
|
||||
#' **DAP**: daptomycin ([J01XX09](https://www.whocc.no/atc_ddd_index/?code=J01XX09)),
|
||||
#' **DOR**: doripenem ([J01DH04](https://www.whocc.no/atc_ddd_index/?code=J01DH04)),
|
||||
#' **DOX**: doxycycline ([J01AA02](https://www.whocc.no/atc_ddd_index/?code=J01AA02)),
|
||||
#' **ETP**: ertapenem ([J01DH03](https://www.whocc.no/atc_ddd_index/?code=J01DH03)),
|
||||
#' **ERY**: erythromycin ([J01FA01](https://www.whocc.no/atc_ddd_index/?code=J01FA01)),
|
||||
#' **ETH**: ethambutol ([J04AK02](https://www.whocc.no/atc_ddd_index/?code=J04AK02)),
|
||||
#' **FLC**: flucloxacillin ([J01CF05](https://www.whocc.no/atc_ddd_index/?code=J01CF05)),
|
||||
#' **FOS**: fosfomycin ([J01XX01](https://www.whocc.no/atc_ddd_index/?code=J01XX01)),
|
||||
#' **FUS**: fusidic acid ([J01XC01](https://www.whocc.no/atc_ddd_index/?code=J01XC01)),
|
||||
#' **GAT**: gatifloxacin ([J01MA16](https://www.whocc.no/atc_ddd_index/?code=J01MA16)),
|
||||
#' **GEN**: gentamicin ([J01GB03](https://www.whocc.no/atc_ddd_index/?code=J01GB03)),
|
||||
#' **GEH**: gentamicin-high (no ATC code),
|
||||
#' **IPM**: imipenem ([J01DH51](https://www.whocc.no/atc_ddd_index/?code=J01DH51)),
|
||||
#' **INH**: isoniazid ([J04AC01](https://www.whocc.no/atc_ddd_index/?code=J04AC01)),
|
||||
#' **KAN**: kanamycin ([J01GB04](https://www.whocc.no/atc_ddd_index/?code=J01GB04)),
|
||||
#' **LVX**: levofloxacin ([J01MA12](https://www.whocc.no/atc_ddd_index/?code=J01MA12)),
|
||||
#' **LIN**: lincomycin ([J01FF02](https://www.whocc.no/atc_ddd_index/?code=J01FF02)),
|
||||
#' **LNZ**: linezolid ([J01XX08](https://www.whocc.no/atc_ddd_index/?code=J01XX08)),
|
||||
#' **MEM**: meropenem ([J01DH02](https://www.whocc.no/atc_ddd_index/?code=J01DH02)),
|
||||
#' **MTR**: metronidazole ([J01XD01](https://www.whocc.no/atc_ddd_index/?code=J01XD01)),
|
||||
#' **MEZ**: mezlocillin ([J01CA10](https://www.whocc.no/atc_ddd_index/?code=J01CA10)),
|
||||
#' **MNO**: minocycline ([J01AA08](https://www.whocc.no/atc_ddd_index/?code=J01AA08)),
|
||||
#' **MFX**: moxifloxacin ([J01MA14](https://www.whocc.no/atc_ddd_index/?code=J01MA14)),
|
||||
#' **NAL**: nalidixic acid ([J01MB02](https://www.whocc.no/atc_ddd_index/?code=J01MB02)),
|
||||
#' **NEO**: neomycin ([J01GB05](https://www.whocc.no/atc_ddd_index/?code=J01GB05)),
|
||||
#' **NET**: netilmicin ([J01GB07](https://www.whocc.no/atc_ddd_index/?code=J01GB07)),
|
||||
#' **NIT**: nitrofurantoin ([J01XE01](https://www.whocc.no/atc_ddd_index/?code=J01XE01)),
|
||||
#' **NOR**: norfloxacin ([J01MA06](https://www.whocc.no/atc_ddd_index/?code=J01MA06)),
|
||||
#' **NOV**: novobiocin ([QJ01XX95](https://www.whocc.no/atc_ddd_index/?code=QJ01XX95)),
|
||||
#' **OFX**: ofloxacin ([J01MA01](https://www.whocc.no/atc_ddd_index/?code=J01MA01)),
|
||||
#' **OXA**: oxacillin ([J01CF04](https://www.whocc.no/atc_ddd_index/?code=J01CF04)),
|
||||
#' **PEN**: penicillin G ([J01CE01](https://www.whocc.no/atc_ddd_index/?code=J01CE01)),
|
||||
#' **PIP**: piperacillin ([J01CA12](https://www.whocc.no/atc_ddd_index/?code=J01CA12)),
|
||||
#' **TZP**: piperacillin/tazobactam ([J01CR05](https://www.whocc.no/atc_ddd_index/?code=J01CR05)),
|
||||
#' **PLB**: polymyxin B ([J01XB02](https://www.whocc.no/atc_ddd_index/?code=J01XB02)),
|
||||
#' **PRI**: pristinamycin ([J01FG01](https://www.whocc.no/atc_ddd_index/?code=J01FG01)),
|
||||
#' **PZA**: pyrazinamide ([J04AK01](https://www.whocc.no/atc_ddd_index/?code=J04AK01)),
|
||||
#' **QDA**: quinupristin/dalfopristin ([J01FG02](https://www.whocc.no/atc_ddd_index/?code=J01FG02)),
|
||||
#' **RIB**: rifabutin ([J04AB04](https://www.whocc.no/atc_ddd_index/?code=J04AB04)),
|
||||
#' **RIF**: rifampicin ([J04AB02](https://www.whocc.no/atc_ddd_index/?code=J04AB02)),
|
||||
#' **RFP**: rifapentine ([J04AB05](https://www.whocc.no/atc_ddd_index/?code=J04AB05)),
|
||||
#' **RXT**: roxithromycin ([J01FA06](https://www.whocc.no/atc_ddd_index/?code=J01FA06)),
|
||||
#' **SIS**: sisomicin ([J01GB08](https://www.whocc.no/atc_ddd_index/?code=J01GB08)),
|
||||
#' **STH**: streptomycin-high (no ATC code),
|
||||
#' **TEC**: teicoplanin ([J01XA02](https://www.whocc.no/atc_ddd_index/?code=J01XA02)),
|
||||
#' **TLV**: telavancin ([J01XA03](https://www.whocc.no/atc_ddd_index/?code=J01XA03)),
|
||||
#' **TCY**: tetracycline ([J01AA07](https://www.whocc.no/atc_ddd_index/?code=J01AA07)),
|
||||
#' **TIC**: ticarcillin ([J01CA13](https://www.whocc.no/atc_ddd_index/?code=J01CA13)),
|
||||
#' **TCC**: ticarcillin/clavulanic acid ([J01CR03](https://www.whocc.no/atc_ddd_index/?code=J01CR03)),
|
||||
#' **TGC**: tigecycline ([J01AA12](https://www.whocc.no/atc_ddd_index/?code=J01AA12)),
|
||||
#' **TOB**: tobramycin ([J01GB01](https://www.whocc.no/atc_ddd_index/?code=J01GB01)),
|
||||
#' **TMP**: trimethoprim ([J01EA01](https://www.whocc.no/atc_ddd_index/?code=J01EA01)),
|
||||
#' **SXT**: trimethoprim/sulfamethoxazole ([J01EE01](https://www.whocc.no/atc_ddd_index/?code=J01EE01)),
|
||||
#' **VAN**: vancomycin ([J01XA01](https://www.whocc.no/atc_ddd_index/?code=J01XA01)).
|
||||
#' @aliases EUCAST
|
||||
#' @rdname eucast_rules
|
||||
#' @export
|
||||
#' @return The input of `x`, possibly with edited values of antibiotics. Or, if `verbose = TRUE`, a [`data.frame`] with all original and new values of the affected bug-drug combinations.
|
||||
#' @source
|
||||
#' - EUCAST Expert Rules. Version 2.0, 2012. \cr
|
||||
#' Leclercq et al. **EUCAST expert rules in antimicrobial susceptibility testing.** *Clin Microbiol Infect.* 2013;19(2):141-60. \cr
|
||||
#' <https://doi.org/10.1111/j.1469-0691.2011.03703.x>
|
||||
#' - EUCAST Expert Rules, Intrinsic Resistance and Exceptional Phenotypes Tables. Version 3.1, 2016. \cr
|
||||
#' <http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf>
|
||||
#' - EUCAST Breakpoint tables for interpretation of MICs and zone diameters. Version 9.0, 2019. \cr
|
||||
#' <http://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Breakpoint_tables/v_9.0_Breakpoint_Tables.xlsx>
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' \donttest{
|
||||
#' a <- data.frame(mo = c("Staphylococcus aureus",
|
||||
#' "Enterococcus faecalis",
|
||||
#' "Escherichia coli",
|
||||
#' "Klebsiella pneumoniae",
|
||||
#' "Pseudomonas aeruginosa"),
|
||||
#' VAN = "-", # Vancomycin
|
||||
#' AMX = "-", # Amoxicillin
|
||||
#' COL = "-", # Colistin
|
||||
#' CAZ = "-", # Ceftazidime
|
||||
#' CXM = "-", # Cefuroxime
|
||||
#' PEN = "S", # Penicillin G
|
||||
#' FOX = "S", # Cefoxitin
|
||||
#' stringsAsFactors = FALSE)
|
||||
#'
|
||||
#' a
|
||||
#' # mo VAN AMX COL CAZ CXM PEN FOX
|
||||
#' # 1 Staphylococcus aureus - - - - - S S
|
||||
#' # 2 Enterococcus faecalis - - - - - S S
|
||||
#' # 3 Escherichia coli - - - - - S S
|
||||
#' # 4 Klebsiella pneumoniae - - - - - S S
|
||||
#' # 5 Pseudomonas aeruginosa - - - - - S S
|
||||
#'
|
||||
#'
|
||||
#' # apply EUCAST rules: 18 results are forced as R or S
|
||||
#' b <- eucast_rules(a)
|
||||
#'
|
||||
#' b
|
||||
#' # mo VAN AMX COL CAZ CXM PEN FOX
|
||||
#' # 1 Staphylococcus aureus - S R R S S S
|
||||
#' # 2 Enterococcus faecalis - - R R R S R
|
||||
#' # 3 Escherichia coli R - - - - R S
|
||||
#' # 4 Klebsiella pneumoniae R R - - - R S
|
||||
#' # 5 Pseudomonas aeruginosa R R - - R R R
|
||||
#'
|
||||
#'
|
||||
#' # do not apply EUCAST rules, but rather get a data.frame
|
||||
#' # with 18 rows, containing all details about the transformations:
|
||||
#' c <- eucast_rules(a, verbose = TRUE)
|
||||
#' }
|
||||
eucast_rules <- function(x,
|
||||
col_mo = NULL,
|
||||
info = interactive(),
|
||||
rules = getOption("AMR.eucast_rules", default = c("breakpoints", "expert")),
|
||||
verbose = FALSE,
|
||||
...) {
|
||||
|
||||
check_dataset_integrity()
|
||||
|
||||
if (verbose == TRUE & interactive()) {
|
||||
txt <- paste0("WARNING: In Verbose mode, the eucast_rules() function does not apply rules to the data, but instead returns a data set in logbook form with extensive info about which rows and columns would be effected and in which way.",
|
||||
"\n\nThis may overwrite your existing data if you use e.g.:",
|
||||
"\ndata <- eucast_rules(data, verbose = TRUE)\n\nDo you want to continue?")
|
||||
if ("rstudioapi" %in% rownames(utils::installed.packages())) {
|
||||
showQuestion <- import_fn("showQuestion", "rstudioapi")
|
||||
q_continue <- showQuestion("Using verbose = TRUE with eucast_rules()", txt)
|
||||
} else {
|
||||
q_continue <- utils::menu(choices = c("OK", "Cancel"), graphics = FALSE, title = txt)
|
||||
}
|
||||
if (q_continue %in% c(FALSE, 2)) {
|
||||
message("Cancelled, returning original data")
|
||||
return(x)
|
||||
}
|
||||
}
|
||||
|
||||
stop_ifnot(is.data.frame(x), "`x` must be a data frame")
|
||||
|
||||
# try to find columns based on type
|
||||
# -- mo
|
||||
if (is.null(col_mo)) {
|
||||
col_mo <- search_type_in_df(x = x, type = "mo")
|
||||
}
|
||||
stop_if(is.null(col_mo), "`col_mo` must be set")
|
||||
|
||||
stop_ifnot(all(rules %in% c("breakpoints", "expert", "other", "all")),
|
||||
'`rules` must be one or more of: "breakpoints", "expert", "other", "all".')
|
||||
|
||||
decimal.mark <- getOption("OutDec")
|
||||
big.mark <- ifelse(decimal.mark != ",", ",", ".")
|
||||
formatnr <- function(x, big = big.mark, dec = decimal.mark) {
|
||||
trimws(format(x, big.mark = big, decimal.mark = dec))
|
||||
}
|
||||
|
||||
warned <- FALSE
|
||||
warn_lacking_rsi_class <- FALSE
|
||||
|
||||
txt_error <- function() {
|
||||
if (info == TRUE) cat("", font_red_bg(font_white(" ERROR ")), "\n\n")
|
||||
}
|
||||
txt_warning <- function() {
|
||||
if (warned == FALSE) {
|
||||
if (info == TRUE) cat("", font_yellow_bg(font_black(" WARNING ")))
|
||||
}
|
||||
warned <<- TRUE
|
||||
}
|
||||
txt_ok <- function(no_added, no_changed) {
|
||||
if (warned == FALSE) {
|
||||
if (no_added + no_changed == 0) {
|
||||
cat(font_subtle(" (no changes)\n"))
|
||||
} else {
|
||||
# opening
|
||||
cat(font_grey(" ("))
|
||||
# additions
|
||||
if (no_added > 0) {
|
||||
if (no_added == 1) {
|
||||
cat(font_green("1 value added"))
|
||||
} else {
|
||||
cat(font_green(formatnr(no_added), "values added"))
|
||||
}
|
||||
}
|
||||
# separator
|
||||
if (no_added > 0 & no_changed > 0) {
|
||||
cat(font_grey(", "))
|
||||
}
|
||||
# changes
|
||||
if (no_changed > 0) {
|
||||
if (no_changed == 1) {
|
||||
cat(font_blue("1 value changed"))
|
||||
} else {
|
||||
cat(font_blue(formatnr(no_changed), "values changed"))
|
||||
}
|
||||
}
|
||||
# closing
|
||||
cat(font_grey(")\n"))
|
||||
}
|
||||
warned <<- FALSE
|
||||
}
|
||||
}
|
||||
|
||||
cols_ab <- get_column_abx(x = x,
|
||||
soft_dependencies = c("AMC",
|
||||
"AMK",
|
||||
"AMX",
|
||||
"AMP",
|
||||
"AZM",
|
||||
"AZL",
|
||||
"ATM",
|
||||
"RID",
|
||||
"FEP",
|
||||
"CTX",
|
||||
"FOX",
|
||||
"CED",
|
||||
"CAZ",
|
||||
"CRO",
|
||||
"CXM",
|
||||
"CHL",
|
||||
"CIP",
|
||||
"CLR",
|
||||
"CLI",
|
||||
"FLC",
|
||||
"COL",
|
||||
"CZO",
|
||||
"DAP",
|
||||
"DOX",
|
||||
"ETP",
|
||||
"ERY",
|
||||
"FOS",
|
||||
"FUS",
|
||||
"GEN",
|
||||
"IPM",
|
||||
"KAN",
|
||||
"LVX",
|
||||
"LIN",
|
||||
"LNZ",
|
||||
"MEM",
|
||||
"MEZ",
|
||||
"MNO",
|
||||
"MFX",
|
||||
"NAL",
|
||||
"NEO",
|
||||
"NET",
|
||||
"NIT",
|
||||
"NOR",
|
||||
"NOV",
|
||||
"OFX",
|
||||
"OXA",
|
||||
"PEN",
|
||||
"PIP",
|
||||
"TZP",
|
||||
"PLB",
|
||||
"PRI",
|
||||
"QDA",
|
||||
"RIF",
|
||||
"RXT",
|
||||
"SIS",
|
||||
"TEC",
|
||||
"TCY",
|
||||
"TIC",
|
||||
"TGC",
|
||||
"TOB",
|
||||
"TMP",
|
||||
"SXT",
|
||||
"VAN"),
|
||||
hard_dependencies = NULL,
|
||||
verbose = verbose,
|
||||
...)
|
||||
|
||||
AMC <- cols_ab["AMC"]
|
||||
AMK <- cols_ab["AMK"]
|
||||
AMP <- cols_ab["AMP"]
|
||||
AMX <- cols_ab["AMX"]
|
||||
ATM <- cols_ab["ATM"]
|
||||
AZL <- cols_ab["AZL"]
|
||||
AZM <- cols_ab["AZM"]
|
||||
CAZ <- cols_ab["CAZ"]
|
||||
CED <- cols_ab["CED"]
|
||||
CHL <- cols_ab["CHL"]
|
||||
CIP <- cols_ab["CIP"]
|
||||
CLI <- cols_ab["CLI"]
|
||||
CLR <- cols_ab["CLR"]
|
||||
COL <- cols_ab["COL"]
|
||||
CRO <- cols_ab["CRO"]
|
||||
CTX <- cols_ab["CTX"]
|
||||
CXM <- cols_ab["CXM"]
|
||||
CZO <- cols_ab["CZO"]
|
||||
DAP <- cols_ab["DAP"]
|
||||
DOX <- cols_ab["DOX"]
|
||||
ERY <- cols_ab["ERY"]
|
||||
ETP <- cols_ab["ETP"]
|
||||
FEP <- cols_ab["FEP"]
|
||||
FLC <- cols_ab["FLC"]
|
||||
FOS <- cols_ab["FOS"]
|
||||
FOX <- cols_ab["FOX"]
|
||||
FUS <- cols_ab["FUS"]
|
||||
GEN <- cols_ab["GEN"]
|
||||
IPM <- cols_ab["IPM"]
|
||||
KAN <- cols_ab["KAN"]
|
||||
LIN <- cols_ab["LIN"]
|
||||
LNZ <- cols_ab["LNZ"]
|
||||
LVX <- cols_ab["LVX"]
|
||||
MEM <- cols_ab["MEM"]
|
||||
MEZ <- cols_ab["MEZ"]
|
||||
MFX <- cols_ab["MFX"]
|
||||
MNO <- cols_ab["MNO"]
|
||||
NAL <- cols_ab["NAL"]
|
||||
NEO <- cols_ab["NEO"]
|
||||
NET <- cols_ab["NET"]
|
||||
NIT <- cols_ab["NIT"]
|
||||
NOR <- cols_ab["NOR"]
|
||||
NOV <- cols_ab["NOV"]
|
||||
OFX <- cols_ab["OFX"]
|
||||
OXA <- cols_ab["OXA"]
|
||||
PEN <- cols_ab["PEN"]
|
||||
PIP <- cols_ab["PIP"]
|
||||
PLB <- cols_ab["PLB"]
|
||||
PRI <- cols_ab["PRI"]
|
||||
QDA <- cols_ab["QDA"]
|
||||
RID <- cols_ab["RID"]
|
||||
RIF <- cols_ab["RIF"]
|
||||
RXT <- cols_ab["RXT"]
|
||||
SAM <- cols_ab["SAM"]
|
||||
SIS <- cols_ab["SIS"]
|
||||
SXT <- cols_ab["SXT"]
|
||||
TCY <- cols_ab["TCY"]
|
||||
TEC <- cols_ab["TEC"]
|
||||
TGC <- cols_ab["TGC"]
|
||||
TIC <- cols_ab["TIC"]
|
||||
TMP <- cols_ab["TMP"]
|
||||
TOB <- cols_ab["TOB"]
|
||||
TZP <- cols_ab["TZP"]
|
||||
VAN <- cols_ab["VAN"]
|
||||
|
||||
ab_missing <- function(ab) {
|
||||
all(ab %in% c(NULL, NA))
|
||||
}
|
||||
|
||||
verbose_info <- data.frame(row = integer(0),
|
||||
col = character(0),
|
||||
mo_fullname = character(0),
|
||||
old = as.rsi(character(0)),
|
||||
new = as.rsi(character(0)),
|
||||
rule = character(0),
|
||||
rule_group = character(0),
|
||||
rule_name = character(0),
|
||||
stringsAsFactors = FALSE)
|
||||
|
||||
# helper function for editing the table
|
||||
edit_rsi <- function(to, rule, rows, cols) {
|
||||
cols <- unique(cols[!is.na(cols) & !is.null(cols)])
|
||||
if (length(rows) > 0 & length(cols) > 0) {
|
||||
before_df <- x_original
|
||||
if (any(!sapply(x[, cols, drop = FALSE], is.rsi), na.rm = TRUE)) {
|
||||
warn_lacking_rsi_class <<- TRUE
|
||||
}
|
||||
tryCatch(
|
||||
# insert into original table
|
||||
x_original[rows, cols] <<- to,
|
||||
warning = function(w) {
|
||||
if (w$message %like% "invalid factor level") {
|
||||
xyz <- sapply(cols, function(col) {
|
||||
x_original[, col] <<- factor(x = as.character(pull(x_original, col)), levels = c(to, levels(pull(x_original, col))))
|
||||
x[, col] <<- factor(x = as.character(pull(x, col)), levels = c(to, levels(pull(x, col))))
|
||||
invisible()
|
||||
})
|
||||
x_original[rows, cols] <<- to
|
||||
warning('Value "', to, '" added to the factor levels of column(s) `', paste(cols, collapse = "`, `"), "` because this value was not an existing factor level.\nA better way is to use as.rsi() on beforehand on antimicrobial columns to guarantee the right structure.", call. = FALSE)
|
||||
txt_warning()
|
||||
warned <<- FALSE
|
||||
} else {
|
||||
warning(w$message, call. = FALSE)
|
||||
txt_warning()
|
||||
cat("\n") # txt_warning() does not append a "\n" on itself
|
||||
}
|
||||
},
|
||||
error = function(e) {
|
||||
txt_error()
|
||||
stop(paste0("In row(s) ", paste(rows[1:min(length(rows), 10)], collapse = ","),
|
||||
ifelse(length(rows) > 10, "...", ""),
|
||||
" while writing value '", to,
|
||||
"' to column(s) `", paste(cols, collapse = "`, `"),
|
||||
"`:\n", e$message),
|
||||
call. = FALSE)
|
||||
}
|
||||
)
|
||||
|
||||
tryCatch(
|
||||
x[rows, cols] <<- x_original[rows, cols],
|
||||
error = function(e) {
|
||||
stop(paste0("In row(s) ", paste(rows[1:min(length(rows), 10)], collapse = ","),
|
||||
"... while writing value '", to,
|
||||
"' to column(s) `", paste(cols, collapse = "`, `"),
|
||||
"`:\n", e$message), call. = FALSE)
|
||||
}
|
||||
)
|
||||
|
||||
# before_df might not be a data.frame, but a tibble or data.table instead
|
||||
old <- as.data.frame(before_df, stringsAsFactors = FALSE)[rows, ]
|
||||
track_changes <- list(added = 0,
|
||||
changed = 0)
|
||||
for (i in seq_len(length(cols))) {
|
||||
verbose_new <- data.frame(row = rows,
|
||||
col = cols[i],
|
||||
mo_fullname = x[rows, "fullname"],
|
||||
old = as.rsi(as.character(old[, cols[i]]), warn = FALSE),
|
||||
new = as.rsi(as.character(x[rows, cols[i]])),
|
||||
rule = font_stripstyle(rule[1]),
|
||||
rule_group = font_stripstyle(rule[2]),
|
||||
rule_name = font_stripstyle(rule[3]),
|
||||
stringsAsFactors = FALSE)
|
||||
colnames(verbose_new) <- c("row", "col", "mo_fullname", "old", "new", "rule", "rule_group", "rule_name")
|
||||
verbose_new <- verbose_new %>% filter(old != new | is.na(old))
|
||||
# save changes to data set 'verbose_info'
|
||||
verbose_info <<- rbind(verbose_info, verbose_new)
|
||||
# count adds and changes
|
||||
track_changes$added <- track_changes$added + verbose_new %>% filter(is.na(old)) %>% nrow()
|
||||
track_changes$changed <- track_changes$changed + verbose_new %>% filter(!is.na(old)) %>% nrow()
|
||||
}
|
||||
# after the applied changes: return list with counts of added and changed
|
||||
return(track_changes)
|
||||
}
|
||||
# no changes were applied: return number of (new) changes: none.
|
||||
return(list(added = 0,
|
||||
changed = 0))
|
||||
}
|
||||
|
||||
# save original table
|
||||
x_original <- x
|
||||
x_original_attr <- attributes(x)
|
||||
x_original <- as.data.frame(x_original, stringsAsFactors = FALSE) # no tibbles, data.tables, etc.
|
||||
|
||||
# join to microorganisms data set
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
x[, col_mo] <- as.mo(x[, col_mo, drop = TRUE])
|
||||
x <- x %>%
|
||||
left_join_microorganisms(by = col_mo, suffix = c("_oldcols", ""))
|
||||
x$gramstain <- mo_gramstain(x[, col_mo, drop = TRUE], language = NULL)
|
||||
x$genus_species <- paste(x$genus, x$species)
|
||||
|
||||
if (ab_missing(AMP) & !ab_missing(AMX)) {
|
||||
# ampicillin column is missing, but amoxicillin is available
|
||||
message(font_blue(paste0("NOTE: Using column `", font_bold(AMX), "` as input for ampicillin (J01CA01) since many EUCAST rules depend on it.")))
|
||||
AMP <- AMX
|
||||
}
|
||||
|
||||
# nolint start
|
||||
# antibiotic classes
|
||||
aminoglycosides <- c(TOB, GEN, KAN, NEO, NET, SIS)
|
||||
tetracyclines <- c(DOX, MNO, TCY) # since EUCAST v3.1 tigecycline (TGC) is set apart
|
||||
polymyxins <- c(PLB, COL)
|
||||
macrolides <- c(ERY, AZM, RXT, CLR) # since EUCAST v3.1 clinda is set apart
|
||||
glycopeptides <- c(VAN, TEC)
|
||||
streptogramins <- c(QDA, PRI) # should officially also be quinupristin/dalfopristin
|
||||
aminopenicillins <- c(AMP, AMX)
|
||||
cephalosporins <- c(FEP, CTX, FOX, CED, CAZ, CRO, CXM, CZO)
|
||||
cephalosporins_except_CAZ <- cephalosporins[cephalosporins != ifelse(is.null(CAZ), "", CAZ)]
|
||||
carbapenems <- c(ETP, IPM, MEM)
|
||||
ureidopenicillins <- c(PIP, TZP, AZL, MEZ)
|
||||
all_betalactams <- c(aminopenicillins, cephalosporins, carbapenems, ureidopenicillins, AMC, OXA, FLC, PEN)
|
||||
fluoroquinolones <- c(OFX, CIP, NOR, LVX, MFX)
|
||||
# nolint end
|
||||
|
||||
# Help function to get available antibiotic column names ------------------
|
||||
get_antibiotic_columns <- function(x, df) {
|
||||
x <- trimws(unlist(strsplit(x, ",", fixed = TRUE)))
|
||||
y <- character(0)
|
||||
for (i in seq_len(length(x))) {
|
||||
if (is.function(get(x[i]))) {
|
||||
stop("Column ", x[i], " is also a function. Please create an issue on github.com/msberends/AMR/issues.")
|
||||
}
|
||||
y <- c(y, tryCatch(get(x[i]), error = function(e) ""))
|
||||
}
|
||||
y[y != "" & y %in% colnames(df)]
|
||||
}
|
||||
get_antibiotic_names <- function(x) {
|
||||
x <- x %>%
|
||||
strsplit(",") %>%
|
||||
unlist() %>%
|
||||
trimws() %>%
|
||||
sapply(function(x) if (x %in% antibiotics$ab) ab_name(x, language = NULL, tolower = TRUE) else x) %>%
|
||||
sort() %>%
|
||||
paste(collapse = ", ")
|
||||
x <- gsub("_", " ", x, fixed = TRUE)
|
||||
x <- gsub("except CAZ", paste("except", ab_name("CAZ", language = NULL, tolower = TRUE)), x, fixed = TRUE)
|
||||
x
|
||||
}
|
||||
format_antibiotic_names <- function(ab_names, ab_results) {
|
||||
ab_names <- trimws(unlist(strsplit(ab_names, ",")))
|
||||
ab_results <- trimws(unlist(strsplit(ab_results, ",")))
|
||||
if (length(ab_results) == 1) {
|
||||
if (length(ab_names) == 1) {
|
||||
# like FOX S
|
||||
x <- paste(ab_names, "is")
|
||||
} else if (length(ab_names) == 2) {
|
||||
# like PEN,FOX S
|
||||
x <- paste(paste0(ab_names, collapse = " and "), "are both")
|
||||
} else {
|
||||
# like PEN,FOX,GEN S (although dependency on > 2 ABx does not exist at the moment)
|
||||
x <- paste(paste0(ab_names, collapse = " and "), "are all")
|
||||
}
|
||||
return(paste0(x, " '", ab_results, "'"))
|
||||
} else {
|
||||
if (length(ab_names) == 2) {
|
||||
# like PEN,FOX S,R
|
||||
paste0(ab_names[1], " is '", ab_results[1], "' and ",
|
||||
ab_names[2], " is '", ab_results[2], "'")
|
||||
} else {
|
||||
# like PEN,FOX,GEN S,R,R (although dependency on > 2 ABx does not exist at the moment)
|
||||
paste0(ab_names[1], " is '", ab_results[1], "' and ",
|
||||
ab_names[2], " is '", ab_results[2], "' and ",
|
||||
ab_names[3], " is '", ab_results[3], "'")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
as.rsi_no_warning <- function(x) suppressWarnings(as.rsi(x))
|
||||
no_added <- 0
|
||||
no_changed <- 0
|
||||
|
||||
# Other rules: enzyme inhibitors ------------------------------------------
|
||||
if (any(c("all", "other") %in% rules)) {
|
||||
if (info == TRUE) {
|
||||
cat(font_bold(paste0("\nRules by this AMR package (",
|
||||
font_red(paste0("v", utils::packageVersion("AMR"), ", ",
|
||||
format(utils::packageDate("AMR"), "%Y"))), "), see ?eucast_rules\n")))
|
||||
}
|
||||
|
||||
ab_enzyme <- subset(antibiotics, name %like% "/")[, c("ab", "name")]
|
||||
ab_enzyme$base_name <- gsub("^([a-zA-Z0-9]+).*", "\\1", ab_enzyme$name)
|
||||
ab_enzyme$base_ab <- as.ab(ab_enzyme$base_name)
|
||||
for (i in seq_len(nrow(ab_enzyme))) {
|
||||
if (all(c(ab_enzyme[i, ]$ab, ab_enzyme[i, ]$base_ab) %in% names(cols_ab), na.rm = TRUE)) {
|
||||
ab_name_base <- ab_name(cols_ab[ab_enzyme[i, ]$base_ab], language = NULL, tolower = TRUE)
|
||||
ab_name_enzyme <- ab_name(cols_ab[ab_enzyme[i, ]$ab], language = NULL, tolower = TRUE)
|
||||
|
||||
# Set base to R where base + enzyme inhibitor is R
|
||||
rule_current <- paste0("Set ", ab_name_base, " (", cols_ab[ab_enzyme[i, ]$base_ab], ") = R where ",
|
||||
ab_name_enzyme, " (", cols_ab[ab_enzyme[i, ]$ab], ") = R")
|
||||
if (info == TRUE) {
|
||||
cat(rule_current)
|
||||
}
|
||||
run_changes <- edit_rsi(to = "R",
|
||||
rule = c(rule_current, "Other rules", ""),
|
||||
rows = which(as.rsi_no_warning(x[, cols_ab[ab_enzyme[i, ]$ab]]) == "R"),
|
||||
cols = cols_ab[ab_enzyme[i, ]$base_ab])
|
||||
no_added <- no_added + run_changes$added
|
||||
no_changed <- no_changed + run_changes$changed
|
||||
# Print number of new changes
|
||||
if (info == TRUE) {
|
||||
# print only on last one of rules in this group
|
||||
txt_ok(no_added = no_added, no_changed = no_changed)
|
||||
# and reset counters
|
||||
no_added <- 0
|
||||
no_changed <- 0
|
||||
}
|
||||
|
||||
# Set base + enzyme inhibitor to S where base is S
|
||||
rule_current <- paste0("Set ", ab_name_enzyme, " (", cols_ab[ab_enzyme[i, ]$ab], ") = S where ",
|
||||
ab_name_base, " (", cols_ab[ab_enzyme[i, ]$base_ab], ") = S")
|
||||
if (info == TRUE) {
|
||||
cat(rule_current)
|
||||
}
|
||||
run_changes <- edit_rsi(to = "S",
|
||||
rule = c(rule_current, "Other rules", ""),
|
||||
rows = which(as.rsi_no_warning(x[, cols_ab[ab_enzyme[i, ]$base_ab]]) == "S"),
|
||||
cols = cols_ab[ab_enzyme[i, ]$ab])
|
||||
no_added <- no_added + run_changes$added
|
||||
no_changed <- no_changed + run_changes$changed
|
||||
# Print number of new changes
|
||||
if (info == TRUE) {
|
||||
# print only on last one of rules in this group
|
||||
txt_ok(no_added = no_added, no_changed = no_changed)
|
||||
# and reset counters
|
||||
no_added <- 0
|
||||
no_changed <- 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (info == TRUE) {
|
||||
cat(font_red("\nSkipping inheritance rules defined by this package, such as setting trimethoprim (TMP) = R where trimethoprim/sulfamethoxazole (SXT) = R.\nUse eucast_rules(..., rules = \"all\") to also apply those rules.\n"))
|
||||
}
|
||||
}
|
||||
|
||||
# Official EUCAST rules ---------------------------------------------------
|
||||
eucast_notification_shown <- FALSE
|
||||
eucast_rules_df <- eucast_rules_file # internal data file
|
||||
for (i in seq_len(nrow(eucast_rules_df))) {
|
||||
|
||||
rule_previous <- eucast_rules_df[max(1, i - 1), "reference.rule"]
|
||||
rule_current <- eucast_rules_df[i, "reference.rule"]
|
||||
rule_next <- eucast_rules_df[min(nrow(eucast_rules_df), i + 1), "reference.rule"]
|
||||
rule_group_previous <- eucast_rules_df[max(1, i - 1), "reference.rule_group"]
|
||||
rule_group_current <- eucast_rules_df[i, "reference.rule_group"]
|
||||
if (is.na(eucast_rules_df[i, 4])) {
|
||||
rule_text <- paste0("always report as '", eucast_rules_df[i, 7], "': ", get_antibiotic_names(eucast_rules_df[i, 6]))
|
||||
} else {
|
||||
rule_text <- paste0("report as '", eucast_rules_df[i, 7], "' when ",
|
||||
format_antibiotic_names(ab_names = get_antibiotic_names(eucast_rules_df[i, 4]),
|
||||
ab_results = eucast_rules_df[i, 5]), ": ",
|
||||
get_antibiotic_names(eucast_rules_df[i, 6]))
|
||||
}
|
||||
if (i == 1) {
|
||||
rule_previous <- ""
|
||||
rule_group_previous <- ""
|
||||
}
|
||||
if (i == nrow(eucast_rules_df)) {
|
||||
rule_next <- ""
|
||||
}
|
||||
|
||||
# don't apply rules if user doesn't want to apply them
|
||||
if (rule_group_current %like% "breakpoint" & !any(c("all", "breakpoints") %in% rules)) {
|
||||
next
|
||||
}
|
||||
if (rule_group_current %like% "expert" & !any(c("all", "expert") %in% rules)) {
|
||||
next
|
||||
}
|
||||
|
||||
if (info == TRUE & !rule_group_current %like% "other" & eucast_notification_shown == FALSE) {
|
||||
cat(paste0("\n", font_grey(strrep("-", options()$width - 1)),
|
||||
"\nRules by the ", font_bold("European Committee on Antimicrobial Susceptibility Testing (EUCAST)"),
|
||||
"\n", font_blue("http://eucast.org/"), "\n"))
|
||||
eucast_notification_shown <- TRUE
|
||||
}
|
||||
|
||||
if (info == TRUE) {
|
||||
# Print rule (group) ------------------------------------------------------
|
||||
if (rule_group_current != rule_group_previous) {
|
||||
# is new rule group, one of Breakpoints, Expert Rules and Other
|
||||
cat(font_bold(
|
||||
ifelse(
|
||||
rule_group_current %like% "breakpoint",
|
||||
paste0("\nEUCAST Clinical Breakpoints (",
|
||||
font_red(paste0("v", EUCAST_VERSION_BREAKPOINTS)), ")\n"),
|
||||
ifelse(
|
||||
rule_group_current %like% "expert",
|
||||
paste0("\nEUCAST Expert Rules, Intrinsic Resistance and Exceptional Phenotypes (",
|
||||
font_red(paste0("v", EUCAST_VERSION_EXPERT_RULES)), ")\n"),
|
||||
""))))
|
||||
}
|
||||
# Print rule -------------------------------------------------------------
|
||||
if (rule_current != rule_previous) {
|
||||
# is new rule within group, print its name
|
||||
if (rule_current %in% c(microorganisms$family,
|
||||
microorganisms$fullname)) {
|
||||
cat(font_italic(rule_current))
|
||||
} else {
|
||||
cat(rule_current)
|
||||
}
|
||||
warned <- FALSE
|
||||
}
|
||||
}
|
||||
|
||||
# Get rule from file ------------------------------------------------------
|
||||
col_mo_property <- eucast_rules_df[i, 1]
|
||||
like_is_one_of <- eucast_rules_df[i, 2]
|
||||
|
||||
# be sure to comprise all coagulase-negative/-positive Staphylococci when they are mentioned
|
||||
if (eucast_rules_df[i, 3] %like% "coagulase") {
|
||||
all_staph <- microorganisms[which(microorganisms$genus == "Staphylococcus"), ]
|
||||
all_staph$CNS_CPS <- suppressWarnings(mo_name(all_staph$mo, Becker = "all", language = NULL))
|
||||
if (eucast_rules_df[i, 3] %like% "coagulase") {
|
||||
eucast_rules_df[i, 3] <- paste0("^(", paste0(all_staph[which(all_staph$CNS_CPS %like% "negative"),
|
||||
"fullname",
|
||||
drop = TRUE],
|
||||
collapse = "|"),
|
||||
")$")
|
||||
} else {
|
||||
eucast_rules_df[i, 3] <- paste0("^(", paste0(all_staph[which(all_staph$CNS_CPS %like% "positive"),
|
||||
"fullname",
|
||||
drop = TRUE],
|
||||
collapse = "|"),
|
||||
")$")
|
||||
}
|
||||
like_is_one_of <- "like"
|
||||
}
|
||||
|
||||
if (like_is_one_of == "is") {
|
||||
# so e.g. 'Enterococcus' will turn into '^Enterococcus$'
|
||||
mo_value <- paste0("^", eucast_rules_df[i, 3], "$")
|
||||
} else if (like_is_one_of == "one_of") {
|
||||
# so 'Clostridium, Actinomyces, ...' will turn into '^(Clostridium|Actinomyces|...)$'
|
||||
mo_value <- paste0("^(",
|
||||
paste(trimws(unlist(strsplit(eucast_rules_df[i, 3], ",", fixed = TRUE))),
|
||||
collapse = "|"),
|
||||
")$")
|
||||
} else if (like_is_one_of == "like") {
|
||||
mo_value <- eucast_rules_df[i, 3]
|
||||
} else {
|
||||
stop("invalid value for column 'like.is.one_of'", call. = FALSE)
|
||||
}
|
||||
|
||||
source_antibiotics <- eucast_rules_df[i, 4]
|
||||
source_value <- trimws(unlist(strsplit(eucast_rules_df[i, 5], ",", fixed = TRUE)))
|
||||
target_antibiotics <- eucast_rules_df[i, 6]
|
||||
target_value <- eucast_rules_df[i, 7]
|
||||
|
||||
if (is.na(source_antibiotics)) {
|
||||
rows <- tryCatch(which(x[, col_mo_property] %like% mo_value),
|
||||
error = function(e) integer(0))
|
||||
} else {
|
||||
source_antibiotics <- get_antibiotic_columns(source_antibiotics, x)
|
||||
if (length(source_value) == 1 & length(source_antibiotics) > 1) {
|
||||
source_value <- rep(source_value, length(source_antibiotics))
|
||||
}
|
||||
if (length(source_antibiotics) == 0) {
|
||||
rows <- integer(0)
|
||||
} else if (length(source_antibiotics) == 1) {
|
||||
rows <- tryCatch(which(x[, col_mo_property] %like% mo_value
|
||||
& as.rsi_no_warning(x[, source_antibiotics[1L]]) == source_value[1L]),
|
||||
error = function(e) integer(0))
|
||||
} else if (length(source_antibiotics) == 2) {
|
||||
rows <- tryCatch(which(x[, col_mo_property] %like% mo_value
|
||||
& as.rsi_no_warning(x[, source_antibiotics[1L]]) == source_value[1L]
|
||||
& as.rsi_no_warning(x[, source_antibiotics[2L]]) == source_value[2L]),
|
||||
error = function(e) integer(0))
|
||||
} else if (length(source_antibiotics) == 3) {
|
||||
rows <- tryCatch(which(x[, col_mo_property] %like% mo_value
|
||||
& as.rsi_no_warning(x[, source_antibiotics[1L]]) == source_value[1L]
|
||||
& as.rsi_no_warning(x[, source_antibiotics[2L]]) == source_value[2L]
|
||||
& as.rsi_no_warning(x[, source_antibiotics[3L]]) == source_value[3L]),
|
||||
error = function(e) integer(0))
|
||||
} else {
|
||||
stop("only 3 antibiotics supported for source_antibiotics ", call. = FALSE)
|
||||
}
|
||||
}
|
||||
|
||||
cols <- get_antibiotic_columns(target_antibiotics, x)
|
||||
|
||||
# Apply rule on data ------------------------------------------------------
|
||||
# this will return the unique number of changes
|
||||
run_changes <- edit_rsi(to = target_value,
|
||||
rule = c(rule_text, rule_group_current, rule_current),
|
||||
rows = rows,
|
||||
cols = cols)
|
||||
no_added <- no_added + run_changes$added
|
||||
no_changed <- no_changed + run_changes$changed
|
||||
|
||||
# Print number of new changes ---------------------------------------------
|
||||
if (info == TRUE & rule_next != rule_current) {
|
||||
# print only on last one of rules in this group
|
||||
txt_ok(no_added = no_added, no_changed = no_changed)
|
||||
# and reset counters
|
||||
no_added <- 0
|
||||
no_changed <- 0
|
||||
}
|
||||
}
|
||||
|
||||
# Print overview ----------------------------------------------------------
|
||||
if (info == TRUE) {
|
||||
if (verbose == TRUE) {
|
||||
wouldve <- "would have "
|
||||
} else {
|
||||
wouldve <- ""
|
||||
}
|
||||
|
||||
verbose_info <- verbose_info %>%
|
||||
arrange(row, rule_group, rule_name, col)
|
||||
|
||||
cat(paste0("\n", font_grey(strrep("-", options()$width - 1)), "\n"))
|
||||
cat(font_bold(paste("The rules", paste0(wouldve, "affected"),
|
||||
formatnr(n_distinct(verbose_info$row)),
|
||||
"out of", formatnr(nrow(x_original)),
|
||||
"rows, making a total of", formatnr(nrow(verbose_info)), "edits\n")))
|
||||
|
||||
n_added <- verbose_info %>% filter(is.na(old)) %>% nrow()
|
||||
n_changed <- verbose_info %>% filter(!is.na(old)) %>% nrow()
|
||||
|
||||
# print added values ----
|
||||
if (n_added == 0) {
|
||||
colour <- cat # is function
|
||||
} else {
|
||||
colour <- font_green # is function
|
||||
}
|
||||
cat(colour(paste0("=> ", wouldve, "added ",
|
||||
font_bold(formatnr(verbose_info %>%
|
||||
filter(is.na(old)) %>%
|
||||
nrow()), "test results"),
|
||||
"\n")))
|
||||
if (n_added > 0) {
|
||||
added_summary <- verbose_info %>%
|
||||
filter(is.na(old)) %>%
|
||||
group_by(new) %>%
|
||||
summarise(n = n())
|
||||
cat(paste(" -",
|
||||
paste0(formatnr(added_summary$n), " test result", ifelse(added_summary$n > 1, "s", ""),
|
||||
" added as ", added_summary$new), collapse = "\n"))
|
||||
}
|
||||
|
||||
# print changed values ----
|
||||
if (n_changed == 0) {
|
||||
colour <- cat # is function
|
||||
} else {
|
||||
colour <- font_blue # is function
|
||||
}
|
||||
if (n_added + n_changed > 0) {
|
||||
cat("\n")
|
||||
}
|
||||
cat(colour(paste0("=> ", wouldve, "changed ",
|
||||
font_bold(formatnr(verbose_info %>%
|
||||
filter(!is.na(old)) %>%
|
||||
nrow()), "test results"),
|
||||
"\n")))
|
||||
if (n_changed > 0) {
|
||||
changed_summary <- verbose_info %>%
|
||||
filter(!is.na(old)) %>%
|
||||
group_by(old, new) %>%
|
||||
summarise(n = n())
|
||||
cat(paste(" -",
|
||||
paste0(formatnr(changed_summary$n), " test result", ifelse(changed_summary$n > 1, "s", ""), " changed from ",
|
||||
changed_summary$old, " to ", changed_summary$new), collapse = "\n"))
|
||||
cat("\n")
|
||||
}
|
||||
cat(paste0(font_grey(strrep("-", options()$width - 1)), "\n"))
|
||||
|
||||
if (verbose == FALSE & nrow(verbose_info) > 0) {
|
||||
cat(paste("\nUse", font_bold("eucast_rules(..., verbose = TRUE)"), "(on your original data) to get a data.frame with all specified edits instead.\n\n"))
|
||||
} else if (verbose == TRUE) {
|
||||
cat(paste0("\nUsed 'Verbose mode' (", font_bold("verbose = TRUE"), "), which returns a data.frame with all specified edits.\nUse ", font_bold("verbose = FALSE"), " to apply the rules on your data.\n\n"))
|
||||
}
|
||||
}
|
||||
|
||||
if (isTRUE(warn_lacking_rsi_class)) {
|
||||
warning("Not all columns with antimicrobial results are of class <rsi>.\n",
|
||||
"Transform eligible columns to class <rsi> on beforehand: your_data %>% mutate_if(is.rsi.eligible, as.rsi)",
|
||||
call. = FALSE)
|
||||
}
|
||||
|
||||
# Return data set ---------------------------------------------------------
|
||||
if (verbose == TRUE) {
|
||||
rownames(verbose_info) <- NULL
|
||||
verbose_info
|
||||
} else {
|
||||
# reset original attributes
|
||||
attributes(x_original) <- x_original_attr
|
||||
x_original
|
||||
}
|
||||
}
|
||||
@@ -1,357 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Filter isolates on result in antimicrobial class
|
||||
#'
|
||||
#' Filter isolates on results in specific antimicrobial classes. This makes it easy to filter on isolates that were tested for e.g. any aminoglycoside, or to filter on carbapenem-resistant isolates without the need to specify the drugs.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x a data set
|
||||
#' @param ab_class an antimicrobial class, like `"carbapenems"`. The columns `group`, `atc_group1` and `atc_group2` of the [antibiotics] data set will be searched (case-insensitive) for this value.
|
||||
#' @param result an antibiotic result: S, I or R (or a combination of more of them)
|
||||
#' @param scope the scope to check which variables to check, can be `"any"` (default) or `"all"`
|
||||
#' @param ... previously used when this package still depended on the `dplyr` package, now ignored
|
||||
#' @details All columns of `x` will be searched for known antibiotic names, abbreviations, brand names and codes (ATC, EARS-Net, WHO, etc.). This means that a filter function like e.g. [filter_aminoglycosides()] will include column names like 'gen', 'genta', 'J01GB03', 'tobra', 'Tobracin', etc.
|
||||
#' @rdname filter_ab_class
|
||||
#' @seealso [antibiotic_class_selectors()] for the `select()` equivalent.
|
||||
#' @export
|
||||
#' @examples
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#'
|
||||
#' # filter on isolates that have any result for any aminoglycoside
|
||||
#' example_isolates %>% filter_ab_class("aminoglycoside")
|
||||
#' example_isolates %>% filter_aminoglycosides()
|
||||
#'
|
||||
#' # this is essentially the same as (but without determination of column names):
|
||||
#' example_isolates %>%
|
||||
#' filter_at(.vars = vars(c("GEN", "TOB", "AMK", "KAN")),
|
||||
#' .vars_predicate = any_vars(. %in% c("S", "I", "R")))
|
||||
#'
|
||||
#'
|
||||
#' # filter on isolates that show resistance to ANY aminoglycoside
|
||||
#' example_isolates %>% filter_aminoglycosides("R", "any")
|
||||
#'
|
||||
#' # filter on isolates that show resistance to ALL aminoglycosides
|
||||
#' example_isolates %>% filter_aminoglycosides("R", "all")
|
||||
#'
|
||||
#' # filter on isolates that show resistance to
|
||||
#' # any aminoglycoside and any fluoroquinolone
|
||||
#' example_isolates %>%
|
||||
#' filter_aminoglycosides("R") %>%
|
||||
#' filter_fluoroquinolones("R")
|
||||
#'
|
||||
#' # filter on isolates that show resistance to
|
||||
#' # all aminoglycosides and all fluoroquinolones
|
||||
#' example_isolates %>%
|
||||
#' filter_aminoglycosides("R", "all") %>%
|
||||
#' filter_fluoroquinolones("R", "all")
|
||||
#'
|
||||
#' # with dplyr 1.0.0 and higher (that adds 'across()'), this is equal:
|
||||
#' example_isolates %>% filter_carbapenems("R", "all")
|
||||
#' example_isolates %>% filter(across(carbapenems(), ~. == "R"))
|
||||
#' }
|
||||
filter_ab_class <- function(x,
|
||||
ab_class,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
|
||||
check_dataset_integrity()
|
||||
stop_ifnot(is.data.frame(x), "`x` must be a data frame")
|
||||
|
||||
# save to return later
|
||||
x_class <- class(x)
|
||||
x.bak <- x
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
|
||||
scope <- scope[1L]
|
||||
if (is.null(result)) {
|
||||
result <- c("S", "I", "R")
|
||||
}
|
||||
# make result = "SI" works too:
|
||||
result <- unlist(strsplit(result, ""))
|
||||
|
||||
stop_ifnot(all(result %in% c("S", "I", "R")), "`result` must be one or more of: 'S', 'I', 'R'")
|
||||
stop_ifnot(all(scope %in% c("any", "all")), "`scope` must be one of: 'any', 'all'")
|
||||
|
||||
# get all columns in data with names that resemble antibiotics
|
||||
ab_in_data <- suppressMessages(get_column_abx(x))
|
||||
if (length(ab_in_data) == 0) {
|
||||
message(font_blue("NOTE: no columns with class <rsi> found (see ?as.rsi), data left unchanged."))
|
||||
return(x.bak)
|
||||
}
|
||||
# get reference data
|
||||
ab_class.bak <- ab_class
|
||||
ab_class <- gsub("[^a-zA-Z0-9]+", ".*", ab_class)
|
||||
ab_class <- gsub("(ph|f)", "(ph|f)", ab_class)
|
||||
ab_class <- gsub("(t|th)", "(t|th)", ab_class)
|
||||
ab_reference <- subset(antibiotics,
|
||||
group %like% ab_class |
|
||||
atc_group1 %like% ab_class |
|
||||
atc_group2 %like% ab_class)
|
||||
ab_group <- find_ab_group(ab_class)
|
||||
if (ab_group == "") {
|
||||
message(font_blue(paste0("NOTE: unknown antimicrobial class '", ab_class.bak, "', data left unchanged.")))
|
||||
return(x.bak)
|
||||
}
|
||||
# get the columns with a group names in the chosen ab class
|
||||
agents <- ab_in_data[names(ab_in_data) %in% ab_reference$ab]
|
||||
if (length(agents) == 0) {
|
||||
message(font_blue(paste0("NOTE: no antimicrobial agents of class ", ab_group,
|
||||
" found (such as ", find_ab_names(ab_class, 2),
|
||||
"), data left unchanged.")))
|
||||
return(x.bak)
|
||||
}
|
||||
|
||||
if (length(result) == 1) {
|
||||
operator <- " is "
|
||||
} else {
|
||||
operator <- " is one of "
|
||||
}
|
||||
if (scope == "any") {
|
||||
scope_txt <- " or "
|
||||
scope_fn <- any
|
||||
} else {
|
||||
scope_txt <- " and "
|
||||
scope_fn <- all
|
||||
if (length(agents) > 1) {
|
||||
operator <- gsub("is", "are", operator)
|
||||
}
|
||||
}
|
||||
if (length(agents) > 1) {
|
||||
scope <- paste(scope, "of columns ")
|
||||
} else {
|
||||
scope <- "column "
|
||||
}
|
||||
|
||||
# sort columns on official name
|
||||
agents <- agents[order(ab_name(names(agents), language = NULL))]
|
||||
|
||||
message(font_blue(paste0("Filtering on ", ab_group, ": ", scope,
|
||||
paste(paste0("`", font_bold(agents, collapse = NULL),
|
||||
"` (", ab_name(names(agents), tolower = TRUE, language = NULL), ")"),
|
||||
collapse = scope_txt),
|
||||
operator, toString(result))))
|
||||
x_transposed <- as.list(as.data.frame(t(x[, agents, drop = FALSE])))
|
||||
filtered <- sapply(x_transposed, function(y) scope_fn(y %in% result, na.rm = TRUE))
|
||||
x <- x[which(filtered), , drop = FALSE]
|
||||
class(x) <- x_class
|
||||
x
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_aminoglycosides <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "aminoglycoside",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_carbapenems <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "carbapenem",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_cephalosporins <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "cephalosporin",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_1st_cephalosporins <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "cephalosporins (1st gen.)",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_2nd_cephalosporins <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "cephalosporins (2nd gen.)",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_3rd_cephalosporins <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "cephalosporins (3rd gen.)",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_4th_cephalosporins <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "cephalosporins (4th gen.)",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_5th_cephalosporins <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "cephalosporins (5th gen.)",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_fluoroquinolones <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "fluoroquinolone",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_glycopeptides <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "glycopeptide",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_macrolides <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "macrolide",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_penicillins <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "penicillin",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
#' @rdname filter_ab_class
|
||||
#' @export
|
||||
filter_tetracyclines <- function(x,
|
||||
result = NULL,
|
||||
scope = "any",
|
||||
...) {
|
||||
filter_ab_class(x = x,
|
||||
ab_class = "tetracycline",
|
||||
result = result,
|
||||
scope = scope,
|
||||
...)
|
||||
}
|
||||
|
||||
find_ab_group <- function(ab_class) {
|
||||
ab_class <- gsub("[^a-zA-Z0-9]", ".*", ab_class)
|
||||
ifelse(ab_class %in% c("aminoglycoside",
|
||||
"carbapenem",
|
||||
"cephalosporin",
|
||||
"fluoroquinolone",
|
||||
"glycopeptide",
|
||||
"macrolide",
|
||||
"tetracycline"),
|
||||
paste0(ab_class, "s"),
|
||||
antibiotics %>%
|
||||
subset(group %like% ab_class |
|
||||
atc_group1 %like% ab_class |
|
||||
atc_group2 %like% ab_class) %>%
|
||||
pull(group) %>%
|
||||
unique() %>%
|
||||
tolower() %>%
|
||||
sort() %>%
|
||||
paste(collapse = "/")
|
||||
)
|
||||
}
|
||||
|
||||
find_ab_names <- function(ab_group, n = 3) {
|
||||
ab_group <- gsub("[^a-zA-Z0-9]", ".*", ab_group)
|
||||
drugs <- antibiotics[which(antibiotics$group %like% ab_group & !antibiotics$ab %like% "[0-9]$"), ]$name
|
||||
paste0(sort(ab_name(sample(drugs, size = min(n, length(drugs)), replace = FALSE),
|
||||
tolower = TRUE, language = NULL)),
|
||||
collapse = ", ")
|
||||
}
|
||||
@@ -1,476 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Determine first (weighted) isolates
|
||||
#'
|
||||
#' Determine first (weighted) isolates of all microorganisms of every patient per episode and (if needed) per specimen type.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x a [`data.frame`] containing isolates.
|
||||
#' @param col_date column name of the result date (or date that is was received on the lab), defaults to the first column of with a date class
|
||||
#' @param col_patient_id column name of the unique IDs of the patients, defaults to the first column that starts with 'patient' or 'patid' (case insensitive)
|
||||
#' @param col_mo column name of the IDs of the microorganisms (see [as.mo()]), defaults to the first column of class [`mo`]. Values will be coerced using [as.mo()].
|
||||
#' @param col_testcode column name of the test codes. Use `col_testcode = NULL` to **not** exclude certain test codes (like test codes for screening). In that case `testcodes_exclude` will be ignored.
|
||||
#' @param col_specimen column name of the specimen type or group
|
||||
#' @param col_icu column name of the logicals (`TRUE`/`FALSE`) whether a ward or department is an Intensive Care Unit (ICU)
|
||||
#' @param col_keyantibiotics column name of the key antibiotics to determine first *weighted* isolates, see [key_antibiotics()]. Defaults to the first column that starts with 'key' followed by 'ab' or 'antibiotics' (case insensitive). Use `col_keyantibiotics = FALSE` to prevent this.
|
||||
#' @param episode_days episode in days after which a genus/species combination will be determined as 'first isolate' again. The default of 365 days is based on the guideline by CLSI, see Source.
|
||||
#' @param testcodes_exclude character vector with test codes that should be excluded (case-insensitive)
|
||||
#' @param icu_exclude logical whether ICU isolates should be excluded (rows with value `TRUE` in column `col_icu`)
|
||||
#' @param specimen_group value in column `col_specimen` to filter on
|
||||
#' @param type type to determine weighed isolates; can be `"keyantibiotics"` or `"points"`, see Details
|
||||
#' @param ignore_I logical to determine whether antibiotic interpretations with `"I"` will be ignored when `type = "keyantibiotics"`, see Details
|
||||
#' @param points_threshold points until the comparison of key antibiotics will lead to inclusion of an isolate when `type = "points"`, see Details
|
||||
#' @param info print progress
|
||||
#' @param include_unknown logical to determine whether 'unknown' microorganisms should be included too, i.e. microbial code `"UNKNOWN"`, which defaults to `FALSE`. For WHONET users, this means that all records with organism code `"con"` (*contamination*) will be excluded at default. Isolates with a microbial ID of `NA` will always be excluded as first isolate.
|
||||
#' @param ... parameters passed on to the [first_isolate()] function
|
||||
#' @details **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 [(ref)](https://www.ncbi.nlm.nih.gov/pubmed/17304462). 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 *S. aureus* isolates would be overestimated, because you included this MRSA more than once. It would be [selection bias](https://en.wikipedia.org/wiki/Selection_bias).
|
||||
#'
|
||||
#' All isolates with a microbial ID of `NA` will be excluded as first isolate.
|
||||
#'
|
||||
#' The functions [filter_first_isolate()] and [filter_first_weighted_isolate()] are helper functions to quickly filter on first isolates. The function [filter_first_isolate()] is essentially equal to one of:
|
||||
#' ```
|
||||
#' x %>% filter(first_isolate(., ...))
|
||||
#' ```
|
||||
#' The function [filter_first_weighted_isolate()] is essentially equal to:
|
||||
#' ```
|
||||
#' x %>%
|
||||
#' mutate(keyab = key_antibiotics(.)) %>%
|
||||
#' mutate(only_weighted_firsts = first_isolate(x,
|
||||
#' col_keyantibiotics = "keyab", ...)) %>%
|
||||
#' filter(only_weighted_firsts == TRUE) %>%
|
||||
#' select(-only_weighted_firsts, -keyab)
|
||||
#' ```
|
||||
#' @section Key antibiotics:
|
||||
#' There are two ways to determine whether isolates can be included as first *weighted* isolates which will give generally the same results:
|
||||
#'
|
||||
#' 1. Using `type = "keyantibiotics"` and parameter `ignore_I`
|
||||
#'
|
||||
#' Any difference from S to R (or vice versa) will (re)select an isolate as a first weighted isolate. With `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. Read more about this in the [key_antibiotics()] function.
|
||||
#'
|
||||
#' 2. Using `type = "points"` and parameter `points_threshold`
|
||||
#'
|
||||
#' 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 `points_threshold`, which default to `2`, an isolate will be (re)selected as a first weighted isolate.
|
||||
#' @rdname first_isolate
|
||||
#' @seealso [key_antibiotics()]
|
||||
#' @export
|
||||
#' @return A [`logical`] vector
|
||||
#' @source Methodology of this function is strictly based on:
|
||||
#'
|
||||
#' **M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 4th Edition**, 2014, *Clinical and Laboratory Standards Institute (CLSI)*. <https://clsi.org/standards/products/microbiology/documents/m39/>.
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' # `example_isolates` is a dataset available in the AMR package.
|
||||
#' # See ?example_isolates.
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' # Filter on first isolates:
|
||||
#' example_isolates %>%
|
||||
#' mutate(first_isolate = first_isolate(.)) %>%
|
||||
#' filter(first_isolate == TRUE)
|
||||
#'
|
||||
#' # Now let's see if first isolates matter:
|
||||
#' A <- example_isolates %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' summarise(count = n_rsi(GEN), # gentamicin availability
|
||||
#' resistance = resistance(GEN)) # gentamicin resistance
|
||||
#'
|
||||
#' B <- example_isolates %>%
|
||||
#' filter_first_weighted_isolate() %>% # the 1st isolate filter
|
||||
#' group_by(hospital_id) %>%
|
||||
#' summarise(count = n_rsi(GEN), # gentamicin availability
|
||||
#' resistance = resistance(GEN)) # gentamicin resistance
|
||||
#'
|
||||
#' # Have a look at A and B.
|
||||
#' # B is more reliable because every isolate is counted only once.
|
||||
#' # Gentamicin resistance in hospital D appears to be 3.7% higher than
|
||||
#' # when you (erroneously) would have used all isolates for analysis.
|
||||
#'
|
||||
#'
|
||||
#' ## OTHER EXAMPLES:
|
||||
#'
|
||||
#' # Short-hand versions:
|
||||
#' example_isolates %>%
|
||||
#' filter_first_isolate()
|
||||
#'
|
||||
#' example_isolates %>%
|
||||
#' filter_first_weighted_isolate()
|
||||
#'
|
||||
#'
|
||||
#' # set key antibiotics to a new variable
|
||||
#' x$keyab <- key_antibiotics(x)
|
||||
#'
|
||||
#' x$first_isolate <- first_isolate(x)
|
||||
#'
|
||||
#' x$first_isolate_weighed <- first_isolate(x, col_keyantibiotics = 'keyab')
|
||||
#'
|
||||
#' x$first_blood_isolate <- first_isolate(x, specimen_group = "Blood")
|
||||
#' }
|
||||
first_isolate <- function(x,
|
||||
col_date = NULL,
|
||||
col_patient_id = NULL,
|
||||
col_mo = NULL,
|
||||
col_testcode = NULL,
|
||||
col_specimen = NULL,
|
||||
col_icu = NULL,
|
||||
col_keyantibiotics = NULL,
|
||||
episode_days = 365,
|
||||
testcodes_exclude = NULL,
|
||||
icu_exclude = FALSE,
|
||||
specimen_group = NULL,
|
||||
type = "keyantibiotics",
|
||||
ignore_I = TRUE,
|
||||
points_threshold = 2,
|
||||
info = interactive(),
|
||||
include_unknown = FALSE,
|
||||
...) {
|
||||
|
||||
dots <- unlist(list(...))
|
||||
if (length(dots) != 0) {
|
||||
# backwards compatibility with old parameters
|
||||
dots.names <- dots %>% names()
|
||||
if ("filter_specimen" %in% dots.names) {
|
||||
specimen_group <- dots[which(dots.names == "filter_specimen")]
|
||||
}
|
||||
if ("tbl" %in% dots.names) {
|
||||
x <- dots[which(dots.names == "tbl")]
|
||||
}
|
||||
}
|
||||
|
||||
stop_ifnot(is.data.frame(x), "`x` must be a data.frame")
|
||||
stop_if(any(dim(x) == 0), "`x` must contain rows and columns")
|
||||
|
||||
# remove data.table, grouping from tibbles, etc.
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
|
||||
# try to find columns based on type
|
||||
# -- mo
|
||||
if (is.null(col_mo)) {
|
||||
col_mo <- search_type_in_df(x = x, type = "mo")
|
||||
stop_if(is.null(col_mo), "`col_mo` must be set")
|
||||
}
|
||||
|
||||
# -- date
|
||||
if (is.null(col_date)) {
|
||||
col_date <- search_type_in_df(x = x, type = "date")
|
||||
stop_if(is.null(col_date), "`col_date` must be set")
|
||||
}
|
||||
|
||||
# -- patient id
|
||||
if (is.null(col_patient_id)) {
|
||||
if (all(c("First name", "Last name", "Sex") %in% colnames(x))) {
|
||||
# WHONET support
|
||||
x$patient_id <- paste(x$`First name`, x$`Last name`, x$Sex)
|
||||
col_patient_id <- "patient_id"
|
||||
message(font_blue(paste0("NOTE: Using combined columns `", font_bold("First name"), "`, `", font_bold("Last name"), "` and `", font_bold("Sex"), "` as input for `col_patient_id`")))
|
||||
} else {
|
||||
col_patient_id <- search_type_in_df(x = x, type = "patient_id")
|
||||
}
|
||||
stop_if(is.null(col_patient_id), "`col_patient_id` must be set")
|
||||
}
|
||||
|
||||
# -- key antibiotics
|
||||
if (is.null(col_keyantibiotics)) {
|
||||
col_keyantibiotics <- search_type_in_df(x = x, type = "keyantibiotics")
|
||||
}
|
||||
if (isFALSE(col_keyantibiotics)) {
|
||||
col_keyantibiotics <- NULL
|
||||
}
|
||||
|
||||
# -- specimen
|
||||
if (is.null(col_specimen) & !is.null(specimen_group)) {
|
||||
col_specimen <- search_type_in_df(x = x, type = "specimen")
|
||||
}
|
||||
if (isFALSE(col_specimen)) {
|
||||
col_specimen <- NULL
|
||||
}
|
||||
|
||||
# check if columns exist
|
||||
check_columns_existance <- function(column, tblname = x) {
|
||||
if (!is.null(column)) {
|
||||
stop_ifnot(column %in% colnames(tblname),
|
||||
"Column `", column, "` not found.", call = FALSE)
|
||||
}
|
||||
}
|
||||
|
||||
check_columns_existance(col_date)
|
||||
check_columns_existance(col_patient_id)
|
||||
check_columns_existance(col_mo)
|
||||
check_columns_existance(col_testcode)
|
||||
check_columns_existance(col_icu)
|
||||
check_columns_existance(col_keyantibiotics)
|
||||
|
||||
# convert dates to Date
|
||||
dates <- as.Date(x[, col_date, drop = TRUE])
|
||||
dates[is.na(dates)] <- as.Date("1970-01-01")
|
||||
x[, col_date] <- dates
|
||||
|
||||
# create original row index
|
||||
x$newvar_row_index <- seq_len(nrow(x))
|
||||
x$newvar_mo <- x[, col_mo, drop = TRUE]
|
||||
x$newvar_genus_species <- paste(mo_genus(x$newvar_mo), mo_species(x$newvar_mo))
|
||||
x$newvar_date <- x[, col_date, drop = TRUE]
|
||||
x$newvar_patient_id <- x[, col_patient_id, drop = TRUE]
|
||||
|
||||
if (is.null(col_testcode)) {
|
||||
testcodes_exclude <- NULL
|
||||
}
|
||||
# remove testcodes
|
||||
if (!is.null(testcodes_exclude) & info == TRUE) {
|
||||
message(font_black(paste0("[Criterion] Exclude test codes: ", toString(paste0("'", testcodes_exclude, "'")))))
|
||||
}
|
||||
|
||||
if (is.null(col_specimen)) {
|
||||
specimen_group <- NULL
|
||||
}
|
||||
|
||||
# filter on specimen group and keyantibiotics when they are filled in
|
||||
if (!is.null(specimen_group)) {
|
||||
check_columns_existance(col_specimen, x)
|
||||
if (info == TRUE) {
|
||||
message(font_black(paste0("[Criterion] Exclude other than specimen group '", specimen_group, "'")))
|
||||
}
|
||||
}
|
||||
if (!is.null(col_keyantibiotics)) {
|
||||
x$newvar_key_ab <- x[, col_keyantibiotics, drop = TRUE]
|
||||
}
|
||||
|
||||
if (is.null(testcodes_exclude)) {
|
||||
testcodes_exclude <- ""
|
||||
}
|
||||
|
||||
# arrange data to the right sorting
|
||||
if (is.null(specimen_group)) {
|
||||
x <- x[order(x$newvar_patient_id,
|
||||
x$newvar_genus_species,
|
||||
x$newvar_date), ]
|
||||
rownames(x) <- NULL
|
||||
row.start <- 1
|
||||
row.end <- nrow(x)
|
||||
} else {
|
||||
# filtering on specimen and only analyse these rows to save time
|
||||
x <- x[order(pull(x, col_specimen),
|
||||
x$newvar_patient_id,
|
||||
x$newvar_genus_species,
|
||||
x$newvar_date), ]
|
||||
rownames(x) <- NULL
|
||||
suppressWarnings(
|
||||
row.start <- which(x %>% pull(col_specimen) == specimen_group) %>% min(na.rm = TRUE)
|
||||
)
|
||||
suppressWarnings(
|
||||
row.end <- which(x %>% pull(col_specimen) == specimen_group) %>% max(na.rm = TRUE)
|
||||
)
|
||||
}
|
||||
|
||||
# no isolates found
|
||||
if (abs(row.start) == Inf | abs(row.end) == Inf) {
|
||||
if (info == TRUE) {
|
||||
message(paste("=> Found", font_bold("no isolates")))
|
||||
}
|
||||
return(rep(FALSE, nrow(x)))
|
||||
}
|
||||
|
||||
# did find some isolates - add new index numbers of rows
|
||||
x$newvar_row_index_sorted <- seq_len(nrow(x))
|
||||
|
||||
scope.size <- nrow(x[which(x$newvar_row_index_sorted %in% c(row.start + 1:row.end) &
|
||||
!is.na(x$newvar_mo)), , drop = FALSE])
|
||||
|
||||
identify_new_year <- function(x, episode_days) {
|
||||
# I asked on StackOverflow:
|
||||
# https://stackoverflow.com/questions/42122245/filter-one-row-every-year
|
||||
if (length(x) == 1) {
|
||||
return(TRUE)
|
||||
}
|
||||
indices <- integer(0)
|
||||
start <- x[1]
|
||||
ind <- 1
|
||||
indices[ind] <- ind
|
||||
for (i in 2:length(x)) {
|
||||
if (isTRUE(as.numeric(x[i] - start) >= episode_days)) {
|
||||
ind <- ind + 1
|
||||
indices[ind] <- i
|
||||
start <- x[i]
|
||||
}
|
||||
}
|
||||
result <- rep(FALSE, length(x))
|
||||
result[indices] <- TRUE
|
||||
return(result)
|
||||
}
|
||||
|
||||
# Analysis of first isolate ----
|
||||
x$other_pat_or_mo <- ifelse(x$newvar_patient_id == lag(x$newvar_patient_id) &
|
||||
x$newvar_genus_species == lag(x$newvar_genus_species),
|
||||
FALSE,
|
||||
TRUE)
|
||||
x$episode_group <- paste(x$newvar_patient_id, x$newvar_genus_species)
|
||||
x$more_than_episode_ago <- unlist(lapply(unique(x$episode_group),
|
||||
function(g,
|
||||
df = x,
|
||||
days = episode_days) {
|
||||
identify_new_year(x = df[which(df$episode_group == g), "newvar_date", drop = TRUE],
|
||||
episode_days = days)
|
||||
}))
|
||||
|
||||
weighted.notice <- ""
|
||||
if (!is.null(col_keyantibiotics)) {
|
||||
weighted.notice <- "weighted "
|
||||
if (info == TRUE) {
|
||||
if (type == "keyantibiotics") {
|
||||
message(font_black(paste0("[Criterion] Base inclusion on key antibiotics, ",
|
||||
ifelse(ignore_I == FALSE, "not ", ""),
|
||||
"ignoring I")))
|
||||
}
|
||||
if (type == "points") {
|
||||
message(font_black(paste0("[Criterion] Base inclusion on key antibiotics, using points threshold of "
|
||||
, points_threshold)))
|
||||
}
|
||||
}
|
||||
type_param <- type
|
||||
|
||||
x$other_key_ab <- !key_antibiotics_equal(y = x$newvar_key_ab,
|
||||
z = lag(x$newvar_key_ab),
|
||||
type = type_param,
|
||||
ignore_I = ignore_I,
|
||||
points_threshold = points_threshold,
|
||||
info = info)
|
||||
# with key antibiotics
|
||||
x$newvar_first_isolate <- if_else(x$newvar_row_index_sorted >= row.start &
|
||||
x$newvar_row_index_sorted <= row.end &
|
||||
x$newvar_genus_species != "" &
|
||||
(x$other_pat_or_mo | x$more_than_episode_ago | x$other_key_ab),
|
||||
TRUE,
|
||||
FALSE)
|
||||
|
||||
} else {
|
||||
# no key antibiotics
|
||||
x$newvar_first_isolate <- if_else(x$newvar_row_index_sorted >= row.start &
|
||||
x$newvar_row_index_sorted <= row.end &
|
||||
x$newvar_genus_species != "" &
|
||||
(x$other_pat_or_mo | x$more_than_episode_ago),
|
||||
TRUE,
|
||||
FALSE)
|
||||
}
|
||||
|
||||
# first one as TRUE
|
||||
x[row.start, "newvar_first_isolate"] <- TRUE
|
||||
# no tests that should be included, or ICU
|
||||
if (!is.null(col_testcode)) {
|
||||
x[which(x[, col_testcode] %in% tolower(testcodes_exclude)), "newvar_first_isolate"] <- FALSE
|
||||
}
|
||||
if (!is.null(col_icu)) {
|
||||
if (icu_exclude == TRUE) {
|
||||
message(font_black("[Criterion] Exclude isolates from ICU.\n"))
|
||||
x[which(as.logical(x[, col_icu, drop = TRUE])), "newvar_first_isolate"] <- FALSE
|
||||
} else {
|
||||
message(font_black("[Criterion] Include isolates from ICU.\n"))
|
||||
}
|
||||
}
|
||||
|
||||
decimal.mark <- getOption("OutDec")
|
||||
big.mark <- ifelse(decimal.mark != ",", ",", ".")
|
||||
|
||||
# handle empty microorganisms
|
||||
if (any(x$newvar_mo == "UNKNOWN", na.rm = TRUE) & info == TRUE) {
|
||||
message(font_blue(paste0("NOTE: ", ifelse(include_unknown == TRUE, "Included ", "Excluded "),
|
||||
format(sum(x$newvar_mo == "UNKNOWN", na.rm = TRUE),
|
||||
decimal.mark = decimal.mark, big.mark = big.mark),
|
||||
" isolates with a microbial ID 'UNKNOWN' (column `", font_bold(col_mo), "`)")))
|
||||
}
|
||||
x[which(x$newvar_mo == "UNKNOWN"), "newvar_first_isolate"] <- include_unknown
|
||||
|
||||
# exclude all NAs
|
||||
if (any(is.na(x$newvar_mo)) & info == TRUE) {
|
||||
message(font_blue(paste0("NOTE: Excluded ", format(sum(is.na(x$newvar_mo), na.rm = TRUE),
|
||||
decimal.mark = decimal.mark, big.mark = big.mark),
|
||||
" isolates with a microbial ID 'NA' (column `", font_bold(col_mo), "`)")))
|
||||
}
|
||||
x[which(is.na(x$newvar_mo)), "newvar_first_isolate"] <- FALSE
|
||||
|
||||
# arrange back according to original sorting again
|
||||
x <- x[order(x$newvar_row_index), ]
|
||||
rownames(x) <- NULL
|
||||
|
||||
if (info == TRUE) {
|
||||
n_found <- base::sum(x$newvar_first_isolate, na.rm = TRUE)
|
||||
p_found_total <- percentage(n_found / nrow(x[which(!is.na(x$newvar_mo)), , drop = FALSE]))
|
||||
p_found_scope <- percentage(n_found / scope.size)
|
||||
# mark up number of found
|
||||
n_found <- base::format(n_found, big.mark = big.mark, decimal.mark = decimal.mark)
|
||||
if (p_found_total != p_found_scope) {
|
||||
msg_txt <- paste0("=> Found ",
|
||||
font_bold(paste0(n_found, " first ", weighted.notice, "isolates")),
|
||||
" (", p_found_scope, " within scope and ", p_found_total, " of total where a microbial ID was available)")
|
||||
} else {
|
||||
msg_txt <- paste0("=> Found ",
|
||||
font_bold(paste0(n_found, " first ", weighted.notice, "isolates")),
|
||||
" (", p_found_total, " of total where a microbial ID was available)")
|
||||
}
|
||||
message(font_black(msg_txt))
|
||||
}
|
||||
|
||||
x$newvar_first_isolate
|
||||
|
||||
}
|
||||
|
||||
#' @rdname first_isolate
|
||||
#' @export
|
||||
filter_first_isolate <- function(x,
|
||||
col_date = NULL,
|
||||
col_patient_id = NULL,
|
||||
col_mo = NULL,
|
||||
...) {
|
||||
subset(x, first_isolate(x = x,
|
||||
col_date = col_date,
|
||||
col_patient_id = col_patient_id,
|
||||
col_mo = col_mo,
|
||||
...))
|
||||
}
|
||||
|
||||
#' @rdname first_isolate
|
||||
#' @export
|
||||
filter_first_weighted_isolate <- function(x,
|
||||
col_date = NULL,
|
||||
col_patient_id = NULL,
|
||||
col_mo = NULL,
|
||||
col_keyantibiotics = NULL,
|
||||
...) {
|
||||
y <- x
|
||||
if (is.null(col_keyantibiotics)) {
|
||||
# first try to look for it
|
||||
col_keyantibiotics <- search_type_in_df(x = x, type = "keyantibiotics")
|
||||
# still NULL? Then create it since we are calling filter_first_WEIGHTED_isolate()
|
||||
if (is.null(col_keyantibiotics)) {
|
||||
y$keyab <- suppressMessages(key_antibiotics(x,
|
||||
col_mo = col_mo,
|
||||
...))
|
||||
col_keyantibiotics <- "keyab"
|
||||
}
|
||||
}
|
||||
|
||||
subset(x, first_isolate(x = y,
|
||||
col_date = col_date,
|
||||
col_patient_id = col_patient_id,
|
||||
col_mo = col_mo,
|
||||
col_keyantibiotics = col_keyantibiotics,
|
||||
...))
|
||||
}
|
||||
@@ -1,203 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' *G*-test for Count Data
|
||||
#'
|
||||
#' [g.test()] performs chi-squared contingency table tests and goodness-of-fit tests, just like [chisq.test()] but is more reliable (1). A *G*-test can be used to see whether the number of observations in each category fits a theoretical expectation (called a ***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 ***G*-test of independence**).
|
||||
#' @inheritSection lifecycle Questioning lifecycle
|
||||
#' @inherit stats::chisq.test params return
|
||||
#' @details If `x` is a matrix with one row or column, or if `x` is a vector and `y` is not given, then a *goodness-of-fit test* is performed (`x` is treated as a one-dimensional contingency table). The entries of `x` must be non-negative integers. In this case, the hypothesis tested is whether the population probabilities equal those in `p`, or are all equal if `p` is not given.
|
||||
#'
|
||||
#' If `x` is a matrix with at least two rows and columns, it is taken as a two-dimensional contingency table: the entries of `x` must be non-negative integers. Otherwise, `x` and `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 *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 `p`, each sample being of size `n = sum(x)`. This simulation is done in \R and may be slow.
|
||||
#'
|
||||
#' ## *G*-test of goodness-of-fit (likelihood ratio test)
|
||||
#' Use the *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 *G*-test may give inaccurate results, and you should use an exact test instead ([fisher.test()]).
|
||||
#'
|
||||
#' The *G*-test of goodness-of-fit is an alternative to the chi-square test of goodness-of-fit ([chisq.test()]); each of these tests has some advantages and some disadvantages, and the results of the two tests are usually very similar.
|
||||
#'
|
||||
#' ## *G*-test of independence
|
||||
#' Use the *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 *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 ([fisher.test()]) is an **exact** test, where the *G*-test is still only an **approximation**. For any 2x2 table, Fisher's Exact test may be slower but will still run in seconds, even if the sum of your observations is multiple millions.
|
||||
#'
|
||||
#' The *G*-test of independence is an alternative to the chi-square test of independence ([chisq.test()]), and they will give approximately the same results.
|
||||
#'
|
||||
#' ## How the test works
|
||||
#' Unlike the exact test of goodness-of-fit ([fisher.test()]), the *G*-test does not directly calculate the probability of obtaining the observed results or something more extreme. Instead, like almost all statistical tests, the *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 *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 *G*-statistic is:
|
||||
#'
|
||||
#' \eqn{G = 2 * sum(x * log(x / E))}
|
||||
#'
|
||||
#' where `E` are the expected values. Since this is chi-square distributed, the p value can be calculated in \R with:
|
||||
#' ```
|
||||
#' p <- stats::pchisq(G, df, lower.tail = FALSE)
|
||||
#' ```
|
||||
#' where `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 *G*-tests for each category, of course.
|
||||
#' @seealso [chisq.test()]
|
||||
#' @references 1. McDonald, J.H. 2014. **Handbook of Biological Statistics (3rd ed.)**. Sparky House Publishing, Baltimore, Maryland. <http://www.biostathandbook.com/gtestgof.html>.
|
||||
#' @source The code for this function is identical to that of [chisq.test()], except that:
|
||||
#' - The calculation of the statistic was changed to \eqn{2 * sum(x * log(x / E))}
|
||||
#' - Yates' continuity correction was removed as it does not apply to a *G*-test
|
||||
#' - The possibility to simulate p values with `simulate.p.value` was removed
|
||||
#' @export
|
||||
#' @importFrom stats pchisq complete.cases
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @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)
|
||||
#' 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 (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)
|
||||
# add fisher.test suggestion
|
||||
if (nr == 2 && nc == 2)
|
||||
warning("`fisher.test()` is always more reliable for 2x2 tables and although much slower, often only takes seconds.")
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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 due to E < 5")
|
||||
|
||||
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")
|
||||
}
|
||||
@@ -1,380 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' PCA biplot with `ggplot2`
|
||||
#'
|
||||
#' Produces a `ggplot2` variant of a so-called [biplot](https://en.wikipedia.org/wiki/Biplot) for PCA (principal component analysis), but is more flexible and more appealing than the base \R [biplot()] function.
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param x an object returned by [pca()], [prcomp()] or [princomp()]
|
||||
#' @inheritParams stats::biplot.prcomp
|
||||
#' @param labels an optional vector of labels for the observations. If set, the labels will be placed below their respective points. When using the [pca()] function as input for `x`, this will be determined automatically based on the attribute `non_numeric_cols`, see [pca()].
|
||||
#' @param labels_textsize the size of the text used for the labels
|
||||
#' @param labels_text_placement adjustment factor the placement of the variable names (`>=1` means further away from the arrow head)
|
||||
#' @param groups an optional vector of groups for the labels, with the same length as `labels`. If set, the points and labels will be coloured according to these groups. When using the [pca()] function as input for `x`, this will be determined automatically based on the attribute `non_numeric_cols`, see [pca()].
|
||||
#' @param ellipse a logical to indicate whether a normal data ellipse should be drawn for each group (set with `groups`)
|
||||
#' @param ellipse_prob statistical size of the ellipse in normal probability
|
||||
#' @param ellipse_size the size of the ellipse line
|
||||
#' @param ellipse_alpha the alpha (transparency) of the ellipse line
|
||||
#' @param points_size the size of the points
|
||||
#' @param points_alpha the alpha (transparency) of the points
|
||||
#' @param arrows a logical to indicate whether arrows should be drawn
|
||||
#' @param arrows_textsize the size of the text for variable names
|
||||
#' @param arrows_colour the colour of the arrow and their text
|
||||
#' @param arrows_size the size (thickness) of the arrow lines
|
||||
#' @param arrows_textsize the size of the text at the end of the arrows
|
||||
#' @param arrows_textangled a logical whether the text at the end of the arrows should be angled
|
||||
#' @param arrows_alpha the alpha (transparency) of the arrows and their text
|
||||
#' @param base_textsize the text size for all plot elements except the labels and arrows
|
||||
#' @param ... Parameters passed on to functions
|
||||
#' @source The [ggplot_pca()] function is based on the `ggbiplot()` function from the `ggbiplot` package by Vince Vu, as found on GitHub: <https://github.com/vqv/ggbiplot> (retrieved: 2 March 2020, their latest commit: [`7325e88`](https://github.com/vqv/ggbiplot/commit/7325e880485bea4c07465a0304c470608fffb5d9); 12 February 2015).
|
||||
#'
|
||||
#' As per their GPL-2 licence that demands documentation of code changes, the changes made based on the source code were:
|
||||
#' 1. Rewritten code to remove the dependency on packages `plyr`, `scales` and `grid`
|
||||
#' 2. Parametrised more options, like arrow and ellipse settings
|
||||
#' 3. Added total amount of explained variance as a caption in the plot
|
||||
#' 4. Cleaned all syntax based on the `lintr` package and added integrity checks
|
||||
#' 5. Updated documentation
|
||||
#' @details The colours for labels and points can be changed by adding another scale layer for colour, like `scale_colour_viridis_d()` or `scale_colour_brewer()`.
|
||||
#' @rdname ggplot_pca
|
||||
#' @export
|
||||
#' @examples
|
||||
#' # `example_isolates` is a dataset available in the AMR package.
|
||||
#' # See ?example_isolates.
|
||||
#'
|
||||
#' # See ?pca for more info about Principal Component Analysis (PCA).
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' pca_model <- example_isolates %>%
|
||||
#' filter(mo_genus(mo) == "Staphylococcus") %>%
|
||||
#' group_by(species = mo_shortname(mo)) %>%
|
||||
#' summarise_if (is.rsi, resistance) %>%
|
||||
#' pca(FLC, AMC, CXM, GEN, TOB, TMP, SXT, CIP, TEC, TCY, ERY)
|
||||
#'
|
||||
#' # old (base R)
|
||||
#' biplot(pca_model)
|
||||
#'
|
||||
#' # new
|
||||
#' ggplot_pca(pca_model)
|
||||
#'
|
||||
#' if (require("ggplot2")) {
|
||||
#' ggplot_pca(pca_model) +
|
||||
#' scale_colour_viridis_d() +
|
||||
#' labs(title = "Title here")
|
||||
#' }
|
||||
#' }
|
||||
ggplot_pca <- function(x,
|
||||
choices = 1:2,
|
||||
scale = TRUE,
|
||||
pc.biplot = TRUE,
|
||||
labels = NULL,
|
||||
labels_textsize = 3,
|
||||
labels_text_placement = 1.5,
|
||||
groups = NULL,
|
||||
ellipse = TRUE,
|
||||
ellipse_prob = 0.68,
|
||||
ellipse_size = 0.5,
|
||||
ellipse_alpha = 0.5,
|
||||
points_size = 2,
|
||||
points_alpha = 0.25,
|
||||
arrows = TRUE,
|
||||
arrows_colour = "darkblue",
|
||||
arrows_size = 0.5,
|
||||
arrows_textsize = 3,
|
||||
arrows_textangled = TRUE,
|
||||
arrows_alpha = 0.75,
|
||||
base_textsize = 10,
|
||||
...) {
|
||||
|
||||
stop_ifnot_installed("ggplot2")
|
||||
stop_ifnot(length(choices) == 2, "`choices` must be of length 2")
|
||||
stop_ifnot(is.logical(arrows), "`arrows` must be TRUE or FALSE")
|
||||
stop_ifnot(is.logical(arrows_textangled), "`arrows_textangled` must be TRUE or FALSE")
|
||||
stop_ifnot(is.logical(ellipse), "`ellipse` must be TRUE or FALSE")
|
||||
stop_ifnot(is.logical(pc.biplot), "`pc.biplot` must be TRUE or FALSE")
|
||||
stop_ifnot(is.logical(scale), "`scale` must be TRUE or FALSE")
|
||||
stop_ifnot(is.numeric(arrows_alpha), "`arrows_alpha` must be numeric")
|
||||
stop_ifnot(is.numeric(arrows_size), "`arrows_size` must be numeric")
|
||||
stop_ifnot(is.numeric(arrows_textsize), "`arrows_textsize` must be numeric")
|
||||
stop_ifnot(is.numeric(base_textsize), "`base_textsize` must be numeric")
|
||||
stop_ifnot(is.numeric(choices), "`choices` must be numeric")
|
||||
stop_ifnot(is.numeric(ellipse_alpha), "`ellipse_alpha` must be numeric")
|
||||
stop_ifnot(is.numeric(ellipse_prob), "`ellipse_prob` must be numeric")
|
||||
stop_ifnot(is.numeric(ellipse_size), "`ellipse_size` must be numeric")
|
||||
stop_ifnot(is.numeric(labels_text_placement), "`labels_text_placement` must be numeric")
|
||||
stop_ifnot(is.numeric(labels_textsize), "`labels_textsize` must be numeric")
|
||||
|
||||
calculations <- pca_calculations(pca_model = x,
|
||||
groups = groups,
|
||||
groups_missing = missing(groups),
|
||||
labels = labels,
|
||||
labels_missing = missing(labels),
|
||||
choices = choices,
|
||||
scale = scale,
|
||||
pc.biplot = pc.biplot,
|
||||
ellipse_prob = ellipse_prob,
|
||||
labels_text_placement = labels_text_placement)
|
||||
choices <- calculations$choices
|
||||
df.u <- calculations$df.u
|
||||
df.v <- calculations$df.v
|
||||
ell <- calculations$ell
|
||||
groups <- calculations$groups
|
||||
group_name <- calculations$group_name
|
||||
labels <- calculations$labels
|
||||
|
||||
# Append the proportion of explained variance to the axis labels
|
||||
if ((1 - as.integer(scale)) == 0) {
|
||||
u.axis.labs <- paste0("Standardised PC", choices)
|
||||
} else {
|
||||
u.axis.labs <- paste0("PC", choices)
|
||||
}
|
||||
u.axis.labs <- paste0(u.axis.labs,
|
||||
paste0("\n(explained var: ",
|
||||
percentage(x$sdev[choices] ^ 2 / sum(x$sdev ^ 2)),
|
||||
")"))
|
||||
|
||||
# Score Labels
|
||||
if (!is.null(labels)) {
|
||||
df.u$labels <- labels
|
||||
}
|
||||
|
||||
# Grouping variable
|
||||
if (!is.null(groups)) {
|
||||
df.u$groups <- groups
|
||||
}
|
||||
|
||||
# Base plot
|
||||
g <- ggplot2::ggplot(data = df.u,
|
||||
ggplot2::aes(x = xvar, y = yvar)) +
|
||||
ggplot2::xlab(u.axis.labs[1]) +
|
||||
ggplot2::ylab(u.axis.labs[2]) +
|
||||
ggplot2::expand_limits(x = c(-1.15, 1.15),
|
||||
y = c(-1.15, 1.15))
|
||||
|
||||
# Draw either labels or points
|
||||
if (!is.null(df.u$labels)) {
|
||||
if (!is.null(df.u$groups)) {
|
||||
g <- g + ggplot2::geom_point(ggplot2::aes(colour = groups),
|
||||
alpha = points_alpha,
|
||||
size = points_size) +
|
||||
ggplot2::geom_text(ggplot2::aes(label = labels, colour = groups),
|
||||
nudge_y = -0.05,
|
||||
size = labels_textsize) +
|
||||
ggplot2::labs(colour = group_name)
|
||||
} else {
|
||||
g <- g + ggplot2::geom_point(alpha = points_alpha,
|
||||
size = points_size) +
|
||||
ggplot2::geom_text(ggplot2::aes(label = labels),
|
||||
nudge_y = -0.05,
|
||||
size = labels_textsize)
|
||||
}
|
||||
} else {
|
||||
if (!is.null(df.u$groups)) {
|
||||
g <- g + ggplot2::geom_point(ggplot2::aes(colour = groups),
|
||||
alpha = points_alpha,
|
||||
size = points_size) +
|
||||
ggplot2::labs(colour = group_name)
|
||||
} else {
|
||||
g <- g + ggplot2::geom_point(alpha = points_alpha,
|
||||
size = points_size)
|
||||
}
|
||||
}
|
||||
|
||||
# Overlay a concentration ellipse if there are groups
|
||||
if (!is.null(df.u$groups) & !is.null(ell) & isTRUE(ellipse)) {
|
||||
g <- g + ggplot2::geom_path(data = ell,
|
||||
ggplot2::aes(colour = groups, group = groups),
|
||||
size = ellipse_size,
|
||||
alpha = points_alpha)
|
||||
}
|
||||
|
||||
# Label the variable axes
|
||||
if (arrows == TRUE) {
|
||||
g <- g + ggplot2::geom_segment(data = df.v,
|
||||
ggplot2::aes(x = 0, y = 0, xend = xvar, yend = yvar),
|
||||
arrow = ggplot2::arrow(length = ggplot2::unit(0.5, "picas"),
|
||||
angle = 20,
|
||||
ends = "last",
|
||||
type = "open"),
|
||||
colour = arrows_colour,
|
||||
size = arrows_size,
|
||||
alpha = arrows_alpha)
|
||||
if (arrows_textangled == TRUE) {
|
||||
g <- g + ggplot2::geom_text(data = df.v,
|
||||
ggplot2::aes(label = varname, x = xvar, y = yvar, angle = angle, hjust = hjust),
|
||||
colour = arrows_colour,
|
||||
size = arrows_textsize,
|
||||
alpha = arrows_alpha)
|
||||
} else {
|
||||
g <- g + ggplot2::geom_text(data = df.v,
|
||||
ggplot2::aes(label = varname, x = xvar, y = yvar, hjust = hjust),
|
||||
colour = arrows_colour,
|
||||
size = arrows_textsize,
|
||||
alpha = arrows_alpha)
|
||||
}
|
||||
}
|
||||
|
||||
# Add caption label about total explained variance
|
||||
g <- g + ggplot2::labs(caption = paste0("Total explained variance: ",
|
||||
percentage(sum(x$sdev[choices] ^ 2 / sum(x$sdev ^ 2)))))
|
||||
|
||||
# mark-up nicely
|
||||
g <- g + ggplot2::theme_minimal(base_size = base_textsize) +
|
||||
ggplot2::theme(panel.grid.major = ggplot2::element_line(colour = "grey85"),
|
||||
panel.grid.minor = ggplot2::element_blank(),
|
||||
# centre title and subtitle
|
||||
plot.title = ggplot2::element_text(hjust = 0.5),
|
||||
plot.subtitle = ggplot2::element_text(hjust = 0.5))
|
||||
|
||||
g
|
||||
}
|
||||
|
||||
#' @importFrom stats qchisq var
|
||||
pca_calculations <- function(pca_model,
|
||||
groups = NULL,
|
||||
groups_missing = TRUE,
|
||||
labels = NULL,
|
||||
labels_missing = TRUE,
|
||||
choices = 1:2,
|
||||
scale = 1,
|
||||
pc.biplot = TRUE,
|
||||
ellipse_prob = 0.68,
|
||||
labels_text_placement = 1.5) {
|
||||
|
||||
non_numeric_cols <- attributes(pca_model)$non_numeric_cols
|
||||
if (groups_missing) {
|
||||
groups <- tryCatch(non_numeric_cols[[1]],
|
||||
error = function(e) NULL)
|
||||
group_name <- tryCatch(colnames(non_numeric_cols[1]),
|
||||
error = function(e) NULL)
|
||||
}
|
||||
if (labels_missing) {
|
||||
labels <- tryCatch(non_numeric_cols[[2]],
|
||||
error = function(e) NULL)
|
||||
}
|
||||
if (!is.null(groups) & is.null(labels)) {
|
||||
# turn them around
|
||||
labels <- groups
|
||||
groups <- NULL
|
||||
group_name <- NULL
|
||||
}
|
||||
|
||||
# Recover the SVD
|
||||
if (inherits(pca_model, "prcomp")) {
|
||||
nobs.factor <- sqrt(nrow(pca_model$x) - 1)
|
||||
d <- pca_model$sdev
|
||||
u <- sweep(pca_model$x, 2, 1 / (d * nobs.factor), FUN = "*")
|
||||
v <- pca_model$rotation
|
||||
} else if (inherits(pca_model, "princomp")) {
|
||||
nobs.factor <- sqrt(pca_model$n.obs)
|
||||
d <- pca_model$sdev
|
||||
u <- sweep(pca_model$scores, 2, 1 / (d * nobs.factor), FUN = "*")
|
||||
v <- pca_model$loadings
|
||||
} else if (inherits(pca_model, "PCA")) {
|
||||
nobs.factor <- sqrt(nrow(pca_model$call$X))
|
||||
d <- unlist(sqrt(pca_model$eig)[1])
|
||||
u <- sweep(pca_model$ind$coord, 2, 1 / (d * nobs.factor), FUN = "*")
|
||||
v <- sweep(pca_model$var$coord, 2, sqrt(pca_model$eig[seq_len(ncol(pca_model$var$coord)), 1]), FUN = "/")
|
||||
} else if (inherits(pca_model, "lda")) {
|
||||
nobs.factor <- sqrt(pca_model$N)
|
||||
d <- pca_model$svd
|
||||
u <- predict(pca_model)$x / nobs.factor
|
||||
v <- pca_model$scaling
|
||||
d.total <- sum(d ^ 2)
|
||||
} else {
|
||||
stop("Expected a object of class prcomp, princomp, PCA, or lda")
|
||||
}
|
||||
|
||||
# Scores
|
||||
choices <- pmin(choices, ncol(u))
|
||||
obs.scale <- 1 - as.integer(scale)
|
||||
df.u <- as.data.frame(sweep(u[, choices], 2, d[choices] ^ obs.scale, FUN = "*"))
|
||||
|
||||
# Directions
|
||||
v <- sweep(v, 2, d ^ as.integer(scale), FUN = "*")
|
||||
df.v <- as.data.frame(v[, choices])
|
||||
|
||||
names(df.u) <- c("xvar", "yvar")
|
||||
names(df.v) <- names(df.u)
|
||||
|
||||
if (isTRUE(pc.biplot)) {
|
||||
df.u <- df.u * nobs.factor
|
||||
}
|
||||
|
||||
# Scale the radius of the correlation circle so that it corresponds to
|
||||
# a data ellipse for the standardized PC scores
|
||||
circle_prob <- 0.69
|
||||
r <- sqrt(qchisq(circle_prob, df = 2)) * prod(colMeans(df.u ^ 2)) ^ (0.25)
|
||||
|
||||
# Scale directions
|
||||
v.scale <- rowSums(v ^ 2)
|
||||
df.v <- r * df.v / sqrt(max(v.scale))
|
||||
|
||||
# Grouping variable
|
||||
if (!is.null(groups)) {
|
||||
df.u$groups <- groups
|
||||
}
|
||||
|
||||
df.v$varname <- rownames(v)
|
||||
|
||||
# Variables for text label placement
|
||||
df.v$angle <- with(df.v, (180 / pi) * atan(yvar / xvar))
|
||||
df.v$hjust <- with(df.v, (1 - labels_text_placement * sign(xvar)) / 2)
|
||||
|
||||
if (!is.null(df.u$groups)) {
|
||||
theta <- c(seq(-pi, pi, length = 50), seq(pi, -pi, length = 50))
|
||||
circle <- cbind(cos(theta), sin(theta))
|
||||
|
||||
df.groups <- lapply(unique(df.u$groups), function(g, df = df.u) {
|
||||
x <- df[which(df$groups == g), , drop = FALSE]
|
||||
if (nrow(x) <= 2) {
|
||||
return(data.frame(X1 = numeric(0),
|
||||
X2 = numeric(0),
|
||||
groups = character(0)))
|
||||
}
|
||||
sigma <- var(cbind(x$xvar, x$yvar))
|
||||
mu <- c(mean(x$xvar), mean(x$yvar))
|
||||
ed <- sqrt(qchisq(ellipse_prob, df = 2))
|
||||
data.frame(sweep(circle %*% chol(sigma) * ed,
|
||||
MARGIN = 2,
|
||||
STATS = mu,
|
||||
FUN = "+"),
|
||||
groups = x$groups[1],
|
||||
stringsAsFactors = FALSE)
|
||||
})
|
||||
ell <- do.call(rbind, df.groups)
|
||||
if (NROW(ell) == 0) {
|
||||
ell <- NULL
|
||||
} else {
|
||||
names(ell)[1:2] <- c("xvar", "yvar")
|
||||
}
|
||||
} else {
|
||||
ell <- NULL
|
||||
}
|
||||
|
||||
list(choices = choices,
|
||||
df.u = df.u,
|
||||
df.v = df.v,
|
||||
ell = ell,
|
||||
groups = groups,
|
||||
group_name = group_name,
|
||||
labels = labels
|
||||
)
|
||||
}
|
||||
@@ -1,400 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' AMR plots with `ggplot2`
|
||||
#'
|
||||
#' Use these functions to create bar plots for antimicrobial resistance analysis. All functions rely on [ggplot2][ggplot2::ggplot()] functions.
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param data a [`data.frame`] with column(s) of class [`rsi`] (see [as.rsi()])
|
||||
#' @param position position adjustment of bars, either `"fill"`, `"stack"` or `"dodge"`
|
||||
#' @param x variable to show on x axis, either `"antibiotic"` (default) or `"interpretation"` or a grouping variable
|
||||
#' @param fill variable to categorise using the plots legend, either `"antibiotic"` (default) or `"interpretation"` or a grouping variable
|
||||
#' @param breaks numeric vector of positions
|
||||
#' @param limits numeric vector of length two providing limits of the scale, use `NA` to refer to the existing minimum or maximum
|
||||
#' @param facet variable to split plots by, either `"interpretation"` (default) or `"antibiotic"` or a grouping variable
|
||||
#' @inheritParams proportion
|
||||
#' @param nrow (when using `facet`) number of rows
|
||||
#' @param colours a named vector with colours for the bars. The names must be one or more of: S, SI, I, IR, R or be `FALSE` to use default [ggplot2][[ggplot2::ggplot()] colours.
|
||||
#' @param datalabels show datalabels using [labels_rsi_count()]
|
||||
#' @param datalabels.size size of the datalabels
|
||||
#' @param datalabels.colour colour of the datalabels
|
||||
#' @param title text to show as title of the plot
|
||||
#' @param subtitle text to show as subtitle of the plot
|
||||
#' @param caption text to show as caption of the plot
|
||||
#' @param x.title text to show as x axis description
|
||||
#' @param y.title text to show as y axis description
|
||||
#' @param ... other parameters passed on to [geom_rsi()]
|
||||
#' @details At default, the names of antibiotics will be shown on the plots using [ab_name()]. This can be set with the `translate_ab` parameter. See [count_df()].
|
||||
#'
|
||||
#' ## The functions
|
||||
#' [geom_rsi()] will take any variable from the data that has an [`rsi`] class (created with [as.rsi()]) using [rsi_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.
|
||||
#'
|
||||
#' [facet_rsi()] creates 2d plots (at default based on S/I/R) using [ggplot2::facet_wrap()].
|
||||
#'
|
||||
#' [scale_y_percent()] transforms the y axis to a 0 to 100% range using [ggplot2::scale_y_continuous()].
|
||||
#'
|
||||
#' [scale_rsi_colours()] sets colours to the bars: pastel blue for S, pastel turquoise for I and pastel red for R, using [ggplot2::scale_fill_manual()].
|
||||
#'
|
||||
#' [theme_rsi()] is a [ggplot2 theme][[ggplot2::theme()] with minimal distraction.
|
||||
#'
|
||||
#' [labels_rsi_count()] print datalabels on the bars with percentage and amount of isolates using [ggplot2::geom_text()].
|
||||
#'
|
||||
#' [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 (`%>%`). See Examples.
|
||||
#' @rdname ggplot_rsi
|
||||
#' @export
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' if (require("ggplot2") & require("dplyr")) {
|
||||
#'
|
||||
#' # get antimicrobial results for drugs against a UTI:
|
||||
#' ggplot(example_isolates %>% select(AMX, NIT, FOS, TMP, CIP)) +
|
||||
#' geom_rsi()
|
||||
#'
|
||||
#' # prettify the plot using some additional functions:
|
||||
#' df <- example_isolates %>% select(AMX, NIT, FOS, TMP, CIP)
|
||||
#' ggplot(df) +
|
||||
#' geom_rsi() +
|
||||
#' scale_y_percent() +
|
||||
#' scale_rsi_colours() +
|
||||
#' labels_rsi_count() +
|
||||
#' theme_rsi()
|
||||
#'
|
||||
#' # or better yet, simplify this using the wrapper function - a single command:
|
||||
#' example_isolates %>%
|
||||
#' select(AMX, NIT, FOS, TMP, CIP) %>%
|
||||
#' ggplot_rsi()
|
||||
#'
|
||||
#' # get only proportions and no counts:
|
||||
#' example_isolates %>%
|
||||
#' select(AMX, NIT, FOS, TMP, CIP) %>%
|
||||
#' ggplot_rsi(datalabels = FALSE)
|
||||
#'
|
||||
#' # add other ggplot2 parameters as you like:
|
||||
#' example_isolates %>%
|
||||
#' select(AMX, NIT, FOS, TMP, CIP) %>%
|
||||
#' ggplot_rsi(width = 0.5,
|
||||
#' colour = "black",
|
||||
#' size = 1,
|
||||
#' linetype = 2,
|
||||
#' alpha = 0.25)
|
||||
#'
|
||||
#' example_isolates %>%
|
||||
#' select(AMX) %>%
|
||||
#' ggplot_rsi(colours = c(SI = "yellow"))
|
||||
#'
|
||||
#' }
|
||||
#'
|
||||
#' \dontrun{
|
||||
#'
|
||||
#' # resistance of ciprofloxacine per age group
|
||||
#' example_isolates %>%
|
||||
#' mutate(first_isolate = first_isolate(.)) %>%
|
||||
#' filter(first_isolate == TRUE,
|
||||
#' mo == as.mo("E. coli")) %>%
|
||||
#' # `age_group` is also a function of this package:
|
||||
#' group_by(age_group = age_groups(age)) %>%
|
||||
#' select(age_group,
|
||||
#' CIP) %>%
|
||||
#' ggplot_rsi(x = "age_group")
|
||||
#'
|
||||
#' # for colourblind mode, use divergent colours from the viridis package:
|
||||
#' example_isolates %>%
|
||||
#' select(AMX, NIT, FOS, TMP, CIP) %>%
|
||||
#' ggplot_rsi() + scale_fill_viridis_d()
|
||||
#' # a shorter version which also adjusts data label colours:
|
||||
#' example_isolates %>%
|
||||
#' select(AMX, NIT, FOS, TMP, CIP) %>%
|
||||
#' ggplot_rsi(colours = FALSE)
|
||||
#'
|
||||
#'
|
||||
#' # it also supports groups (don't forget to use the group var on `x` or `facet`):
|
||||
#' example_isolates %>%
|
||||
#' select(hospital_id, AMX, NIT, FOS, TMP, CIP) %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' ggplot_rsi(x = "hospital_id",
|
||||
#' facet = "antibiotic",
|
||||
#' nrow = 1,
|
||||
#' title = "AMR of Anti-UTI Drugs Per Hospital",
|
||||
#' x.title = "Hospital",
|
||||
#' datalabels = FALSE)
|
||||
#' }
|
||||
ggplot_rsi <- function(data,
|
||||
position = NULL,
|
||||
x = "antibiotic",
|
||||
fill = "interpretation",
|
||||
# params = list(),
|
||||
facet = NULL,
|
||||
breaks = seq(0, 1, 0.1),
|
||||
limits = NULL,
|
||||
translate_ab = "name",
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE,
|
||||
language = get_locale(),
|
||||
nrow = NULL,
|
||||
colours = c(S = "#61a8ff",
|
||||
SI = "#61a8ff",
|
||||
I = "#61f7ff",
|
||||
IR = "#ff6961",
|
||||
R = "#ff6961"),
|
||||
datalabels = TRUE,
|
||||
datalabels.size = 2.5,
|
||||
datalabels.colour = "gray15",
|
||||
title = NULL,
|
||||
subtitle = NULL,
|
||||
caption = NULL,
|
||||
x.title = "Antimicrobial",
|
||||
y.title = "Proportion",
|
||||
...) {
|
||||
|
||||
stop_ifnot_installed("ggplot2")
|
||||
|
||||
x <- x[1]
|
||||
facet <- facet[1]
|
||||
|
||||
# we work with aes_string later on
|
||||
x_deparse <- deparse(substitute(x))
|
||||
if (x_deparse != "x") {
|
||||
x <- x_deparse
|
||||
}
|
||||
if (x %like% '".*"') {
|
||||
x <- substr(x, 2, nchar(x) - 1)
|
||||
}
|
||||
facet_deparse <- deparse(substitute(facet))
|
||||
if (facet_deparse != "facet") {
|
||||
facet <- facet_deparse
|
||||
}
|
||||
if (facet %like% '".*"') {
|
||||
facet <- substr(facet, 2, nchar(facet) - 1)
|
||||
}
|
||||
if (facet %in% c("NULL", "")) {
|
||||
facet <- NULL
|
||||
}
|
||||
|
||||
if (is.null(position)) {
|
||||
position <- "fill"
|
||||
}
|
||||
|
||||
p <- ggplot2::ggplot(data = data) +
|
||||
geom_rsi(position = position, x = x, fill = fill, translate_ab = translate_ab,
|
||||
combine_SI = combine_SI, combine_IR = combine_IR, ...) +
|
||||
theme_rsi()
|
||||
|
||||
if (fill == "interpretation") {
|
||||
# set RSI colours
|
||||
if (isFALSE(colours) & missing(datalabels.colour)) {
|
||||
# set datalabel colour to middle gray
|
||||
datalabels.colour <- "gray50"
|
||||
}
|
||||
p <- p + scale_rsi_colours(colours = colours)
|
||||
}
|
||||
|
||||
if (identical(position, "fill")) {
|
||||
# proportions, so use y scale with percentage
|
||||
p <- p + scale_y_percent(breaks = breaks, limits = limits)
|
||||
}
|
||||
|
||||
if (datalabels == TRUE) {
|
||||
p <- p + labels_rsi_count(position = position,
|
||||
x = x,
|
||||
translate_ab = translate_ab,
|
||||
combine_SI = combine_SI,
|
||||
combine_IR = combine_IR,
|
||||
datalabels.size = datalabels.size,
|
||||
datalabels.colour = datalabels.colour)
|
||||
}
|
||||
|
||||
if (!is.null(facet)) {
|
||||
p <- p + facet_rsi(facet = facet, nrow = nrow)
|
||||
}
|
||||
|
||||
p <- p + ggplot2::labs(title = title,
|
||||
subtitle = subtitle,
|
||||
caption = caption,
|
||||
x = x.title,
|
||||
y = y.title)
|
||||
|
||||
p
|
||||
}
|
||||
|
||||
#' @rdname ggplot_rsi
|
||||
#' @export
|
||||
geom_rsi <- function(position = NULL,
|
||||
x = c("antibiotic", "interpretation"),
|
||||
fill = "interpretation",
|
||||
translate_ab = "name",
|
||||
language = get_locale(),
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE,
|
||||
...) {
|
||||
|
||||
stop_ifnot_installed("ggplot2")
|
||||
stop_if(is.data.frame(position), "`position` is invalid. Did you accidentally use '%>%' instead of '+'?")
|
||||
|
||||
y <- "value"
|
||||
if (missing(position) | is.null(position)) {
|
||||
position <- "fill"
|
||||
}
|
||||
|
||||
if (identical(position, "fill")) {
|
||||
position <- ggplot2::position_fill(vjust = 0.5, reverse = TRUE)
|
||||
}
|
||||
|
||||
x <- x[1]
|
||||
|
||||
# we work with aes_string later on
|
||||
x_deparse <- deparse(substitute(x))
|
||||
if (x_deparse != "x") {
|
||||
x <- x_deparse
|
||||
}
|
||||
if (x %like% '".*"') {
|
||||
x <- substr(x, 2, nchar(x) - 1)
|
||||
}
|
||||
|
||||
if (tolower(x) %in% tolower(c("ab", "abx", "antibiotics"))) {
|
||||
x <- "antibiotic"
|
||||
} else if (tolower(x) %in% tolower(c("SIR", "RSI", "interpretations", "result"))) {
|
||||
x <- "interpretation"
|
||||
}
|
||||
|
||||
ggplot2::layer(geom = "bar", stat = "identity", position = position,
|
||||
mapping = ggplot2::aes_string(x = x, y = y, fill = fill),
|
||||
params = list(...), data = function(x) {
|
||||
rsi_df(data = x,
|
||||
translate_ab = translate_ab,
|
||||
language = language,
|
||||
combine_SI = combine_SI,
|
||||
combine_IR = combine_IR)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
#' @rdname ggplot_rsi
|
||||
#' @export
|
||||
facet_rsi <- function(facet = c("interpretation", "antibiotic"), nrow = NULL) {
|
||||
|
||||
stop_ifnot_installed("ggplot2")
|
||||
|
||||
facet <- facet[1]
|
||||
|
||||
# we work with aes_string later on
|
||||
facet_deparse <- deparse(substitute(facet))
|
||||
if (facet_deparse != "facet") {
|
||||
facet <- facet_deparse
|
||||
}
|
||||
if (facet %like% '".*"') {
|
||||
facet <- substr(facet, 2, nchar(facet) - 1)
|
||||
}
|
||||
|
||||
if (tolower(facet) %in% tolower(c("SIR", "RSI", "interpretations", "result"))) {
|
||||
facet <- "interpretation"
|
||||
} else if (tolower(facet) %in% tolower(c("ab", "abx", "antibiotics"))) {
|
||||
facet <- "antibiotic"
|
||||
}
|
||||
|
||||
ggplot2::facet_wrap(facets = facet, scales = "free_x", nrow = nrow)
|
||||
}
|
||||
|
||||
#' @rdname ggplot_rsi
|
||||
#' @export
|
||||
scale_y_percent <- function(breaks = seq(0, 1, 0.1), limits = NULL) {
|
||||
stop_ifnot_installed("ggplot2")
|
||||
|
||||
if (all(breaks[breaks != 0] > 1)) {
|
||||
breaks <- breaks / 100
|
||||
}
|
||||
ggplot2::scale_y_continuous(breaks = breaks,
|
||||
labels = percentage(breaks),
|
||||
limits = limits)
|
||||
}
|
||||
|
||||
#' @rdname ggplot_rsi
|
||||
#' @export
|
||||
scale_rsi_colours <- function(colours = c(S = "#61a8ff",
|
||||
SI = "#61a8ff",
|
||||
I = "#61f7ff",
|
||||
IR = "#ff6961",
|
||||
R = "#ff6961")) {
|
||||
stop_ifnot_installed("ggplot2")
|
||||
# previous colour: palette = "RdYlGn"
|
||||
# previous colours: values = c("#b22222", "#ae9c20", "#7cfc00")
|
||||
|
||||
if (!identical(colours, FALSE)) {
|
||||
original_cols <- c(S = "#61a8ff",
|
||||
SI = "#61a8ff",
|
||||
I = "#61f7ff",
|
||||
IR = "#ff6961",
|
||||
R = "#ff6961")
|
||||
colours <- replace(original_cols, names(colours), colours)
|
||||
ggplot2::scale_fill_manual(values = colours)
|
||||
}
|
||||
}
|
||||
|
||||
#' @rdname ggplot_rsi
|
||||
#' @export
|
||||
theme_rsi <- function() {
|
||||
stop_ifnot_installed("ggplot2")
|
||||
ggplot2::theme_minimal(base_size = 10) +
|
||||
ggplot2::theme(panel.grid.major.x = ggplot2::element_blank(),
|
||||
panel.grid.minor = ggplot2::element_blank(),
|
||||
panel.grid.major.y = ggplot2::element_line(colour = "grey75"),
|
||||
# center title and subtitle
|
||||
plot.title = ggplot2::element_text(hjust = 0.5),
|
||||
plot.subtitle = ggplot2::element_text(hjust = 0.5))
|
||||
}
|
||||
|
||||
#' @rdname ggplot_rsi
|
||||
#' @export
|
||||
labels_rsi_count <- function(position = NULL,
|
||||
x = "antibiotic",
|
||||
translate_ab = "name",
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE,
|
||||
datalabels.size = 3,
|
||||
datalabels.colour = "gray15") {
|
||||
stop_ifnot_installed("ggplot2")
|
||||
if (is.null(position)) {
|
||||
position <- "fill"
|
||||
}
|
||||
if (identical(position, "fill")) {
|
||||
position <- ggplot2::position_fill(vjust = 0.5, reverse = TRUE)
|
||||
}
|
||||
x_name <- x
|
||||
ggplot2::geom_text(mapping = ggplot2::aes_string(label = "lbl",
|
||||
x = x,
|
||||
y = "value"),
|
||||
position = position,
|
||||
inherit.aes = FALSE,
|
||||
size = datalabels.size,
|
||||
colour = datalabels.colour,
|
||||
lineheight = 0.75,
|
||||
data = function(x) {
|
||||
transformed <- rsi_df(data = x,
|
||||
translate_ab = translate_ab,
|
||||
combine_SI = combine_SI,
|
||||
combine_IR = combine_IR)
|
||||
transformed$gr <- transformed[, x_name, drop = TRUE]
|
||||
transformed %>%
|
||||
group_by(gr) %>%
|
||||
mutate(lbl = paste0("n=", isolates)) %>%
|
||||
ungroup() %>%
|
||||
select(-gr)
|
||||
})
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
globalVariables(c("ab",
|
||||
"ab_txt",
|
||||
"angle",
|
||||
"antibiotics",
|
||||
"atc_group1",
|
||||
"atc_group2",
|
||||
"code",
|
||||
"data",
|
||||
"fullname",
|
||||
"fullname_lower",
|
||||
"g_species",
|
||||
"genus",
|
||||
"gr",
|
||||
"group",
|
||||
"hjust",
|
||||
"input",
|
||||
"isolates",
|
||||
"lang",
|
||||
"lookup",
|
||||
"microorganisms",
|
||||
"microorganisms.codes",
|
||||
"microorganisms.old",
|
||||
"mo",
|
||||
"name",
|
||||
"new",
|
||||
"observations",
|
||||
"old",
|
||||
"old_name",
|
||||
"pattern",
|
||||
"R",
|
||||
"rsi_translation",
|
||||
"rule_group",
|
||||
"rule_name",
|
||||
"se_max",
|
||||
"se_min",
|
||||
"species",
|
||||
"species_id",
|
||||
"total",
|
||||
"txt",
|
||||
"value",
|
||||
"varname",
|
||||
"xvar",
|
||||
"year",
|
||||
"yvar"))
|
||||
@@ -1,233 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Guess antibiotic column
|
||||
#'
|
||||
#' This tries to find a column name in a data set based on information from the [antibiotics] data set. Also supports WHONET abbreviations.
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param x a [`data.frame`]
|
||||
#' @param search_string a text to search `x` for, will be checked with [as.ab()] if this value is not a column in `x`
|
||||
#' @param verbose a logical to indicate whether additional info should be printed
|
||||
#' @details You can look for an antibiotic (trade) name or abbreviation and it will search `x` and the [antibiotics] data set for any column containing a name or code of that antibiotic. **Longer columns names take precendence over shorter column names.**
|
||||
#' @return A column name of `x`, or `NULL` when no result is found.
|
||||
#' @export
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' df <- data.frame(amox = "S",
|
||||
#' tetr = "R")
|
||||
#'
|
||||
#' guess_ab_col(df, "amoxicillin")
|
||||
#' # [1] "amox"
|
||||
#' guess_ab_col(df, "J01AA07") # ATC code of tetracycline
|
||||
#' # [1] "tetr"
|
||||
#'
|
||||
#' guess_ab_col(df, "J01AA07", verbose = TRUE)
|
||||
#' # NOTE: Using column `tetr` as input for `J01AA07` (tetracycline).
|
||||
#' # [1] "tetr"
|
||||
#'
|
||||
#' # WHONET codes
|
||||
#' df <- data.frame(AMP_ND10 = "R",
|
||||
#' AMC_ED20 = "S")
|
||||
#' guess_ab_col(df, "ampicillin")
|
||||
#' # [1] "AMP_ND10"
|
||||
#' guess_ab_col(df, "J01CR02")
|
||||
#' # [1] "AMC_ED20"
|
||||
#' guess_ab_col(df, as.ab("augmentin"))
|
||||
#' # [1] "AMC_ED20"
|
||||
#'
|
||||
#' # Longer names take precendence:
|
||||
#' df <- data.frame(AMP_ED2 = "S",
|
||||
#' AMP_ED20 = "S")
|
||||
#' guess_ab_col(df, "ampicillin")
|
||||
#' # [1] "AMP_ED20"
|
||||
guess_ab_col <- function(x = NULL, search_string = NULL, verbose = FALSE) {
|
||||
if (is.null(x) & is.null(search_string)) {
|
||||
return(as.name("guess_ab_col"))
|
||||
}
|
||||
stop_ifnot(is.data.frame(x), "`x` must be a data.frame")
|
||||
|
||||
if (length(search_string) > 1) {
|
||||
warning("argument 'search_string' has length > 1 and only the first element will be used")
|
||||
search_string <- search_string[1]
|
||||
}
|
||||
search_string <- as.character(search_string)
|
||||
|
||||
if (search_string %in% colnames(x)) {
|
||||
ab_result <- search_string
|
||||
} else {
|
||||
search_string.ab <- suppressWarnings(as.ab(search_string))
|
||||
if (search_string.ab %in% colnames(x)) {
|
||||
ab_result <- colnames(x)[colnames(x) == search_string.ab][1L]
|
||||
|
||||
} else if (any(tolower(colnames(x)) %in% tolower(unlist(ab_property(search_string.ab, "abbreviations", language = NULL))))) {
|
||||
ab_result <- colnames(x)[tolower(colnames(x)) %in% tolower(unlist(ab_property(search_string.ab, "abbreviations", language = NULL)))][1L]
|
||||
|
||||
} else {
|
||||
# sort colnames on length - longest first
|
||||
cols <- colnames(x[, x %>% colnames() %>% nchar() %>% order() %>% rev()])
|
||||
df_trans <- data.frame(cols = cols,
|
||||
abs = suppressWarnings(as.ab(cols)),
|
||||
stringsAsFactors = FALSE)
|
||||
ab_result <- df_trans[which(df_trans$abs == search_string.ab), "cols"]
|
||||
ab_result <- ab_result[!is.na(ab_result)][1L]
|
||||
}
|
||||
}
|
||||
|
||||
if (length(ab_result) == 0) {
|
||||
if (verbose == TRUE) {
|
||||
message(paste0("No column found as input for `", search_string,
|
||||
"` (", ab_name(search_string, language = NULL, tolower = TRUE), ")."))
|
||||
}
|
||||
return(NULL)
|
||||
} else {
|
||||
if (verbose == TRUE) {
|
||||
message(font_blue(paste0("NOTE: Using column `", font_bold(ab_result), "` as input for `", search_string,
|
||||
"` (", ab_name(search_string, language = NULL, tolower = TRUE), ").")))
|
||||
}
|
||||
return(ab_result)
|
||||
}
|
||||
}
|
||||
|
||||
get_column_abx <- function(x,
|
||||
soft_dependencies = NULL,
|
||||
hard_dependencies = NULL,
|
||||
verbose = FALSE,
|
||||
...) {
|
||||
|
||||
message(font_blue("NOTE: Auto-guessing columns suitable for analysis"), appendLF = FALSE)
|
||||
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
if (NROW(x) > 10000) {
|
||||
# only test maximum of 10,000 values per column
|
||||
message(font_blue(paste0(" (using only ", font_bold("the first 10,000 rows"), ")...")), appendLF = FALSE)
|
||||
x <- x[1:10000, , drop = FALSE]
|
||||
} else {
|
||||
message(font_blue("..."), appendLF = FALSE)
|
||||
}
|
||||
x_bak <- x
|
||||
# only check columns that are a valid AB code, ATC code, name, abbreviation or synonym,
|
||||
# or already have the rsi class (as.rsi)
|
||||
# and that have no more than 50% invalid values
|
||||
vectr_antibiotics <- unique(toupper(unlist(antibiotics[, c("ab", "atc", "name", "abbreviations", "synonyms")])))
|
||||
vectr_antibiotics <- vectr_antibiotics[!is.na(vectr_antibiotics) & nchar(vectr_antibiotics) >= 3]
|
||||
x_columns <- sapply(colnames(x), function(col, df = x_bak) {
|
||||
if (toupper(col) %in% vectr_antibiotics |
|
||||
is.rsi(as.data.frame(df)[, col]) |
|
||||
is.rsi.eligible(as.data.frame(df)[, col], threshold = 0.5)) {
|
||||
return(col)
|
||||
} else {
|
||||
return(NA_character_)
|
||||
}
|
||||
})
|
||||
x_columns <- x_columns[!is.na(x_columns)]
|
||||
x <- x[, x_columns, drop = FALSE] # without drop = TRUE, x will become a vector when x_columns is length 1
|
||||
|
||||
df_trans <- data.frame(colnames = colnames(x),
|
||||
abcode = suppressWarnings(as.ab(colnames(x))))
|
||||
df_trans <- df_trans[!is.na(df_trans$abcode), ]
|
||||
x <- as.character(df_trans$colnames)
|
||||
names(x) <- df_trans$abcode
|
||||
|
||||
# add from self-defined dots (...):
|
||||
# such as get_column_abx(example_isolates %>% rename(thisone = AMX), amox = "thisone")
|
||||
dots <- list(...)
|
||||
if (length(dots) > 0) {
|
||||
newnames <- suppressWarnings(as.ab(names(dots)))
|
||||
if (any(is.na(newnames))) {
|
||||
warning("Invalid antibiotic reference(s): ", toString(names(dots)[is.na(newnames)]),
|
||||
call. = FALSE, immediate. = TRUE)
|
||||
}
|
||||
# turn all NULLs to NAs
|
||||
dots <- unlist(lapply(dots, function(x) if (is.null(x)) NA else x))
|
||||
names(dots) <- newnames
|
||||
dots <- dots[!is.na(names(dots))]
|
||||
# merge, but overwrite automatically determined ones by 'dots'
|
||||
x <- c(x[!x %in% dots & !names(x) %in% names(dots)], dots)
|
||||
# delete NAs, this will make e.g. eucast_rules(... TMP = NULL) work to prevent TMP from being used
|
||||
x <- x[!is.na(x)]
|
||||
}
|
||||
|
||||
if (length(x) == 0) {
|
||||
message(font_blue("No columns found."))
|
||||
return(x)
|
||||
}
|
||||
|
||||
# sort on name
|
||||
x <- x[order(names(x), x)]
|
||||
duplicates <- c(x[base::duplicated(x)], x[base::duplicated(names(x))])
|
||||
duplicates <- duplicates[unique(names(duplicates))]
|
||||
x <- c(x[!names(x) %in% names(duplicates)], duplicates)
|
||||
x <- x[order(names(x), x)]
|
||||
|
||||
# succeeded with auto-guessing
|
||||
message(font_blue("OK."))
|
||||
|
||||
for (i in seq_len(length(x))) {
|
||||
if (verbose == TRUE & !names(x[i]) %in% names(duplicates)) {
|
||||
message(font_blue(paste0("NOTE: Using column `", font_bold(x[i]), "` as input for `", names(x)[i],
|
||||
"` (", ab_name(names(x)[i], tolower = TRUE, language = NULL), ").")))
|
||||
}
|
||||
if (names(x[i]) %in% names(duplicates)) {
|
||||
warning(font_red(paste0("Using column `", font_bold(x[i]), "` as input for `", names(x)[i],
|
||||
"` (", ab_name(names(x)[i], tolower = TRUE, language = NULL),
|
||||
"), although it was matched for multiple antibiotics or columns.")),
|
||||
call. = FALSE,
|
||||
immediate. = verbose)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!is.null(hard_dependencies)) {
|
||||
hard_dependencies <- unique(hard_dependencies)
|
||||
if (!all(hard_dependencies %in% names(x))) {
|
||||
# missing a hard dependency will return NA and consequently the data will not be analysed
|
||||
missing <- hard_dependencies[!hard_dependencies %in% names(x)]
|
||||
generate_warning_abs_missing(missing, any = FALSE)
|
||||
return(NA)
|
||||
}
|
||||
}
|
||||
if (!is.null(soft_dependencies)) {
|
||||
soft_dependencies <- unique(soft_dependencies)
|
||||
if (!all(soft_dependencies %in% names(x))) {
|
||||
# missing a soft dependency may lower the reliability
|
||||
missing <- soft_dependencies[!soft_dependencies %in% names(x)]
|
||||
missing_txt <- paste(paste0(ab_name(missing, tolower = TRUE, language = NULL),
|
||||
" (", font_bold(missing, collapse = NULL), ")"),
|
||||
collapse = ", ")
|
||||
message(font_blue("NOTE: Reliability would be improved if these antimicrobial results would be available too:",
|
||||
missing_txt))
|
||||
}
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
generate_warning_abs_missing <- function(missing, any = FALSE) {
|
||||
missing <- paste0(missing, " (", ab_name(missing, tolower = TRUE, language = NULL), ")")
|
||||
if (any == TRUE) {
|
||||
any_txt <- c(" any of", "is")
|
||||
} else {
|
||||
any_txt <- c("", "are")
|
||||
}
|
||||
warning(paste0("Introducing NAs since", any_txt[1], " these antimicrobials ", any_txt[2], " required: ",
|
||||
paste(missing, collapse = ", ")),
|
||||
immediate. = TRUE,
|
||||
call. = FALSE)
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Join [microorganisms] to a data set
|
||||
#'
|
||||
#' Join the data set [microorganisms] easily to an existing table or character vector.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @rdname join
|
||||
#' @name join
|
||||
#' @aliases join inner_join
|
||||
#' @param x existing table to join, or character vector
|
||||
#' @param by a variable to join by - if left empty will search for a column with class [`mo`] (created with [as.mo()]) or will be `"mo"` if that column name exists in `x`, could otherwise be a column name of `x` with values that exist in `microorganisms$mo` (like `by = "bacteria_id"`), or another column in [microorganisms] (but then it should be named, like `by = c("my_genus_species" = "fullname")`)
|
||||
#' @param suffix if there are non-joined duplicate variables in `x` and `y`, these suffixes will be added to the output to disambiguate them. Should be a character vector of length 2.
|
||||
#' @param ... ignored
|
||||
#' @details **Note:** As opposed to the `join()` functions of `dplyr`, [`character`] vectors are supported and at default existing columns will get a suffix `"2"` and the newly joined columns will not get a suffix.
|
||||
#'
|
||||
#' These functions rely on [merge()], a base R function to do joins.
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
#' @examples
|
||||
#' left_join_microorganisms(as.mo("K. pneumoniae"))
|
||||
#' left_join_microorganisms("B_KLBSL_PNE")
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' example_isolates %>% left_join_microorganisms()
|
||||
#'
|
||||
#' df <- data.frame(date = seq(from = as.Date("2018-01-01"),
|
||||
#' to = as.Date("2018-01-07"),
|
||||
#' by = 1),
|
||||
#' bacteria = as.mo(c("S. aureus", "MRSA", "MSSA", "STAAUR",
|
||||
#' "E. coli", "E. coli", "E. coli")),
|
||||
#' stringsAsFactors = FALSE)
|
||||
#' colnames(df)
|
||||
#' df_joined <- left_join_microorganisms(df, "bacteria")
|
||||
#' colnames(df_joined)
|
||||
#' }
|
||||
inner_join_microorganisms <- function(x, by = NULL, suffix = c("2", ""), ...) {
|
||||
check_dataset_integrity()
|
||||
check_groups_before_join(x, "inner_join_microorganisms")
|
||||
checked <- joins_check_df(x, by)
|
||||
x_class <- get_prejoined_class(x)
|
||||
x <- checked$x
|
||||
by <- checked$by
|
||||
join <- suppressWarnings(
|
||||
inner_join(x = x, y = microorganisms, by = by, suffix = suffix, ...)
|
||||
)
|
||||
if (NROW(join) > NROW(x)) {
|
||||
warning("The newly joined tbl contains ", nrow(join) - nrow(x), " rows more that its original.")
|
||||
}
|
||||
class(join) <- x_class
|
||||
join
|
||||
}
|
||||
|
||||
#' @rdname join
|
||||
#' @export
|
||||
left_join_microorganisms <- function(x, by = NULL, suffix = c("2", ""), ...) {
|
||||
check_dataset_integrity()
|
||||
check_groups_before_join(x, "left_join_microorganisms")
|
||||
checked <- joins_check_df(x, by)
|
||||
x_class <- get_prejoined_class(x)
|
||||
x <- checked$x
|
||||
by <- checked$by
|
||||
join <- suppressWarnings(
|
||||
left_join(x = x, y = microorganisms, by = by, suffix = suffix, ...)
|
||||
)
|
||||
if (NROW(join) > NROW(x)) {
|
||||
warning("The newly joined tbl contains ", nrow(join) - nrow(x), " rows more that its original.")
|
||||
}
|
||||
class(join) <- x_class
|
||||
join
|
||||
}
|
||||
|
||||
#' @rdname join
|
||||
#' @export
|
||||
right_join_microorganisms <- function(x, by = NULL, suffix = c("2", ""), ...) {
|
||||
check_dataset_integrity()
|
||||
check_groups_before_join(x, "right_join_microorganisms")
|
||||
checked <- joins_check_df(x, by)
|
||||
x_class <- get_prejoined_class(x)
|
||||
x <- checked$x
|
||||
by <- checked$by
|
||||
join <- suppressWarnings(
|
||||
right_join(x = x, y = microorganisms, by = by, suffix = suffix, ...)
|
||||
)
|
||||
if (NROW(join) > NROW(x)) {
|
||||
warning("The newly joined tbl contains ", nrow(join) - nrow(x), " rows more that its original.")
|
||||
}
|
||||
class(join) <- x_class
|
||||
join
|
||||
}
|
||||
|
||||
#' @rdname join
|
||||
#' @export
|
||||
full_join_microorganisms <- function(x, by = NULL, suffix = c("2", ""), ...) {
|
||||
check_dataset_integrity()
|
||||
check_groups_before_join(x, "full_join_microorganisms")
|
||||
checked <- joins_check_df(x, by)
|
||||
x_class <- get_prejoined_class(x)
|
||||
x <- checked$x
|
||||
by <- checked$by
|
||||
join <- suppressWarnings(
|
||||
full_join(x = x, y = microorganisms, by = by, suffix = suffix, ...)
|
||||
)
|
||||
if (NROW(join) > NROW(x)) {
|
||||
warning("The newly joined tbl contains ", nrow(join) - nrow(x), " rows more that its original.")
|
||||
}
|
||||
class(join) <- x_class
|
||||
join
|
||||
}
|
||||
|
||||
#' @rdname join
|
||||
#' @export
|
||||
semi_join_microorganisms <- function(x, by = NULL, ...) {
|
||||
check_dataset_integrity()
|
||||
check_groups_before_join(x, "semi_join_microorganisms")
|
||||
x_class <- get_prejoined_class(x)
|
||||
checked <- joins_check_df(x, by)
|
||||
x <- checked$x
|
||||
by <- checked$by
|
||||
join <- suppressWarnings(
|
||||
semi_join(x = x, y = microorganisms, by = by, ...)
|
||||
)
|
||||
class(join) <- x_class
|
||||
join
|
||||
}
|
||||
|
||||
#' @rdname join
|
||||
#' @export
|
||||
anti_join_microorganisms <- function(x, by = NULL, ...) {
|
||||
check_dataset_integrity()
|
||||
check_groups_before_join(x, "anti_join_microorganisms")
|
||||
checked <- joins_check_df(x, by)
|
||||
x_class <- get_prejoined_class(x)
|
||||
x <- checked$x
|
||||
by <- checked$by
|
||||
join <- suppressWarnings(
|
||||
anti_join(x = x, y = microorganisms, by = by, ...)
|
||||
)
|
||||
class(join) <- x_class
|
||||
join
|
||||
}
|
||||
|
||||
joins_check_df <- function(x, by) {
|
||||
if (!any(class(x) %in% c("data.frame", "matrix"))) {
|
||||
x <- data.frame(mo = as.mo(x), stringsAsFactors = FALSE)
|
||||
if (is.null(by)) {
|
||||
by <- "mo"
|
||||
}
|
||||
}
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
if (is.null(by)) {
|
||||
# search for column with class `mo` and return first one found
|
||||
by <- colnames(x)[lapply(x, is.mo) == TRUE][1]
|
||||
if (is.na(by)) {
|
||||
if ("mo" %in% colnames(x)) {
|
||||
by <- "mo"
|
||||
x[, "mo"] <- as.mo(x[, "mo"])
|
||||
} else {
|
||||
stop("Cannot join - no column found with name 'mo' or with class <mo>.", call. = FALSE)
|
||||
}
|
||||
}
|
||||
message('Joining, by = "', by, '"') # message same as dplyr::join functions
|
||||
}
|
||||
if (is.null(names(by))) {
|
||||
joinby <- colnames(microorganisms)[1]
|
||||
names(joinby) <- by
|
||||
} else {
|
||||
joinby <- by
|
||||
}
|
||||
list(x = x,
|
||||
by = joinby)
|
||||
}
|
||||
|
||||
get_prejoined_class <- function(x) {
|
||||
if (is.data.frame(x)) {
|
||||
class(x)
|
||||
} else {
|
||||
"data.frame"
|
||||
}
|
||||
}
|
||||
|
||||
check_groups_before_join <- function(x, fn) {
|
||||
if (is.data.frame(x) && !is.null(attributes(x)$groups)) {
|
||||
warning("Groups are dropped, since the ", fn, "() function relies on merge() from base R, not on join() from dplyr.", call. = FALSE)
|
||||
}
|
||||
}
|
||||
@@ -1,333 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Key antibiotics for first *weighted* isolates
|
||||
#'
|
||||
#' These function can be used to determine first isolates (see [first_isolate()]). Using key antibiotics to determine first isolates is more reliable than without key antibiotics. These selected isolates will then be called first *weighted* isolates.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x table with antibiotics coloms, like `AMX` or `amox`
|
||||
#' @param y,z characters to compare
|
||||
#' @inheritParams first_isolate
|
||||
#' @param universal_1,universal_2,universal_3,universal_4,universal_5,universal_6 column names of **broad-spectrum** antibiotics, case-insensitive. At default, the columns containing these antibiotics will be guessed with [guess_ab_col()].
|
||||
#' @param GramPos_1,GramPos_2,GramPos_3,GramPos_4,GramPos_5,GramPos_6 column names of antibiotics for **Gram-positives**, case-insensitive. At default, the columns containing these antibiotics will be guessed with [guess_ab_col()].
|
||||
#' @param GramNeg_1,GramNeg_2,GramNeg_3,GramNeg_4,GramNeg_5,GramNeg_6 column names of antibiotics for **Gram-negatives**, case-insensitive. At default, the columns containing these antibiotics will be guessed with [guess_ab_col()].
|
||||
#' @param warnings give warning about missing antibiotic columns, they will anyway be ignored
|
||||
#' @param ... other parameters passed on to function
|
||||
#' @details The function [key_antibiotics()] returns a character vector with 12 antibiotic results for every isolate. These isolates can then be compared using [key_antibiotics_equal()], to check if two isolates have generally the same antibiogram. Missing and invalid values are replaced with a dot (`"."`) by [key_antibiotics()] and ignored by [key_antibiotics_equal()].
|
||||
#'
|
||||
#' The [first_isolate()] function only uses this function on the same microbial species from the same patient. Using this, e.g. an MRSA will be included after a susceptible *S. aureus* (MSSA) is found within the same patient episode. Without key antibiotic comparison it would not. See [first_isolate()] for more info.
|
||||
#'
|
||||
#' At default, the antibiotics that are used for **Gram-positive bacteria** are:
|
||||
#' - Amoxicillin
|
||||
#' - Amoxicillin/clavulanic acid
|
||||
#' - Cefuroxime
|
||||
#' - Piperacillin/tazobactam
|
||||
#' - Ciprofloxacin
|
||||
#' - Trimethoprim/sulfamethoxazole
|
||||
#' - Vancomycin
|
||||
#' - Teicoplanin
|
||||
#' - Tetracycline
|
||||
#' - Erythromycin
|
||||
#' - Oxacillin
|
||||
#' - Rifampin
|
||||
#'
|
||||
#' At default the antibiotics that are used for **Gram-negative bacteria** are:
|
||||
#' - Amoxicillin
|
||||
#' - Amoxicillin/clavulanic acid
|
||||
#' - Cefuroxime
|
||||
#' - Piperacillin/tazobactam
|
||||
#' - Ciprofloxacin
|
||||
#' - Trimethoprim/sulfamethoxazole
|
||||
#' - Gentamicin
|
||||
#' - Tobramycin
|
||||
#' - Colistin
|
||||
#' - Cefotaxime
|
||||
#' - Ceftazidime
|
||||
#' - Meropenem
|
||||
#'
|
||||
#' The function [key_antibiotics_equal()] checks the characters returned by [key_antibiotics()] for equality, and returns a [`logical`] vector.
|
||||
#' @inheritSection first_isolate Key antibiotics
|
||||
#' @rdname key_antibiotics
|
||||
#' @export
|
||||
#' @seealso [first_isolate()]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' # `example_isolates` is a dataset available in the AMR package.
|
||||
#' # See ?example_isolates.
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' # set key antibiotics to a new variable
|
||||
#' my_patients <- example_isolates %>%
|
||||
#' mutate(keyab = key_antibiotics(.)) %>%
|
||||
#' mutate(
|
||||
#' # now calculate first isolates
|
||||
#' first_regular = first_isolate(., col_keyantibiotics = FALSE),
|
||||
#' # and first WEIGHTED isolates
|
||||
#' first_weighted = first_isolate(., 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 well as 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(x,
|
||||
col_mo = NULL,
|
||||
universal_1 = guess_ab_col(x, "amoxicillin"),
|
||||
universal_2 = guess_ab_col(x, "amoxicillin/clavulanic acid"),
|
||||
universal_3 = guess_ab_col(x, "cefuroxime"),
|
||||
universal_4 = guess_ab_col(x, "piperacillin/tazobactam"),
|
||||
universal_5 = guess_ab_col(x, "ciprofloxacin"),
|
||||
universal_6 = guess_ab_col(x, "trimethoprim/sulfamethoxazole"),
|
||||
GramPos_1 = guess_ab_col(x, "vancomycin"),
|
||||
GramPos_2 = guess_ab_col(x, "teicoplanin"),
|
||||
GramPos_3 = guess_ab_col(x, "tetracycline"),
|
||||
GramPos_4 = guess_ab_col(x, "erythromycin"),
|
||||
GramPos_5 = guess_ab_col(x, "oxacillin"),
|
||||
GramPos_6 = guess_ab_col(x, "rifampin"),
|
||||
GramNeg_1 = guess_ab_col(x, "gentamicin"),
|
||||
GramNeg_2 = guess_ab_col(x, "tobramycin"),
|
||||
GramNeg_3 = guess_ab_col(x, "colistin"),
|
||||
GramNeg_4 = guess_ab_col(x, "cefotaxime"),
|
||||
GramNeg_5 = guess_ab_col(x, "ceftazidime"),
|
||||
GramNeg_6 = guess_ab_col(x, "meropenem"),
|
||||
warnings = TRUE,
|
||||
...) {
|
||||
|
||||
dots <- unlist(list(...))
|
||||
if (length(dots) != 0) {
|
||||
# backwards compatibility with old parameters
|
||||
dots.names <- dots %>% names()
|
||||
if ("info" %in% dots.names) {
|
||||
warnings <- dots[which(dots.names == "info")]
|
||||
}
|
||||
}
|
||||
|
||||
# try to find columns based on type
|
||||
# -- mo
|
||||
if (is.null(col_mo)) {
|
||||
col_mo <- search_type_in_df(x = x, type = "mo")
|
||||
}
|
||||
stop_if(is.null(col_mo), "`col_mo` must be set")
|
||||
|
||||
# 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)
|
||||
check_available_columns <- function(x, col.list, warnings = TRUE) {
|
||||
# check columns
|
||||
col.list <- col.list[!is.na(col.list) & !is.null(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 seq_len(length(col.list))) {
|
||||
if (is.null(col.list[i]) | isTRUE(is.na(col.list[i]))) {
|
||||
col.list[i] <- NA
|
||||
} else if (toupper(col.list[i]) %in% colnames(x)) {
|
||||
col.list[i] <- toupper(col.list[i])
|
||||
} else if (tolower(col.list[i]) %in% colnames(x)) {
|
||||
col.list[i] <- tolower(col.list[i])
|
||||
} else if (!col.list[i] %in% colnames(x)) {
|
||||
col.list[i] <- NA
|
||||
}
|
||||
}
|
||||
if (!all(col.list %in% colnames(x))) {
|
||||
if (warnings == TRUE) {
|
||||
warning("Some columns do not exist and will be ignored: ",
|
||||
col.list.bak[!(col.list %in% colnames(x))] %>% toString(),
|
||||
".\nTHIS MAY STRONGLY INFLUENCE THE OUTCOME.",
|
||||
immediate. = TRUE,
|
||||
call. = FALSE)
|
||||
}
|
||||
}
|
||||
col.list
|
||||
}
|
||||
|
||||
col.list <- check_available_columns(x = x, col.list = col.list, warnings = 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.null(gram_positive)]
|
||||
gram_positive <- gram_positive[!is.na(gram_positive)]
|
||||
if (length(gram_positive) < 12) {
|
||||
warning("only using ", length(gram_positive), " different antibiotics as key antibiotics for Gram-positives. See ?key_antibiotics.", call. = FALSE)
|
||||
}
|
||||
|
||||
gram_negative <- c(universal,
|
||||
GramNeg_1, GramNeg_2, GramNeg_3,
|
||||
GramNeg_4, GramNeg_5, GramNeg_6)
|
||||
gram_negative <- gram_negative[!is.null(gram_negative)]
|
||||
gram_negative <- gram_negative[!is.na(gram_negative)]
|
||||
if (length(gram_negative) < 12) {
|
||||
warning("only using ", length(gram_negative), " different antibiotics as key antibiotics for Gram-negatives. See ?key_antibiotics.", call. = FALSE)
|
||||
}
|
||||
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
x[, col_mo] <- as.mo(x[, col_mo, drop = TRUE])
|
||||
x$gramstain <- mo_gramstain(x[, col_mo, drop = TRUE], language = NULL)
|
||||
x$key_ab <- NA_character_
|
||||
|
||||
# Gram +
|
||||
x$key_ab <- if_else(x$gramstain == "Gram-positive",
|
||||
tryCatch(apply(X = x[, gram_positive],
|
||||
MARGIN = 1,
|
||||
FUN = function(x) paste(x, collapse = "")),
|
||||
error = function(e) paste0(rep(".", 12), collapse = "")),
|
||||
x$key_ab)
|
||||
|
||||
# Gram -
|
||||
x$key_ab <- if_else(x$gramstain == "Gram-negative",
|
||||
tryCatch(apply(X = x[, gram_negative],
|
||||
MARGIN = 1,
|
||||
FUN = function(x) paste(x, collapse = "")),
|
||||
error = function(e) paste0(rep(".", 12), collapse = "")),
|
||||
x$key_ab)
|
||||
|
||||
# format
|
||||
key_abs <- toupper(gsub("[^SIR]", ".", gsub("(NA|NULL)", ".", x$key_ab)))
|
||||
|
||||
if (n_distinct(key_abs) == 1) {
|
||||
warning("No distinct key antibiotics determined.", call. = FALSE)
|
||||
}
|
||||
|
||||
key_abs
|
||||
|
||||
}
|
||||
|
||||
#' @rdname key_antibiotics
|
||||
#' @export
|
||||
key_antibiotics_equal <- function(y,
|
||||
z,
|
||||
type = c("keyantibiotics", "points"),
|
||||
ignore_I = TRUE,
|
||||
points_threshold = 2,
|
||||
info = FALSE) {
|
||||
# y is active row, z is lag
|
||||
x <- y
|
||||
y <- z
|
||||
|
||||
type <- type[1]
|
||||
|
||||
stop_ifnot(length(x) == length(y), "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 <- progress_estimated(length(x))
|
||||
on.exit(close(p))
|
||||
}
|
||||
|
||||
for (i in seq_len(length(x))) {
|
||||
|
||||
if (info_needed == TRUE) {
|
||||
p$tick()
|
||||
}
|
||||
|
||||
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 ?key_antibiotics')
|
||||
}
|
||||
}
|
||||
}
|
||||
if (info_needed == TRUE) {
|
||||
close(p)
|
||||
}
|
||||
result
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Kurtosis of the sample
|
||||
#'
|
||||
#' @description Kurtosis is a measure of the "tailedness" of the probability distribution of a real-valued random variable.
|
||||
#' @inheritSection lifecycle Questioning lifecycle
|
||||
#' @param x a vector of values, a [`matrix`] or a [`data.frame`]
|
||||
#' @param na.rm a logical value indicating whether `NA` values should be stripped before the computation proceeds.
|
||||
#' @seealso [skewness()]
|
||||
#' @rdname kurtosis
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
kurtosis <- function(x, na.rm = FALSE) {
|
||||
UseMethod("kurtosis")
|
||||
}
|
||||
|
||||
#' @method 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)
|
||||
}
|
||||
|
||||
#' @method kurtosis matrix
|
||||
#' @rdname kurtosis
|
||||
#' @export
|
||||
kurtosis.matrix <- function(x, na.rm = FALSE) {
|
||||
base::apply(x, 2, kurtosis.default, na.rm = na.rm)
|
||||
}
|
||||
|
||||
#' @method kurtosis data.frame
|
||||
#' @rdname kurtosis
|
||||
#' @export
|
||||
kurtosis.data.frame <- function(x, na.rm = FALSE) {
|
||||
base::sapply(x, kurtosis.default, na.rm = na.rm)
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
###############
|
||||
# NOTE TO SELF: could also have done this with the 'lifecycle' package, but why add a package dependency for such an easy job??
|
||||
###############
|
||||
|
||||
#' Lifecycles of functions in the `AMR` package
|
||||
#' @name lifecycle
|
||||
#' @rdname lifecycle
|
||||
#' @description Functions in this `AMR` package are categorised using [the lifecycle circle of the Tidyverse as found on www.tidyverse.org/lifecycle](https://www.Tidyverse.org/lifecycle).
|
||||
#'
|
||||
#' \if{html}{\figure{lifecycle_Tidyverse.svg}{options: height=200px style=margin-bottom:5px} \cr}
|
||||
#' This page contains a section for every lifecycle (with text borrowed from the aforementioned Tidyverse website), so they can be used in the manual pages of the functions.
|
||||
#' @section Experimental lifecycle:
|
||||
#' \if{html}{\figure{lifecycle_experimental.svg}{options: style=margin-bottom:5px} \cr}
|
||||
#' The [lifecycle][AMR::lifecycle] of this function is **experimental**. An experimental function is in early stages of development. The unlying code might be changing frequently. Experimental functions might be removed without deprecation, so you are generally best off waiting until a function is more mature before you use it in production code. Experimental functions are only available in development versions of this `AMR` package and will thus not be included in releases that are submitted to CRAN, since such functions have not yet matured enough.
|
||||
#' @section Maturing lifecycle:
|
||||
#' \if{html}{\figure{lifecycle_maturing.svg}{options: style=margin-bottom:5px} \cr}
|
||||
#' The [lifecycle][AMR::lifecycle] of this function is **maturing**. The unlying code of a maturing function has been roughed out, but finer details might still change. Since this function needs wider usage and more extensive testing, you are very welcome [to suggest changes at our repository](https://github.com/msberends/AMR/issues) or [write us an email (see section 'Contact Us')][AMR::AMR].
|
||||
#' @section Stable lifecycle:
|
||||
#' \if{html}{\figure{lifecycle_stable.svg}{options: style=margin-bottom:5px} \cr}
|
||||
#' The [lifecycle][AMR::lifecycle] of this function is **stable**. In a stable function, major changes are unlikely. This means that the unlying code will generally evolve by adding new arguments; removing arguments or changing the meaning of existing arguments will be avoided.
|
||||
#'
|
||||
#' If the unlying code needs breaking changes, they will occur gradually. For example, a parameter will be deprecated and first continue to work, but will emit an message informing you of the change. Next, typically after at least one newly released version on CRAN, the message will be transformed to an error.
|
||||
#' @section Retired lifecycle:
|
||||
#' \if{html}{\figure{lifecycle_retired.svg}{options: style=margin-bottom:5px} \cr}
|
||||
#' The [lifecycle][AMR::lifecycle] of this function is **retired**. A retired function is no longer under active development, and (if appropiate) a better alternative is available. No new arguments will be added, and only the most critical bugs will be fixed. In a future version, this function will be removed.
|
||||
#' @section Questioning lifecycle:
|
||||
#' \if{html}{\figure{lifecycle_questioning.svg}{options: style=margin-bottom:5px} \cr}
|
||||
#' The [lifecycle][AMR::lifecycle] of this function is **questioning**. This function might be no longer be optimal approach, or is it questionable whether this function should be in this `AMR` package at all.
|
||||
NULL
|
||||
@@ -1,131 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Pattern Matching
|
||||
#'
|
||||
#' Convenient wrapper around [grep()] to match a pattern: `x %like% pattern`. It always returns a [`logical`] vector and is always case-insensitive (use `x %like_case% pattern` for case-sensitive matching). Also, `pattern` can be as long as `x` to compare items of each index in both vectors, or they both can have the same length to iterate over all cases.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x a character vector where matches are sought, or an object which can be coerced by [as.character()] to a character vector.
|
||||
#' @param pattern a character string containing a regular expression (or [`character`] string for `fixed = TRUE`) to be matched in the given character vector. Coerced by [as.character()] to a character string if possible. If a [`character`] vector of length 2 or more is supplied, the first element is used with a warning.
|
||||
#' @param ignore.case if `FALSE`, the pattern matching is *case sensitive* and if `TRUE`, case is ignored during matching.
|
||||
#' @return A [`logical`] vector
|
||||
#' @name like
|
||||
#' @rdname like
|
||||
#' @export
|
||||
#' @details
|
||||
#' The `%like%` function:
|
||||
#' * Is case insensitive (use `%like_case%` for case-sensitive matching)
|
||||
#' * Supports multiple patterns
|
||||
#' * Checks if `pattern` is a regular expression and sets `fixed = TRUE` if not, to greatly improve speed
|
||||
#' * Tries again with `perl = TRUE` if regex fails
|
||||
#'
|
||||
#' 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 [`like` function from the `data.table` package](https://github.com/Rdatatable/data.table/blob/master/R/like.R)
|
||||
#' @seealso [base::grep()]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @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 isolates whose name start with 'Ent' or 'ent'
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' example_isolates %>%
|
||||
#' filter(mo_name(mo) %like% "^ent")
|
||||
#' }
|
||||
like <- function(x, pattern, ignore.case = TRUE) {
|
||||
# set to fixed if no regex found
|
||||
fixed <- all(!grepl("[\\[$.^*?+-}{|)(]", pattern))
|
||||
if (ignore.case == TRUE) {
|
||||
# set here, otherwise if fixed = TRUE, this warning will be thrown: argument 'ignore.case = TRUE' will be ignored
|
||||
x <- tolower(x)
|
||||
pattern <- tolower(pattern)
|
||||
}
|
||||
|
||||
if (length(pattern) > 1) {
|
||||
if (length(x) != length(pattern)) {
|
||||
if (length(x) == 1) {
|
||||
x <- rep(x, length(pattern))
|
||||
}
|
||||
# return TRUE for every 'x' that matches any 'pattern', FALSE otherwise
|
||||
res <- sapply(pattern, function(pttrn) base::grepl(pttrn, x, ignore.case = FALSE, fixed = fixed))
|
||||
res2 <- as.logical(rowSums(res))
|
||||
# get only first item of every hit in pattern
|
||||
res2[duplicated(res)] <- FALSE
|
||||
res2[rowSums(res) == 0] <- NA
|
||||
return(res2)
|
||||
} else {
|
||||
# x and pattern are of same length, so items with each other
|
||||
res <- vector(length = length(pattern))
|
||||
for (i in seq_len(length(res))) {
|
||||
if (is.factor(x[i])) {
|
||||
res[i] <- as.integer(x[i]) %in% base::grep(pattern[i], levels(x[i]), ignore.case = FALSE, fixed = fixed)
|
||||
} else {
|
||||
res[i] <- base::grepl(pattern[i], x[i], ignore.case = FALSE, fixed = fixed)
|
||||
}
|
||||
}
|
||||
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 = FALSE, fixed = fixed)
|
||||
} else {
|
||||
tryCatch(base::grepl(pattern, x, ignore.case = FALSE, fixed = fixed),
|
||||
error = function(e) {
|
||||
if (grepl("invalid reg(ular )?exp", e$message, ignore.case = TRUE)) {
|
||||
# try with perl = TRUE:
|
||||
return(base::grepl(pattern = pattern,
|
||||
x = x,
|
||||
ignore.case = FALSE,
|
||||
fixed = fixed,
|
||||
perl = TRUE))
|
||||
} else {
|
||||
# stop otherwise
|
||||
stop(e$message)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#' @rdname like
|
||||
#' @export
|
||||
"%like%" <- function(x, pattern) {
|
||||
like(x, pattern, ignore.case = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname like
|
||||
#' @export
|
||||
"%like_case%" <- function(x, pattern) {
|
||||
like(x, pattern, ignore.case = FALSE)
|
||||
}
|
||||
@@ -1,277 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Class 'mic'
|
||||
#'
|
||||
#' This transforms a vector to a new class [`mic`], which is an ordered [`factor`] with valid MIC values as levels. Invalid MIC values will be translated as `NA` with a warning.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @rdname as.mic
|
||||
#' @param x vector
|
||||
#' @param na.rm a logical indicating whether missing values should be removed
|
||||
#' @details To interpret MIC values as RSI values, use [as.rsi()] on MIC values. It supports guidelines from EUCAST and CLSI.
|
||||
#' @return Ordered [`factor`] with new class [`mic`]
|
||||
#' @aliases mic
|
||||
#' @export
|
||||
#' @seealso [as.rsi()]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @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
|
||||
#'
|
||||
#' # interpret MIC values
|
||||
#' as.rsi(x = as.mic(2),
|
||||
#' mo = as.mo("S. pneumoniae"),
|
||||
#' ab = "AMX",
|
||||
#' guideline = "EUCAST")
|
||||
#' as.rsi(x = as.mic(4),
|
||||
#' mo = as.mo("S. pneumoniae"),
|
||||
#' ab = "AMX",
|
||||
#' guideline = "EUCAST")
|
||||
#'
|
||||
#' plot(mic_data)
|
||||
#' barplot(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)
|
||||
# transform Unicode for >= and <=
|
||||
x <- gsub("\u2264", "<=", x, fixed = TRUE)
|
||||
x <- gsub("\u2265", ">=", x, fixed = TRUE)
|
||||
# remove space between operator and number ("<= 0.002" -> "<=0.002")
|
||||
x <- gsub("(<|=|>) +", "\\1", x)
|
||||
# transform => to >= and =< to <=
|
||||
x <- gsub("=<", "<=", x, fixed = TRUE)
|
||||
x <- gsub("=>", ">=", x, fixed = TRUE)
|
||||
# dots without a leading zero must start with 0
|
||||
x <- gsub("([^0-9]|^)[.]", "\\10.", x)
|
||||
# values like "<=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)
|
||||
# keep only one zero before dot
|
||||
x <- gsub("0+[.]", "0.", x)
|
||||
# starting 00 is probably 0.0 if there's no dot yet
|
||||
x[!x %like% "[.]"] <- gsub("^00", "0.0", x[!x %like% "[.]"])
|
||||
# remove last zeroes
|
||||
x <- gsub("([.].?)0+$", "\\1", x)
|
||||
x <- gsub("(.*[.])0+$", "\\10", x)
|
||||
# remove ending .0 again
|
||||
x[x %like% "[.]"] <- gsub("0+$", "", x[x %like% "[.]"])
|
||||
# never end with dot
|
||||
x <- gsub("[.]$", "", x)
|
||||
# force to be character
|
||||
x <- as.character(x)
|
||||
# trim it
|
||||
x <- trimws(x)
|
||||
|
||||
## previously unempty values now empty - should return a warning later on
|
||||
x[x.bak != "" & x == ""] <- "invalid"
|
||||
|
||||
# these are allowed MIC values and will become factor levels
|
||||
ops <- c("<", "<=", "", ">=", ">")
|
||||
lvls <- c(c(t(sapply(ops, function(x) paste0(x, "0.00", 1:9)))),
|
||||
unique(c(t(sapply(ops, function(x) paste0(x, sort(as.double(paste0("0.0",
|
||||
sort(c(1:99, 125, 128, 256, 512, 625)))))))))),
|
||||
unique(c(t(sapply(ops, function(x) paste0(x, sort(as.double(paste0("0.",
|
||||
c(1:99, 125, 128, 256, 512))))))))),
|
||||
c(t(sapply(ops, function(x) paste0(x, sort(c(1:9, 1.5)))))),
|
||||
c(t(sapply(ops, function(x) paste0(x, c(10:98)[9:98 %% 2 == TRUE])))),
|
||||
c(t(sapply(ops, function(x) paste0(x, sort(c(2 ^ c(7:10), 80 * c(2:12))))))))
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
structure(.Data = factor(x, levels = lvls, ordered = TRUE),
|
||||
class = c("mic", "ordered", "factor"))
|
||||
}
|
||||
}
|
||||
|
||||
all_valid_mics <- function(x) {
|
||||
x_mic <- tryCatch(suppressWarnings(as.mic(x[!is.na(x)])),
|
||||
error = function(e) NA)
|
||||
!any(is.na(x_mic)) & !all(is.na(x))
|
||||
}
|
||||
|
||||
#' @rdname as.mic
|
||||
#' @export
|
||||
is.mic <- function(x) {
|
||||
inherits(x, "mic")
|
||||
}
|
||||
|
||||
#' @method as.double mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
as.double.mic <- function(x, ...) {
|
||||
as.double(gsub("(<|=|>)+", "", as.character(x)))
|
||||
}
|
||||
|
||||
#' @method as.integer mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
as.integer.mic <- function(x, ...) {
|
||||
as.integer(gsub("(<|=|>)+", "", as.character(x)))
|
||||
}
|
||||
|
||||
#' @method as.numeric mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
as.numeric.mic <- function(x, ...) {
|
||||
as.numeric(gsub("(<|=|>)+", "", as.character(x)))
|
||||
}
|
||||
|
||||
#' @method droplevels mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
droplevels.mic <- function(x, exclude = ifelse(anyNA(levels(x)), NULL, NA), ...) {
|
||||
x <- droplevels.factor(x, exclude = exclude, ...)
|
||||
class(x) <- c("mic", "ordered", "factor")
|
||||
x
|
||||
}
|
||||
|
||||
#' @method print mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.mic <- function(x, ...) {
|
||||
cat("Class <mic>\n")
|
||||
print(as.character(x), quote = FALSE)
|
||||
}
|
||||
|
||||
#' @method summary mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
summary.mic <- function(object, ...) {
|
||||
x <- object
|
||||
n_total <- x %>% length()
|
||||
x <- x[!is.na(x)]
|
||||
n <- x %>% length()
|
||||
c(
|
||||
"Class" = "mic",
|
||||
"<NA>" = n_total - n,
|
||||
"Min." = sort(x)[1] %>% as.character(),
|
||||
"Max." = sort(x)[n] %>% as.character()
|
||||
)
|
||||
}
|
||||
|
||||
#' @method plot mic
|
||||
#' @export
|
||||
#' @importFrom graphics barplot axis par
|
||||
#' @noRd
|
||||
plot.mic <- function(x,
|
||||
main = paste("MIC values of", deparse(substitute(x))),
|
||||
ylab = "Frequency",
|
||||
xlab = "MIC value",
|
||||
axes = FALSE,
|
||||
...) {
|
||||
barplot(table(droplevels.factor(x)),
|
||||
ylab = ylab,
|
||||
xlab = xlab,
|
||||
axes = axes,
|
||||
main = main,
|
||||
...)
|
||||
axis(2, seq(0, max(table(droplevels.factor(x)))))
|
||||
}
|
||||
|
||||
#' @method barplot mic
|
||||
#' @export
|
||||
#' @importFrom graphics barplot axis
|
||||
#' @noRd
|
||||
barplot.mic <- function(height,
|
||||
main = paste("MIC values of", deparse(substitute(height))),
|
||||
ylab = "Frequency",
|
||||
xlab = "MIC value",
|
||||
axes = FALSE,
|
||||
...) {
|
||||
barplot(table(droplevels.factor(height)),
|
||||
ylab = ylab,
|
||||
xlab = xlab,
|
||||
axes = axes,
|
||||
main = main,
|
||||
...)
|
||||
axis(2, seq(0, max(table(droplevels.factor(height)))))
|
||||
}
|
||||
|
||||
#' @method [ mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[.mic" <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
#' @method [[ mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[.mic" <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
#' @method [<- mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[<-.mic" <- function(i, j, ..., value) {
|
||||
value <- as.mic(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
y
|
||||
}
|
||||
#' @method [[<- mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[<-.mic" <- function(i, j, ..., value) {
|
||||
value <- as.mic(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
y
|
||||
}
|
||||
#' @method c mic
|
||||
#' @export
|
||||
#' @noRd
|
||||
c.mic <- function(x, ...) {
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(x)
|
||||
y
|
||||
}
|
||||
@@ -1,445 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Property of a microorganism
|
||||
#'
|
||||
#' Use these functions to return a specific property of a microorganism. All input values will be evaluated internally with [as.mo()], which makes it possible to use microbial abbreviations, codes and names as input. Please see *Examples*.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param x any (vector of) text that can be coerced to a valid microorganism code with [as.mo()]
|
||||
#' @param property one of the column names of the [microorganisms] data set or `"shortname"`
|
||||
#' @param language language of the returned text, defaults to system language (see [get_locale()]) and can also be set with `getOption("AMR_locale")`. Use `language = NULL` or `language = ""` to prevent translation.
|
||||
#' @param ... other parameters passed on to [as.mo()]
|
||||
#' @param open browse the URL using [utils::browseURL()]
|
||||
#' @details All functions will return the most recently known taxonomic property according to the Catalogue of Life, except for [mo_ref()], [mo_authors()] and [mo_year()]. Please refer to this example, knowing that *Escherichia blattae* was renamed to *Shimwellia blattae* in 2010:
|
||||
#' - `mo_name("Escherichia blattae")` will return `"Shimwellia blattae"` (with a message about the renaming)
|
||||
#' - `mo_ref("Escherichia blattae")` will return `"Burgess et al., 1973"` (with a message about the renaming)
|
||||
#' - `mo_ref("Shimwellia blattae")` will return `"Priest et al., 2010"` (without a message)
|
||||
#'
|
||||
#' The short name - [mo_shortname()] - almost always returns the first character of the genus and the full species, like `"E. coli"`. Exceptions are abbreviations of staphylococci (like *"CoNS"*, Coagulase-Negative Staphylococci) and beta-haemolytic streptococci (like *"GBS"*, Group B Streptococci). Please bear in mind that e.g. *E. coli* could mean *Escherichia coli* (kingdom of Bacteria) as well as *Entamoeba coli* (kingdom of Protozoa). Returning to the full name will be done using [as.mo()] internally, giving priority to bacteria and human pathogens, i.e. `"E. coli"` will be considered *Escherichia coli*. In other words, `mo_fullname(mo_shortname("Entamoeba coli"))` returns `"Escherichia coli"`.
|
||||
#'
|
||||
#' Since the top-level of the taxonomy is sometimes referred to as 'kingdom' and sometimes as 'domain', the functions [mo_kingdom()] and [mo_domain()] return the exact same results.
|
||||
#'
|
||||
#' The Gram stain - [mo_gramstain()] - will be determined based on the taxonomic kingdom and phylum. According to Cavalier-Smith (2002, [PMID 11837318](https://pubmed.ncbi.nlm.nih.gov/11837318)), who defined subkingdoms Negibacteria and Posibacteria, only these phyla are Posibacteria: Actinobacteria, Chloroflexi, Firmicutes and Tenericutes. These bacteria are considered Gram-positive - all other bacteria are considered Gram-negative. Species outside the kingdom of Bacteria will return a value `NA`.
|
||||
#'
|
||||
#' All output will be [translate]d where possible.
|
||||
#'
|
||||
#' The function [mo_url()] will return the direct URL to the online database entry, which also shows the scientific reference of the concerned species.
|
||||
#' @inheritSection catalogue_of_life Catalogue of Life
|
||||
#' @inheritSection as.mo Source
|
||||
#' @rdname mo_property
|
||||
#' @name mo_property
|
||||
#' @return
|
||||
#' - An [`integer`] in case of [mo_year()]
|
||||
#' - A [`list`] in case of [mo_taxonomy()] and [mo_info()]
|
||||
#' - A named [`character`] in case of [mo_url()]
|
||||
#' - A [`double`] in case of [mo_snomed()]
|
||||
#' - A [`character`] in all other cases
|
||||
#' @export
|
||||
#' @seealso [microorganisms]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' # taxonomic tree -----------------------------------------------------------
|
||||
#' mo_kingdom("E. coli") # "Bacteria"
|
||||
#' mo_phylum("E. coli") # "Proteobacteria"
|
||||
#' mo_class("E. coli") # "Gammaproteobacteria"
|
||||
#' mo_order("E. coli") # "Enterobacterales"
|
||||
#' mo_family("E. coli") # "Enterobacteriaceae"
|
||||
#' mo_genus("E. coli") # "Escherichia"
|
||||
#' mo_species("E. coli") # "coli"
|
||||
#' mo_subspecies("E. coli") # ""
|
||||
#'
|
||||
#' # colloquial properties ----------------------------------------------------
|
||||
#' mo_name("E. coli") # "Escherichia coli"
|
||||
#' mo_fullname("E. coli") # "Escherichia coli" - same as mo_name()
|
||||
#' mo_shortname("E. coli") # "E. coli"
|
||||
#'
|
||||
#' # other properties ---------------------------------------------------------
|
||||
#' mo_gramstain("E. coli") # "Gram-negative"
|
||||
#' mo_snomed("E. coli") # 112283007, 116395006, ... (SNOMED codes)
|
||||
#' mo_type("E. coli") # "Bacteria" (equal to kingdom, but may be translated)
|
||||
#' mo_rank("E. coli") # "species"
|
||||
#' mo_url("E. coli") # get the direct url to the online database entry
|
||||
#' mo_synonyms("E. coli") # get previously accepted taxonomic names
|
||||
#'
|
||||
#' # scientific reference -----------------------------------------------------
|
||||
#' mo_ref("E. coli") # "Castellani et al., 1919"
|
||||
#' mo_authors("E. coli") # "Castellani et al."
|
||||
#' mo_year("E. coli") # 1919
|
||||
#'
|
||||
#' # abbreviations known in the field -----------------------------------------
|
||||
#' mo_genus("MRSA") # "Staphylococcus"
|
||||
#' mo_species("MRSA") # "aureus"
|
||||
#' mo_shortname("VISA") # "S. aureus"
|
||||
#' mo_gramstain("VISA") # "Gram-positive"
|
||||
#'
|
||||
#' mo_genus("EHEC") # "Escherichia"
|
||||
#' mo_species("EHEC") # "coli"
|
||||
#'
|
||||
#' # known subspecies ---------------------------------------------------------
|
||||
#' mo_name("doylei") # "Campylobacter jejuni doylei"
|
||||
#' mo_genus("doylei") # "Campylobacter"
|
||||
#' mo_species("doylei") # "jejuni"
|
||||
#' mo_subspecies("doylei") # "doylei"
|
||||
#'
|
||||
#' mo_fullname("K. pneu rh") # "Klebsiella pneumoniae rhinoscleromatis"
|
||||
#' mo_shortname("K. pneu rh") # "K. pneumoniae"
|
||||
#'
|
||||
#' \donttest{
|
||||
#' # Becker classification, see ?as.mo ----------------------------------------
|
||||
#' mo_fullname("S. epi") # "Staphylococcus epidermidis"
|
||||
#' mo_fullname("S. epi", Becker = TRUE) # "Coagulase-negative Staphylococcus (CoNS)"
|
||||
#' mo_shortname("S. epi") # "S. epidermidis"
|
||||
#' mo_shortname("S. epi", Becker = TRUE) # "CoNS"
|
||||
#'
|
||||
#' # Lancefield classification, see ?as.mo ------------------------------------
|
||||
#' mo_fullname("S. pyo") # "Streptococcus pyogenes"
|
||||
#' mo_fullname("S. pyo", Lancefield = TRUE) # "Streptococcus group A"
|
||||
#' mo_shortname("S. pyo") # "S. pyogenes"
|
||||
#' mo_shortname("S. pyo", Lancefield = TRUE) # "GAS" (='Group A Streptococci')
|
||||
#'
|
||||
#'
|
||||
#' # language support for German, Dutch, Spanish, Portuguese, Italian and French
|
||||
#' mo_gramstain("E. coli", language = "de") # "Gramnegativ"
|
||||
#' mo_gramstain("E. coli", language = "nl") # "Gram-negatief"
|
||||
#' mo_gramstain("E. coli", language = "es") # "Gram negativo"
|
||||
#'
|
||||
#' # mo_type is equal to mo_kingdom, but mo_kingdom will remain official
|
||||
#' mo_kingdom("E. coli") # "Bacteria" on a German system
|
||||
#' mo_type("E. coli") # "Bakterien" on a German system
|
||||
#' mo_type("E. coli") # "Bacteria" on an English system
|
||||
#'
|
||||
#' mo_fullname("S. pyogenes",
|
||||
#' Lancefield = TRUE,
|
||||
#' language = "de") # "Streptococcus Gruppe A"
|
||||
#' mo_fullname("S. pyogenes",
|
||||
#' Lancefield = TRUE,
|
||||
#' language = "nl") # "Streptococcus groep A"
|
||||
#'
|
||||
#'
|
||||
#' # get a list with the complete taxonomy (from kingdom to subspecies)
|
||||
#' mo_taxonomy("E. coli")
|
||||
#' # get a list with the taxonomy, the authors, Gram-stain and URL to the online database
|
||||
#' mo_info("E. coli")
|
||||
#' }
|
||||
mo_name <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "fullname", ...), language = language, only_unknown = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_fullname <- mo_name
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_shortname <- function(x, language = get_locale(), ...) {
|
||||
x.mo <- as.mo(x, ...)
|
||||
|
||||
metadata <- get_mo_failures_uncertainties_renamed()
|
||||
|
||||
replace_empty <- function(x) {
|
||||
x[x == ""] <- "spp."
|
||||
x
|
||||
}
|
||||
|
||||
# get first char of genus and complete species in English
|
||||
shortnames <- paste0(substr(mo_genus(x.mo, language = NULL), 1, 1), ". ", replace_empty(mo_species(x.mo, language = NULL)))
|
||||
|
||||
# exceptions for Staphylococci
|
||||
shortnames[shortnames == "S. coagulase-negative"] <- "CoNS"
|
||||
shortnames[shortnames == "S. coagulase-positive"] <- "CoPS"
|
||||
# exceptions for Streptococci: Streptococcus Group A -> GAS
|
||||
shortnames[shortnames %like% "S. group [ABCDFGHK]"] <- paste0("G", gsub("S. group ([ABCDFGHK])", "\\1", shortnames[shortnames %like% "S. group [ABCDFGHK]"]), "S")
|
||||
|
||||
load_mo_failures_uncertainties_renamed(metadata)
|
||||
translate_AMR(shortnames, language = language, only_unknown = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_subspecies <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "subspecies", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_species <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "species", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_genus <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "genus", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_family <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "family", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_order <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "order", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_class <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "class", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_phylum <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "phylum", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_kingdom <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "kingdom", ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_domain <- mo_kingdom
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_type <- function(x, language = get_locale(), ...) {
|
||||
translate_AMR(mo_validate(x = x, property = "kingdom", ...), language = language, only_unknown = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_gramstain <- function(x, language = get_locale(), ...) {
|
||||
x.mo <- as.mo(x, ...)
|
||||
metadata <- get_mo_failures_uncertainties_renamed()
|
||||
|
||||
x.phylum <- mo_phylum(x.mo)
|
||||
# DETERMINE GRAM STAIN FOR BACTERIA
|
||||
# Source: https://itis.gov/servlet/SingleRpt/SingleRpt?search_topic=TSN&search_value=956097
|
||||
# It says this:
|
||||
# Kingdom Bacteria (Cavalier-Smith, 2002)
|
||||
# Subkingdom Posibacteria (Cavalier-Smith, 2002)
|
||||
# Direct Children:
|
||||
# Phylum Actinobacteria (Cavalier-Smith, 2002)
|
||||
# Phylum Chloroflexi (Garrity and Holt, 2002)
|
||||
# Phylum Firmicutes (corrig. Gibbons and Murray, 1978)
|
||||
# Phylum Tenericutes (Murray, 1984)
|
||||
x <- NA_character_
|
||||
# make all bacteria Gram negative
|
||||
x[mo_kingdom(x.mo) == "Bacteria"] <- "Gram-negative"
|
||||
# overwrite these phyla with Gram positive
|
||||
x[x.phylum %in% c("Actinobacteria",
|
||||
"Chloroflexi",
|
||||
"Firmicutes",
|
||||
"Tenericutes")
|
||||
| x.mo == "B_GRAMP"] <- "Gram-positive"
|
||||
|
||||
load_mo_failures_uncertainties_renamed(metadata)
|
||||
translate_AMR(x, language = language, only_unknown = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_snomed <- function(x, ...) {
|
||||
mo_validate(x = x, property = "snomed", ...)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_ref <- function(x, ...) {
|
||||
mo_validate(x = x, property = "ref", ...)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_authors <- function(x, ...) {
|
||||
x <- mo_validate(x = x, property = "ref", ...)
|
||||
# remove last 4 digits and presumably the comma and space that preceed them
|
||||
x[!is.na(x)] <- gsub(",? ?[0-9]{4}", "", x[!is.na(x)])
|
||||
suppressWarnings(x)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_year <- function(x, ...) {
|
||||
x <- mo_validate(x = x, property = "ref", ...)
|
||||
# get last 4 digits
|
||||
x[!is.na(x)] <- gsub(".*([0-9]{4})$", "\\1", x[!is.na(x)])
|
||||
suppressWarnings(as.integer(x))
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_rank <- function(x, ...) {
|
||||
mo_validate(x = x, property = "rank", ...)
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_taxonomy <- function(x, language = get_locale(), ...) {
|
||||
x <- as.mo(x, ...)
|
||||
metadata <- get_mo_failures_uncertainties_renamed()
|
||||
|
||||
result <- base::list(kingdom = mo_kingdom(x, language = language),
|
||||
phylum = mo_phylum(x, language = language),
|
||||
class = mo_class(x, language = language),
|
||||
order = mo_order(x, language = language),
|
||||
family = mo_family(x, language = language),
|
||||
genus = mo_genus(x, language = language),
|
||||
species = mo_species(x, language = language),
|
||||
subspecies = mo_subspecies(x, language = language))
|
||||
|
||||
load_mo_failures_uncertainties_renamed(metadata)
|
||||
result
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_synonyms <- function(x, ...) {
|
||||
x <- as.mo(x, ...)
|
||||
metadata <- get_mo_failures_uncertainties_renamed()
|
||||
|
||||
IDs <- mo_name(x = x, language = NULL)
|
||||
syns <- lapply(IDs, function(newname) {
|
||||
res <- sort(microorganisms.old[which(microorganisms.old$fullname_new == newname), "fullname"])
|
||||
if (length(res) == 0) {
|
||||
NULL
|
||||
} else {
|
||||
res
|
||||
}
|
||||
})
|
||||
if (length(syns) > 1) {
|
||||
names(syns) <- mo_name(x)
|
||||
result <- syns
|
||||
} else {
|
||||
result <- unlist(syns)
|
||||
}
|
||||
|
||||
load_mo_failures_uncertainties_renamed(metadata)
|
||||
result
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_info <- function(x, language = get_locale(), ...) {
|
||||
x <- as.mo(x, ...)
|
||||
metadata <- get_mo_failures_uncertainties_renamed()
|
||||
|
||||
info <- lapply(x, function(y)
|
||||
c(mo_taxonomy(y, language = language),
|
||||
list(synonyms = mo_synonyms(y),
|
||||
gramstain = mo_gramstain(y, language = language),
|
||||
url = unname(mo_url(y, open = FALSE)),
|
||||
ref = mo_ref(y))))
|
||||
if (length(info) > 1) {
|
||||
names(info) <- mo_name(x)
|
||||
result <- info
|
||||
} else {
|
||||
result <- info[[1L]]
|
||||
}
|
||||
|
||||
load_mo_failures_uncertainties_renamed(metadata)
|
||||
result
|
||||
}
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_url <- function(x, open = FALSE, ...) {
|
||||
mo <- as.mo(x = x, ... = ...)
|
||||
mo_names <- mo_name(mo)
|
||||
metadata <- get_mo_failures_uncertainties_renamed()
|
||||
|
||||
df <- data.frame(mo, stringsAsFactors = FALSE) %>%
|
||||
left_join(select(microorganisms, mo, source, species_id), by = "mo")
|
||||
df$url <- ifelse(df$source == "CoL",
|
||||
paste0(catalogue_of_life$url_CoL, "details/species/id/", df$species_id, "/"),
|
||||
ifelse(df$source == "DSMZ",
|
||||
paste0(catalogue_of_life$url_DSMZ, "/advanced_search?adv[taxon-name]=", gsub(" ", "+", mo_names), "/"),
|
||||
NA_character_))
|
||||
u <- df$url
|
||||
names(u) <- mo_names
|
||||
|
||||
if (open == TRUE) {
|
||||
if (length(u) > 1) {
|
||||
warning("only the first URL will be opened, as `browseURL()` only suports one string.")
|
||||
}
|
||||
utils::browseURL(u[1L])
|
||||
}
|
||||
|
||||
load_mo_failures_uncertainties_renamed(metadata)
|
||||
u
|
||||
}
|
||||
|
||||
|
||||
#' @rdname mo_property
|
||||
#' @export
|
||||
mo_property <- function(x, property = "fullname", language = get_locale(), ...) {
|
||||
stop_ifnot(length(property) == 1L, "'property' must be of length 1")
|
||||
stop_ifnot(property %in% colnames(microorganisms),
|
||||
"invalid property: '", property, "' - use a column name of the `microorganisms` data set")
|
||||
|
||||
translate_AMR(mo_validate(x = x, property = property, ...), language = language, only_unknown = TRUE)
|
||||
}
|
||||
|
||||
mo_validate <- function(x, property, ...) {
|
||||
|
||||
check_dataset_integrity()
|
||||
|
||||
dots <- list(...)
|
||||
Becker <- dots$Becker
|
||||
if (is.null(Becker)) {
|
||||
Becker <- FALSE
|
||||
}
|
||||
Lancefield <- dots$Lancefield
|
||||
if (is.null(Lancefield)) {
|
||||
Lancefield <- FALSE
|
||||
}
|
||||
|
||||
# try to catch an error when inputting an invalid parameter
|
||||
# so the 'call.' can be set to FALSE
|
||||
tryCatch(x[1L] %in% MO_lookup[1, property, drop = TRUE],
|
||||
error = function(e) stop(e$message, call. = FALSE))
|
||||
|
||||
if (is.mo(x)
|
||||
& !Becker %in% c(TRUE, "all")
|
||||
& !Lancefield %in% c(TRUE, "all")) {
|
||||
# this will not reset mo_uncertainties and mo_failures
|
||||
# because it's already a valid MO
|
||||
x <- exec_as.mo(x, property = property, initial_search = FALSE, ...)
|
||||
} else if (!all(x %in% MO_lookup[, property, drop = TRUE])
|
||||
| Becker %in% c(TRUE, "all")
|
||||
| Lancefield %in% c(TRUE, "all")) {
|
||||
x <- exec_as.mo(x, property = property, ...)
|
||||
}
|
||||
|
||||
if (property == "mo") {
|
||||
return(to_class_mo(x))
|
||||
} else if (property == "snomed") {
|
||||
return(as.double(eval(parse(text = x))))
|
||||
} else {
|
||||
return(x)
|
||||
}
|
||||
}
|
||||
@@ -1,267 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' User-defined reference data set for microorganisms
|
||||
#'
|
||||
#' @description These functions can be used to predefine your own reference to be used in [as.mo()] and consequently all `mo_*` functions like [mo_genus()] and [mo_gramstain()].
|
||||
#'
|
||||
#' This is **the fastest way** to have your organisation (or analysis) specific codes picked up and translated by this package.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param path location of your reference file, see Details. Can be `""`, `NULL` or `FALSE` to delete the reference file.
|
||||
#' @rdname mo_source
|
||||
#' @name mo_source
|
||||
#' @aliases set_mo_source get_mo_source
|
||||
#' @details The reference file can be a text file seperated with commas (CSV) or tabs or pipes, an Excel file (either 'xls' or 'xlsx' format) or an R object file (extension '.rds'). To use an Excel file, you need to have the `readxl` package installed.
|
||||
#'
|
||||
#' [set_mo_source()] will check the file for validity: it must be a [`data.frame`], must have a column named `"mo"` which contains values from [`microorganisms$mo`][microorganisms] and must have a reference column with your own defined values. If all tests pass, [set_mo_source()] will read the file into R and export it to `"~/.mo_source.rds"`. This compressed data file will then be used at default for MO determination (function [as.mo()] and consequently all `mo_*` functions like [mo_genus()] and [mo_gramstain()]). The location of the original file will be saved as option with `options(mo_source = path)`. Its timestamp will be saved with `options(mo_source_datetime = ...)`.
|
||||
#'
|
||||
#' [get_mo_source()] will return the data set by reading `"~/.mo_source.rds"` with [readRDS()]. If the original file has changed (the file defined with `path`), it will call [set_mo_source()] to update the data file automatically.
|
||||
#'
|
||||
#' Reading an Excel file (`.xlsx`) with only one row has a size of 8-9 kB. The compressed file created with [set_mo_source()] will then have a size of 0.1 kB and can be read by [get_mo_source()] in only a couple of microseconds (millionths of a second).
|
||||
#'
|
||||
#' @section How to setup:
|
||||
#'
|
||||
#' Imagine this data on a sheet of an Excel file (mo codes were looked up in the [microorganisms] data set). The first column contains the organisation specific codes, the second column contains an MO code from this package:
|
||||
#'
|
||||
#' ```
|
||||
#' | A | B |
|
||||
#' --|--------------------|--------------|
|
||||
#' 1 | Organisation XYZ | mo |
|
||||
#' 2 | lab_mo_ecoli | B_ESCHR_COLI |
|
||||
#' 3 | lab_mo_kpneumoniae | B_KLBSL_PNMN |
|
||||
#' 4 | | |
|
||||
#' ```
|
||||
#'
|
||||
#' We save it as `"home/me/ourcodes.xlsx"`. Now we have to set it as a source:
|
||||
#'
|
||||
#' ```
|
||||
#' set_mo_source("home/me/ourcodes.xlsx")
|
||||
#' #> NOTE: Created mo_source file '~/.mo_source.rds' from 'home/me/ourcodes.xlsx'
|
||||
#' #> (columns "Organisation XYZ" and "mo")
|
||||
#' ```
|
||||
#'
|
||||
#' It has now created a file `"~/.mo_source.rds"` with the contents of our Excel file. Only the first column with foreign values and the 'mo' column will be kept when creating the RDS file.
|
||||
#'
|
||||
#' And now we can use it in our functions:
|
||||
#'
|
||||
#' ```
|
||||
#' as.mo("lab_mo_ecoli")
|
||||
#' #> [1] B_ESCHR_COLI
|
||||
#'
|
||||
#' mo_genus("lab_mo_kpneumoniae")
|
||||
#' #> [1] "Klebsiella"
|
||||
#'
|
||||
#' # other input values still work too
|
||||
#' as.mo(c("Escherichia coli", "E. coli", "lab_mo_ecoli"))
|
||||
#' #> [1] B_ESCHR_COLI B_ESCHR_COLI B_ESCHR_COLI
|
||||
#' ```
|
||||
#'
|
||||
#' If we edit the Excel file by, let's say, adding row 4 like this:
|
||||
#'
|
||||
#' ```
|
||||
#' | A | B |
|
||||
#' --|--------------------|--------------|
|
||||
#' 1 | Organisation XYZ | mo |
|
||||
#' 2 | lab_mo_ecoli | B_ESCHR_COLI |
|
||||
#' 3 | lab_mo_kpneumoniae | B_KLBSL_PNMN |
|
||||
#' 4 | lab_Staph_aureus | B_STPHY_AURS |
|
||||
#' 5 | | |
|
||||
#' ```
|
||||
#'
|
||||
#' ...any new usage of an MO function in this package will update your data file:
|
||||
#'
|
||||
#' ```
|
||||
#' as.mo("lab_mo_ecoli")
|
||||
#' #> NOTE: Updated mo_source file '~/.mo_source.rds' from 'home/me/ourcodes.xlsx'
|
||||
#' #> (columns "Organisation XYZ" and "mo")
|
||||
#' #> [1] B_ESCHR_COLI
|
||||
#'
|
||||
#' mo_genus("lab_Staph_aureus")
|
||||
#' #> [1] "Staphylococcus"
|
||||
#' ```
|
||||
#'
|
||||
#' To delete the reference data file, just use `""`, `NULL` or `FALSE` as input for [set_mo_source()]:
|
||||
#'
|
||||
#' ```
|
||||
#' set_mo_source(NULL)
|
||||
#' # Removed mo_source file '~/.mo_source.rds'.
|
||||
#' ```
|
||||
#'
|
||||
#' If the original Excel file is moved or deleted, the mo_source file will be removed upon the next use of [as.mo()]. If the mo_source file is manually deleted (i.e. without using [set_mo_source()]), the references to the mo_source file will be removed upon the next use of [as.mo()].
|
||||
#' @export
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
set_mo_source <- function(path) {
|
||||
|
||||
file_location <- path.expand("~/mo_source.rds")
|
||||
|
||||
stop_ifnot(length(path) == 1, "`path` must be of length 1")
|
||||
|
||||
if (is.null(path) || path %in% c(FALSE, "")) {
|
||||
options(mo_source = NULL)
|
||||
options(mo_source_timestamp = NULL)
|
||||
if (file.exists(file_location)) {
|
||||
unlink(file_location)
|
||||
message(font_red(paste0("Removed mo_source file '", font_bold(file_location), "'")))
|
||||
}
|
||||
return(invisible())
|
||||
}
|
||||
|
||||
stop_ifnot(file.exists(path),
|
||||
"file not found: ", path)
|
||||
|
||||
if (path %like% "[.]rds$") {
|
||||
df <- readRDS(path)
|
||||
|
||||
} else if (path %like% "[.]xlsx?$") {
|
||||
# is Excel file (old or new)
|
||||
read_excel <- import_fn("read_excel", "readxl")
|
||||
df <- read_excel(path)
|
||||
|
||||
} else if (path %like% "[.]tsv$") {
|
||||
df <- utils::read.table(header = TRUE, sep = "\t", stringsAsFactors = FALSE)
|
||||
|
||||
} else {
|
||||
# try comma first
|
||||
try(
|
||||
df <- utils::read.table(header = TRUE, sep = ",", stringsAsFactors = FALSE),
|
||||
silent = TRUE)
|
||||
if (!mo_source_isvalid(df, stop_on_error = FALSE)) {
|
||||
# try tab
|
||||
try(
|
||||
df <- utils::read.table(header = TRUE, sep = "\t", stringsAsFactors = FALSE),
|
||||
silent = TRUE)
|
||||
}
|
||||
if (!mo_source_isvalid(df, stop_on_error = FALSE)) {
|
||||
# try pipe
|
||||
try(
|
||||
df <- utils::read.table(header = TRUE, sep = "|", stringsAsFactors = FALSE),
|
||||
silent = TRUE)
|
||||
}
|
||||
}
|
||||
|
||||
# check integrity
|
||||
mo_source_isvalid(df)
|
||||
|
||||
df <- subset(df, !is.na(mo))
|
||||
|
||||
# keep only first two columns, second must be mo
|
||||
if (colnames(df)[1] == "mo") {
|
||||
df <- df[, c(colnames(df)[2], "mo")]
|
||||
} else {
|
||||
df <- df[, c(colnames(df)[1], "mo")]
|
||||
}
|
||||
|
||||
df <- as.data.frame(df, stringAsFactors = FALSE)
|
||||
|
||||
# success
|
||||
if (file.exists(file_location)) {
|
||||
action <- "Updated"
|
||||
} else {
|
||||
action <- "Created"
|
||||
}
|
||||
saveRDS(df, file_location)
|
||||
options(mo_source = path)
|
||||
options(mo_source_timestamp = as.character(file.info(path)$mtime))
|
||||
message(font_blue(paste0("NOTE: ",
|
||||
action, " mo_source file '", font_bold(file_location), "'",
|
||||
" from '", font_bold(path), "'",
|
||||
'\n (columns "', colnames(df)[1], '" and "', colnames(df)[2], '")')))
|
||||
}
|
||||
|
||||
#' @rdname mo_source
|
||||
#' @export
|
||||
get_mo_source <- function() {
|
||||
if (is.null(getOption("mo_source", NULL))) {
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
if (!file.exists(path.expand("~/mo_source.rds"))) {
|
||||
options(mo_source = NULL)
|
||||
options(mo_source_timestamp = NULL)
|
||||
message(font_blue("NOTE: Removed references to deleted mo_source file (see ?mo_source)"))
|
||||
return(NULL)
|
||||
}
|
||||
|
||||
old_time <- as.POSIXct(getOption("mo_source_timestamp"))
|
||||
new_time <- as.POSIXct(as.character(file.info(getOption("mo_source", ""))$mtime))
|
||||
|
||||
if (is.na(new_time)) {
|
||||
# source file was deleted, remove reference too
|
||||
set_mo_source("")
|
||||
return(NULL)
|
||||
}
|
||||
if (new_time != old_time) {
|
||||
# set updated source
|
||||
set_mo_source(getOption("mo_source"))
|
||||
}
|
||||
file_location <- path.expand("~/mo_source.rds")
|
||||
readRDS(file_location)
|
||||
}
|
||||
|
||||
mo_source_isvalid <- function(x, refer_to_name = "`reference_df`", stop_on_error = TRUE) {
|
||||
|
||||
check_dataset_integrity()
|
||||
|
||||
if (deparse(substitute(x)) == "get_mo_source()") {
|
||||
return(TRUE)
|
||||
}
|
||||
if (identical(x, get_mo_source())) {
|
||||
return(TRUE)
|
||||
}
|
||||
if (is.null(x)) {
|
||||
if (stop_on_error == TRUE) {
|
||||
stop(refer_to_name, " cannot be NULL", call. = FALSE)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
}
|
||||
if (!is.data.frame(x)) {
|
||||
if (stop_on_error == TRUE) {
|
||||
stop(refer_to_name, " must be a data.frame", call. = FALSE)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
}
|
||||
if (!"mo" %in% colnames(x)) {
|
||||
if (stop_on_error == TRUE) {
|
||||
stop(refer_to_name, " must contain a column 'mo'", call. = FALSE)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
}
|
||||
if (!all(x$mo %in% c("", microorganisms$mo, microorganisms.translation$mo_old), na.rm = TRUE)) {
|
||||
if (stop_on_error == TRUE) {
|
||||
invalid <- x[which(!x$mo %in% c("", microorganisms$mo, microorganisms.translation$mo_old)), , drop = FALSE]
|
||||
if (nrow(invalid) > 1) {
|
||||
plural <- "s"
|
||||
} else {
|
||||
plural <- ""
|
||||
}
|
||||
stop("Value", plural, " ", paste0("'", invalid[, 1, drop = TRUE], "'", collapse = ", "),
|
||||
" found in ", tolower(refer_to_name),
|
||||
", but with invalid microorganism code", plural, " ", paste0("'", invalid$mo, "'", collapse = ", "),
|
||||
call. = FALSE)
|
||||
} else {
|
||||
return(FALSE)
|
||||
}
|
||||
}
|
||||
TRUE
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' 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 `p = 1` will return `NA`.
|
||||
#' @inheritSection lifecycle Questioning lifecycle
|
||||
#' @param p p value
|
||||
#' @param emptychar text to show when `p > 0.1`
|
||||
#' @return Text
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
p_symbol <- function(p, emptychar = " ") {
|
||||
|
||||
p <- as.double(p)
|
||||
s <- rep(NA_character_, length(p))
|
||||
|
||||
s[p <= 1] <- emptychar
|
||||
s[p <= 0.100] <- "."
|
||||
s[p <= 0.050] <- "*"
|
||||
s[p <= 0.010] <- "**"
|
||||
s[p <= 0.001] <- "***"
|
||||
|
||||
s
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Principal Component Analysis (for AMR)
|
||||
#'
|
||||
#' Performs a principal component analysis (PCA) based on a data set with automatic determination for afterwards plotting the groups and labels, and automatic filtering on only suitable (i.e. non-empty and numeric) variables.
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param x a [data.frame] containing numeric columns
|
||||
#' @param ... columns of `x` to be selected for PCA, can be unquoted since it supports quasiquotation.
|
||||
#' @inheritParams stats::prcomp
|
||||
#' @details The [pca()] function takes a [data.frame] as input and performs the actual PCA with the \R function [prcomp()].
|
||||
#'
|
||||
#' The result of the [pca()] function is a [prcomp] object, with an additional attribute `non_numeric_cols` which is a vector with the column names of all columns that do not contain numeric values. These are probably the groups and labels, and will be used by [ggplot_pca()].
|
||||
#' @return An object of classes [pca] and [prcomp]
|
||||
#' @importFrom stats prcomp
|
||||
#' @export
|
||||
#' @examples
|
||||
#' # `example_isolates` is a dataset available in the AMR package.
|
||||
#' # See ?example_isolates.
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' # calculate the resistance per group first
|
||||
#' library(dplyr)
|
||||
#' 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.rsi, resistance) # then get resistance of all drugs
|
||||
#'
|
||||
#' # now conduct PCA for certain antimicrobial agents
|
||||
#' pca_result <- resistance_data %>%
|
||||
#' pca(AMC, CXM, CTX, CAZ, GEN, TOB, TMP, SXT)
|
||||
#'
|
||||
#' pca_result
|
||||
#' summary(pca_result)
|
||||
#' biplot(pca_result)
|
||||
#' ggplot_pca(pca_result) # a new and convenient plot function
|
||||
#' }
|
||||
pca <- function(x,
|
||||
...,
|
||||
retx = TRUE,
|
||||
center = TRUE,
|
||||
scale. = TRUE,
|
||||
tol = NULL,
|
||||
rank. = NULL) {
|
||||
|
||||
stop_ifnot(is.data.frame(x), "`x` must be a data.frame")
|
||||
stop_if(any(dim(x) == 0), "`x` must contain rows and columns")
|
||||
|
||||
# unset data.table, tibble, etc.
|
||||
# also removes groups made by dplyr::group_by
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
x.bak <- x
|
||||
|
||||
# defuse R expressions, this replaces rlang::enquos()
|
||||
dots <- substitute(list(...))
|
||||
if (length(dots) > 1) {
|
||||
new_list <- list(0)
|
||||
for (i in seq_len(length(dots) - 1)) {
|
||||
new_list[[i]] <- tryCatch(eval(dots[[i + 1]], envir = x),
|
||||
error = function(e) stop(e$message, call. = FALSE))
|
||||
if (length(new_list[[i]]) == 1) {
|
||||
if (is.character(new_list[[i]]) & new_list[[i]] %in% colnames(x)) {
|
||||
# this is to support quoted variables: df %>% pca("mycol1", "mycol2")
|
||||
new_list[[i]] <- x[, new_list[[i]]]
|
||||
} else {
|
||||
# remove item - it's a parameter like `center`
|
||||
new_list[[i]] <- NULL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x <- as.data.frame(new_list, stringsAsFactors = FALSE)
|
||||
if (any(sapply(x, function(y) !is.numeric(y)))) {
|
||||
warning("Be sure to first calculate the resistance (or susceptibility) of variables with antimicrobial test results, since PCA works with numeric variables only. Please see Examples in ?pca.")
|
||||
}
|
||||
|
||||
# set column names
|
||||
tryCatch(colnames(x) <- as.character(dots)[2:length(dots)],
|
||||
error = function(e) warning("column names could not be set"))
|
||||
|
||||
# keep only numeric columns
|
||||
x <- x[, sapply(x, function(y) is.numeric(y))]
|
||||
# bind the data set with the non-numeric columns
|
||||
x <- cbind(x.bak[, sapply(x.bak, function(y) !is.numeric(y) & !all(is.na(y))), drop = FALSE], x)
|
||||
}
|
||||
|
||||
x <- ungroup(x) # would otherwise select the grouping vars
|
||||
x <- x[rowSums(is.na(x)) == 0, ] # remove columns containing NAs
|
||||
|
||||
pca_data <- x[, which(sapply(x, function(x) is.numeric(x)))]
|
||||
|
||||
message(font_blue(paste0("NOTE: Columns selected for PCA: ", paste0(font_bold(colnames(pca_data)), collapse = "/"),
|
||||
".\n Total observations available: ", nrow(pca_data), ".")))
|
||||
|
||||
pca_model <- prcomp(pca_data, retx = retx, center = center, scale. = scale., tol = tol, rank. = rank.)
|
||||
attr(pca_model, "non_numeric_cols") <- x[, sapply(x, function(y) !is.numeric(y) & !all(is.na(y))), drop = FALSE]
|
||||
class(pca_model) <- c("pca", class(pca_model))
|
||||
pca_model
|
||||
}
|
||||
@@ -1,284 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Calculate microbial resistance
|
||||
#'
|
||||
#' @description These functions can be used to calculate the (co-)resistance or susceptibility of microbial isolates (i.e. percentage of S, SI, I, IR or R). All functions support quasiquotation with pipes, can be used in `summarise()` from the `dplyr` package and also support grouped variables, please see *Examples*.
|
||||
#'
|
||||
#' [resistance()] should be used to calculate resistance, [susceptibility()] should be used to calculate susceptibility.\cr
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @param ... one or more vectors (or columns) with antibiotic interpretations. They will be transformed internally with [as.rsi()] if needed. Use multiple columns to calculate (the lack of) co-resistance: the probability where one of two drugs have a resistant or susceptible result. See Examples.
|
||||
#' @param minimum the minimum allowed number of available (tested) isolates. Any isolate count lower than `minimum` will return `NA` with a warning. The default number of `30` isolates is advised by the Clinical and Laboratory Standards Institute (CLSI) as best practice, see Source.
|
||||
#' @param as_percent a logical to indicate whether the output must be returned as a hundred fold with % sign (a character). A value of `0.123456` will then be returned as `"12.3%"`.
|
||||
#' @param only_all_tested (for combination therapies, i.e. using more than one variable for `...`): a logical to indicate that isolates must be tested for all antibiotics, see section *Combination therapy* below
|
||||
#' @param data a [`data.frame`] containing columns with class [`rsi`] (see [as.rsi()])
|
||||
#' @param translate_ab a column name of the [antibiotics] data set to translate the antibiotic abbreviations to, using [ab_property()]. Use a value
|
||||
#' @inheritParams ab_property
|
||||
#' @param combine_SI a logical to indicate whether all values of S and I must be merged into one, so the output only consists of S+I vs. R (susceptible vs. resistant). This used to be the parameter `combine_IR`, but this now follows the redefinition by EUCAST about the interpretion of I (increased exposure) in 2019, see section 'Interpretation of S, I and R' below. Default is `TRUE`.
|
||||
#' @param combine_IR a logical to indicate whether all values of I and R must be merged into one, so the output only consists of S vs. I+R (susceptible vs. non-susceptible). This is outdated, see parameter `combine_SI`.
|
||||
#' @inheritSection as.rsi Interpretation of R and S/I
|
||||
#' @details
|
||||
#' The function [resistance()] is equal to the function [proportion_R()]. The function [susceptibility()] is equal to the function [proportion_SI()].
|
||||
#'
|
||||
#' **Remember that you should filter your table to let it contain only first isolates!** This is needed to exclude duplicates and to reduce selection bias. Use [first_isolate()] to determine them in your data set.
|
||||
#'
|
||||
#' These functions are not meant to count isolates, but to calculate the proportion of resistance/susceptibility. Use the [`count()`][AMR::count()] functions to count isolates. The function [susceptibility()] is essentially equal to `count_susceptible() / count_all()`. *Low counts can influence the outcome - the `proportion` functions may camouflage this, since they only return the proportion (albeit being dependent on the `minimum` parameter).*
|
||||
#'
|
||||
#' The function [proportion_df()] takes any variable from `data` that has an [`rsi`] class (created with [as.rsi()]) and calculates the proportions R, I and S. It also supports grouped variables. The function [rsi_df()] works exactly like [proportion_df()], but adds the number of isolates.
|
||||
#' @section Combination therapy:
|
||||
#' When using more than one variable for `...` (= combination therapy)), use `only_all_tested` to only count isolates that are tested for all antibiotics/variables that you test them for. See this example for two antibiotics, Drug A and Drug B, about how [susceptibility()] works to calculate the %SI:
|
||||
#'
|
||||
#' ```
|
||||
#' --------------------------------------------------------------------
|
||||
#' only_all_tested = FALSE only_all_tested = TRUE
|
||||
#' ----------------------- -----------------------
|
||||
#' Drug A Drug B include as include as include as include as
|
||||
#' numerator denominator numerator denominator
|
||||
#' -------- -------- ---------- ----------- ---------- -----------
|
||||
#' S or I S or I X X X X
|
||||
#' R S or I X X X X
|
||||
#' <NA> S or I X X - -
|
||||
#' S or I R X X X X
|
||||
#' R R - X - X
|
||||
#' <NA> R - - - -
|
||||
#' S or I <NA> X X - -
|
||||
#' R <NA> - - - -
|
||||
#' <NA> <NA> - - - -
|
||||
#' --------------------------------------------------------------------
|
||||
#' ```
|
||||
#'
|
||||
#' Please note that, in combination therapies, for `only_all_tested = TRUE` applies that:
|
||||
#' ```
|
||||
#' count_S() + count_I() + count_R() = count_all()
|
||||
#' proportion_S() + proportion_I() + proportion_R() = 1
|
||||
#' ```
|
||||
#' and that, in combination therapies, for `only_all_tested = FALSE` applies that:
|
||||
#' ```
|
||||
#' count_S() + count_I() + count_R() >= count_all()
|
||||
#' proportion_S() + proportion_I() + proportion_R() >= 1
|
||||
#' ```
|
||||
#'
|
||||
#' Using `only_all_tested` has no impact when only using one antibiotic as input.
|
||||
#' @source **M39 Analysis and Presentation of Cumulative Antimicrobial Susceptibility Test Data, 4th Edition**, 2014, *Clinical and Laboratory Standards Institute (CLSI)*. <https://clsi.org/standards/products/microbiology/documents/m39/>.
|
||||
#' @seealso [AMR::count()] to count resistant and susceptible isolates.
|
||||
#' @return A [`double`] or, when `as_percent = TRUE`, a [`character`].
|
||||
#' @rdname proportion
|
||||
#' @aliases portion
|
||||
#' @name proportion
|
||||
#' @export
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' # example_isolates is a data set available in the AMR package.
|
||||
#' ?example_isolates
|
||||
#'
|
||||
#' resistance(example_isolates$AMX) # determines %R
|
||||
#' susceptibility(example_isolates$AMX) # determines %S+I
|
||||
#'
|
||||
#' # be more specific
|
||||
#' proportion_S(example_isolates$AMX)
|
||||
#' proportion_SI(example_isolates$AMX)
|
||||
#' proportion_I(example_isolates$AMX)
|
||||
#' proportion_IR(example_isolates$AMX)
|
||||
#' proportion_R(example_isolates$AMX)
|
||||
#'
|
||||
#' if (require("dplyr")) {
|
||||
#' example_isolates %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' summarise(r = resistance(CIP),
|
||||
#' n = n_rsi(CIP)) # n_rsi works like n_distinct in dplyr, see ?n_rsi
|
||||
#'
|
||||
#' example_isolates %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' summarise(R = resistance(CIP, as_percent = TRUE),
|
||||
#' SI = susceptibility(CIP, as_percent = TRUE),
|
||||
#' n1 = count_all(CIP), # the actual total; sum of all three
|
||||
#' n2 = n_rsi(CIP), # same - analogous to n_distinct
|
||||
#' total = n()) # NOT the number 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:
|
||||
#' example_isolates %>% susceptibility(AMC) # %SI = 76.3%
|
||||
#' example_isolates %>% count_all(AMC) # n = 1879
|
||||
#'
|
||||
#' example_isolates %>% susceptibility(GEN) # %SI = 75.4%
|
||||
#' example_isolates %>% count_all(GEN) # n = 1855
|
||||
#'
|
||||
#' example_isolates %>% susceptibility(AMC, GEN) # %SI = 94.1%
|
||||
#' example_isolates %>% count_all(AMC, GEN) # n = 1939
|
||||
#'
|
||||
#'
|
||||
#' # See Details on how `only_all_tested` works. Example:
|
||||
#' example_isolates %>%
|
||||
#' summarise(numerator = count_susceptible(AMC, GEN),
|
||||
#' denominator = count_all(AMC, GEN),
|
||||
#' proportion = susceptibility(AMC, GEN))
|
||||
#'
|
||||
#' example_isolates %>%
|
||||
#' summarise(numerator = count_susceptible(AMC, GEN, only_all_tested = TRUE),
|
||||
#' denominator = count_all(AMC, GEN, only_all_tested = TRUE),
|
||||
#' proportion = susceptibility(AMC, GEN, only_all_tested = TRUE))
|
||||
#'
|
||||
#'
|
||||
#' example_isolates %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' summarise(cipro_p = susceptibility(CIP, as_percent = TRUE),
|
||||
#' cipro_n = count_all(CIP),
|
||||
#' genta_p = susceptibility(GEN, as_percent = TRUE),
|
||||
#' genta_n = count_all(GEN),
|
||||
#' combination_p = susceptibility(CIP, GEN, as_percent = TRUE),
|
||||
#' combination_n = count_all(CIP, GEN))
|
||||
#'
|
||||
#' # Get proportions S/I/R immediately of all rsi columns
|
||||
#' example_isolates %>%
|
||||
#' select(AMX, CIP) %>%
|
||||
#' proportion_df(translate = FALSE)
|
||||
#'
|
||||
#' # It also supports grouping variables
|
||||
#' example_isolates %>%
|
||||
#' select(hospital_id, AMX, CIP) %>%
|
||||
#' group_by(hospital_id) %>%
|
||||
#' proportion_df(translate = FALSE)
|
||||
#' }
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' # calculate current empiric combination therapy of Helicobacter gastritis:
|
||||
#' my_table %>%
|
||||
#' filter(first_isolate == TRUE,
|
||||
#' genus == "Helicobacter") %>%
|
||||
#' summarise(p = susceptibility(AMX, MTR), # amoxicillin with metronidazole
|
||||
#' n = count_all(AMX, MTR))
|
||||
#' }
|
||||
resistance <- function(...,
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = "R",
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
susceptibility <- function(...,
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = c("S", "I"),
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
proportion_R <- function(...,
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = "R",
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
proportion_IR <- function(...,
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = c("I", "R"),
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
proportion_I <- function(...,
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = "I",
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
proportion_SI <- function(...,
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = c("S", "I"),
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
proportion_S <- function(...,
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE) {
|
||||
rsi_calc(...,
|
||||
ab_result = "S",
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
only_all_tested = only_all_tested,
|
||||
only_count = FALSE)
|
||||
}
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
proportion_df <- function(data,
|
||||
translate_ab = "name",
|
||||
language = get_locale(),
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE) {
|
||||
|
||||
rsi_calc_df(type = "proportion",
|
||||
data = data,
|
||||
translate_ab = translate_ab,
|
||||
language = language,
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
combine_SI = combine_SI,
|
||||
combine_IR = combine_IR,
|
||||
combine_SI_missing = missing(combine_SI))
|
||||
}
|
||||
@@ -1,381 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' 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 `se_min` and `se_max`. See *Examples* for a real live example.
|
||||
#' @inheritSection lifecycle Maturing lifecycle
|
||||
#' @param col_ab column name of `x` containing antimicrobial interpretations (`"R"`, `"I"` and `"S"`)
|
||||
#' @param col_date column name of the date, will be used to calculate years if this column doesn't consist of years already, defaults to the first column of with a date class
|
||||
#' @param year_min lowest year to use in the prediction model, dafaults to the lowest year in `col_date`
|
||||
#' @param year_max highest year to use in the prediction model, defaults to 10 years after today
|
||||
#' @param year_every unit of sequence between lowest year found in the data and `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. 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.
|
||||
#' @param I_as_S a logical to indicate whether values `I` should be treated as `S` (will otherwise be treated as `R`). The default, `TRUE`, follows the redefinition by EUCAST about the interpretion of I (increased exposure) in 2019, see section *Interpretation of S, I and R* below.
|
||||
#' @param preserve_measurements a logical to indicate whether predictions of years that are actually available in the data should be overwritten by the original data. The standard errors of those years will be `NA`.
|
||||
#' @param info a logical to indicate whether textual analysis should be printed with the name and [summary()] of the statistical model.
|
||||
#' @param main title of the plot
|
||||
#' @param ribbon a logical to indicate whether a ribbon should be shown (default) or error bars
|
||||
#' @param ... parameters passed on to functions
|
||||
#' @inheritSection as.rsi Interpretation of R and S/I
|
||||
#' @inheritParams first_isolate
|
||||
#' @inheritParams graphics::plot
|
||||
#' @details Valid options for the statistical model (parameter `model`) are:
|
||||
#' - `"binomial"` or `"binom"` or `"logit"`: a generalised linear regression model with binomial distribution
|
||||
#' - `"loglin"` or `"poisson"`: a generalised log-linear regression model with poisson distribution
|
||||
#' - `"lin"` or `"linear"`: a linear regression model
|
||||
#' @return A [`data.frame`] with extra class [`resistance_predict`] with columns:
|
||||
#' - `year`
|
||||
#' - `value`, the same as `estimated` when `preserve_measurements = FALSE`, and a combination of `observed` and `estimated` otherwise
|
||||
#' - `se_min`, the lower bound of the standard error with a minimum of `0` (so the standard error will never go below 0%)
|
||||
#' - `se_max` the upper bound of the standard error with a maximum of `1` (so the standard error will never go above 100%)
|
||||
#' - `observations`, the total number of available observations in that year, i.e. \eqn{S + I + R}
|
||||
#' - `observed`, the original observed resistant percentages
|
||||
#' - `estimated`, the estimated resistant percentages, calculated by the model
|
||||
#'
|
||||
#' Furthermore, the model itself is available as an attribute: `attributes(x)$model`, please see *Examples*.
|
||||
#' @seealso The [proportion()] functions to calculate resistance
|
||||
#'
|
||||
#' Models: [lm()] [glm()]
|
||||
#' @rdname resistance_predict
|
||||
#' @export
|
||||
#' @importFrom stats predict glm lm
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' x <- resistance_predict(example_isolates,
|
||||
#' col_ab = "AMX",
|
||||
#' year_min = 2010,
|
||||
#' model = "binomial")
|
||||
#' plot(x)
|
||||
#' if (require("ggplot2")) {
|
||||
#' ggplot_rsi_predict(x)
|
||||
#' }
|
||||
#'
|
||||
#' # using dplyr:
|
||||
#' if (require("dplyr")) {
|
||||
#' x <- example_isolates %>%
|
||||
#' filter_first_isolate() %>%
|
||||
#' filter(mo_genus(mo) == "Staphylococcus") %>%
|
||||
#' resistance_predict("PEN", model = "binomial")
|
||||
#' plot(x)
|
||||
#'
|
||||
#' # get the model from the object
|
||||
#' mymodel <- attributes(x)$model
|
||||
#' summary(mymodel)
|
||||
#' }
|
||||
#'
|
||||
#' # create nice plots with ggplot2 yourself
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' library(ggplot2)
|
||||
#'
|
||||
#' data <- example_isolates %>%
|
||||
#' filter(mo == as.mo("E. coli")) %>%
|
||||
#' resistance_predict(col_ab = "AMX",
|
||||
#' col_date = "date",
|
||||
#' model = "binomial",
|
||||
#' 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 = "%R",
|
||||
#' x = "Year") +
|
||||
#' theme_minimal(base_size = 13)
|
||||
#' }
|
||||
resistance_predict <- function(x,
|
||||
col_ab,
|
||||
col_date = NULL,
|
||||
year_min = NULL,
|
||||
year_max = NULL,
|
||||
year_every = 1,
|
||||
minimum = 30,
|
||||
model = NULL,
|
||||
I_as_S = TRUE,
|
||||
preserve_measurements = TRUE,
|
||||
info = interactive(),
|
||||
...) {
|
||||
|
||||
stop_ifnot(is.data.frame(x), "`x` must be a data.frame")
|
||||
stop_if(any(dim(x) == 0), "`x` must contain rows and columns")
|
||||
stop_if(is.null(model), 'choose a regression model with the `model` parameter, e.g. resistance_predict(..., model = "binomial")')
|
||||
stop_ifnot(col_ab %in% colnames(x),
|
||||
"column `", col_ab, "` not found")
|
||||
|
||||
dots <- unlist(list(...))
|
||||
if (length(dots) != 0) {
|
||||
# backwards compatibility with old parameters
|
||||
dots.names <- dots %>% names()
|
||||
if ("tbl" %in% dots.names) {
|
||||
x <- dots[which(dots.names == "tbl")]
|
||||
}
|
||||
if ("I_as_R" %in% dots.names) {
|
||||
warning("`I_as_R is deprecated - use I_as_S instead.", call. = FALSE)
|
||||
}
|
||||
}
|
||||
|
||||
# -- date
|
||||
if (is.null(col_date)) {
|
||||
col_date <- search_type_in_df(x = x, type = "date")
|
||||
stop_if(is.null(col_date), "`col_date` must be set")
|
||||
}
|
||||
stop_ifnot(col_date %in% colnames(x),
|
||||
"column `", col_date, "` not found")
|
||||
|
||||
# no grouped tibbles
|
||||
x <- as.data.frame(x, stringsAsFactors = FALSE)
|
||||
|
||||
year <- function(x) {
|
||||
# don't depend on lubridate or so, would be overkill for only this function
|
||||
if (all(grepl("^[0-9]{4}$", x))) {
|
||||
as.integer(x)
|
||||
} else {
|
||||
as.integer(format(as.Date(x), "%Y"))
|
||||
}
|
||||
}
|
||||
|
||||
df <- x
|
||||
df[, col_ab] <- droplevels(as.rsi(df[, col_ab, drop = TRUE]))
|
||||
if (I_as_S == TRUE) {
|
||||
# then I as S
|
||||
df[, col_ab] <- gsub("I", "S", df[, col_ab, drop = TRUE])
|
||||
} else {
|
||||
# then I as R
|
||||
df[, col_ab] <- gsub("I", "R", df[, col_ab, drop = TRUE])
|
||||
}
|
||||
df[, col_ab] <- ifelse(is.na(df[, col_ab, drop = TRUE]), 0, df[, col_ab, drop = TRUE])
|
||||
|
||||
# remove rows with NAs
|
||||
df <- subset(df, !is.na(df[, col_ab, drop = TRUE]))
|
||||
df$year <- year(df[, col_date, drop = TRUE])
|
||||
df <- as.data.frame(rbind(table(df[, c("year", col_ab)])), stringsAsFactors = FALSE)
|
||||
df$year <- as.integer(rownames(df))
|
||||
rownames(df) <- NULL
|
||||
|
||||
df <- subset(df, sum(df$R + df$S, na.rm = TRUE) >= minimum)
|
||||
df_matrix <- as.matrix(df[, c("R", "S"), drop = FALSE])
|
||||
|
||||
stop_if(NROW(df) == 0, "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()) + 10
|
||||
}
|
||||
|
||||
years <- list(year = seq(from = year_min, to = year_max, by = year_every))
|
||||
|
||||
if (model %in% c("binomial", "binom", "logit")) {
|
||||
model <- "binomial"
|
||||
model_lm <- with(df, glm(df_matrix ~ year, family = binomial))
|
||||
if (info == TRUE) {
|
||||
cat("\nLogistic regression model (logit) with binomial distribution")
|
||||
cat("\n------------------------------------------------------------\n")
|
||||
print(summary(model_lm))
|
||||
}
|
||||
|
||||
predictmodel <- predict(model_lm, newdata = years, type = "response", se.fit = TRUE)
|
||||
prediction <- predictmodel$fit
|
||||
se <- predictmodel$se.fit
|
||||
|
||||
} else if (model %in% c("loglin", "poisson")) {
|
||||
model <- "poisson"
|
||||
model_lm <- with(df, glm(R ~ year, family = poisson))
|
||||
if (info == TRUE) {
|
||||
cat("\nLog-linear regression model (loglin) with poisson distribution")
|
||||
cat("\n--------------------------------------------------------------\n")
|
||||
print(summary(model_lm))
|
||||
}
|
||||
|
||||
predictmodel <- predict(model_lm, newdata = years, type = "response", se.fit = TRUE)
|
||||
prediction <- predictmodel$fit
|
||||
se <- predictmodel$se.fit
|
||||
|
||||
} else if (model %in% c("lin", "linear")) {
|
||||
model <- "linear"
|
||||
model_lm <- with(df, lm((R / (R + S)) ~ year))
|
||||
if (info == TRUE) {
|
||||
cat("\nLinear regression model")
|
||||
cat("\n-----------------------\n")
|
||||
print(summary(model_lm))
|
||||
}
|
||||
|
||||
predictmodel <- predict(model_lm, newdata = years, se.fit = TRUE)
|
||||
prediction <- predictmodel$fit
|
||||
se <- predictmodel$se.fit
|
||||
|
||||
} else {
|
||||
stop("no valid model selected. See ?resistance_predict.")
|
||||
}
|
||||
|
||||
# prepare the output dataframe
|
||||
df_prediction <- data.frame(year = unlist(years),
|
||||
value = prediction,
|
||||
se_min = prediction - se,
|
||||
se_max = prediction + se,
|
||||
stringsAsFactors = FALSE)
|
||||
|
||||
if (model == "poisson") {
|
||||
df_prediction$value <- as.integer(format(df_prediction$value, scientific = FALSE))
|
||||
df_prediction$se_min <- as.integer(df_prediction$se_min)
|
||||
df_prediction$se_max <- as.integer(df_prediction$se_max)
|
||||
|
||||
} else {
|
||||
# se_max not above 1
|
||||
df_prediction$se_max <- ifelse(df_prediction$se_max > 1, 1, df_prediction$se_max)
|
||||
}
|
||||
# se_min not below 0
|
||||
df_prediction$se_min <- ifelse(df_prediction$se_min < 0, 0, df_prediction$se_min)
|
||||
|
||||
df_observations <- data.frame(year = df$year,
|
||||
observations = df$R + df$S,
|
||||
observed = df$R / (df$R + df$S),
|
||||
stringsAsFactors = FALSE)
|
||||
df_prediction <- df_prediction %>%
|
||||
left_join(df_observations, by = "year")
|
||||
df_prediction$estimated <- df_prediction$value
|
||||
|
||||
if (preserve_measurements == TRUE) {
|
||||
# replace estimated data by observed data
|
||||
df_prediction$value <- ifelse(!is.na(df_prediction$observed), df_prediction$observed, df_prediction$value)
|
||||
df_prediction$se_min <- ifelse(!is.na(df_prediction$observed), NA, df_prediction$se_min)
|
||||
df_prediction$se_max <- ifelse(!is.na(df_prediction$observed), NA, df_prediction$se_max)
|
||||
}
|
||||
|
||||
df_prediction$value <- ifelse(df_prediction$value > 1, 1, ifelse(df_prediction$value < 0, 0, df_prediction$value))
|
||||
df_prediction <- df_prediction[order(df_prediction$year), ]
|
||||
|
||||
structure(
|
||||
.Data = df_prediction,
|
||||
class = c("resistance_predict", "data.frame"),
|
||||
I_as_S = I_as_S,
|
||||
model_title = model,
|
||||
model = model_lm,
|
||||
ab = col_ab
|
||||
)
|
||||
}
|
||||
|
||||
#' @rdname resistance_predict
|
||||
#' @export
|
||||
rsi_predict <- resistance_predict
|
||||
|
||||
#' @method plot resistance_predict
|
||||
#' @export
|
||||
#' @importFrom graphics axis arrows points
|
||||
#' @rdname resistance_predict
|
||||
plot.resistance_predict <- function(x, main = paste("Resistance Prediction of", x_name), ...) {
|
||||
x_name <- paste0(ab_name(attributes(x)$ab), " (", attributes(x)$ab, ")")
|
||||
|
||||
if (attributes(x)$I_as_S == TRUE) {
|
||||
ylab <- "%R"
|
||||
} else {
|
||||
ylab <- "%IR"
|
||||
}
|
||||
# get plot() generic; this was moved from the 'graphics' pkg to the 'base' pkg in R 4.0.0
|
||||
if (as.integer(R.Version()$major) >= 4) {
|
||||
plot <- import_fn("plot", "base")
|
||||
} else {
|
||||
plot <- import_fn("plot", "graphics")
|
||||
}
|
||||
plot(x = x$year,
|
||||
y = x$value,
|
||||
ylim = c(0, 1),
|
||||
yaxt = "n", # no y labels
|
||||
pch = 19, # closed dots
|
||||
ylab = paste0("Percentage (", ylab, ")"),
|
||||
xlab = "Year",
|
||||
main = main,
|
||||
sub = paste0("(n = ", sum(x$observations, na.rm = TRUE),
|
||||
", model: ", attributes(x)$model_title, ")"),
|
||||
cex.sub = 0.75)
|
||||
|
||||
|
||||
axis(side = 2, at = seq(0, 1, 0.1), labels = paste0(0:10 * 10, "%"))
|
||||
|
||||
# hack for error bars: https://stackoverflow.com/a/22037078/4575331
|
||||
arrows(x0 = x$year,
|
||||
y0 = x$se_min,
|
||||
x1 = x$year,
|
||||
y1 = x$se_max,
|
||||
length = 0.05, angle = 90, code = 3, lwd = 1.5)
|
||||
|
||||
# overlay grey points for prediction
|
||||
points(x = subset(x, is.na(observations))$year,
|
||||
y = subset(x, is.na(observations))$value,
|
||||
pch = 19,
|
||||
col = "grey40")
|
||||
}
|
||||
|
||||
#' @rdname resistance_predict
|
||||
#' @export
|
||||
ggplot_rsi_predict <- function(x,
|
||||
main = paste("Resistance Prediction of", x_name),
|
||||
ribbon = TRUE,
|
||||
...) {
|
||||
|
||||
stop_ifnot_installed("ggplot2")
|
||||
stop_ifnot(inherits(x, "resistance_predict"), "`x` must be a resistance prediction model created with resistance_predict()")
|
||||
|
||||
x_name <- paste0(ab_name(attributes(x)$ab), " (", attributes(x)$ab, ")")
|
||||
|
||||
if (attributes(x)$I_as_S == TRUE) {
|
||||
ylab <- "%R"
|
||||
} else {
|
||||
ylab <- "%IR"
|
||||
}
|
||||
|
||||
p <- ggplot2::ggplot(x, ggplot2::aes(x = year, y = value)) +
|
||||
ggplot2::geom_point(data = subset(x, !is.na(observations)),
|
||||
size = 2) +
|
||||
scale_y_percent(limits = c(0, 1)) +
|
||||
ggplot2::labs(title = main,
|
||||
y = paste0("Percentage (", ylab, ")"),
|
||||
x = "Year",
|
||||
caption = paste0("(n = ", sum(x$observations, na.rm = TRUE),
|
||||
", model: ", attributes(x)$model_title, ")"))
|
||||
|
||||
if (ribbon == TRUE) {
|
||||
p <- p + ggplot2::geom_ribbon(ggplot2::aes(ymin = se_min, ymax = se_max), alpha = 0.25)
|
||||
} else {
|
||||
p <- p + ggplot2::geom_errorbar(ggplot2::aes(ymin = se_min, ymax = se_max), na.rm = TRUE, width = 0.5)
|
||||
}
|
||||
p <- p +
|
||||
# overlay grey points for prediction
|
||||
ggplot2::geom_point(data = subset(x, is.na(observations)),
|
||||
size = 2,
|
||||
colour = "grey40")
|
||||
p
|
||||
}
|
||||
@@ -1,703 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Class 'rsi'
|
||||
#'
|
||||
#' Interpret minimum inhibitory concentration (MIC) values and disk diffusion diameters according to EUCAST or CLSI, or clean up existing R/SI values. This transforms the input to a new class [`rsi`], which is an ordered factor with levels `S < I < R`. Invalid antimicrobial interpretations will be translated as `NA` with a warning.
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @rdname as.rsi
|
||||
#' @param x vector of values (for class [`mic`]: an MIC value in mg/L, for class [`disk`]: a disk diffusion radius in millimetres)
|
||||
#' @param mo any (vector of) text that can be coerced to a valid microorganism code with [as.mo()]
|
||||
#' @param ab any (vector of) text that can be coerced to a valid antimicrobial code with [as.ab()]
|
||||
#' @param uti (Urinary Tract Infection) A vector with [logical]s (`TRUE` or `FALSE`) to specify whether a UTI specific interpretation from the guideline should be chosen. For using [as.rsi()] on a [data.frame], this can also be a column containing [logical]s or when left blank, the data set will be search for a 'specimen' and rows containing 'urin' in that column will be regarded isolates from a UTI. See *Examples*.
|
||||
#' @inheritParams first_isolate
|
||||
#' @param guideline defaults to the latest included EUCAST guideline, see Details for all options
|
||||
#' @param conserve_capped_values a logical to indicate that MIC values starting with `">"` (but not `">="`) must always return "R" , and that MIC values starting with `"<"` (but not `"<="`) must always return "S"
|
||||
#' @param threshold maximum fraction of invalid antimicrobial interpretations of `x`, please see *Examples*
|
||||
#' @param ... parameters passed on to methods
|
||||
#' @details
|
||||
#' When using [as.rsi()] on untransformed data, the data will be cleaned to only contain values S, I and R. When using the function on data with class [`mic`] (using [as.mic()]) or class [`disk`] (using [as.disk()]), the data will be interpreted based on the guideline set with the `guideline` parameter.
|
||||
#'
|
||||
#' Supported guidelines to be used as input for the `guideline` parameter are: `r paste0('"', sort(unique(AMR::rsi_translation$guideline)), '"', collapse = ", ")`. Simply using `"CLSI"` or `"EUCAST"` for input will automatically select the latest version of that guideline.
|
||||
#'
|
||||
#' When using `conserve_capped_values = TRUE`, an MIC value of e.g. ">2" will always return "R", even if the breakpoint according to the chosen guideline is ">=4". This is to prevent that capped values from raw laboratory data would not be treated conservatively. The default behaviour (`conserve_capped_values = FALSE`) considers ">2" to be lower than ">=4" and will in this case return "S" or "I".
|
||||
#'
|
||||
#' The repository of this package [contains a machine readable version](https://github.com/msberends/AMR/blob/master/data-raw/rsi_translation.txt) of all guidelines. This is a CSV file consisting of `r format(nrow(AMR::rsi_translation), big.mark = ",")` rows and `r ncol(AMR::rsi_translation)` columns. This file is machine readable, since it contains one row for every unique combination of the test method (MIC or disk diffusion), the antimicrobial agent and the microorganism. **This allows for easy implementation of these rules in laboratory information systems (LIS)**. Note that it only contains interpretation guidelines for humans - interpretation guidelines from CLSI for animals were removed.
|
||||
#'
|
||||
#' After using [as.rsi()], you can use [eucast_rules()] to (1) apply inferred susceptibility and resistance based on results of other antimicrobials and (2) apply intrinsic resistance based on taxonomic properties of a microorganism.
|
||||
#'
|
||||
#' The function [is.rsi.eligible()] returns `TRUE` when a columns contains at most 5% invalid antimicrobial interpretations (not S and/or I and/or R), and `FALSE` otherwise. The threshold of 5% can be set with the `threshold` parameter.
|
||||
#' @section Interpretation of R and S/I:
|
||||
#' In 2019, the European Committee on Antimicrobial Susceptibility Testing (EUCAST) has decided to change the definitions of susceptibility testing categories R and S/I as shown below (<http://www.eucast.org/newsiandr/>).
|
||||
#'
|
||||
#' - **R = Resistant**\cr
|
||||
#' A microorganism is categorised as *Resistant* when there is a high likelihood of therapeutic failure even when there is increased exposure. Exposure is a function of how the mode of administration, dose, dosing interval, infusion time, as well as distribution and excretion of the antimicrobial agent will influence the infecting organism at the site of infection.
|
||||
#' - **S = Susceptible**\cr
|
||||
#' A microorganism is categorised as *Susceptible, standard dosing regimen*, when there is a high likelihood of therapeutic success using a standard dosing regimen of the agent.
|
||||
#' - **I = Increased exposure, but still susceptible**\cr
|
||||
#' A microorganism is categorised as *Susceptible, Increased exposure* when there is a high likelihood of therapeutic success because exposure to the agent is increased by adjusting the dosing regimen or by its concentration at the site of infection.
|
||||
#'
|
||||
#' This AMR package honours this new insight. Use [susceptibility()] (equal to [proportion_SI()]) to determine antimicrobial susceptibility and [count_susceptible()] (equal to [count_SI()]) to count susceptible isolates.
|
||||
#' @return Ordered factor with new class [`rsi`]
|
||||
#' @aliases rsi
|
||||
#' @export
|
||||
#' @seealso [as.mic()]
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @examples
|
||||
#' summary(example_isolates) # see all R/SI results at a glance
|
||||
#'
|
||||
#' # For INTERPRETING disk diffusion and MIC values -----------------------
|
||||
#'
|
||||
#' # a whole data set, even with combined MIC values and disk zones
|
||||
#' df <- data.frame(microorganism = "E. coli",
|
||||
#' AMP = as.mic(8),
|
||||
#' CIP = as.mic(0.256),
|
||||
#' GEN = as.disk(18),
|
||||
#' TOB = as.disk(16),
|
||||
#' NIT = as.mic(32))
|
||||
#' as.rsi(df)
|
||||
#'
|
||||
#' \dontrun{
|
||||
#'
|
||||
#' # the dplyr way
|
||||
#' library(dplyr)
|
||||
#' df %>%
|
||||
#' mutate_at(vars(AMP:TOB), as.rsi, mo = "E. coli")
|
||||
#'
|
||||
#' df %>%
|
||||
#' mutate_at(vars(AMP:TOB), as.rsi, mo = .$microorganism)
|
||||
#'
|
||||
#' # to include information about urinary tract infections (UTI)
|
||||
#' data.frame(mo = "E. coli",
|
||||
#' NIT = c("<= 2", 32),
|
||||
#' from_the_bladder = c(TRUE, FALSE)) %>%
|
||||
#' as.rsi(uti = "from_the_bladder")
|
||||
#'
|
||||
#' data.frame(mo = "E. coli",
|
||||
#' NIT = c("<= 2", 32),
|
||||
#' specimen = c("urine", "blood")) %>%
|
||||
#' as.rsi() # automatically determines urine isolates
|
||||
#'
|
||||
#' df %>%
|
||||
#' mutate_at(vars(AMP:NIT), as.rsi, mo = "E. coli", uti = TRUE)
|
||||
#' }
|
||||
#'
|
||||
#' # for single values
|
||||
#' as.rsi(x = as.mic(2),
|
||||
#' mo = as.mo("S. pneumoniae"),
|
||||
#' ab = "AMP",
|
||||
#' guideline = "EUCAST")
|
||||
#'
|
||||
#' as.rsi(x = as.disk(18),
|
||||
#' mo = "Strep pneu", # `mo` will be coerced with as.mo()
|
||||
#' ab = "ampicillin", # and `ab` with as.ab()
|
||||
#' guideline = "EUCAST")
|
||||
#'
|
||||
#'
|
||||
#' # For CLEANING existing R/SI values ------------------------------------
|
||||
#'
|
||||
#' as.rsi(c("S", "I", "R", "A", "B", "C"))
|
||||
#' as.rsi("<= 0.002; S") # will return "S"
|
||||
#'
|
||||
#' rsi_data <- as.rsi(c(rep("S", 474), rep("I", 36), rep("R", 370)))
|
||||
#' is.rsi(rsi_data)
|
||||
#' plot(rsi_data) # for percentages
|
||||
#' barplot(rsi_data) # for frequencies
|
||||
#'
|
||||
#' \dontrun{
|
||||
#' library(dplyr)
|
||||
#' example_isolates %>%
|
||||
#' mutate_at(vars(PEN:RIF), as.rsi)
|
||||
#'
|
||||
#' # fastest way to transform all columns with already valid AMR results to class `rsi`:
|
||||
#' example_isolates %>%
|
||||
#' mutate_if(is.rsi.eligible, as.rsi)
|
||||
#'
|
||||
#' # note: from dplyr 1.0.0 on, this will be:
|
||||
#' # example_isolates %>%
|
||||
#' # mutate(across(is.rsi.eligible, as.rsi))
|
||||
#'
|
||||
#' # default threshold of `is.rsi.eligible` is 5%.
|
||||
#' is.rsi.eligible(WHONET$`First name`) # fails, >80% is invalid
|
||||
#' is.rsi.eligible(WHONET$`First name`, threshold = 0.99) # succeeds
|
||||
#' }
|
||||
as.rsi <- function(x, ...) {
|
||||
UseMethod("as.rsi")
|
||||
}
|
||||
|
||||
#' @rdname as.rsi
|
||||
#' @export
|
||||
is.rsi <- function(x) {
|
||||
inherits(x, "rsi")
|
||||
}
|
||||
|
||||
#' @rdname as.rsi
|
||||
#' @export
|
||||
is.rsi.eligible <- function(x, threshold = 0.05) {
|
||||
stop_if(NCOL(x) > 1, "`x` must be a one-dimensional vector.")
|
||||
|
||||
if (any(c("logical",
|
||||
"numeric",
|
||||
"integer",
|
||||
"mo",
|
||||
"Date",
|
||||
"POSIXct",
|
||||
"rsi",
|
||||
"raw",
|
||||
"hms")
|
||||
%in% class(x))) {
|
||||
# no transformation needed
|
||||
FALSE
|
||||
} else {
|
||||
x <- x[!is.na(x) & !is.null(x) & !identical(x, "")]
|
||||
if (length(x) == 0) {
|
||||
return(FALSE)
|
||||
}
|
||||
checked <- suppressWarnings(as.rsi(x))
|
||||
outcome <- sum(is.na(checked)) / length(x)
|
||||
outcome <= threshold
|
||||
}
|
||||
}
|
||||
|
||||
#' @export
|
||||
as.rsi.default <- function(x, ...) {
|
||||
if (is.rsi(x)) {
|
||||
x
|
||||
} else if (identical(levels(x), c("S", "I", "R"))) {
|
||||
structure(x, class = c("rsi", "ordered", "factor"))
|
||||
} else if (inherits(x, "integer") & all(x %in% c(1:3, NA))) {
|
||||
x[x == 1] <- "S"
|
||||
x[x == 2] <- "I"
|
||||
x[x == 3] <- "R"
|
||||
structure(.Data = factor(x, levels = c("S", "I", "R"), ordered = TRUE),
|
||||
class = c("rsi", "ordered", "factor"))
|
||||
} else {
|
||||
|
||||
ab <- deparse(substitute(x))
|
||||
if (!any(x %like% "(R|S|I)", na.rm = TRUE)) {
|
||||
if (!is.na(suppressWarnings(as.ab(ab)))) {
|
||||
# check if they are actually MICs or disks now that the antibiotic name is valid
|
||||
if (all_valid_mics(x)) {
|
||||
as.rsi(as.mic(x), ab = ab, ...)
|
||||
} else if (all_valid_disks(x)) {
|
||||
as.rsi(as.disk(x), ab = ab, ...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x <- as.character(unlist(x))
|
||||
x.bak <- x
|
||||
|
||||
na_before <- length(x[is.na(x) | x == ""])
|
||||
# remove all spaces
|
||||
x <- gsub(" +", "", x)
|
||||
# remove all MIC-like values: numbers, operators and periods
|
||||
x <- gsub("[0-9.,;:<=>]+", "", x)
|
||||
# remove everything between brackets, and 'high' and 'low'
|
||||
x <- gsub("([(].*[)])", "", x)
|
||||
x <- gsub("(high|low)", "", x, ignore.case = TRUE)
|
||||
# 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 <- length(x[is.na(x) | x == ""])
|
||||
|
||||
if (!isFALSE(list(...)$warn)) { # so as.rsi(..., warn = FALSE) will never throw a warning
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
structure(.Data = factor(x, levels = c("S", "I", "R"), ordered = TRUE),
|
||||
class = c("rsi", "ordered", "factor"))
|
||||
}
|
||||
}
|
||||
|
||||
#' @rdname as.rsi
|
||||
#' @export
|
||||
as.rsi.mic <- function(x,
|
||||
mo,
|
||||
ab = deparse(substitute(x)),
|
||||
guideline = "EUCAST",
|
||||
uti = FALSE,
|
||||
conserve_capped_values = FALSE,
|
||||
...) {
|
||||
stop_if(missing(mo),
|
||||
'No information was supplied about the microorganisms (missing parameter "mo"). See ?as.rsi.\n\n',
|
||||
"To transform certain columns with e.g. mutate_at(), use\n",
|
||||
"`data %>% mutate_at(vars(...), as.rsi, mo = .$x)`, where x is your column with microorganisms.\n\n",
|
||||
"To tranform all MIC variables in a data set, use `as.rsi(data)` or `data %>% as.rsi()`.", call = FALSE)
|
||||
|
||||
ab_coerced <- suppressWarnings(as.ab(ab))
|
||||
mo_coerced <- suppressWarnings(as.mo(mo))
|
||||
guideline_coerced <- get_guideline(guideline)
|
||||
if (is.na(ab_coerced)) {
|
||||
message(font_red(paste0("Unknown drug: `", font_bold(ab), "`. Rename this column to a drug name or code, and check the output with as.ab().")))
|
||||
return(as.rsi(rep(NA, length(x))))
|
||||
}
|
||||
if (length(mo_coerced) == 1) {
|
||||
mo_coerced <- rep(mo_coerced, length(x))
|
||||
}
|
||||
if (length(uti) == 1) {
|
||||
uti <- rep(uti, length(x))
|
||||
}
|
||||
|
||||
message(font_blue(paste0("=> Interpreting MIC values of `", font_bold(ab), "` (",
|
||||
ifelse(ab_coerced != ab, paste0(ab_coerced, ", "), ""),
|
||||
ab_name(ab_coerced, tolower = TRUE), ") using guideline ", font_bold(guideline_coerced), " ... ")),
|
||||
appendLF = FALSE)
|
||||
result <- exec_as.rsi(method = "mic",
|
||||
x = x,
|
||||
mo = mo_coerced,
|
||||
ab = ab_coerced,
|
||||
guideline = guideline_coerced,
|
||||
uti = uti,
|
||||
conserve_capped_values = conserve_capped_values) # exec_as.rsi will return message(font_blue(" OK."))
|
||||
result
|
||||
}
|
||||
|
||||
#' @rdname as.rsi
|
||||
#' @export
|
||||
as.rsi.disk <- function(x,
|
||||
mo,
|
||||
ab = deparse(substitute(x)),
|
||||
guideline = "EUCAST",
|
||||
uti = FALSE,
|
||||
...) {
|
||||
stop_if(missing(mo),
|
||||
'No information was supplied about the microorganisms (missing parameter "mo"). See ?as.rsi.\n\n',
|
||||
"To transform certain columns with e.g. mutate_at(), use\n",
|
||||
"`data %>% mutate_at(vars(...), as.rsi, mo = .$x)`, where x is your column with microorganisms.\n\n",
|
||||
"To tranform all disk diffusion zones in a data set, use `as.rsi(data)` or `data %>% as.rsi()`.", call = FALSE)
|
||||
|
||||
ab_coerced <- suppressWarnings(as.ab(ab))
|
||||
mo_coerced <- suppressWarnings(as.mo(mo))
|
||||
guideline_coerced <- get_guideline(guideline)
|
||||
if (is.na(ab_coerced)) {
|
||||
message(font_red(paste0("Unknown drug: `", font_bold(ab), "`. Rename this column to a drug name or code, and check the output with as.ab().")))
|
||||
return(as.rsi(rep(NA, length(x))))
|
||||
}
|
||||
if (length(mo_coerced) == 1) {
|
||||
mo_coerced <- rep(mo_coerced, length(x))
|
||||
}
|
||||
if (length(uti) == 1) {
|
||||
uti <- rep(uti, length(x))
|
||||
}
|
||||
|
||||
message(font_blue(paste0("=> Interpreting disk zones of `", font_bold(ab), "` (",
|
||||
ifelse(ab_coerced != ab, paste0(ab_coerced, ", "), ""),
|
||||
ab_name(ab_coerced, tolower = TRUE), ") using guideline ", font_bold(guideline_coerced), " ... ")),
|
||||
appendLF = FALSE)
|
||||
result <- exec_as.rsi(method = "disk",
|
||||
x = x,
|
||||
mo = mo_coerced,
|
||||
ab = ab_coerced,
|
||||
guideline = guideline_coerced,
|
||||
uti = uti) # exec_as.rsi will return message(font_blue(" OK."))
|
||||
result
|
||||
}
|
||||
|
||||
#' @rdname as.rsi
|
||||
#' @export
|
||||
as.rsi.data.frame <- function(x,
|
||||
col_mo = NULL,
|
||||
guideline = "EUCAST",
|
||||
uti = NULL,
|
||||
conserve_capped_values = FALSE,
|
||||
...) {
|
||||
# try to find columns based on type
|
||||
# -- mo
|
||||
if (is.null(col_mo)) {
|
||||
col_mo <- search_type_in_df(x = x, type = "mo")
|
||||
stop_if(is.null(col_mo), "`col_mo` must be set")
|
||||
}
|
||||
|
||||
# -- UTIs
|
||||
col_uti <- uti
|
||||
if (is.null(col_uti)) {
|
||||
col_uti <- search_type_in_df(x = x, type = "uti")
|
||||
}
|
||||
if (!is.null(col_uti)) {
|
||||
if (is.logical(col_uti)) {
|
||||
# already a logical vector as input
|
||||
if (length(col_uti) == 1) {
|
||||
uti <- rep(col_uti, NROW(x))
|
||||
} else {
|
||||
uti <- col_uti
|
||||
}
|
||||
} else {
|
||||
# column found, transform to logical
|
||||
uti <- as.logical(x[, col_uti, drop = TRUE])
|
||||
}
|
||||
} else {
|
||||
# look for specimen column and make logicals of the urines
|
||||
col_specimen <- suppressMessages(search_type_in_df(x = x, type = "specimen"))
|
||||
if (!is.null(col_specimen)) {
|
||||
uti <- x[, col_specimen, drop = TRUE] %like% "urin"
|
||||
values <- sort(unique(x[uti, col_specimen, drop = TRUE]))
|
||||
if (length(values) > 1) {
|
||||
plural <- c("s", "", "")
|
||||
} else {
|
||||
plural <- c("", "s", "a ")
|
||||
}
|
||||
message(font_blue(paste0("NOTE: Assuming value", plural[1], " ",
|
||||
paste(paste0('"', values, '"'), collapse = ", "),
|
||||
" in column `", font_bold(col_specimen),
|
||||
"` reflect", plural[2], " ", plural[3], "urinary tract infection", plural[1], ".\n Use `as.rsi(uti = FALSE)` to prevent this.")))
|
||||
} else {
|
||||
# no data about UTI's found
|
||||
uti <- FALSE
|
||||
}
|
||||
}
|
||||
|
||||
i <- 0
|
||||
ab_cols <- colnames(x)[sapply(x, function(y) {
|
||||
i <<- i + 1
|
||||
check <- is.mic(y) | is.disk(y)
|
||||
ab <- colnames(x)[i]
|
||||
ab_coerced <- suppressWarnings(as.ab(ab))
|
||||
if (is.na(ab_coerced)) {
|
||||
# not even a valid AB code
|
||||
return(FALSE)
|
||||
} else if (!check & all_valid_mics(y)) {
|
||||
message(font_blue(paste0("NOTE: Assuming column `", ab, "` (",
|
||||
ifelse(ab_coerced != ab, paste0(ab_coerced, ", "), ""),
|
||||
ab_name(ab_coerced, tolower = TRUE), ") contains MIC values.")))
|
||||
return(TRUE)
|
||||
} else if (!check & all_valid_disks(y)) {
|
||||
message(font_blue(paste0("NOTE: Assuming column `", ab, "` (",
|
||||
ifelse(ab_coerced != ab, paste0(ab_coerced, ", "), ""),
|
||||
ab_name(ab_coerced, tolower = TRUE), ") contains disk zones.")))
|
||||
return(TRUE)
|
||||
} else {
|
||||
return(check)
|
||||
}
|
||||
})]
|
||||
|
||||
stop_if(length(ab_cols) == 0,
|
||||
"no columns with MIC values or disk zones found in this data set. Use as.mic() or as.disk() to transform antimicrobial columns.")
|
||||
|
||||
# set type per column
|
||||
types <- character(length(ab_cols))
|
||||
types[sapply(x[, ab_cols], is.mic)] <- "mic"
|
||||
types[types == "" & sapply(x[, ab_cols], all_valid_mics)] <- "mic"
|
||||
types[sapply(x[, ab_cols], is.disk)] <- "disk"
|
||||
types[types == "" & sapply(x[, ab_cols], all_valid_disks)] <- "disk"
|
||||
|
||||
for (i in seq_len(length(ab_cols))) {
|
||||
if (types[i] == "mic") {
|
||||
x[, ab_cols[i]] <- as.rsi.mic(x = x %>% pull(ab_cols[i]),
|
||||
mo = x %>% pull(col_mo),
|
||||
ab = ab_cols[i],
|
||||
guideline = guideline,
|
||||
uti = uti,
|
||||
conserve_capped_values = conserve_capped_values)
|
||||
} else if (types[i] == "disk") {
|
||||
x[, ab_cols[i]] <- as.rsi.disk(x = x %>% pull(ab_cols[i]),
|
||||
mo = x %>% pull(col_mo),
|
||||
ab = ab_cols[i],
|
||||
guideline = guideline,
|
||||
uti = uti)
|
||||
}
|
||||
}
|
||||
|
||||
x
|
||||
}
|
||||
|
||||
get_guideline <- function(guideline) {
|
||||
guideline_param <- toupper(guideline)
|
||||
if (guideline_param %in% c("CLSI", "EUCAST")) {
|
||||
guideline_param <- rev(sort(subset(rsi_translation, guideline %like% guideline_param)$guideline))[1L]
|
||||
}
|
||||
if (!guideline_param %like% " ") {
|
||||
# like 'EUCAST2020', should be 'EUCAST 2020'
|
||||
guideline_param <- gsub("([a-z]+)([0-9]+)", "\\1 \\2", guideline_param, ignore.case = TRUE)
|
||||
}
|
||||
|
||||
stop_ifnot(guideline_param %in% rsi_translation$guideline,
|
||||
"invalid guideline: '", guideline,
|
||||
"'.\nValid guidelines are: ", paste0("'", unique(rsi_translation$guideline), "'", collapse = ", "), call = FALSE)
|
||||
|
||||
guideline_param
|
||||
|
||||
}
|
||||
|
||||
exec_as.rsi <- function(method, x, mo, ab, guideline, uti, conserve_capped_values) {
|
||||
if (method == "mic") {
|
||||
x <- as.mic(x) # when as.rsi.mic is called directly
|
||||
} else if (method == "disk") {
|
||||
x <- as.disk(x) # when as.rsi.disk is called directly
|
||||
}
|
||||
|
||||
warned <- FALSE
|
||||
method_param <- toupper(method)
|
||||
|
||||
mo_genus <- as.mo(mo_genus(mo))
|
||||
mo_family <- as.mo(mo_family(mo))
|
||||
mo_order <- as.mo(mo_order(mo))
|
||||
mo_becker <- as.mo(mo, Becker = TRUE)
|
||||
mo_lancefield <- as.mo(mo, Lancefield = TRUE)
|
||||
mo_other <- as.mo(rep("UNKNOWN", length(mo)))
|
||||
|
||||
guideline_coerced <- get_guideline(guideline)
|
||||
if (guideline_coerced != guideline) {
|
||||
message(font_blue(paste0("Note: Using guideline ", font_bold(guideline_coerced), " as input for `guideline`.")))
|
||||
}
|
||||
|
||||
new_rsi <- rep(NA_character_, length(x))
|
||||
ab_param <- ab
|
||||
trans <- rsi_translation %>%
|
||||
subset(guideline == guideline_coerced & method == method_param & ab == ab_param)
|
||||
trans$lookup <- paste(trans$mo, trans$ab)
|
||||
|
||||
lookup_mo <- paste(mo, ab)
|
||||
lookup_genus <- paste(mo_genus, ab)
|
||||
lookup_family <- paste(mo_family, ab)
|
||||
lookup_order <- paste(mo_order, ab)
|
||||
lookup_becker <- paste(mo_becker, ab)
|
||||
lookup_lancefield <- paste(mo_lancefield, ab)
|
||||
lookup_other <- paste(mo_other, ab)
|
||||
|
||||
if (all(trans$uti == TRUE, na.rm = TRUE) & all(uti == FALSE)) {
|
||||
message(font_red("WARNING."))
|
||||
warning("Interpretation of ", font_bold(ab_name(ab, tolower = TRUE)), " for some microorganisms is only available for (uncomplicated) urinary tract infections (UTI).\n Use parameter 'uti' to set which isolates are from urine. See ?as.rsi.", call. = FALSE)
|
||||
warned <- TRUE
|
||||
}
|
||||
|
||||
for (i in seq_len(length(x))) {
|
||||
get_record <- trans %>%
|
||||
# no UTI for now
|
||||
subset(lookup %in% c(lookup_mo[i],
|
||||
lookup_genus[i],
|
||||
lookup_family[i],
|
||||
lookup_order[i],
|
||||
lookup_becker[i],
|
||||
lookup_lancefield[i],
|
||||
lookup_other[i]))
|
||||
|
||||
if (isTRUE(uti[i])) {
|
||||
get_record <- get_record %>%
|
||||
# be as specific as possible (i.e. prefer species over genus):
|
||||
# desc(uti) = TRUE on top and FALSE on bottom
|
||||
arrange(desc(uti), desc(nchar(mo))) # 'uti' is a column in rsi_translation
|
||||
} else {
|
||||
get_record <- get_record %>%
|
||||
filter(uti == FALSE) %>% # 'uti' is a column in rsi_translation
|
||||
arrange(desc(nchar(mo)))
|
||||
}
|
||||
get_record <- get_record[1L, ]
|
||||
|
||||
if (NROW(get_record) > 0) {
|
||||
if (is.na(x[i])) {
|
||||
new_rsi[i] <- NA_character_
|
||||
} else if (method == "mic") {
|
||||
mic_input <- x[i]
|
||||
mic_S <- as.mic(get_record$breakpoint_S)
|
||||
mic_R <- as.mic(get_record$breakpoint_R)
|
||||
new_rsi[i] <- ifelse(isTRUE(conserve_capped_values) & mic_input %like% "^<[0-9]", "S",
|
||||
ifelse(isTRUE(conserve_capped_values) & mic_input %like% "^>[0-9]", "R",
|
||||
ifelse(isTRUE(which(levels(mic_input) == mic_input) <= which(levels(mic_S) == mic_S)), "S",
|
||||
ifelse(isTRUE(which(levels(mic_input) == mic_input) >= which(levels(mic_R) == mic_R)), "R",
|
||||
ifelse(!is.na(get_record$breakpoint_S) & !is.na(get_record$breakpoint_R), "I",
|
||||
NA_character_)))))
|
||||
} else if (method == "disk") {
|
||||
new_rsi[i] <- ifelse(isTRUE(as.double(x[i]) >= as.double(get_record$breakpoint_S)), "S",
|
||||
ifelse(isTRUE(as.double(x[i]) <= as.double(get_record$breakpoint_R)), "R",
|
||||
ifelse(!is.na(get_record$breakpoint_S) & !is.na(get_record$breakpoint_R), "I",
|
||||
NA_character_)))
|
||||
}
|
||||
}
|
||||
}
|
||||
if (warned == FALSE) {
|
||||
message(font_green("OK."))
|
||||
}
|
||||
structure(.Data = factor(new_rsi, levels = c("S", "I", "R"), ordered = TRUE),
|
||||
class = c("rsi", "ordered", "factor"))
|
||||
}
|
||||
|
||||
#' @method print rsi
|
||||
#' @export
|
||||
#' @noRd
|
||||
print.rsi <- function(x, ...) {
|
||||
cat("Class <rsi>\n")
|
||||
print(as.character(x), quote = FALSE)
|
||||
}
|
||||
|
||||
#' @method droplevels rsi
|
||||
#' @export
|
||||
#' @noRd
|
||||
droplevels.rsi <- function(x, exclude = if (anyNA(levels(x))) NULL else NA, ...) {
|
||||
x <- droplevels.factor(x, exclude = exclude, ...)
|
||||
class(x) <- c("rsi", "ordered", "factor")
|
||||
x
|
||||
}
|
||||
|
||||
#' @method summary rsi
|
||||
#' @export
|
||||
#' @noRd
|
||||
summary.rsi <- function(object, ...) {
|
||||
x <- object
|
||||
n <- sum(!is.na(x))
|
||||
S <- sum(x == "S", na.rm = TRUE)
|
||||
I <- sum(x == "I", na.rm = TRUE)
|
||||
R <- sum(x == "R", na.rm = TRUE)
|
||||
value <- c(
|
||||
"Class" = "rsi",
|
||||
"%R" = paste0(percentage(R / n), " (n=", R, ")"),
|
||||
"%SI" = paste0(percentage((S + I) / n), " (n=", S + I, ")"),
|
||||
"- %S" = paste0(percentage(S / n), " (n=", S, ")"),
|
||||
"- %I" = paste0(percentage(I / n), " (n=", I, ")")
|
||||
)
|
||||
class(value) <- c("summaryDefault", "table")
|
||||
value
|
||||
}
|
||||
|
||||
#' @method plot rsi
|
||||
#' @export
|
||||
#' @importFrom graphics text axis
|
||||
#' @noRd
|
||||
plot.rsi <- function(x,
|
||||
lwd = 2,
|
||||
ylim = NULL,
|
||||
ylab = "Percentage",
|
||||
xlab = "Antimicrobial Interpretation",
|
||||
main = paste("Resistance Overview of", deparse(substitute(x))),
|
||||
axes = FALSE,
|
||||
...) {
|
||||
data <- as.data.frame(table(x), stringsAsFactors = FALSE)
|
||||
colnames(data) <- c("x", "n")
|
||||
data$s <- round((data$n / sum(data$n)) * 100, 1)
|
||||
|
||||
if (!"S" %in% data$x) {
|
||||
data <- rbind(data, data.frame(x = "S", n = 0, s = 0))
|
||||
}
|
||||
if (!"I" %in% data$x) {
|
||||
data <- rbind(data, data.frame(x = "I", n = 0, s = 0))
|
||||
}
|
||||
if (!"R" %in% data$x) {
|
||||
data <- rbind(data, data.frame(x = "R", n = 0, s = 0))
|
||||
}
|
||||
|
||||
# don't use as.rsi() here, it will confuse plot()
|
||||
data$x <- factor(data$x, levels = c("S", "I", "R"), ordered = TRUE)
|
||||
|
||||
ymax <- if_else(max(data$s) > 95, 105, 100)
|
||||
|
||||
# get plot() generic; this was moved from the 'graphics' pkg to the 'base' pkg in R 4.0.0
|
||||
if (as.integer(R.Version()$major) >= 4) {
|
||||
plot <- import_fn("plot", "base")
|
||||
} else {
|
||||
plot <- import_fn("plot", "graphics")
|
||||
}
|
||||
plot(x = data$x,
|
||||
y = data$s,
|
||||
lwd = lwd,
|
||||
ylim = c(0, ymax),
|
||||
ylab = ylab,
|
||||
xlab = xlab,
|
||||
main = main,
|
||||
axes = axes,
|
||||
...)
|
||||
# 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, ")"))
|
||||
}
|
||||
|
||||
|
||||
#' @method barplot rsi
|
||||
#' @export
|
||||
#' @importFrom graphics barplot axis par
|
||||
#' @noRd
|
||||
barplot.rsi <- function(height,
|
||||
col = c("chartreuse4", "chartreuse3", "brown3"),
|
||||
xlab = ifelse(beside, "Antimicrobial Interpretation", ""),
|
||||
main = paste("Resistance Overview of", deparse(substitute(height))),
|
||||
ylab = "Frequency",
|
||||
beside = TRUE,
|
||||
axes = beside,
|
||||
...) {
|
||||
|
||||
if (axes == TRUE) {
|
||||
par(mar = c(5, 4, 4, 2) + 0.1)
|
||||
} else {
|
||||
par(mar = c(2, 4, 4, 2) + 0.1)
|
||||
}
|
||||
|
||||
barplot(as.matrix(table(height)),
|
||||
col = col,
|
||||
xlab = xlab,
|
||||
main = main,
|
||||
ylab = ylab,
|
||||
beside = beside,
|
||||
axes = FALSE,
|
||||
...)
|
||||
# y axis, 0-100%
|
||||
axis(side = 2, at = seq(0, max(table(height)) + max(table(height)) * 1.1, by = 25))
|
||||
if (axes == TRUE && beside == TRUE) {
|
||||
axis(side = 1, labels = levels(height), at = c(1, 2, 3) + 0.5, lwd = 0)
|
||||
}
|
||||
}
|
||||
|
||||
#' @method [<- rsi
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[<-.rsi" <- function(i, j, ..., value) {
|
||||
value <- as.rsi(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
y
|
||||
}
|
||||
#' @method [[<- rsi
|
||||
#' @export
|
||||
#' @noRd
|
||||
"[[<-.rsi" <- function(i, j, ..., value) {
|
||||
value <- as.rsi(value)
|
||||
y <- NextMethod()
|
||||
attributes(y) <- attributes(i)
|
||||
y
|
||||
}
|
||||
#' @method c rsi
|
||||
#' @export
|
||||
#' @noRd
|
||||
c.rsi <- function(x, ...) {
|
||||
y <- unlist(lapply(list(...), as.character))
|
||||
x <- as.character(x)
|
||||
as.rsi(c(x, y))
|
||||
}
|
||||
@@ -1,324 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
dots2vars <- function(...) {
|
||||
# this function is to give more informative output about
|
||||
# variable names in count_* and proportion_* functions
|
||||
dots <- substitute(list(...))
|
||||
paste(as.character(dots)[2:length(dots)], collapse = ", ")
|
||||
}
|
||||
|
||||
rsi_calc <- function(...,
|
||||
ab_result,
|
||||
minimum = 0,
|
||||
as_percent = FALSE,
|
||||
only_all_tested = FALSE,
|
||||
only_count = FALSE) {
|
||||
|
||||
stop_ifnot(is.numeric(minimum), "`minimum` must be numeric", call = -2)
|
||||
stop_ifnot(is.logical(as_percent), "`as_percent` must be logical", call = -2)
|
||||
stop_ifnot(is.logical(only_all_tested), "`only_all_tested` must be logical", call = -2)
|
||||
|
||||
data_vars <- dots2vars(...)
|
||||
|
||||
dots_df <- switch(1, ...)
|
||||
if (is.data.frame(dots_df)) {
|
||||
# make sure to remove all other classes like tibbles, data.tables, etc
|
||||
dots_df <- as.data.frame(dots_df, stringsAsFactors = FALSE)
|
||||
}
|
||||
|
||||
dots <- base::eval(base::substitute(base::alist(...)))
|
||||
stop_if(length(dots) == 0, "no variables selected", call = -2)
|
||||
|
||||
stop_if("also_single_tested" %in% names(dots),
|
||||
"`also_single_tested` was replaced by `only_all_tested`.\n",
|
||||
"Please read Details in the help page (`?proportion`) as this may have a considerable impact on your analysis.", call = -2)
|
||||
ndots <- length(dots)
|
||||
|
||||
if (is.data.frame(dots_df)) {
|
||||
# data.frame passed with other columns, like: example_isolates %>% proportion_S(AMC, GEN)
|
||||
|
||||
dots <- as.character(dots)
|
||||
# remove first element, it's the data.frame
|
||||
if (length(dots) == 1) {
|
||||
dots <- character(0)
|
||||
} else {
|
||||
dots <- dots[2:length(dots)]
|
||||
}
|
||||
if (length(dots) == 0 | all(dots == "df")) {
|
||||
# for complete data.frames, like example_isolates %>% select(AMC, GEN) %>% proportion_S()
|
||||
# and the old rsi function, which has "df" as name of the first parameter
|
||||
x <- dots_df
|
||||
} else {
|
||||
# get dots that are in column names already, and the ones that will be once evaluated using dots_df or global env
|
||||
# this is to support susceptibility(example_isolates, AMC, dplyr::all_of(some_vector_with_AB_names))
|
||||
dots <- c(dots[dots %in% colnames(dots_df)],
|
||||
eval(parse(text = dots[!dots %in% colnames(dots_df)]), envir = dots_df, enclos = globalenv()))
|
||||
dots_not_exist <- dots[!dots %in% colnames(dots_df)]
|
||||
stop_if(length(dots_not_exist) > 0, "column(s) not found: ", paste0("'", dots_not_exist, "'", collapse = ", "), call = -2)
|
||||
x <- dots_df[, dots, drop = FALSE]
|
||||
}
|
||||
} else if (ndots == 1) {
|
||||
# only 1 variable passed (can also be data.frame), like: proportion_S(example_isolates$AMC) and example_isolates$AMC %>% proportion_S()
|
||||
x <- dots_df
|
||||
} else {
|
||||
# multiple variables passed without pipe, like: proportion_S(example_isolates$AMC, example_isolates$GEN)
|
||||
x <- NULL
|
||||
try(x <- as.data.frame(dots, stringsAsFactors = FALSE), silent = TRUE)
|
||||
if (is.null(x)) {
|
||||
# support for example_isolates %>% group_by(hospital_id) %>% summarise(amox = susceptibility(GEN, AMX))
|
||||
x <- as.data.frame(list(...), stringsAsFactors = FALSE)
|
||||
}
|
||||
}
|
||||
|
||||
if (is.null(x)) {
|
||||
warning("argument is NULL (check if columns exist): returning NA", call. = FALSE)
|
||||
return(NA)
|
||||
}
|
||||
|
||||
print_warning <- FALSE
|
||||
|
||||
ab_result <- as.rsi(ab_result)
|
||||
|
||||
if (is.data.frame(x)) {
|
||||
rsi_integrity_check <- character(0)
|
||||
for (i in seq_len(ncol(x))) {
|
||||
# check integrity of columns: force <rsi> class
|
||||
if (!is.rsi(x[, i, drop = TRUE])) {
|
||||
rsi_integrity_check <- c(rsi_integrity_check, as.character(x[, i, drop = TRUE]))
|
||||
x[, i] <- suppressWarnings(as.rsi(x[, i, drop = TRUE])) # warning will be given later
|
||||
print_warning <- TRUE
|
||||
}
|
||||
}
|
||||
if (length(rsi_integrity_check) > 0) {
|
||||
# this will give a warning for invalid results, of all input columns (so only 1 warning)
|
||||
rsi_integrity_check <- as.rsi(rsi_integrity_check)
|
||||
}
|
||||
|
||||
x_transposed <- as.list(as.data.frame(t(x)))
|
||||
if (only_all_tested == TRUE) {
|
||||
# no NAs in any column
|
||||
y <- apply(X = as.data.frame(lapply(x, as.integer), stringsAsFactors = FALSE),
|
||||
MARGIN = 1,
|
||||
FUN = base::min)
|
||||
numerator <- sum(as.integer(y) %in% as.integer(ab_result), na.rm = TRUE)
|
||||
denominator <- sum(sapply(x_transposed, function(y) !(any(is.na(y)))))
|
||||
} else {
|
||||
# may contain NAs in any column
|
||||
other_values <- base::setdiff(c(NA, levels(ab_result)), ab_result)
|
||||
numerator <- sum(sapply(x_transposed, function(y) any(y %in% ab_result, na.rm = TRUE)))
|
||||
denominator <- sum(sapply(x_transposed, function(y) !(all(y %in% other_values) & any(is.na(y)))))
|
||||
}
|
||||
} else {
|
||||
# x is not a data.frame
|
||||
if (!is.rsi(x)) {
|
||||
x <- as.rsi(x)
|
||||
print_warning <- TRUE
|
||||
}
|
||||
numerator <- sum(x %in% ab_result, na.rm = TRUE)
|
||||
denominator <- sum(x %in% levels(ab_result), na.rm = TRUE)
|
||||
}
|
||||
|
||||
if (print_warning == TRUE) {
|
||||
warning("Increase speed by transforming to class <rsi> on beforehand: your_data %>% mutate_if(is.rsi.eligible, as.rsi)",
|
||||
call. = FALSE)
|
||||
}
|
||||
|
||||
if (only_count == TRUE) {
|
||||
return(numerator)
|
||||
}
|
||||
|
||||
if (denominator < minimum) {
|
||||
if (data_vars != "") {
|
||||
data_vars <- paste(" for", data_vars)
|
||||
}
|
||||
warning("Introducing NA: only ", denominator, " results available", data_vars, " (`minimum` = ", minimum, ").", call. = FALSE)
|
||||
fraction <- NA
|
||||
} else {
|
||||
fraction <- numerator / denominator
|
||||
}
|
||||
|
||||
if (as_percent == TRUE) {
|
||||
percentage(fraction, digits = 1)
|
||||
} else {
|
||||
fraction
|
||||
}
|
||||
}
|
||||
|
||||
rsi_calc_df <- function(type, # "proportion", "count" or "both"
|
||||
data,
|
||||
translate_ab = "name",
|
||||
language = get_locale(),
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE,
|
||||
combine_SI_missing = FALSE) {
|
||||
|
||||
check_dataset_integrity()
|
||||
stop_ifnot(is.data.frame(data), "`data` must be a data.frame", call = -2)
|
||||
stop_if(any(dim(data) == 0), "`data` must contain rows and columns", call = -2)
|
||||
stop_ifnot(any(sapply(data, is.rsi), na.rm = TRUE), "no columns with class <rsi> found. See ?as.rsi.", call = -2)
|
||||
if (isTRUE(combine_IR) & isTRUE(combine_SI_missing)) {
|
||||
combine_SI <- FALSE
|
||||
}
|
||||
stop_if(isTRUE(combine_SI) & isTRUE(combine_IR), "either `combine_SI` or `combine_IR` can be TRUE, not both", call = -2)
|
||||
stop_ifnot(is.numeric(minimum), "`minimum` must be numeric", call = -2)
|
||||
stop_ifnot(is.logical(as_percent), "`as_percent` must be logical", call = -2)
|
||||
|
||||
translate_ab <- get_translate_ab(translate_ab)
|
||||
|
||||
# select only groups and antibiotics
|
||||
if (has_groups(data)) {
|
||||
data_has_groups <- TRUE
|
||||
groups <- setdiff(names(get_groups(data)), ".rows") # get_groups is from poorman.R
|
||||
data <- data[, c(groups, colnames(data)[sapply(data, is.rsi)]), drop = FALSE]
|
||||
} else {
|
||||
data_has_groups <- FALSE
|
||||
data <- data[, colnames(data)[sapply(data, is.rsi)], drop = FALSE]
|
||||
}
|
||||
|
||||
data <- as.data.frame(data, stringsAsFactors = FALSE)
|
||||
if (isTRUE(combine_SI) | isTRUE(combine_IR)) {
|
||||
for (i in seq_len(ncol(data))) {
|
||||
if (is.rsi(data[, i, drop = TRUE])) {
|
||||
data[, i] <- as.character(data[, i, drop = TRUE])
|
||||
if (isTRUE(combine_SI)) {
|
||||
data[, i] <- gsub("(I|S)", "SI", data[, i, drop = TRUE])
|
||||
} else if (isTRUE(combine_IR)) {
|
||||
data[, i] <- gsub("(I|R)", "IR", data[, i, drop = TRUE])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sum_it <- function(.data) {
|
||||
out <- data.frame(antibiotic = character(0),
|
||||
interpretation = character(0),
|
||||
value = double(0),
|
||||
isolates = integer(0),
|
||||
stringsAsFactors = FALSE)
|
||||
if (data_has_groups) {
|
||||
group_values <- unique(.data[, which(colnames(.data) %in% groups), drop = FALSE])
|
||||
rownames(group_values) <- NULL
|
||||
.data <- .data[, which(!colnames(.data) %in% groups), drop = FALSE]
|
||||
}
|
||||
for (i in seq_len(ncol(.data))) {
|
||||
values <- .data[, i, drop = TRUE]
|
||||
if (isTRUE(combine_SI)) {
|
||||
values <- factor(values, levels = c("SI", "R"), ordered = TRUE)
|
||||
} else if (isTRUE(combine_IR)) {
|
||||
values <- factor(values, levels = c("S", "IR"), ordered = TRUE)
|
||||
} else {
|
||||
values <- factor(values, levels = c("S", "I", "R"), ordered = TRUE)
|
||||
}
|
||||
col_results <- as.data.frame(as.matrix(table(values)))
|
||||
col_results$interpretation <- rownames(col_results)
|
||||
col_results$isolates <- col_results[, 1, drop = TRUE]
|
||||
if (NROW(col_results) > 0 && sum(col_results$isolates, na.rm = TRUE) > 0) {
|
||||
if (sum(col_results$isolates, na.rm = TRUE) >= minimum) {
|
||||
col_results$value <- col_results$isolates / sum(col_results$isolates, na.rm = TRUE)
|
||||
} else {
|
||||
col_results$value <- rep(NA_real_, NROW(col_results))
|
||||
}
|
||||
out_new <- data.frame(antibiotic = ifelse(isFALSE(translate_ab),
|
||||
colnames(.data)[i],
|
||||
ab_property(colnames(.data)[i], property = translate_ab, language = language)),
|
||||
interpretation = col_results$interpretation,
|
||||
value = col_results$value,
|
||||
isolates = col_results$isolates,
|
||||
stringsAsFactors = FALSE)
|
||||
if (data_has_groups) {
|
||||
if (nrow(group_values) < nrow(out_new)) {
|
||||
# repeat group_values for the number of rows in out_new
|
||||
repeated <- rep(seq_len(nrow(group_values)),
|
||||
each = nrow(out_new) / nrow(group_values))
|
||||
group_values <- group_values[repeated, , drop = FALSE]
|
||||
}
|
||||
out_new <- cbind(group_values, out_new)
|
||||
}
|
||||
out <- rbind(out, out_new)
|
||||
}
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
# support dplyr groups
|
||||
apply_group <- function(.data, fn, groups, ...) {
|
||||
grouped <- split(x = .data, f = lapply(groups, function(x, .data) as.factor(.data[, x]), .data))
|
||||
res <- do.call(rbind, unname(lapply(grouped, fn, ...)))
|
||||
if (any(groups %in% colnames(res))) {
|
||||
class(res) <- c("grouped_data", class(res))
|
||||
attr(res, "groups") <- groups[groups %in% colnames(res)]
|
||||
}
|
||||
res
|
||||
}
|
||||
|
||||
if (data_has_groups) {
|
||||
out <- apply_group(data, "sum_it", groups)
|
||||
} else {
|
||||
out <- sum_it(data)
|
||||
}
|
||||
|
||||
# apply factors for right sorting in interpretation
|
||||
if (isTRUE(combine_SI)) {
|
||||
out$interpretation <- factor(out$interpretation, levels = c("SI", "R"), ordered = TRUE)
|
||||
} else if (isTRUE(combine_IR)) {
|
||||
out$interpretation <- factor(out$interpretation, levels = c("S", "IR"), ordered = TRUE)
|
||||
} else {
|
||||
# don't use as.rsi() here, as it would add the class <rsi> and we would like
|
||||
# the same data structure as output, regardless of input
|
||||
out$interpretation <- factor(out$interpretation, levels = c("S", "I", "R"), ordered = TRUE)
|
||||
}
|
||||
|
||||
if (data_has_groups) {
|
||||
# ordering by the groups and two more: "antibiotic" and "interpretation"
|
||||
out <- ungroup(out[do.call("order", out[, seq_len(length(groups) + 2)]), ])
|
||||
} else {
|
||||
out <- out[order(out$antibiotic, out$interpretation), ]
|
||||
}
|
||||
|
||||
if (type == "proportion") {
|
||||
out <- subset(out, select = -c(isolates))
|
||||
} else if (type == "count") {
|
||||
out$value <- out$isolates
|
||||
out <- subset(out, select = -c(isolates))
|
||||
}
|
||||
|
||||
rownames(out) <- NULL
|
||||
out
|
||||
}
|
||||
|
||||
get_translate_ab <- function(translate_ab) {
|
||||
translate_ab <- as.character(translate_ab)[1L]
|
||||
if (translate_ab %in% c("TRUE", "official")) {
|
||||
return("name")
|
||||
} else if (translate_ab %in% c(NA_character_, "FALSE")) {
|
||||
return(FALSE)
|
||||
} else {
|
||||
translate_ab <- tolower(translate_ab)
|
||||
stop_ifnot(translate_ab %in% colnames(AMR::antibiotics),
|
||||
"invalid value for 'translate_ab', this must be a column name of the antibiotics data set\n",
|
||||
"or TRUE (equals 'name') or FALSE to not translate at all.",
|
||||
call = FALSE)
|
||||
translate_ab
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' @rdname proportion
|
||||
#' @export
|
||||
rsi_df <- function(data,
|
||||
translate_ab = "name",
|
||||
language = get_locale(),
|
||||
minimum = 30,
|
||||
as_percent = FALSE,
|
||||
combine_SI = TRUE,
|
||||
combine_IR = FALSE) {
|
||||
|
||||
rsi_calc_df(type = "both",
|
||||
data = data,
|
||||
translate_ab = translate_ab,
|
||||
language = language,
|
||||
minimum = minimum,
|
||||
as_percent = as_percent,
|
||||
combine_SI = combine_SI,
|
||||
combine_IR = combine_IR,
|
||||
combine_SI_missing = missing(combine_SI))
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' 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.
|
||||
#' @inheritSection lifecycle Questioning lifecycle
|
||||
#' @param x a vector of values, a [`matrix`] or a [`data.frame`]
|
||||
#' @param na.rm a logical value indicating whether `NA` values should be stripped before the computation proceeds.
|
||||
#' @seealso [kurtosis()]
|
||||
#' @rdname skewness
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @export
|
||||
skewness <- function(x, na.rm = FALSE) {
|
||||
UseMethod("skewness")
|
||||
}
|
||||
|
||||
#' @method 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)
|
||||
}
|
||||
|
||||
#' @method skewness matrix
|
||||
#' @rdname skewness
|
||||
#' @export
|
||||
skewness.matrix <- function(x, na.rm = FALSE) {
|
||||
base::apply(x, 2, skewness.default, na.rm = na.rm)
|
||||
}
|
||||
|
||||
#' @method skewness data.frame
|
||||
#' @rdname skewness
|
||||
#' @export
|
||||
skewness.data.frame <- function(x, na.rm = FALSE) {
|
||||
base::sapply(x, skewness.default, na.rm = na.rm)
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' Translate strings from AMR package
|
||||
#'
|
||||
#' For language-dependent output of AMR functions, like [mo_name()], [mo_gramstain()], [mo_type()] and [ab_name()].
|
||||
#' @inheritSection lifecycle Stable lifecycle
|
||||
#' @details Strings will be translated to foreign languages if they are defined in a local translation file. Additions to this file can be suggested at our repository. The file can be found here: <https://github.com/msberends/AMR/blob/master/data-raw/translations.tsv>.
|
||||
#'
|
||||
#' Currently supported languages are (besides English): `r paste(sort(gsub(";.*", "", ISOcodes::ISO_639_2[which(ISOcodes::ISO_639_2$Alpha_2 %in% unique(AMR:::translations_file$lang)), "Name"])), collapse = ", ")`. Please note that currently not all these languages have translations available for all antimicrobial agents and colloquial microorganism names.
|
||||
#'
|
||||
#' Please suggest your own translations [by creating a new issue on our repository](https://github.com/msberends/AMR/issues/new?title=Translations).
|
||||
#'
|
||||
#' This file will be read by all functions where a translated output can be desired, like all [mo_property()] functions ([mo_name()], [mo_gramstain()], [mo_type()], etc.).
|
||||
#'
|
||||
#' The system language will be used at default, if that language is supported. The system language can be overwritten with `Sys.setenv(AMR_locale = yourlanguage)`.
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @rdname translate
|
||||
#' @name translate
|
||||
#' @export
|
||||
#' @examples
|
||||
#' # The 'language' parameter of below functions
|
||||
#' # will be set automatically to your system language
|
||||
#' # with get_locale()
|
||||
#'
|
||||
#' # English
|
||||
#' mo_name("CoNS", language = "en")
|
||||
#' #> "Coagulase-negative Staphylococcus (CoNS)"
|
||||
#'
|
||||
#' # German
|
||||
#' mo_name("CoNS", language = "de")
|
||||
#' #> "Koagulase-negative Staphylococcus (KNS)"
|
||||
#'
|
||||
#' # Dutch
|
||||
#' mo_name("CoNS", language = "nl")
|
||||
#' #> "Coagulase-negatieve Staphylococcus (CNS)"
|
||||
#'
|
||||
#' # Spanish
|
||||
#' mo_name("CoNS", language = "es")
|
||||
#' #> "Staphylococcus coagulasa negativo (SCN)"
|
||||
#'
|
||||
#' # Italian
|
||||
#' mo_name("CoNS", language = "it")
|
||||
#' #> "Staphylococcus negativo coagulasi (CoNS)"
|
||||
#'
|
||||
#' # Portuguese
|
||||
#' mo_name("CoNS", language = "pt")
|
||||
#' #> "Staphylococcus coagulase negativo (CoNS)"
|
||||
get_locale <- function() {
|
||||
if (!is.null(getOption("AMR_locale", default = NULL))) {
|
||||
return(getOption("AMR_locale"))
|
||||
}
|
||||
|
||||
lang <- Sys.getlocale("LC_COLLATE")
|
||||
|
||||
# Check the locale settings for a start with one of these languages:
|
||||
|
||||
# grepl() with ignore.case = FALSE is faster than %like%
|
||||
|
||||
if (grepl("^(English|en_|EN_)", lang, ignore.case = FALSE)) {
|
||||
# as first option to optimise speed
|
||||
"en"
|
||||
} else if (grepl("^(German|Deutsch|de_|DE_)", lang, ignore.case = FALSE)) {
|
||||
"de"
|
||||
} else if (grepl("^(Dutch|Nederlands|nl_|NL_)", lang, ignore.case = FALSE)) {
|
||||
"nl"
|
||||
} else if (grepl("^(Spanish|Espa.+ol|es_|ES_)", lang, ignore.case = FALSE)) {
|
||||
"es"
|
||||
} else if (grepl("^(Italian|Italiano|it_|IT_)", lang, ignore.case = FALSE)) {
|
||||
"it"
|
||||
} else if (grepl("^(French|Fran.+ais|fr_|FR_)", lang, ignore.case = FALSE)) {
|
||||
"fr"
|
||||
} else if (grepl("^(Portuguese|Portugu.+s|pt_|PT_)", lang, ignore.case = FALSE)) {
|
||||
"pt"
|
||||
} else {
|
||||
# other language -> set to English
|
||||
"en"
|
||||
}
|
||||
}
|
||||
|
||||
# translate strings based on inst/translations.tsv
|
||||
translate_AMR <- function(from, language = get_locale(), only_unknown = FALSE) {
|
||||
|
||||
if (is.null(language)) {
|
||||
return(from)
|
||||
}
|
||||
if (language %in% c("en", "", NA)) {
|
||||
return(from)
|
||||
}
|
||||
|
||||
df_trans <- translations_file # internal data file
|
||||
|
||||
stop_ifnot(language %in% df_trans$lang,
|
||||
"unsupported language: '", language, "' - use one of: ",
|
||||
paste0("'", sort(unique(df_trans$lang)), "'", collapse = ", "),
|
||||
call = FALSE)
|
||||
|
||||
df_trans <- subset(df_trans, lang == language)
|
||||
if (only_unknown == TRUE) {
|
||||
df_trans <- subset(df_trans, pattern %like% "unknown")
|
||||
}
|
||||
|
||||
# default case sensitive if value if 'ignore.case' is missing:
|
||||
df_trans$ignore.case[is.na(df_trans$ignore.case)] <- FALSE
|
||||
# default not using regular expressions (fixed = TRUE) if 'fixed' is missing:
|
||||
df_trans$fixed[is.na(df_trans$fixed)] <- TRUE
|
||||
|
||||
# check if text to look for is in one of the patterns
|
||||
any_form_in_patterns <- tryCatch(any(from %like% paste0("(", paste(df_trans$pattern, collapse = "|"), ")")),
|
||||
error = function(e) {
|
||||
warning("Translation not possible. Please open an issue on GitHub (https://github.com/msberends/AMR/issues).", call. = FALSE)
|
||||
return(FALSE)
|
||||
})
|
||||
if (NROW(df_trans) == 0 | !any_form_in_patterns) {
|
||||
return(from)
|
||||
}
|
||||
|
||||
for (i in seq_len(nrow(df_trans))) {
|
||||
from <- gsub(x = from,
|
||||
pattern = df_trans$pattern[i],
|
||||
replacement = df_trans$replacement[i],
|
||||
fixed = df_trans$fixed[i],
|
||||
ignore.case = df_trans$ignore.case[i])
|
||||
}
|
||||
|
||||
# force UTF-8 for diacritics
|
||||
base::enc2utf8(from)
|
||||
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
#' WHOCC: WHO Collaborating Centre for Drug Statistics Methodology
|
||||
#'
|
||||
#' All antimicrobial drugs and their official names, ATC codes, ATC groups and defined daily dose (DDD) are included in this package, using the WHO Collaborating Centre for Drug Statistics Methodology.
|
||||
#' @section WHOCC:
|
||||
#' \if{html}{\figure{logo_who.png}{options: height=60px style=margin-bottom:5px} \cr}
|
||||
#' This package contains **all ~550 antibiotic, antimycotic and antiviral drugs** and their Anatomical Therapeutic Chemical (ATC) codes, ATC groups and Defined Daily Dose (DDD) from the World Health Organization Collaborating Centre for Drug Statistics Methodology (WHOCC, <https://www.whocc.no>) and the Pharmaceuticals Community Register of the European Commission (<http://ec.europa.eu/health/documents/community-register/html/atc.htm>).
|
||||
#'
|
||||
#' These have become the gold standard for international drug utilisation monitoring and research.
|
||||
#'
|
||||
#' The WHOCC is located in Oslo at the Norwegian Institute of Public Health and funded by the Norwegian government. The European Commission is the executive of the European Union and promotes its general interest.
|
||||
#'
|
||||
#' **NOTE: The WHOCC copyright does not allow use for commercial purposes, unlike any other info from this package.** See <https://www.whocc.no/copyright_disclaimer/.>
|
||||
#' @inheritSection AMR Read more on our website!
|
||||
#' @name WHOCC
|
||||
#' @rdname WHOCC
|
||||
#' @examples
|
||||
#' as.ab("meropenem")
|
||||
#' ab_name("J01DH02")
|
||||
#'
|
||||
#' ab_tradenames("flucloxacillin")
|
||||
NULL
|
||||
@@ -1,67 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
.onLoad <- function(libname, pkgname) {
|
||||
assign(x = "MO_lookup",
|
||||
value = create_MO_lookup(),
|
||||
envir = asNamespace("AMR"))
|
||||
|
||||
assign(x = "MO.old_lookup",
|
||||
value = create_MO.old_lookup(),
|
||||
envir = asNamespace("AMR"))
|
||||
}
|
||||
|
||||
# maybe add survey later: "https://www.surveymonkey.com/r/AMR_for_R"
|
||||
|
||||
create_MO_lookup <- function() {
|
||||
MO_lookup <- AMR::microorganisms
|
||||
|
||||
MO_lookup$kingdom_index <- 99
|
||||
MO_lookup[which(MO_lookup$kingdom == "Bacteria" | MO_lookup$mo == "UNKNOWN"), "kingdom_index"] <- 1
|
||||
MO_lookup[which(MO_lookup$kingdom == "Fungi"), "kingdom_index"] <- 2
|
||||
MO_lookup[which(MO_lookup$kingdom == "Protozoa"), "kingdom_index"] <- 3
|
||||
MO_lookup[which(MO_lookup$kingdom == "Archaea"), "kingdom_index"] <- 4
|
||||
|
||||
# use this paste instead of `fullname` to work with Viridans Group Streptococci, etc.
|
||||
MO_lookup$fullname_lower <- tolower(trimws(paste(MO_lookup$genus,
|
||||
MO_lookup$species,
|
||||
MO_lookup$subspecies)))
|
||||
MO_lookup[MO_lookup$genus == "" | grepl("^[(]unknown ", MO_lookup$fullname), "fullname_lower"] <- tolower(trimws(MO_lookup[MO_lookup$genus == "" | grepl("^[(]unknown ", MO_lookup$fullname),
|
||||
"fullname"]))
|
||||
MO_lookup$fullname_lower <- gsub("[^.a-z0-9/ \\-]+", "", MO_lookup$fullname_lower)
|
||||
|
||||
# add a column with only "e coli" like combinations
|
||||
MO_lookup$g_species <- gsub("^([a-z])[a-z]+ ([a-z]+) ?.*", "\\1 \\2", MO_lookup$fullname_lower)
|
||||
|
||||
# so arrange data on prevalence first, then kingdom, then full name
|
||||
MO_lookup[order(MO_lookup$prevalence, MO_lookup$kingdom_index, MO_lookup$fullname_lower), ]
|
||||
}
|
||||
|
||||
create_MO.old_lookup <- function() {
|
||||
MO.old_lookup <- AMR::microorganisms.old
|
||||
MO.old_lookup$fullname_lower <- gsub("[^.a-z0-9/ \\-]+", "", tolower(trimws(MO.old_lookup$fullname)))
|
||||
|
||||
# add a column with only "e coli" like combinations
|
||||
MO.old_lookup$g_species <- gsub("^([a-z])[a-z]+ ([a-z]+) ?.*", "\\1 \\2", MO.old_lookup$fullname_lower)
|
||||
|
||||
# so arrange data on prevalence first, then full name
|
||||
MO.old_lookup[order(MO.old_lookup$prevalence, MO.old_lookup$fullname_lower), ]
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
% AMR (for R)
|
||||
|
||||
# `AMR` (for R)
|
||||
<img src="https://msberends.github.io/AMR/works_great_on.png" align="center" height="150px" />
|
||||
|
||||
`AMR` is a free, open-source and independent R package to simplify the analysis and prediction of Antimicrobial Resistance (AMR) and to work with microbial and antimicrobial data and properties, by using evidence-based methods. Our aim is to provide a standard for clean and reproducible antimicrobial resistance data analysis, that can therefore empower epidemiological analyses to continuously enable surveillance and treatment evaluation in any setting.
|
||||
|
||||
After installing this package, R knows ~70,000 distinct microbial species and all ~550 antibiotic, antimycotic and antiviral drugs by name and code (including ATC, EARS-NET, LOINC and SNOMED CT), and knows all about valid R/SI and MIC values. It supports any data format, including WHONET/EARS-Net data.
|
||||
|
||||
This package is fully independent of any other R package and works on Windows, macOS and Linux with all versions of R since R-3.0.0 (April 2013). It was designed to work in any setting, including those with very limited resources. It was created for both routine data analysis and academic research at the Faculty of Medical Sciences of the University of Groningen, in collaboration with non-profit organisations Certe Medical Diagnostics and Advice and University Medical Center Groningen. This R package is actively maintained and free software; you can freely use and distribute it for both personal and commercial (but not patent) purposes under the terms of the GNU General Public License version 2.0 (GPL-2), as published by the Free Software Foundation.
|
||||
|
||||
This is the development source of the `AMR` package for R. Not a developer? Then please visit our website [https://msberends.github.io/AMR](https://msberends.github.io/AMR) to read more about this package.
|
||||
|
||||
*NOTE: this source code is on GitHub (https://github.com/msberends/AMR), but also automatically mirrored to GitLab (https://gitlab.com/msberends/AMR).*
|
||||
|
||||
### How to get this package
|
||||
Please see [our website](https://msberends.github.io/AMR/#get-this-package).
|
||||
|
||||
### Copyright
|
||||
|
||||
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
|
||||
@@ -1,193 +0,0 @@
|
||||
# ==================================================================== #
|
||||
# TITLE #
|
||||
# Antimicrobial Resistance (AMR) Analysis #
|
||||
# #
|
||||
# SOURCE #
|
||||
# https://github.com/msberends/AMR #
|
||||
# #
|
||||
# LICENCE #
|
||||
# (c) 2018-2020 Berends MS, Luz CF et al. #
|
||||
# #
|
||||
# This R package is free software; you can freely use and distribute #
|
||||
# it for both personal and commercial purposes under the terms of the #
|
||||
# GNU General Public License version 2.0 (GNU GPL-2), as published by #
|
||||
# the Free Software Foundation. #
|
||||
# #
|
||||
# We created this package for both routine data analysis and academic #
|
||||
# research and it was publicly released in the hope that it will be #
|
||||
# useful, but it comes WITHOUT ANY WARRANTY OR LIABILITY. #
|
||||
# Visit our website for more info: https://msberends.github.io/AMR. #
|
||||
# ==================================================================== #
|
||||
|
||||
title: "AMR (for R)"
|
||||
url: "https://msberends.github.io/AMR"
|
||||
|
||||
development:
|
||||
mode: "release" # improves indexing by search engines
|
||||
version_tooltip: "Latest development version"
|
||||
|
||||
news:
|
||||
one_page: true
|
||||
|
||||
navbar:
|
||||
title: "AMR (for R)"
|
||||
left:
|
||||
- text: "Home"
|
||||
icon: "fa-home"
|
||||
href: "index.html"
|
||||
- text: "How to"
|
||||
icon: "fa-question-circle"
|
||||
menu:
|
||||
- text: "Conduct AMR analysis"
|
||||
icon: "fa-directions"
|
||||
href: "articles/AMR.html"
|
||||
- text: "Predict antimicrobial resistance"
|
||||
icon: "fa-dice"
|
||||
href: "articles/resistance_predict.html"
|
||||
- text: "Conduct principal component analysis for AMR"
|
||||
icon: "fa-compress"
|
||||
href: "articles/PCA.html"
|
||||
- text: "Determine multi-drug resistance (MDR)"
|
||||
icon: "fa-skull-crossbones"
|
||||
href: "articles/MDR.html"
|
||||
- text: "Work with WHONET data"
|
||||
icon: "fa-globe-americas"
|
||||
href: "articles/WHONET.html"
|
||||
- text: "Import data from SPSS/SAS/Stata"
|
||||
icon: "fa-file-upload"
|
||||
href: "articles/SPSS.html"
|
||||
- text: "Apply EUCAST rules"
|
||||
icon: "fa-exchange-alt"
|
||||
href: "articles/EUCAST.html"
|
||||
- text: "Get properties of a microorganism"
|
||||
icon: "fa-bug"
|
||||
href: "reference/mo_property.html" # reference instead of article
|
||||
- text: "Get properties of an antibiotic"
|
||||
icon: "fa-capsules"
|
||||
href: "reference/ab_property.html" # reference instead of article
|
||||
- text: "Other: benchmarks"
|
||||
icon: "fa-shipping-fast"
|
||||
href: "articles/benchmarks.html"
|
||||
- text: "Manual"
|
||||
icon: "fa-book-open"
|
||||
href: "reference/index.html"
|
||||
- text: "Authors"
|
||||
icon: "fa-users"
|
||||
href: "authors.html"
|
||||
- text: "Changelog"
|
||||
icon: "far fa-newspaper"
|
||||
href: "news/index.html"
|
||||
right:
|
||||
- text: "Source Code"
|
||||
icon: "fab fa-github"
|
||||
href: "https://github.com/msberends/AMR"
|
||||
- text: "Survey"
|
||||
icon: "fa-clipboard-list"
|
||||
href: "survey.html"
|
||||
|
||||
reference:
|
||||
- title: "Cleaning your data"
|
||||
desc: >
|
||||
Functions for cleaning and optimising your data, to be able to add
|
||||
variables later on (like taxonomic properties) or to fix and extend
|
||||
antibiotic interpretations by applying [EUCAST rules](http://www.eucast.org/expert_rules_and_intrinsic_resistance/).
|
||||
contents:
|
||||
- starts_with("as.")
|
||||
- "`eucast_rules`"
|
||||
- "`ab_from_text`"
|
||||
- "`guess_ab_col`"
|
||||
- "`mo_source`"
|
||||
- title: "Enhancing your data"
|
||||
desc: >
|
||||
Functions to add new data to your existing data, such as the determination
|
||||
of first isolates, multi-drug resistant microorganisms (MDRO), getting
|
||||
properties of microorganisms or antibiotics and determining the age of
|
||||
patients or divide ages into age groups.
|
||||
contents:
|
||||
- "`ab_property`"
|
||||
- "`age_groups`"
|
||||
- "`age`"
|
||||
- "`atc_online_property`"
|
||||
- "`first_isolate`"
|
||||
- "`join`"
|
||||
- "`key_antibiotics`"
|
||||
- "`mdro`"
|
||||
- "`mo_property`"
|
||||
- "`p_symbol`"
|
||||
- title: "Analysing your data"
|
||||
desc: >
|
||||
Functions for conducting AMR analysis, like counting isolates, calculating
|
||||
resistance or susceptibility, or make plots.
|
||||
contents:
|
||||
- "`proportion`"
|
||||
- "`count`"
|
||||
- "`availability`"
|
||||
- "`bug_drug_combinations`"
|
||||
- "`resistance_predict`"
|
||||
- "`pca`"
|
||||
- "`antibiotic_class_selectors`"
|
||||
- "`filter_ab_class`"
|
||||
- "`g.test`"
|
||||
- "`ggplot_rsi`"
|
||||
- "`ggplot_pca`"
|
||||
- "`kurtosis`"
|
||||
- "`skewness`"
|
||||
- title: "Included data sets"
|
||||
desc: >
|
||||
Scientifically reliable references for microorganisms and
|
||||
antibiotics, and example data sets to use for practise.
|
||||
contents:
|
||||
- "`microorganisms`"
|
||||
- "`antibiotics`"
|
||||
- "`antivirals`"
|
||||
- "`example_isolates`"
|
||||
- "`example_isolates_unclean`"
|
||||
- "`rsi_translation`"
|
||||
- "`microorganisms.codes`"
|
||||
- "`microorganisms.old`"
|
||||
- "`WHONET`"
|
||||
- title: "Background information"
|
||||
desc: >
|
||||
Some pages about our package and its external sources. Be sure to read our [How To's](./../articles/index.html)
|
||||
for more information about how to work with functions in this package.
|
||||
contents:
|
||||
- "`AMR`"
|
||||
- "`catalogue_of_life`"
|
||||
- "`catalogue_of_life_version`"
|
||||
- "`WHOCC`"
|
||||
- "`lifecycle`"
|
||||
- title: "Other functions"
|
||||
desc: >
|
||||
These functions are mostly for internal use, but some of
|
||||
them may also be suitable for your analysis. Especially the
|
||||
'like' function can be useful: `if (x %like% y) {...}`.
|
||||
contents:
|
||||
- "`get_locale`"
|
||||
- "`like`"
|
||||
- title: "Deprecated functions"
|
||||
desc: >
|
||||
These functions are deprecated, meaning that they will still
|
||||
work but show a warning with every use and will be removed
|
||||
in a future version.
|
||||
contents:
|
||||
- "`AMR-deprecated`"
|
||||
|
||||
authors:
|
||||
Matthijs S. Berends:
|
||||
href: https://www.rug.nl/staff/m.s.berends/
|
||||
Christian F. Luz:
|
||||
href: https://www.rug.nl/staff/c.f.luz/
|
||||
Alexander W. Friedrich:
|
||||
href: https://www.rug.nl/staff/a.w.friedrich/
|
||||
Bhanu N. M. Sinha:
|
||||
href: https://www.rug.nl/staff/b.sinha/
|
||||
Casper J. Albers:
|
||||
href: https://www.rug.nl/staff/c.j.albers/
|
||||
Corinna Glasner:
|
||||
href: https://www.rug.nl/staff/c.glasner/
|
||||
|
||||
template:
|
||||
assets: "pkgdown/logos" # use logos in this folder
|
||||
params:
|
||||
noindex: false
|
||||
bootswatch: "flatly"
|
||||
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 9.7 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1,425 @@
|
||||
<!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">
|
||||
<meta name="description" content="AMR">
|
||||
<title>How to apply EUCAST rules • AMR (for R)</title>
|
||||
<!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png">
|
||||
<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.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
|
||||
<script src="../extra.js"></script><meta property="og:title" content="How to apply EUCAST rules">
|
||||
<meta property="og:description" content="AMR">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="active nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>How to apply EUCAST rules</h1>
|
||||
|
||||
|
||||
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/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_intrinsic_resistance/" class="external-link">on
|
||||
their website</a>:</p>
|
||||
<blockquote>
|
||||
<p><em>EUCAST expert rules are a tabulated collection of expert
|
||||
knowledge on intrinsic resistances, exceptional resistance phenotypes
|
||||
and interpretive rules that may be applied to antimicrobial
|
||||
susceptibility testing in order to 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 intrinsic resistance and unusual phenotypes (v3.3, 2021).</p>
|
||||
<p>Moreover, the <code><a href="../reference/eucast_rules.html">eucast_rules()</a></code> function we use for this
|
||||
purpose can also apply additional rules, like forcing
|
||||
<help title="ATC: J01CA01">ampicillin</help> = R in isolates when
|
||||
<help title="ATC: J01CR02">amoxicillin/clavulanic acid</help> = R.</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 impossible 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
|
||||
ampicillin 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
|
||||
(namely, <em>Klebsiella</em>). EUCAST expert rules solve this, that can
|
||||
be applied using <code><a href="../reference/eucast_rules.html">eucast_rules()</a></code>:</p>
|
||||
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">oops</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html" class="external-link">data.frame</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"</span>,</span>
|
||||
<span> <span class="st">"Escherichia"</span></span>
|
||||
<span> <span class="op">)</span>,</span>
|
||||
<span> ampicillin <span class="op">=</span> <span class="st">"S"</span></span>
|
||||
<span><span class="op">)</span></span>
|
||||
<span><span class="va">oops</span></span>
|
||||
<span><span class="co"># mo ampicillin</span></span>
|
||||
<span><span class="co"># 1 Klebsiella S</span></span>
|
||||
<span><span class="co"># 2 Escherichia S</span></span>
|
||||
<span></span>
|
||||
<span><span class="fu"><a href="../reference/eucast_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><span class="op">)</span></span>
|
||||
<span><span class="co"># mo ampicillin</span></span>
|
||||
<span><span class="co"># 1 Klebsiella R</span></span>
|
||||
<span><span class="co"># 2 Escherichia S</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
|
||||
antibiotics:</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"</span>, <span class="st">"Escherichia"</span><span class="op">)</span>,</span>
|
||||
<span> <span class="st">"ampicillin"</span></span>
|
||||
<span><span class="op">)</span></span>
|
||||
<span><span class="co"># [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"</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"># [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>, is basically a form of imputation, and is part of the
|
||||
<code><a href="../reference/eucast_rules.html">eucast_rules()</a></code> function as well:</p>
|
||||
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">data</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html" class="external-link">data.frame</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> stringsAsFactors <span class="op">=</span> <span class="cn">FALSE</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/eucast_rules.html">eucast_rules</a></span><span class="op">(</span><span class="va">data</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">S</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"><h2>On this page</h2>
|
||||
</nav></aside>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,495 @@
|
||||
<!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">
|
||||
<meta name="description" content="AMR">
|
||||
<title>How to determine multi-drug resistance (MDR) • AMR (for R)</title>
|
||||
<!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png">
|
||||
<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.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
|
||||
<script src="../extra.js"></script><meta property="og:title" content="How to determine multi-drug resistance (MDR)">
|
||||
<meta property="og:description" content="AMR">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="active nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>How to determine multi-drug resistance (MDR)</h1>
|
||||
|
||||
|
||||
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/vignettes/MDR.Rmd" class="external-link"><code>vignettes/MDR.Rmd</code></a></small>
|
||||
<div class="d-none name"><code>MDR.Rmd</code></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<p>With the function <code><a href="../reference/mdro.html">mdro()</a></code>, you can determine which
|
||||
micro-organisms are multi-drug resistant organisms (MDRO).</p>
|
||||
<div class="section level3">
|
||||
<h3 id="type-of-input">Type of input<a class="anchor" aria-label="anchor" href="#type-of-input"></a>
|
||||
</h3>
|
||||
<p>The <code><a href="../reference/mdro.html">mdro()</a></code> function takes a data set as input, such as a
|
||||
regular <code>data.frame</code>. It tries to automatically determine the
|
||||
right columns for info about your isolates, such as the name of the
|
||||
species and all columns with results of antimicrobial agents. See the
|
||||
help page for more info about how to set the right settings for your
|
||||
data with the command <code><a href="../reference/mdro.html">?mdro</a></code>.</p>
|
||||
<p>For WHONET data (and most other data), all settings are automatically
|
||||
set correctly.</p>
|
||||
</div>
|
||||
<div class="section level3">
|
||||
<h3 id="guidelines">Guidelines<a class="anchor" aria-label="anchor" href="#guidelines"></a>
|
||||
</h3>
|
||||
<p>The <code><a href="../reference/mdro.html">mdro()</a></code> function support multiple guidelines. You can
|
||||
select a guideline with the <code>guideline</code> parameter. Currently
|
||||
supported guidelines are (case-insensitive):</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>guideline = "CMI2012"</code> (default)</p>
|
||||
<p>Magiorakos AP, Srinivasan A <em>et al.</em> “Multidrug-resistant,
|
||||
extensively drug-resistant and pandrug-resistant bacteria: an
|
||||
international expert proposal for interim standard definitions for
|
||||
acquired resistance.” Clinical Microbiology and Infection (2012) (<a href="https://www.clinicalmicrobiologyandinfection.com/article/S1198-743X(14)61632-3/fulltext" class="external-link">link</a>)</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>guideline = "EUCAST3.2"</code> (or simply
|
||||
<code>guideline = "EUCAST"</code>)</p>
|
||||
<p>The European international guideline - EUCAST Expert Rules Version
|
||||
3.2 “Intrinsic Resistance and Unusual Phenotypes” (<a href="https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/2020/Intrinsic_Resistance_and_Unusual_Phenotypes_Tables_v3.2_20200225.pdf" class="external-link">link</a>)</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>guideline = "EUCAST3.1"</code></p>
|
||||
<p>The European international guideline - EUCAST Expert Rules Version
|
||||
3.1 “Intrinsic Resistance and Exceptional Phenotypes Tables” (<a href="https://www.eucast.org/fileadmin/src/media/PDFs/EUCAST_files/Expert_Rules/Expert_rules_intrinsic_exceptional_V3.1.pdf" class="external-link">link</a>)</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>guideline = "TB"</code></p>
|
||||
<p>The international guideline for multi-drug resistant tuberculosis -
|
||||
World Health Organization “Companion handbook to the WHO guidelines for
|
||||
the programmatic management of drug-resistant tuberculosis” (<a href="https://www.who.int/tb/publications/pmdt_companionhandbook/en/" class="external-link">link</a>)</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>guideline = "MRGN"</code></p>
|
||||
<p>The German national guideline - Mueller <em>et al.</em> (2015)
|
||||
Antimicrobial Resistance and Infection Control 4:7. DOI:
|
||||
10.1186/s13756-015-0047-6</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>guideline = "BRMO"</code></p>
|
||||
<p>The Dutch national guideline - Rijksinstituut voor Volksgezondheid en
|
||||
Milieu “WIP-richtlijn BRMO (Bijzonder Resistente Micro-Organismen)
|
||||
(ZKH)” (<a href="https://www.rivm.nl/wip-richtlijn-brmo-bijzonder-resistente-micro-organismen-zkh" class="external-link">link</a>)</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Please suggest your own (country-specific) guidelines by letting us
|
||||
know: <a href="https://github.com/msberends/AMR/issues/new" class="external-link uri">https://github.com/msberends/AMR/issues/new</a>.</p>
|
||||
<div class="section level4">
|
||||
<h4 id="custom-guidelines">Custom Guidelines<a class="anchor" aria-label="anchor" href="#custom-guidelines"></a>
|
||||
</h4>
|
||||
<p>You can also use your own custom guideline. Custom guidelines can be
|
||||
set with the <code><a href="../reference/mdro.html">custom_mdro_guideline()</a></code> function. This is of
|
||||
great importance if you have custom rules to determine MDROs in your
|
||||
hospital, e.g., rules that are dependent on ward, state of contact
|
||||
isolation or other variables in your data.</p>
|
||||
<p>If you are familiar with <code><a href="https://dplyr.tidyverse.org/reference/case_when.html" class="external-link">case_when()</a></code> of the
|
||||
<code>dplyr</code> package, you will recognise the input method to set
|
||||
your own rules. Rules must be set using what R considers to be the
|
||||
‘formula notation’:</p>
|
||||
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">custom</span> <span class="op"><-</span> <span class="fu"><a href="../reference/mdro.html">custom_mdro_guideline</a></span><span class="op">(</span></span>
|
||||
<span> <span class="va">CIP</span> <span class="op">==</span> <span class="st">"R"</span> <span class="op">&</span> <span class="va">age</span> <span class="op">></span> <span class="fl">60</span> <span class="op">~</span> <span class="st">"Elderly Type A"</span>,</span>
|
||||
<span> <span class="va">ERY</span> <span class="op">==</span> <span class="st">"R"</span> <span class="op">&</span> <span class="va">age</span> <span class="op">></span> <span class="fl">60</span> <span class="op">~</span> <span class="st">"Elderly Type B"</span></span>
|
||||
<span><span class="op">)</span></span></code></pre></div>
|
||||
<p>If a row/an isolate matches the first rule, the value after the first
|
||||
<code>~</code> (in this case <em>‘Elderly Type A’</em>) will be set as
|
||||
MDRO value. Otherwise, the second rule will be tried and so on. The
|
||||
maximum number of rules is unlimited.</p>
|
||||
<p>You can print the rules set in the console for an overview. Colours
|
||||
will help reading it if your console supports colours.</p>
|
||||
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">custom</span></span>
|
||||
<span><span class="co"># A set of custom MDRO rules:</span></span>
|
||||
<span><span class="co"># 1. If CIP is "R" and age is higher than 60 then: Elderly Type A</span></span>
|
||||
<span><span class="co"># 2. If ERY is "R" and age is higher than 60 then: Elderly Type B</span></span>
|
||||
<span><span class="co"># 3. Otherwise: Negative</span></span>
|
||||
<span><span class="co"># </span></span>
|
||||
<span><span class="co"># Unmatched rows will return NA.</span></span>
|
||||
<span><span class="co"># Results will be of class 'factor', with ordered levels: Negative < Elderly Type A < Elderly Type B</span></span></code></pre></div>
|
||||
<p>The outcome of the function can be used for the
|
||||
<code>guideline</code> argument in the <code><a href="../reference/mdro.html">mdro()</a></code> function:</p>
|
||||
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">x</span> <span class="op"><-</span> <span class="fu"><a href="../reference/mdro.html">mdro</a></span><span class="op">(</span><span class="va">example_isolates</span>, guideline <span class="op">=</span> <span class="va">custom</span><span class="op">)</span></span>
|
||||
<span><span class="fu"><a href="https://rdrr.io/r/base/table.html" class="external-link">table</a></span><span class="op">(</span><span class="va">x</span><span class="op">)</span></span>
|
||||
<span><span class="co"># x</span></span>
|
||||
<span><span class="co"># Negative Elderly Type A Elderly Type B </span></span>
|
||||
<span><span class="co"># 1070 198 732</span></span></code></pre></div>
|
||||
<p>The rules set (the <code>custom</code> object in this case) could be
|
||||
exported to a shared file location using <code><a href="https://rdrr.io/r/base/readRDS.html" class="external-link">saveRDS()</a></code> if you
|
||||
collaborate with multiple users. The custom rules set could then be
|
||||
imported using <code><a href="https://rdrr.io/r/base/readRDS.html" class="external-link">readRDS()</a></code>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section level3">
|
||||
<h3 id="examples">Examples<a class="anchor" aria-label="anchor" href="#examples"></a>
|
||||
</h3>
|
||||
<p>The <code><a href="../reference/mdro.html">mdro()</a></code> function always returns an ordered
|
||||
<code>factor</code> for predefined guidelines. For example, the output
|
||||
of the default guideline by Magiorakos <em>et al.</em> returns a
|
||||
<code>factor</code> with levels ‘Negative’, ‘MDR’, ‘XDR’ or ‘PDR’ in
|
||||
that order.</p>
|
||||
<p>The next example uses the <code>example_isolates</code> data set.
|
||||
This is a data set included with this package and contains full
|
||||
antibiograms of 2,000 microbial isolates. It reflects reality and can be
|
||||
used to practise AMR data analysis. If we test the MDR/XDR/PDR guideline
|
||||
on this data set, we get:</p>
|
||||
<div class="sourceCode" id="cb4"><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"># to support pipes: %>%</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>
|
||||
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">example_isolates</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/mdro.html">mdro</a></span><span class="op">(</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<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="op">)</span> <span class="co"># show frequency table of the result</span></span>
|
||||
<span><span class="co"># Warning: in mdro(): NA introduced for isolates where the available percentage of</span></span>
|
||||
<span><span class="co"># antimicrobial classes was below 50% (set with pct_required_classes)</span></span></code></pre></div>
|
||||
<p>(16 isolates had no test results)</p>
|
||||
<p><strong>Frequency table</strong></p>
|
||||
<p>Class: factor > ordered (numeric)<br>
|
||||
Length: 2,000<br>
|
||||
Levels: 4: Negative < Multi-drug-resistant (MDR) < Extensively
|
||||
drug-resistant …<br>
|
||||
Available: 1,729 (86.45%, NA: 271 = 13.55%)<br>
|
||||
Unique: 2</p>
|
||||
<table style="width:100%;" class="table">
|
||||
<colgroup>
|
||||
<col width="4%">
|
||||
<col width="38%">
|
||||
<col width="9%">
|
||||
<col width="12%">
|
||||
<col width="16%">
|
||||
<col width="19%">
|
||||
</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">Negative</td>
|
||||
<td align="right">1601</td>
|
||||
<td align="right">92.6%</td>
|
||||
<td align="right">1601</td>
|
||||
<td align="right">92.6%</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td align="left">2</td>
|
||||
<td align="left">Multi-drug-resistant (MDR)</td>
|
||||
<td align="right">128</td>
|
||||
<td align="right">7.4%</td>
|
||||
<td align="right">1729</td>
|
||||
<td align="right">100.0%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>For another example, I will create a data set to determine multi-drug
|
||||
resistant TB:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># random_rsi() is a helper function to generate</span></span>
|
||||
<span><span class="co"># a random vector with values S, I and R</span></span>
|
||||
<span><span class="va">my_TB_data</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html" class="external-link">data.frame</a></span><span class="op">(</span></span>
|
||||
<span> rifampicin <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> isoniazid <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> gatifloxacin <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> ethambutol <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> pyrazinamide <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> moxifloxacin <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> kanamycin <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span></span>
|
||||
<span><span class="op">)</span></span></code></pre></div>
|
||||
<p>Because all column names are automatically verified for valid drug
|
||||
names or codes, this would have worked exactly the same way:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">my_TB_data</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html" class="external-link">data.frame</a></span><span class="op">(</span></span>
|
||||
<span> RIF <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> INH <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> GAT <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> ETH <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> PZA <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> MFX <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span>,</span>
|
||||
<span> KAN <span class="op">=</span> <span class="fu"><a href="../reference/random.html">random_rsi</a></span><span class="op">(</span><span class="fl">5000</span><span class="op">)</span></span>
|
||||
<span><span class="op">)</span></span></code></pre></div>
|
||||
<p>The data set now looks like this:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><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">my_TB_data</span><span class="op">)</span></span>
|
||||
<span><span class="co"># rifampicin isoniazid gatifloxacin ethambutol pyrazinamide moxifloxacin</span></span>
|
||||
<span><span class="co"># 1 S R S R R R</span></span>
|
||||
<span><span class="co"># 2 I I S R S S</span></span>
|
||||
<span><span class="co"># 3 I I R I S R</span></span>
|
||||
<span><span class="co"># 4 R I S S I R</span></span>
|
||||
<span><span class="co"># 5 R R S R R I</span></span>
|
||||
<span><span class="co"># 6 R R R I S I</span></span>
|
||||
<span><span class="co"># kanamycin</span></span>
|
||||
<span><span class="co"># 1 S</span></span>
|
||||
<span><span class="co"># 2 R</span></span>
|
||||
<span><span class="co"># 3 I</span></span>
|
||||
<span><span class="co"># 4 R</span></span>
|
||||
<span><span class="co"># 5 R</span></span>
|
||||
<span><span class="co"># 6 S</span></span></code></pre></div>
|
||||
<p>We can now add the interpretation of MDR-TB to our data set. You can
|
||||
use:</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="fu"><a href="../reference/mdro.html">mdro</a></span><span class="op">(</span><span class="va">my_TB_data</span>, guideline <span class="op">=</span> <span class="st">"TB"</span><span class="op">)</span></span></code></pre></div>
|
||||
<p>or its shortcut <code><a href="../reference/mdro.html">mdr_tb()</a></code>:</p>
|
||||
<div class="sourceCode" id="cb10"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">my_TB_data</span><span class="op">$</span><span class="va">mdr</span> <span class="op"><-</span> <span class="fu"><a href="../reference/mdro.html">mdr_tb</a></span><span class="op">(</span><span class="va">my_TB_data</span><span class="op">)</span></span>
|
||||
<span><span class="co"># ℹ No column found as input for col_mo, assuming all rows contain</span></span>
|
||||
<span><span class="co"># Mycobacterium tuberculosis.</span></span></code></pre></div>
|
||||
<p>Create a frequency table of the results:</p>
|
||||
<div class="sourceCode" id="cb11"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><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">my_TB_data</span><span class="op">$</span><span class="va">mdr</span><span class="op">)</span></span></code></pre></div>
|
||||
<p><strong>Frequency table</strong></p>
|
||||
<p>Class: factor > ordered (numeric)<br>
|
||||
Length: 5,000<br>
|
||||
Levels: 5: Negative < Mono-resistant < Poly-resistant <
|
||||
Multi-drug-resistant <…<br>
|
||||
Available: 5,000 (100%, NA: 0 = 0%)<br>
|
||||
Unique: 5</p>
|
||||
<table style="width:100%;" class="table">
|
||||
<colgroup>
|
||||
<col width="4%">
|
||||
<col width="38%">
|
||||
<col width="9%">
|
||||
<col width="12%">
|
||||
<col width="16%">
|
||||
<col width="19%">
|
||||
</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">Mono-resistant</td>
|
||||
<td align="right">3268</td>
|
||||
<td align="right">65.36%</td>
|
||||
<td align="right">3268</td>
|
||||
<td align="right">65.36%</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td align="left">2</td>
|
||||
<td align="left">Negative</td>
|
||||
<td align="right">961</td>
|
||||
<td align="right">19.22%</td>
|
||||
<td align="right">4229</td>
|
||||
<td align="right">84.58%</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td align="left">3</td>
|
||||
<td align="left">Multi-drug-resistant</td>
|
||||
<td align="right">438</td>
|
||||
<td align="right">8.76%</td>
|
||||
<td align="right">4667</td>
|
||||
<td align="right">93.34%</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td align="left">4</td>
|
||||
<td align="left">Poly-resistant</td>
|
||||
<td align="right">232</td>
|
||||
<td align="right">4.64%</td>
|
||||
<td align="right">4899</td>
|
||||
<td align="right">97.98%</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td align="left">5</td>
|
||||
<td align="left">Extensively drug-resistant</td>
|
||||
<td align="right">101</td>
|
||||
<td align="right">2.02%</td>
|
||||
<td align="right">5000</td>
|
||||
<td align="right">100.00%</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</main><aside class="col-md-3"><nav id="toc"><h2>On this page</h2>
|
||||
</nav></aside>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,336 @@
|
||||
<!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">
|
||||
<meta name="description" content="AMR">
|
||||
<title>How to conduct principal component analysis (PCA) for AMR • AMR (for R)</title>
|
||||
<!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png">
|
||||
<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.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
|
||||
<script src="../extra.js"></script><meta property="og:title" content="How to conduct principal component analysis (PCA) for AMR">
|
||||
<meta property="og:description" content="AMR">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="active nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>How to conduct principal component analysis (PCA) for AMR</h1>
|
||||
|
||||
|
||||
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/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://msberends.github.io/AMR/">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"># Rows: 2,000</span></span>
|
||||
<span><span class="co"># Columns: 46</span></span>
|
||||
<span><span class="co"># $ date <span style="color: #949494; font-style: italic;"><date></span> 2002-01-02, 2002-01-03, 2002-01-07, 2002-01-07, 2002-01-13, 2…</span></span>
|
||||
<span><span class="co"># $ patient <span style="color: #949494; font-style: italic;"><chr></span> "A77334", "A77334", "067927", "067927", "067927", "067927", "4…</span></span>
|
||||
<span><span class="co"># $ age <span style="color: #949494; font-style: italic;"><dbl></span> 65, 65, 45, 45, 45, 45, 78, 78, 45, 79, 67, 67, 71, 71, 75, 50…</span></span>
|
||||
<span><span class="co"># $ gender <span style="color: #949494; font-style: italic;"><chr></span> "F", "F", "F", "F", "F", "F", "M", "M", "F", "F", "M", "M", "M…</span></span>
|
||||
<span><span class="co"># $ ward <span style="color: #949494; font-style: italic;"><chr></span> "Clinical", "Clinical", "ICU", "ICU", "ICU", "ICU", "Clinical"…</span></span>
|
||||
<span><span class="co"># $ mo <span style="color: #949494; font-style: italic;"><mo></span> "B_ESCHR_COLI", "B_ESCHR_COLI", "B_STPHY_EPDR", "B_STPHY_EPDR",…</span></span>
|
||||
<span><span class="co"># $ PEN <span style="color: #949494; font-style: italic;"><rsi></span> R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, R, S,…</span></span>
|
||||
<span><span class="co"># $ OXA <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ FLC <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, R, R, R, R, S, S, R, S, S, S, NA, NA, NA, NA, NA, R, R…</span></span>
|
||||
<span><span class="co"># $ AMX <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, R, R, NA, NA, NA, NA, NA, NA, R, NA, N…</span></span>
|
||||
<span><span class="co"># $ AMC <span style="color: #949494; font-style: italic;"><rsi></span> I, I, NA, NA, NA, NA, S, S, NA, NA, S, S, I, I, R, I, I, NA, N…</span></span>
|
||||
<span><span class="co"># $ AMP <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, R, R, NA, NA, NA, NA, NA, NA, R, NA, N…</span></span>
|
||||
<span><span class="co"># $ TZP <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ CZO <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, NA,…</span></span>
|
||||
<span><span class="co"># $ FEP <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ CXM <span style="color: #949494; font-style: italic;"><rsi></span> I, I, R, R, R, R, S, S, R, S, S, S, S, S, NA, S, S, R, R, S, S…</span></span>
|
||||
<span><span class="co"># $ FOX <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, NA,…</span></span>
|
||||
<span><span class="co"># $ CTX <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, S, S…</span></span>
|
||||
<span><span class="co"># $ CAZ <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, R, R, R, R, R, R, R, R, R, R, NA, NA, NA, S, S, R, R, …</span></span>
|
||||
<span><span class="co"># $ CRO <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, S, S…</span></span>
|
||||
<span><span class="co"># $ GEN <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ TOB <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, S, S, NA, NA, NA, NA, S, S, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ AMK <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ KAN <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ TMP <span style="color: #949494; font-style: italic;"><rsi></span> R, R, S, S, R, R, R, R, S, S, NA, NA, S, S, S, S, S, R, R, R, …</span></span>
|
||||
<span><span class="co"># $ SXT <span style="color: #949494; font-style: italic;"><rsi></span> R, R, S, S, NA, NA, NA, NA, S, S, NA, NA, S, S, S, S, S, NA, N…</span></span>
|
||||
<span><span class="co"># $ NIT <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R,…</span></span>
|
||||
<span><span class="co"># $ FOS <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ LNZ <span style="color: #949494; font-style: italic;"><rsi></span> R, R, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, R, R, R, R, N…</span></span>
|
||||
<span><span class="co"># $ CIP <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, NA, NA, NA, NA, S, S…</span></span>
|
||||
<span><span class="co"># $ MFX <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ VAN <span style="color: #949494; font-style: italic;"><rsi></span> R, R, S, S, S, S, S, S, S, S, NA, NA, R, R, R, R, R, S, S, S, …</span></span>
|
||||
<span><span class="co"># $ TEC <span style="color: #949494; font-style: italic;"><rsi></span> R, R, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, R, R, R, R, N…</span></span>
|
||||
<span><span class="co"># $ TCY <span style="color: #949494; font-style: italic;"><rsi></span> R, R, S, S, S, S, S, S, S, I, S, S, NA, NA, I, R, R, S, I, R, …</span></span>
|
||||
<span><span class="co"># $ TGC <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, S, S, S, S, S, S, S, NA, S, S, NA, NA, NA, R, R, S, NA…</span></span>
|
||||
<span><span class="co"># $ DOX <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, S, S, S, S, S, S, S, NA, S, S, NA, NA, NA, R, R, S, NA…</span></span>
|
||||
<span><span class="co"># $ ERY <span style="color: #949494; font-style: italic;"><rsi></span> R, R, R, R, R, R, S, S, R, S, S, S, R, R, R, R, R, R, R, R, S,…</span></span>
|
||||
<span><span class="co"># $ CLI <span style="color: #949494; font-style: italic;"><rsi></span> R, R, NA, NA, NA, R, NA, NA, NA, NA, NA, NA, R, R, R, R, R, NA…</span></span>
|
||||
<span><span class="co"># $ AZM <span style="color: #949494; font-style: italic;"><rsi></span> R, R, R, R, R, R, S, S, R, S, S, S, R, R, R, R, R, R, R, R, S,…</span></span>
|
||||
<span><span class="co"># $ IPM <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, S, S, NA, S, S…</span></span>
|
||||
<span><span class="co"># $ MEM <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ MTR <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ CHL <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ COL <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, R, R, R, R, R, R, R, R, R, R, NA, NA, NA, R, R, R, R, …</span></span>
|
||||
<span><span class="co"># $ MUP <span style="color: #949494; font-style: italic;"><rsi></span> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…</span></span>
|
||||
<span><span class="co"># $ RIF <span style="color: #949494; font-style: italic;"><rsi></span> R, R, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, R, R, R, R, R, N…</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"><-</span> <span class="va">example_isolates</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</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">%>%</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.rsi</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">%>%</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>
|
||||
<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"># <span style="color: #949494;"># A tibble: 6 × 10</span></span></span>
|
||||
<span><span class="co"># <span style="color: #949494;"># Groups: order [5]</span></span></span>
|
||||
<span><span class="co"># order genus AMC CXM CTX CAZ GEN TOB TMP SXT</span></span>
|
||||
<span><span class="co"># <span style="color: #949494; font-style: italic;"><chr></span> <span style="color: #949494; font-style: italic;"><chr></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span></span></span>
|
||||
<span><span class="co"># <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"># <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"># <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"># <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"># <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"># <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"><-</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"># ℹ Columns selected for PCA: "AMC", "CAZ", "CTX", "CXM", "GEN", "SXT", "TMP"</span></span>
|
||||
<span><span class="co"># and "TOB". Total 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"># Groups (n=4, named as 'order'):</span></span>
|
||||
<span><span class="co"># [1] "Caryophanales" "Enterobacterales" "Lactobacillales" "Pseudomonadales"</span></span>
|
||||
<span><span class="co"># Importance of components:</span></span>
|
||||
<span><span class="co"># PC1 PC2 PC3 PC4 PC5 PC6 PC7</span></span>
|
||||
<span><span class="co"># Standard deviation 2.1539 1.6807 0.6138 0.33879 0.20808 0.03140 9.577e-17</span></span>
|
||||
<span><span class="co"># Proportion of Variance 0.5799 0.3531 0.0471 0.01435 0.00541 0.00012 0.000e+00</span></span>
|
||||
<span><span class="co"># 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"># Groups (n=4, named as 'order'):</span></span>
|
||||
<span><span class="co"># [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" width="750"></p>
|
||||
<p>But we can’t 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" 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" width="750"></p>
|
||||
</div>
|
||||
</main><aside class="col-md-3"><nav id="toc"><h2>On this page</h2>
|
||||
</nav></aside>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 93 KiB |
@@ -0,0 +1,502 @@
|
||||
<!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">
|
||||
<meta name="description" content="AMR">
|
||||
<title>How to import data from SPSS / SAS / Stata • AMR (for R)</title>
|
||||
<!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png">
|
||||
<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.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
|
||||
<script src="../extra.js"></script><meta property="og:title" content="How to import data from SPSS / SAS / Stata">
|
||||
<meta property="og:description" content="AMR">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="active nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>How to import data from SPSS / SAS / Stata</h1>
|
||||
<h4 data-toc-skip class="author">Dr. Matthijs
|
||||
Berends</h4>
|
||||
|
||||
<h4 data-toc-skip class="date">06 January 2023</h4>
|
||||
|
||||
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/vignettes/SPSS.Rmd" class="external-link"><code>vignettes/SPSS.Rmd</code></a></small>
|
||||
<div class="d-none name"><code>SPSS.Rmd</code></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="section level2">
|
||||
<h2 id="spss-sas-stata">SPSS / SAS / Stata<a class="anchor" aria-label="anchor" href="#spss-sas-stata"></a>
|
||||
</h2>
|
||||
<p>SPSS (Statistical Package for the Social Sciences) is probably the
|
||||
most well-known software package for statistical analysis. SPSS is
|
||||
easier to learn than R, because in SPSS you only have to click a menu to
|
||||
run parts of your analysis. Because of its user-friendliness, it is
|
||||
taught at universities and particularly useful for students who are new
|
||||
to statistics. From my experience, I would guess that pretty much all
|
||||
(bio)medical students know it at the time they graduate. SAS and Stata
|
||||
are comparable statistical packages popular in big industries.</p>
|
||||
</div>
|
||||
<div class="section level2">
|
||||
<h2 id="compared-to-r">Compared to R<a class="anchor" aria-label="anchor" href="#compared-to-r"></a>
|
||||
</h2>
|
||||
<p>As said, SPSS is easier to learn than R. But SPSS, SAS and Stata come
|
||||
with major downsides when comparing it with R:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>R is highly modular.</strong></p>
|
||||
<p>The <a href="https://cran.r-project.org/" class="external-link">official R network
|
||||
(CRAN)</a> features more than 16,000 packages at the time of writing,
|
||||
our <code>AMR</code> package being one of them. All these packages were
|
||||
peer-reviewed before publication. Aside from this official channel,
|
||||
there are also developers who choose not to submit to CRAN, but rather
|
||||
keep it on their own public repository, like GitHub. So there may even
|
||||
be a lot more than 14,000 packages out there.</p>
|
||||
<p>Bottom line is, you can really extend it yourself or ask somebody to
|
||||
do this for you. Take for example our <code>AMR</code> package. Among
|
||||
other things, it adds reliable reference data to R to help you with the
|
||||
data cleaning and analysis. SPSS, SAS and Stata will never know what a
|
||||
valid MIC value is or what the Gram stain of <em>E. coli</em> is. Or
|
||||
that all species of <em>Klebiella</em> are resistant to amoxicillin and
|
||||
that Floxapen<sup>®</sup> is a trade name of flucloxacillin. These facts
|
||||
and properties are often needed to clean existing data, which would be
|
||||
very inconvenient in a software package without reliable reference data.
|
||||
See below for a demonstration.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>R is extremely flexible.</strong></p>
|
||||
<p>Because you write the syntax yourself, you can do anything you want.
|
||||
The flexibility in transforming, arranging, grouping and summarising
|
||||
data, or drawing plots, is endless - with SPSS, SAS or Stata you are
|
||||
bound to their algorithms and format styles. They may be a bit flexible,
|
||||
but you can probably never create that very specific publication-ready
|
||||
plot without using other (paid) software. If you sometimes write
|
||||
syntaxes in SPSS to run a complete analysis or to ‘automate’ some of
|
||||
your work, you could do this a lot less time in R. You will notice that
|
||||
writing syntaxes in R is a lot more nifty and clever than in SPSS.
|
||||
Still, as working with any statistical package, you will have to have
|
||||
knowledge about what you are doing (statistically) and what you are
|
||||
willing to accomplish.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>R can be easily automated.</strong></p>
|
||||
<p>Over the last years, <a href="https://rmarkdown.rstudio.com/" class="external-link">R
|
||||
Markdown</a> has really made an interesting development. With R
|
||||
Markdown, you can very easily produce reports, whether the format has to
|
||||
be Word, PowerPoint, a website, a PDF document or just the raw data to
|
||||
Excel. It even allows the use of a reference file containing the layout
|
||||
style (e.g. fonts and colours) of your organisation. I use this a lot to
|
||||
generate weekly and monthly reports automatically. Just write the code
|
||||
once and enjoy the automatically updated reports at any interval you
|
||||
like.</p>
|
||||
<p>For an even more professional environment, you could create <a href="https://shiny.rstudio.com/" class="external-link">Shiny apps</a>: live manipulation of
|
||||
data using a custom made website. The webdesign knowledge needed
|
||||
(JavaScript, CSS, HTML) is almost <em>zero</em>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>R has a huge community.</strong></p>
|
||||
<p>Many R users just ask questions on websites like <a href="https://stackoverflow.com" class="external-link">StackOverflow.com</a>, the largest
|
||||
online community for programmers. At the time of writing, <a href="https://stackoverflow.com/questions/tagged/r?sort=votes" class="external-link">476,194
|
||||
R-related questions</a> have already been asked on this platform (that
|
||||
covers questions and answers for any programming language). In my own
|
||||
experience, most questions are answered within a couple of
|
||||
minutes.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>R understands any data type, including
|
||||
SPSS/SAS/Stata.</strong></p>
|
||||
<p>And that’s not vice versa I’m afraid. You can import data from any
|
||||
source into R. For example from SPSS, SAS and Stata (<a href="https://haven.tidyverse.org/" class="external-link">link</a>), from Minitab, Epi Info
|
||||
and EpiData (<a href="https://cran.r-project.org/package=foreign" class="external-link">link</a>), from Excel
|
||||
(<a href="https://readxl.tidyverse.org/" class="external-link">link</a>), from flat files like
|
||||
CSV, TXT or TSV (<a href="https://readr.tidyverse.org/" class="external-link">link</a>), or
|
||||
directly from databases and datawarehouses from anywhere on the world
|
||||
(<a href="https://dbplyr.tidyverse.org/" class="external-link">link</a>). You can even scrape
|
||||
websites to download tables that are live on the internet (<a href="https://github.com/hadley/rvest" class="external-link">link</a>) or get the results of
|
||||
an API call and transform it into data in only one command (<a href="https://github.com/Rdatatable/data.table/wiki/Convenience-features-of-fread" class="external-link">link</a>).</p>
|
||||
<p>And the best part - you can export from R to most data formats as
|
||||
well. So you can import an SPSS file, do your analysis neatly in R and
|
||||
export the resulting tables to Excel files for sharing.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>R is completely free and open-source.</strong></p>
|
||||
<p>No strings attached. It was created and is being maintained by
|
||||
volunteers who believe that (data) science should be open and publicly
|
||||
available to everybody. SPSS, SAS and Stata are quite expensive. IBM
|
||||
SPSS Staticstics only comes with subscriptions nowadays, varying <a href="https://www.ibm.com/products/spss-statistics/pricing" class="external-link">between USD
|
||||
1,300 and USD 8,500</a> per user <em>per year</em>. SAS Analytics Pro
|
||||
costs <a href="https://www.sas.com/store/products-solutions/sas-analytics-pro/prodPERSANL.html" class="external-link">around
|
||||
USD 10,000</a> per computer. Stata also has a business model with
|
||||
subscription fees, varying <a href="https://www.stata.com/order/new/bus/single-user-licenses/dl/" class="external-link">between
|
||||
USD 600 and USD 2,800</a> per computer per year, but lower prices come
|
||||
with a limitation of the number of variables you can work with. And
|
||||
still they do not offer the above benefits of R.</p>
|
||||
<p>If you are working at a midsized or small company, you can save it
|
||||
tens of thousands of dollars by using R instead of e.g. SPSS - gaining
|
||||
even more functions and flexibility. And all R enthousiasts can do as
|
||||
much PR as they want (like I do here), because nobody is officially
|
||||
associated with or affiliated by R. It is really free.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>R is (nowadays) the preferred analysis software in
|
||||
academic papers.</strong></p>
|
||||
<p>At present, R is among the world most powerful statistical languages,
|
||||
and it is generally very popular in science (Bollmann <em>et al.</em>,
|
||||
2017). For all the above reasons, the number of references to R as an
|
||||
analysis method in academic papers <a href="https://r4stats.com/2014/08/20/r-passes-spss-in-scholarly-use-stata-growing-rapidly/" class="external-link">is
|
||||
rising continuously</a> and has even surpassed SPSS for academic use
|
||||
(Muenchen, 2014).</p>
|
||||
<p>I believe that the thing with SPSS is, that it has always had a great
|
||||
user interface which is very easy to learn and use. Back when they
|
||||
developed it, they had very little competition, let alone from R. R
|
||||
didn’t even had a professional user interface until the last decade
|
||||
(called RStudio, see below). How people used R between the nineties and
|
||||
2010 is almost completely incomparable to how R is being used now. The
|
||||
language itself <a href="https://www.tidyverse.org/packages/" class="external-link">has been
|
||||
restyled completely</a> by volunteers who are dedicated professionals in
|
||||
the field of data science. SPSS was great when there was nothing else
|
||||
that could compete. But now in 2023, I don’t see any reason why SPSS
|
||||
would be of any better use than R.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>To demonstrate the first point:</p>
|
||||
<div class="sourceCode" id="cb1"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># not all values are valid MIC values:</span></span>
|
||||
<span><span class="fu"><a href="../reference/as.mic.html">as.mic</a></span><span class="op">(</span><span class="fl">0.125</span><span class="op">)</span></span>
|
||||
<span><span class="co"># Class 'mic'</span></span>
|
||||
<span><span class="co"># [1] 0.125</span></span>
|
||||
<span><span class="fu"><a href="../reference/as.mic.html">as.mic</a></span><span class="op">(</span><span class="st">"testvalue"</span><span class="op">)</span></span>
|
||||
<span><span class="co"># Class 'mic'</span></span>
|
||||
<span><span class="co"># [1] <NA></span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># the Gram stain is available for all bacteria:</span></span>
|
||||
<span><span class="fu"><a href="../reference/mo_property.html">mo_gramstain</a></span><span class="op">(</span><span class="st">"E. coli"</span><span class="op">)</span></span>
|
||||
<span><span class="co"># [1] "Gram-negative"</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># Klebsiella is intrinsic resistant to amoxicillin, according to EUCAST:</span></span>
|
||||
<span><span class="va">klebsiella_test</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/data.frame.html" class="external-link">data.frame</a></span><span class="op">(</span></span>
|
||||
<span> mo <span class="op">=</span> <span class="st">"klebsiella"</span>,</span>
|
||||
<span> amox <span class="op">=</span> <span class="st">"S"</span>,</span>
|
||||
<span> stringsAsFactors <span class="op">=</span> <span class="cn">FALSE</span></span>
|
||||
<span><span class="op">)</span></span>
|
||||
<span><span class="va">klebsiella_test</span> <span class="co"># (our original data)</span></span>
|
||||
<span><span class="co"># mo amox</span></span>
|
||||
<span><span class="co"># 1 klebsiella S</span></span>
|
||||
<span><span class="fu"><a href="../reference/eucast_rules.html">eucast_rules</a></span><span class="op">(</span><span class="va">klebsiella_test</span>, info <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span> <span class="co"># (the edited data by EUCAST rules)</span></span>
|
||||
<span><span class="co"># mo amox</span></span>
|
||||
<span><span class="co"># 1 klebsiella R</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># hundreds of trade names can be translated to a name, trade name or an ATC code:</span></span>
|
||||
<span><span class="fu"><a href="../reference/ab_property.html">ab_name</a></span><span class="op">(</span><span class="st">"floxapen"</span><span class="op">)</span></span>
|
||||
<span><span class="co"># [1] "Flucloxacillin"</span></span>
|
||||
<span><span class="fu"><a href="../reference/ab_property.html">ab_tradenames</a></span><span class="op">(</span><span class="st">"floxapen"</span><span class="op">)</span></span>
|
||||
<span><span class="co"># [1] "culpen" "floxacillin" "floxacillin sodium" </span></span>
|
||||
<span><span class="co"># [4] "floxapen" "floxapen sodium salt" "fluclox" </span></span>
|
||||
<span><span class="co"># [7] "flucloxacilina" "flucloxacillin" "flucloxacilline" </span></span>
|
||||
<span><span class="co"># [10] "flucloxacillinum" "fluorochloroxacillin" "staphylex"</span></span>
|
||||
<span><span class="fu"><a href="../reference/ab_property.html">ab_atc</a></span><span class="op">(</span><span class="st">"floxapen"</span><span class="op">)</span></span>
|
||||
<span><span class="co"># [1] "J01CF05"</span></span></code></pre></div>
|
||||
</div>
|
||||
<div class="section level2">
|
||||
<h2 id="import-data-from-spsssasstata">Import data from SPSS/SAS/Stata<a class="anchor" aria-label="anchor" href="#import-data-from-spsssasstata"></a>
|
||||
</h2>
|
||||
<div class="section level3">
|
||||
<h3 id="rstudio">RStudio<a class="anchor" aria-label="anchor" href="#rstudio"></a>
|
||||
</h3>
|
||||
<p>To work with R, probably the best option is to use <a href="https://www.rstudio.com/products/rstudio/" class="external-link">RStudio</a>. It is an
|
||||
open-source and free desktop environment which not only allows you to
|
||||
run R code, but also supports project management, version management,
|
||||
package management and convenient import menus to work with other data
|
||||
sources. You can also install <a href="https://www.rstudio.com/products/rstudio/" class="external-link">RStudio Server</a> on a
|
||||
private or corporate server, which brings nothing less than the complete
|
||||
RStudio software to you as a website (at home or at work).</p>
|
||||
<p>To import a data file, just click <em>Import Dataset</em> in the
|
||||
Environment tab:</p>
|
||||
<p><img src="https://github.com/msberends/AMR/raw/main/docs/import1.png"></p>
|
||||
<p>If additional packages are needed, RStudio will ask you if they
|
||||
should be installed on beforehand.</p>
|
||||
<p>In the the window that opens, you can define all options (parameters)
|
||||
that should be used for import and you’re ready to go:</p>
|
||||
<p><img src="https://github.com/msberends/AMR/raw/main/docs/import2.png"></p>
|
||||
<p>If you want named variables to be imported as factors so it resembles
|
||||
SPSS more, use <code>as_factor()</code>.</p>
|
||||
<p>The difference is this:</p>
|
||||
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">SPSS_data</span></span>
|
||||
<span><span class="co"># # A tibble: 4,203 x 4</span></span>
|
||||
<span><span class="co"># v001 sex status statusage</span></span>
|
||||
<span><span class="co"># <dbl> <dbl+lbl> <dbl+lbl> <dbl></span></span>
|
||||
<span><span class="co"># 1 10002 1 1 76.6</span></span>
|
||||
<span><span class="co"># 2 10004 0 1 59.1</span></span>
|
||||
<span><span class="co"># 3 10005 1 1 54.5</span></span>
|
||||
<span><span class="co"># 4 10006 1 1 54.1</span></span>
|
||||
<span><span class="co"># 5 10007 1 1 57.7</span></span>
|
||||
<span><span class="co"># 6 10008 1 1 62.8</span></span>
|
||||
<span><span class="co"># 7 10010 0 1 63.7</span></span>
|
||||
<span><span class="co"># 8 10011 1 1 73.1</span></span>
|
||||
<span><span class="co"># 9 10017 1 1 56.7</span></span>
|
||||
<span><span class="co"># 10 10018 0 1 66.6</span></span>
|
||||
<span><span class="co"># # ... with 4,193 more rows</span></span>
|
||||
<span></span>
|
||||
<span><span class="fu">as_factor</span><span class="op">(</span><span class="va">SPSS_data</span><span class="op">)</span></span>
|
||||
<span><span class="co"># # A tibble: 4,203 x 4</span></span>
|
||||
<span><span class="co"># v001 sex status statusage</span></span>
|
||||
<span><span class="co"># <dbl> <fct> <fct> <dbl></span></span>
|
||||
<span><span class="co"># 1 10002 Male alive 76.6</span></span>
|
||||
<span><span class="co"># 2 10004 Female alive 59.1</span></span>
|
||||
<span><span class="co"># 3 10005 Male alive 54.5</span></span>
|
||||
<span><span class="co"># 4 10006 Male alive 54.1</span></span>
|
||||
<span><span class="co"># 5 10007 Male alive 57.7</span></span>
|
||||
<span><span class="co"># 6 10008 Male alive 62.8</span></span>
|
||||
<span><span class="co"># 7 10010 Female alive 63.7</span></span>
|
||||
<span><span class="co"># 8 10011 Male alive 73.1</span></span>
|
||||
<span><span class="co"># 9 10017 Male alive 56.7</span></span>
|
||||
<span><span class="co"># 10 10018 Female alive 66.6</span></span>
|
||||
<span><span class="co"># # ... with 4,193 more rows</span></span></code></pre></div>
|
||||
</div>
|
||||
<div class="section level3">
|
||||
<h3 id="base-r">Base R<a class="anchor" aria-label="anchor" href="#base-r"></a>
|
||||
</h3>
|
||||
<p>To import data from SPSS, SAS or Stata, you can use the <a href="https://haven.tidyverse.org/" class="external-link">great <code>haven</code> package</a>
|
||||
yourself:</p>
|
||||
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># download and install the latest version:</span></span>
|
||||
<span><span class="fu"><a href="https://rdrr.io/r/utils/install.packages.html" class="external-link">install.packages</a></span><span class="op">(</span><span class="st">"haven"</span><span class="op">)</span></span>
|
||||
<span><span class="co"># load the package you just installed:</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://haven.tidyverse.org" class="external-link">haven</a></span><span class="op">)</span></span></code></pre></div>
|
||||
<p>You can now import files as follows:</p>
|
||||
<div class="section level4">
|
||||
<h4 id="spss">SPSS<a class="anchor" aria-label="anchor" href="#spss"></a>
|
||||
</h4>
|
||||
<p>To read files from SPSS into R:</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># read any SPSS file based on file extension (best way):</span></span>
|
||||
<span><span class="fu">read_spss</span><span class="op">(</span>file <span class="op">=</span> <span class="st">"path/to/file"</span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># read .sav or .zsav file:</span></span>
|
||||
<span><span class="fu">read_sav</span><span class="op">(</span>file <span class="op">=</span> <span class="st">"path/to/file"</span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># read .por file:</span></span>
|
||||
<span><span class="fu">read_por</span><span class="op">(</span>file <span class="op">=</span> <span class="st">"path/to/file"</span><span class="op">)</span></span></code></pre></div>
|
||||
<p>Do not forget about <code>as_factor()</code>, as mentioned above.</p>
|
||||
<p>To export your R objects to the SPSS file format:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># save as .sav file:</span></span>
|
||||
<span><span class="fu">write_sav</span><span class="op">(</span>data <span class="op">=</span> <span class="va">yourdata</span>, path <span class="op">=</span> <span class="st">"path/to/file"</span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># save as compressed .zsav file:</span></span>
|
||||
<span><span class="fu">write_sav</span><span class="op">(</span>data <span class="op">=</span> <span class="va">yourdata</span>, path <span class="op">=</span> <span class="st">"path/to/file"</span>, compress <span class="op">=</span> <span class="cn">TRUE</span><span class="op">)</span></span></code></pre></div>
|
||||
</div>
|
||||
<div class="section level4">
|
||||
<h4 id="sas">SAS<a class="anchor" aria-label="anchor" href="#sas"></a>
|
||||
</h4>
|
||||
<p>To read files from SAS into R:</p>
|
||||
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># read .sas7bdat + .sas7bcat files:</span></span>
|
||||
<span><span class="fu">read_sas</span><span class="op">(</span>data_file <span class="op">=</span> <span class="st">"path/to/file"</span>, catalog_file <span class="op">=</span> <span class="cn">NULL</span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># read SAS transport files (version 5 and version 8):</span></span>
|
||||
<span><span class="fu">read_xpt</span><span class="op">(</span>file <span class="op">=</span> <span class="st">"path/to/file"</span><span class="op">)</span></span></code></pre></div>
|
||||
<p>To export your R objects to the SAS file format:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># save as regular SAS file:</span></span>
|
||||
<span><span class="fu">write_sas</span><span class="op">(</span>data <span class="op">=</span> <span class="va">yourdata</span>, path <span class="op">=</span> <span class="st">"path/to/file"</span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># the SAS transport format is an open format</span></span>
|
||||
<span><span class="co"># (required for submission of the data to the FDA)</span></span>
|
||||
<span><span class="fu">write_xpt</span><span class="op">(</span>data <span class="op">=</span> <span class="va">yourdata</span>, path <span class="op">=</span> <span class="st">"path/to/file"</span>, version <span class="op">=</span> <span class="fl">8</span><span class="op">)</span></span></code></pre></div>
|
||||
</div>
|
||||
<div class="section level4">
|
||||
<h4 id="stata">Stata<a class="anchor" aria-label="anchor" href="#stata"></a>
|
||||
</h4>
|
||||
<p>To read files from Stata into R:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># read .dta file:</span></span>
|
||||
<span><span class="fu">read_stata</span><span class="op">(</span>file <span class="op">=</span> <span class="st">"/path/to/file"</span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># works exactly the same:</span></span>
|
||||
<span><span class="fu">read_dta</span><span class="op">(</span>file <span class="op">=</span> <span class="st">"/path/to/file"</span><span class="op">)</span></span></code></pre></div>
|
||||
<p>To export your R objects to the Stata file format:</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># save as .dta file, Stata version 14:</span></span>
|
||||
<span><span class="co"># (supports Stata v8 until v15 at the time of writing)</span></span>
|
||||
<span><span class="fu">write_dta</span><span class="op">(</span>data <span class="op">=</span> <span class="va">yourdata</span>, path <span class="op">=</span> <span class="st">"/path/to/file"</span>, version <span class="op">=</span> <span class="fl">14</span><span class="op">)</span></span></code></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main><aside class="col-md-3"><nav id="toc"><h2>On this page</h2>
|
||||
</nav></aside>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,426 @@
|
||||
<!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">
|
||||
<meta name="description" content="AMR">
|
||||
<title>How to work with WHONET data • AMR (for R)</title>
|
||||
<!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png">
|
||||
<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.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
|
||||
<script src="../extra.js"></script><meta property="og:title" content="How to work with WHONET data">
|
||||
<meta property="og:description" content="AMR">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="active nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>How to work with WHONET data</h1>
|
||||
|
||||
|
||||
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/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"><-</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://msberends.github.io/AMR/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 don’t 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://msberends.github.io/AMR/">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://msberends.github.io/AMR/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.rsi.html">as.rsi()</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"><-</span> <span class="va">WHONET</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</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">%>%</a></span></span>
|
||||
<span> <span class="co"># transform everything from "AMP_ND10" to "CIP_EE" to the new `rsi` 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.rsi</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 let’s 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">%>%</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 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</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">%>%</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></code></pre></div>
|
||||
<p><strong>Frequency table</strong></p>
|
||||
<p>Class: factor > ordered > rsi (numeric)<br>
|
||||
Length: 500<br>
|
||||
Levels: 3: S < I < R<br>
|
||||
Available: 481 (96.2%, NA: 19 = 3.8%)<br>
|
||||
Unique: 3</p>
|
||||
<p>Drug: Amoxicillin/clavulanic acid (AMC, J01CR02)<br>
|
||||
Drug group: Beta-lactams/penicillins<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_rsi.html">ggplot_rsi()</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">%>%</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">%>%</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">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/ggplot_rsi.html">ggplot_rsi</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" width="720"></p>
|
||||
</div>
|
||||
</main><aside class="col-md-3"><nav id="toc"><h2>On this page</h2>
|
||||
</nav></aside>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 73 KiB |
@@ -0,0 +1,174 @@
|
||||
<!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="16x16" href="../favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png"><link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png"><link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png"><link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png"><link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png"><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.2.2/bootstrap.min.css" rel="stylesheet"><script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet"><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous"><!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></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://msberends.github.io/AMR/logo.svg"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@msberends"><meta name="twitter:site" content="@msberends"><!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]--></head><body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul><form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off"></form>
|
||||
|
||||
<ul class="navbar-nav"><li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>
|
||||
<p class="section-desc"></p>
|
||||
|
||||
<dl><dt><a href="AMR.html">How to conduct AMR data analysis</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="EUCAST.html">How to apply EUCAST rules</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="MDR.html">How to determine multi-drug resistance (MDR)</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="PCA.html">How to conduct principal component analysis (PCA) for AMR</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="SPSS.html">How to import data from SPSS / SAS / Stata</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="WHONET.html">How to work with WHONET data</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="datasets.html">Data sets for download / own use</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="resistance_predict.html">How to predict antimicrobial resistance</a></dt>
|
||||
<dd>
|
||||
</dd><dt><a href="welcome_to_AMR.html">Welcome to the `AMR` package</a></dt>
|
||||
<dd>
|
||||
</dd></dl></div>
|
||||
</main></div>
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p><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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p><p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
<!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">
|
||||
<meta name="description" content="AMR">
|
||||
<title>How to predict antimicrobial resistance • AMR (for R)</title>
|
||||
<!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png">
|
||||
<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.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
|
||||
<script src="../extra.js"></script><meta property="og:title" content="How to predict antimicrobial resistance">
|
||||
<meta property="og:description" content="AMR">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="active nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>How to predict antimicrobial resistance</h1>
|
||||
|
||||
|
||||
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/vignettes/resistance_predict.Rmd" class="external-link"><code>vignettes/resistance_predict.Rmd</code></a></small>
|
||||
<div class="d-none name"><code>resistance_predict.Rmd</code></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="section level2">
|
||||
<h2 id="needed-r-packages">Needed R packages<a class="anchor" aria-label="anchor" href="#needed-r-packages"></a>
|
||||
</h2>
|
||||
<p>As with many uses in R, we need some additional packages for AMR data
|
||||
analysis. Our package works closely together with the <a href="https://www.tidyverse.org" class="external-link">tidyverse packages</a> <a href="https://dplyr.tidyverse.org/" class="external-link"><code>dplyr</code></a> and <a href="https://ggplot2.tidyverse.org" class="external-link"><code>ggplot2</code></a>. The
|
||||
tidyverse tremendously improves the way we conduct data science - it
|
||||
allows for a very natural way of writing syntaxes and creating beautiful
|
||||
plots in R.</p>
|
||||
<p>Our <code>AMR</code> package depends on these packages and even
|
||||
extends their use and functions.</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://dplyr.tidyverse.org" class="external-link">dplyr</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://ggplot2.tidyverse.org" class="external-link">ggplot2</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://msberends.github.io/AMR/">AMR</a></span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># (if not yet installed, install with:)</span></span>
|
||||
<span><span class="co"># install.packages(c("tidyverse", "AMR"))</span></span></code></pre></div>
|
||||
</div>
|
||||
<div class="section level2">
|
||||
<h2 id="prediction-analysis">Prediction analysis<a class="anchor" aria-label="anchor" href="#prediction-analysis"></a>
|
||||
</h2>
|
||||
<p>Our package contains a function <code><a href="../reference/resistance_predict.html">resistance_predict()</a></code>,
|
||||
which takes the same input as functions for <a href="./AMR.html">other
|
||||
AMR data analysis</a>. Based on a date column, it calculates cases per
|
||||
year and uses a regression model to predict antimicrobial
|
||||
resistance.</p>
|
||||
<p>It is basically as easy as:</p>
|
||||
<div class="sourceCode" id="cb2"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="co"># resistance prediction of piperacillin/tazobactam (TZP):</span></span>
|
||||
<span><span class="fu"><a href="../reference/resistance_predict.html">resistance_predict</a></span><span class="op">(</span>tbl <span class="op">=</span> <span class="va">example_isolates</span>, col_date <span class="op">=</span> <span class="st">"date"</span>, col_ab <span class="op">=</span> <span class="st">"TZP"</span>, model <span class="op">=</span> <span class="st">"binomial"</span><span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># or:</span></span>
|
||||
<span><span class="va">example_isolates</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/resistance_predict.html">resistance_predict</a></span><span class="op">(</span></span>
|
||||
<span> col_ab <span class="op">=</span> <span class="st">"TZP"</span>,</span>
|
||||
<span> model <span class="op">=</span> <span class="st">"binomial"</span></span>
|
||||
<span> <span class="op">)</span></span>
|
||||
<span></span>
|
||||
<span><span class="co"># to bind it to object 'predict_TZP' for example:</span></span>
|
||||
<span><span class="va">predict_TZP</span> <span class="op"><-</span> <span class="va">example_isolates</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/resistance_predict.html">resistance_predict</a></span><span class="op">(</span></span>
|
||||
<span> col_ab <span class="op">=</span> <span class="st">"TZP"</span>,</span>
|
||||
<span> model <span class="op">=</span> <span class="st">"binomial"</span></span>
|
||||
<span> <span class="op">)</span></span></code></pre></div>
|
||||
<p>The function will look for a date column itself if
|
||||
<code>col_date</code> is not set.</p>
|
||||
<p>When running any of these commands, a summary of the regression model
|
||||
will be printed unless using
|
||||
<code>resistance_predict(..., info = FALSE)</code>.</p>
|
||||
<p>This text is only a printed summary - the actual result (output) of
|
||||
the function is a <code>data.frame</code> containing for each year: the
|
||||
number of observations, the actual observed resistance, the estimated
|
||||
resistance and the standard error below and above the estimation:</p>
|
||||
<div class="sourceCode" id="cb3"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">predict_TZP</span></span>
|
||||
<span><span class="co"># <span style="color: #949494;"># A tibble: 32 × 7</span></span></span>
|
||||
<span><span class="co"># year value se_min se_max observations observed estimated</span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;">*</span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><int></span> <span style="color: #949494; font-style: italic;"><dbl></span> <span style="color: #949494; font-style: italic;"><dbl></span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 1</span> <span style="text-decoration: underline;">2</span>002 0.2 <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 15 0.2 0.056<span style="text-decoration: underline;">2</span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 2</span> <span style="text-decoration: underline;">2</span>003 0.062<span style="text-decoration: underline;">5</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 32 0.062<span style="text-decoration: underline;">5</span> 0.061<span style="text-decoration: underline;">6</span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 3</span> <span style="text-decoration: underline;">2</span>004 0.085<span style="text-decoration: underline;">4</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 82 0.085<span style="text-decoration: underline;">4</span> 0.067<span style="text-decoration: underline;">6</span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 4</span> <span style="text-decoration: underline;">2</span>005 0.05 <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 60 0.05 0.074<span style="text-decoration: underline;">1</span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 5</span> <span style="text-decoration: underline;">2</span>006 0.050<span style="text-decoration: underline;">8</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 59 0.050<span style="text-decoration: underline;">8</span> 0.081<span style="text-decoration: underline;">2</span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 6</span> <span style="text-decoration: underline;">2</span>007 0.121 <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 66 0.121 0.088<span style="text-decoration: underline;">9</span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 7</span> <span style="text-decoration: underline;">2</span>008 0.041<span style="text-decoration: underline;">7</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 72 0.041<span style="text-decoration: underline;">7</span> 0.097<span style="text-decoration: underline;">2</span></span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 8</span> <span style="text-decoration: underline;">2</span>009 0.016<span style="text-decoration: underline;">4</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 61 0.016<span style="text-decoration: underline;">4</span> 0.106 </span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;"> 9</span> <span style="text-decoration: underline;">2</span>010 0.056<span style="text-decoration: underline;">6</span> <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 53 0.056<span style="text-decoration: underline;">6</span> 0.116 </span></span>
|
||||
<span><span class="co"># <span style="color: #BCBCBC;">10</span> <span style="text-decoration: underline;">2</span>011 0.183 <span style="color: #BB0000;">NA</span> <span style="color: #BB0000;">NA</span> 93 0.183 0.127 </span></span>
|
||||
<span><span class="co"># <span style="color: #949494;"># … with 22 more rows</span></span></span></code></pre></div>
|
||||
<p>The function <code>plot</code> is available in base R, and can be
|
||||
extended by other packages to depend the output based on the type of
|
||||
input. We extended its function to cope with resistance predictions:</p>
|
||||
<div class="sourceCode" id="cb4"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="fu"><a href="../reference/plot.html">plot</a></span><span class="op">(</span><span class="va">predict_TZP</span><span class="op">)</span></span></code></pre></div>
|
||||
<p><img src="resistance_predict_files/figure-html/unnamed-chunk-4-1.png" width="720"></p>
|
||||
<p>This is the fastest way to plot the result. It automatically adds the
|
||||
right axes, error bars, titles, number of available observations and
|
||||
type of model.</p>
|
||||
<p>We also support the <code>ggplot2</code> package with our custom
|
||||
function <code><a href="../reference/resistance_predict.html">ggplot_rsi_predict()</a></code> to create more appealing
|
||||
plots:</p>
|
||||
<div class="sourceCode" id="cb5"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="fu"><a href="../reference/resistance_predict.html">ggplot_rsi_predict</a></span><span class="op">(</span><span class="va">predict_TZP</span><span class="op">)</span></span></code></pre></div>
|
||||
<p><img src="resistance_predict_files/figure-html/unnamed-chunk-5-1.png" width="720"></p>
|
||||
<div class="sourceCode" id="cb6"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span></span>
|
||||
<span><span class="co"># choose for error bars instead of a ribbon</span></span>
|
||||
<span><span class="fu"><a href="../reference/resistance_predict.html">ggplot_rsi_predict</a></span><span class="op">(</span><span class="va">predict_TZP</span>, ribbon <span class="op">=</span> <span class="cn">FALSE</span><span class="op">)</span></span></code></pre></div>
|
||||
<p><img src="resistance_predict_files/figure-html/unnamed-chunk-5-2.png" width="720"></p>
|
||||
<div class="section level3">
|
||||
<h3 id="choosing-the-right-model">Choosing the right model<a class="anchor" aria-label="anchor" href="#choosing-the-right-model"></a>
|
||||
</h3>
|
||||
<p>Resistance is not easily predicted; if we look at vancomycin
|
||||
resistance in Gram-positive bacteria, the spread (i.e. standard error)
|
||||
is enormous:</p>
|
||||
<div class="sourceCode" id="cb7"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">example_isolates</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/filter.html" class="external-link">filter</a></span><span class="op">(</span><span class="fu"><a href="../reference/mo_property.html">mo_gramstain</a></span><span class="op">(</span><span class="va">mo</span>, language <span class="op">=</span> <span class="cn">NULL</span><span class="op">)</span> <span class="op">==</span> <span class="st">"Gram-positive"</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/resistance_predict.html">resistance_predict</a></span><span class="op">(</span>col_ab <span class="op">=</span> <span class="st">"VAN"</span>, year_min <span class="op">=</span> <span class="fl">2010</span>, info <span class="op">=</span> <span class="cn">FALSE</span>, model <span class="op">=</span> <span class="st">"binomial"</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/resistance_predict.html">ggplot_rsi_predict</a></span><span class="op">(</span><span class="op">)</span></span></code></pre></div>
|
||||
<p><img src="resistance_predict_files/figure-html/unnamed-chunk-6-1.png" width="720"></p>
|
||||
<p>Vancomycin resistance could be 100% in ten years, but might remain
|
||||
very low.</p>
|
||||
<p>You can define the model with the <code>model</code> parameter. The
|
||||
model chosen above is a generalised linear regression model using a
|
||||
binomial distribution, assuming that a period of zero resistance was
|
||||
followed by a period of increasing resistance leading slowly to more and
|
||||
more resistance.</p>
|
||||
<p>Valid values are:</p>
|
||||
<table class="table">
|
||||
<colgroup>
|
||||
<col width="32%">
|
||||
<col width="25%">
|
||||
<col width="42%">
|
||||
</colgroup>
|
||||
<thead><tr class="header">
|
||||
<th>Input values</th>
|
||||
<th>Function used by R</th>
|
||||
<th>Type of model</th>
|
||||
</tr></thead>
|
||||
<tbody>
|
||||
<tr class="odd">
|
||||
<td>
|
||||
<code>"binomial"</code> or <code>"binom"</code> or
|
||||
<code>"logit"</code>
|
||||
</td>
|
||||
<td><code>glm(..., family = binomial)</code></td>
|
||||
<td>Generalised linear model with binomial distribution</td>
|
||||
</tr>
|
||||
<tr class="even">
|
||||
<td>
|
||||
<code>"loglin"</code> or <code>"poisson"</code>
|
||||
</td>
|
||||
<td><code>glm(..., family = poisson)</code></td>
|
||||
<td>Generalised linear model with poisson distribution</td>
|
||||
</tr>
|
||||
<tr class="odd">
|
||||
<td>
|
||||
<code>"lin"</code> or <code>"linear"</code>
|
||||
</td>
|
||||
<td><code><a href="https://rdrr.io/r/stats/lm.html" class="external-link">lm()</a></code></td>
|
||||
<td>Linear model</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>For the vancomycin resistance in Gram-positive bacteria, a linear
|
||||
model might be more appropriate:</p>
|
||||
<div class="sourceCode" id="cb8"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">example_isolates</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="https://dplyr.tidyverse.org/reference/filter.html" class="external-link">filter</a></span><span class="op">(</span><span class="fu"><a href="../reference/mo_property.html">mo_gramstain</a></span><span class="op">(</span><span class="va">mo</span>, language <span class="op">=</span> <span class="cn">NULL</span><span class="op">)</span> <span class="op">==</span> <span class="st">"Gram-positive"</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/resistance_predict.html">resistance_predict</a></span><span class="op">(</span>col_ab <span class="op">=</span> <span class="st">"VAN"</span>, year_min <span class="op">=</span> <span class="fl">2010</span>, info <span class="op">=</span> <span class="cn">FALSE</span>, model <span class="op">=</span> <span class="st">"linear"</span><span class="op">)</span> <span class="op"><a href="https://magrittr.tidyverse.org/reference/pipe.html" class="external-link">%>%</a></span></span>
|
||||
<span> <span class="fu"><a href="../reference/resistance_predict.html">ggplot_rsi_predict</a></span><span class="op">(</span><span class="op">)</span></span></code></pre></div>
|
||||
<p><img src="resistance_predict_files/figure-html/unnamed-chunk-7-1.png" width="720"></p>
|
||||
<p>The model itself is also available from the object, as an
|
||||
<code>attribute</code>:</p>
|
||||
<div class="sourceCode" id="cb9"><pre class="downlit sourceCode r">
|
||||
<code class="sourceCode R"><span><span class="va">model</span> <span class="op"><-</span> <span class="fu"><a href="https://rdrr.io/r/base/attributes.html" class="external-link">attributes</a></span><span class="op">(</span><span class="va">predict_TZP</span><span class="op">)</span><span class="op">$</span><span class="va">model</span></span>
|
||||
<span></span>
|
||||
<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">model</span><span class="op">)</span><span class="op">$</span><span class="va">family</span></span>
|
||||
<span><span class="co"># </span></span>
|
||||
<span><span class="co"># Family: binomial </span></span>
|
||||
<span><span class="co"># Link function: logit</span></span>
|
||||
<span></span>
|
||||
<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">model</span><span class="op">)</span><span class="op">$</span><span class="va">coefficients</span></span>
|
||||
<span><span class="co"># Estimate Std. Error z value Pr(>|z|)</span></span>
|
||||
<span><span class="co"># (Intercept) -200.67944891 46.17315349 -4.346237 1.384932e-05</span></span>
|
||||
<span><span class="co"># year 0.09883005 0.02295317 4.305725 1.664395e-05</span></span></code></pre></div>
|
||||
</div>
|
||||
</div>
|
||||
</main><aside class="col-md-3"><nav id="toc"><h2>On this page</h2>
|
||||
</nav></aside>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 68 KiB |
@@ -0,0 +1,291 @@
|
||||
<!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">
|
||||
<meta name="description" content="AMR">
|
||||
<title>Welcome to the `AMR` package • AMR (for R)</title>
|
||||
<!-- favicons --><link rel="icon" type="image/png" sizes="16x16" href="../favicon-16x16.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="../favicon-32x32.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="180x180" href="../apple-touch-icon.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="120x120" href="../apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="76x76" href="../apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" type="image/png" sizes="60x60" href="../apple-touch-icon-60x60.png">
|
||||
<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.2.2/bootstrap.min.css" rel="stylesheet">
|
||||
<script src="../deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="../deps/Fira_Code-0.4.4/font.css" rel="stylesheet">
|
||||
<!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous">
|
||||
<!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></script><!-- pkgdown --><script src="../pkgdown.js"></script><link href="../extra.css" rel="stylesheet">
|
||||
<script src="../extra.js"></script><meta property="og:title" content="Welcome to the `AMR` package">
|
||||
<meta property="og:description" content="AMR">
|
||||
<meta property="og:image" content="https://msberends.github.io/AMR/logo.svg">
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:creator" content="@msberends">
|
||||
<meta name="twitter:site" content="@msberends">
|
||||
<!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="../index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="../articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="../articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="../reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="../news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="../search.json" id="search-input" placeholder="Search for" autocomplete="off">
|
||||
</form>
|
||||
|
||||
<ul class="navbar-nav">
|
||||
<li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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>Welcome to the `AMR` package</h1>
|
||||
|
||||
|
||||
<small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/vignettes/welcome_to_AMR.Rmd" class="external-link"><code>vignettes/welcome_to_AMR.Rmd</code></a></small>
|
||||
<div class="d-none name"><code>welcome_to_AMR.Rmd</code></div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<p>Note: to keep the package size as small as possible, we only included
|
||||
this vignette on CRAN. You can read more vignettes on our website about
|
||||
how to conduct AMR data analysis, determine MDROs, find explanation of
|
||||
EUCAST rules, and much more: <a href="https://msberends.github.io/AMR/articles/" class="uri">https://msberends.github.io/AMR/articles/</a>.</p>
|
||||
<hr>
|
||||
<p>The <code>AMR</code> package is a <a href="https://msberends.github.io/AMR/#copyright">free and
|
||||
open-source</a> R package with <a href="https://en.wikipedia.org/wiki/Dependency_hell" class="external-link">zero
|
||||
dependencies</a> to simplify the analysis and prediction of
|
||||
Antimicrobial Resistance (AMR) and to work with microbial and
|
||||
antimicrobial data and properties, by using evidence-based methods.
|
||||
<strong>Our aim is to provide a standard</strong> for clean and
|
||||
reproducible AMR data analysis, that can therefore empower
|
||||
epidemiological analyses to continuously enable surveillance and
|
||||
treatment evaluation in any setting.</p>
|
||||
<p>This work was published in the Journal of Statistical Software
|
||||
(Volume 104(3); <a href="https://doi.org/10.18637/jss.v104.i03" class="external-link">DOI
|
||||
10.18637/jss.v104.i03</a>) and formed the basis of two PhD theses (<a href="https://doi.org/10.33612/diss.177417131" class="external-link">DOI
|
||||
10.33612/diss.177417131</a> and <a href="https://doi.org/10.33612/diss.192486375" class="external-link">DOI
|
||||
10.33612/diss.192486375</a>).</p>
|
||||
<p>After installing this package, R knows ~52,000 distinct microbial
|
||||
species and all ~600 antibiotic, antimycotic and antiviral drugs by name
|
||||
and code (including ATC, EARS-Net, ASIARS-Net, PubChem, LOINC and SNOMED
|
||||
CT), and knows all about valid R/SI and MIC values. The integral
|
||||
breakpoint guidelines from CLSI and EUCAST are included from the last 10
|
||||
years. It supports and can read any data format, including WHONET
|
||||
data.</p>
|
||||
<p>The <code>AMR</code> package is available in English, Chinese,
|
||||
Danish, Dutch, French, German, Greek, Italian, Japanese, Polish,
|
||||
Portuguese, Russian, Spanish, Swedish, Turkish and Ukrainian.
|
||||
Antimicrobial drug (group) names and colloquial microorganism names are
|
||||
provided in these languages.</p>
|
||||
<p>This package is fully independent of any other R package and works on
|
||||
Windows, macOS and Linux with all versions of R since R-3.0 (April
|
||||
2013). <strong>It was designed to work in any setting, including those
|
||||
with very limited resources</strong>. Since its first public release in
|
||||
early 2018, this package has been downloaded from more than 175
|
||||
countries.</p>
|
||||
<p>This package can be used for:</p>
|
||||
<ul>
|
||||
<li>Reference for the taxonomy of microorganisms, since the package
|
||||
contains all microbial (sub)species from the List of Prokaryotic names
|
||||
with Standing in Nomenclature (LPSN) and the Global Biodiversity
|
||||
Information Facility (GBIF)</li>
|
||||
<li>Interpreting raw MIC and disk diffusion values, based on the latest
|
||||
CLSI or EUCAST guidelines</li>
|
||||
<li>Retrieving antimicrobial drug names, doses and forms of
|
||||
administration from clinical health care records</li>
|
||||
<li>Determining first isolates to be used for AMR data analysis</li>
|
||||
<li>Calculating antimicrobial resistance</li>
|
||||
<li>Determining multi-drug resistance (MDR) / multi-drug resistant
|
||||
organisms (MDRO)</li>
|
||||
<li>Calculating (empirical) susceptibility of both mono therapy and
|
||||
combination therapies</li>
|
||||
<li>Predicting future antimicrobial resistance using regression
|
||||
models</li>
|
||||
<li>Getting properties for any microorganism (like Gram stain, species,
|
||||
genus or family)</li>
|
||||
<li>Getting properties for any antibiotic (like name, code of
|
||||
EARS-Net/ATC/LOINC/PubChem, defined daily dose or trade name)</li>
|
||||
<li>Plotting antimicrobial resistance</li>
|
||||
<li>Applying EUCAST expert rules</li>
|
||||
<li>Getting SNOMED codes of a microorganism, or getting properties of a
|
||||
microorganism based on a SNOMED code</li>
|
||||
<li>Getting LOINC codes of an antibiotic, or getting properties of an
|
||||
antibiotic based on a LOINC code</li>
|
||||
<li>Machine reading the EUCAST and CLSI guidelines from 2011-2020 to
|
||||
translate MIC values and disk diffusion diameters to R/SI</li>
|
||||
<li>Principal component analysis for AMR</li>
|
||||
</ul>
|
||||
<p>All reference data sets (about microorganisms, antibiotics, R/SI
|
||||
interpretation, EUCAST rules, etc.) in this <code>AMR</code> package are
|
||||
publicly and freely available. We continually export our data sets to
|
||||
formats for use in R, SPSS, SAS, Stata and Excel. We also supply flat
|
||||
files that are machine-readable and suitable for input in any software
|
||||
program, such as laboratory information systems. Please find <a href="https://msberends.github.io/AMR/articles/datasets.html">all
|
||||
download links on our website</a>, which is automatically updated with
|
||||
every code change.</p>
|
||||
<p>This R package was created for both routine data analysis and
|
||||
academic research at the Faculty of Medical Sciences of the <a href="https://www.rug.nl" class="external-link">University of Groningen</a>, in collaboration
|
||||
with non-profit organisations <a href="https://www.certe.nl" class="external-link">Certe
|
||||
Medical Diagnostics and Advice Foundation</a> and <a href="https://www.umcg.nl" class="external-link">University Medical Center Groningen</a>, and
|
||||
is being <a href="./news">actively and durably maintained</a> by two
|
||||
public healthcare organisations in the Netherlands.</p>
|
||||
<hr>
|
||||
<p><small> This AMR package for R is free, open-source software and
|
||||
licensed under the <a href="https://msberends.github.io/AMR/LICENSE-text.html">GNU General
|
||||
Public License v2.0 (GPL-2)</a>. These requirements are consequently
|
||||
legally binding: modifications must be released under the same license
|
||||
when distributing the package, changes made to the code must be
|
||||
documented, source code must be made available when the package is
|
||||
distributed, and a copy of the license and copyright notice must be
|
||||
included with the package. </small></p>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p>
|
||||
<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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p>
|
||||
<p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,257 @@
|
||||
<!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="16x16" href="favicon-16x16.png"><link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png"><link rel="apple-touch-icon" type="image/png" sizes="180x180" href="apple-touch-icon.png"><link rel="apple-touch-icon" type="image/png" sizes="120x120" href="apple-touch-icon-120x120.png"><link rel="apple-touch-icon" type="image/png" sizes="76x76" href="apple-touch-icon-76x76.png"><link rel="apple-touch-icon" type="image/png" sizes="60x60" href="apple-touch-icon-60x60.png"><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.2.2/bootstrap.min.css" rel="stylesheet"><script src="deps/bootstrap-5.2.2/bootstrap.bundle.min.js"></script><link href="deps/Fira_Code-0.4.4/font.css" rel="stylesheet"><!-- Font Awesome icons --><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/all.min.css" integrity="sha256-mmgLkCYLUQbXn0B1SRqzHar6dCnv9oZFPEC1g1cwlkk=" crossorigin="anonymous"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.12.1/css/v4-shims.min.css" integrity="sha256-wZjR52fzng1pJHwx4aV2AO3yyTOXrcDW7jBpJtTwVxw=" crossorigin="anonymous"><!-- bootstrap-toc --><script src="https://cdn.jsdelivr.net/gh/afeld/bootstrap-toc@v1.0.1/dist/bootstrap-toc.min.js" integrity="sha256-4veVQbu7//Lk5TSmc7YV48MxtMy98e26cf5MrgZYnwo=" crossorigin="anonymous"></script><!-- headroom.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/headroom.min.js" integrity="sha256-AsUX4SJE1+yuDu5+mAVzJbuYNPHj/WroHuZ8Ir/CkE0=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/headroom/0.11.0/jQuery.headroom.min.js" integrity="sha256-ZX/yNShbjqsohH1k95liqY9Gd8uOiE1S4vZc+9KQ1K4=" crossorigin="anonymous"></script><!-- clipboard.js --><script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js" integrity="sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=" crossorigin="anonymous"></script><!-- search --><script src="https://cdnjs.cloudflare.com/ajax/libs/fuse.js/6.4.6/fuse.js" integrity="sha512-zv6Ywkjyktsohkbp9bb45V6tEMoWhzFzXis+LrMehmJZZSys19Yxf1dopHx7WzIKxr5tK2dVcYmaCk2uqdjF4A==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/autocomplete.js/0.38.0/autocomplete.jquery.min.js" integrity="sha512-GU9ayf+66Xx2TmpxqJpliWbT5PiGYxpaG8rfnBEk1LL8l1KGkRShhngwdXK1UgqhAzWpZHSiYPc09/NwDQIGyg==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mark.js/8.11.1/mark.min.js" integrity="sha512-5CYOlHXGh6QpOFA/TeTylKLWfB3ftPsde7AnmhuitiTX4K5SqCLBeKro6sPS8ilsz1Q4NRx3v8Ko2IBiszzdww==" crossorigin="anonymous"></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://msberends.github.io/AMR/logo.svg"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@msberends"><meta name="twitter:site" content="@msberends"><!-- mathjax --><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js" integrity="sha256-nvJJv9wWKEm88qvoQl9ekL2J+k/RWIsaSScxxlsrv8k=" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/config/TeX-AMS-MML_HTMLorMML.js" integrity="sha256-84DKXVJXs0/F8OTMzX4UR909+jtl4G7SPypPavF+GfA=" crossorigin="anonymous"></script><!--[if lt IE 9]>
|
||||
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
|
||||
<![endif]--></head><body>
|
||||
<a href="#main" class="visually-hidden-focusable">Skip to contents</a>
|
||||
|
||||
|
||||
<nav class="navbar fixed-top navbar-dark navbar-expand-lg bg-primary"><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="">1.8.2.9085</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">
|
||||
<a class="nav-link" href="index.html">
|
||||
<span class="fa fa-home"></span>
|
||||
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item dropdown">
|
||||
<a href="#" class="nav-link dropdown-toggle" data-bs-toggle="dropdown" role="button" aria-expanded="false" aria-haspopup="true" id="dropdown--how-to">
|
||||
<span class="fa fa-question-circle"></span>
|
||||
|
||||
How to
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="dropdown--how-to">
|
||||
<a class="dropdown-item" href="articles/AMR.html">
|
||||
<span class="fa fa-directions"></span>
|
||||
|
||||
Conduct AMR analysis
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/resistance_predict.html">
|
||||
<span class="fa fa-dice"></span>
|
||||
|
||||
Predict antimicrobial resistance
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/datasets.html">
|
||||
<span class="fa fa-database"></span>
|
||||
|
||||
Data sets for download / own use
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/PCA.html">
|
||||
<span class="fa fa-compress"></span>
|
||||
|
||||
Conduct principal component analysis for AMR
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/MDR.html">
|
||||
<span class="fa fa-skull-crossbones"></span>
|
||||
|
||||
Determine multi-drug resistance (MDR)
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/WHONET.html">
|
||||
<span class="fa fa-globe-americas"></span>
|
||||
|
||||
Work with WHONET data
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/SPSS.html">
|
||||
<span class="fa fa-file-upload"></span>
|
||||
|
||||
Import data from SPSS/SAS/Stata
|
||||
</a>
|
||||
<a class="dropdown-item" href="articles/EUCAST.html">
|
||||
<span class="fa fa-exchange-alt"></span>
|
||||
|
||||
Apply EUCAST rules
|
||||
</a>
|
||||
<a class="dropdown-item" href="reference/mo_property.html">
|
||||
<span class="fa fa-bug"></span>
|
||||
|
||||
Get taxonomy of a microorganism
|
||||
</a>
|
||||
<a class="dropdown-item" href="reference/ab_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antibiotic drug
|
||||
</a>
|
||||
<a class="dropdown-item" href="reference/av_property.html">
|
||||
<span class="fa fa-capsules"></span>
|
||||
|
||||
Get properties of an antiviral drug
|
||||
</a>
|
||||
</div>
|
||||
</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>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="news/index.html">
|
||||
<span class="far fa far fa-newspaper"></span>
|
||||
|
||||
Changelog
|
||||
</a>
|
||||
</li>
|
||||
</ul><form class="form-inline my-2 my-lg-0" role="search">
|
||||
<input type="search" class="form-control me-sm-2" aria-label="Toggle navigation" name="search-input" data-search-index="search.json" id="search-input" placeholder="Search for" autocomplete="off"></form>
|
||||
|
||||
<ul class="navbar-nav"><li class="nav-item">
|
||||
<a class="external-link nav-link" href="https://github.com/msberends/AMR">
|
||||
<span class="fab fa fab 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 citation">
|
||||
<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>Christian F. Luz</strong>. Author, 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>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>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>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>Judith M. Fonville</strong>. Contributor.
|
||||
</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>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>
|
||||
<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>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>Bart C. Meijer</strong>. Contributor.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Dmytro Mykhailenko</strong>. Contributor.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Anton Mymrikov</strong>. Contributor.
|
||||
</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>Jonas Salm</strong>. Contributor.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Rogier P. Schade</strong>. Contributor.
|
||||
</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>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>
|
||||
</ul></div>
|
||||
|
||||
<div class="section level2 citation">
|
||||
<h2 id="citation">Citation</h2>
|
||||
<p><small class="dont-index">Source: <a href="https://github.com/msberends/AMR/blob/HEAD/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), 1–31.
|
||||
<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"><h2>On this page</h2>
|
||||
</nav></aside></div>
|
||||
|
||||
|
||||
<footer><div class="pkgdown-footer-left">
|
||||
<p></p><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 General Public License version 2.0 (GPL-2)</a>.<br>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.</p>
|
||||
</div>
|
||||
|
||||
<div class="pkgdown-footer-right">
|
||||
<p></p><p><a target="_blank" href="https://www.rug.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_rug.svg" style="max-width: 150px;"></a><a target="_blank" href="https://www.umcg.nl" class="external-link"><img src="https://github.com/msberends/AMR/raw/main/pkgdown/logos/logo_umcg.svg" style="max-width: 150px;"></a></p>
|
||||
</div>
|
||||
|
||||
</footer></div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
|
||||