(v1.4.0.9012) reference_df fix

This commit is contained in:
dr. M.S. (Matthijs) Berends 2020-11-05 01:11:49 +01:00
parent 5a607abb36
commit 423879c034
19 changed files with 98 additions and 66 deletions

View File

@ -1,6 +1,6 @@
Package: AMR
Version: 1.4.0.9011
Date: 2020-10-27
Version: 1.4.0.9012
Date: 2020-11-05
Title: Antimicrobial Resistance Analysis
Authors@R: c(
person(role = c("aut", "cre"),

View File

@ -1,5 +1,5 @@
# AMR 1.4.0.9011
## <small>Last updated: 27 October 2020</small>
# AMR 1.4.0.9012
## <small>Last updated: 5 November 2020</small>
### New
* Functions `is_gram_negative()` and `is_gram_positive()` as wrappers around `mo_gramstain()`. They always return `TRUE` or `FALSE`, thus always return `FALSE` for species outside the taxonomic kingdom of Bacteria.
@ -9,7 +9,7 @@
* For all function parameters in the code, it is now defined what the exact type of user input should be (inspired by the [`typed`](https://github.com/moodymudskipper/typed) package). If the user input for a certain function does not meet the requirements for a specific parameter (such as the class or length), an informative error will be thrown. This makes the package more robust and the use of it more reproducible and reliable. In total, more than 400 arguments were defined.
* Deprecated function `p_symbol()` that not really fits the scope of this package. It will be removed in a future version. See [here](https://github.com/msberends/AMR/blob/v1.4.0/R/p_symbol.R) for the source code to preserve it.
* Better determination of disk zones and MIC values when running `as.rsi()` on a data.frame
* Updated coagulase-negative staphylococci with Becker *et al.* 2020 (PMID 32056452), meaning that the species *S. argensis*, *S. caeli*, *S. debuckii*, *S. edaphicus* and *S. pseudoxylosus* are now all considered CoNS
* Updated coagulase-negative staphylococci determination with Becker *et al.* 2020 (PMID 32056452), meaning that the species *S. argensis*, *S. caeli*, *S. debuckii*, *S. edaphicus* and *S. pseudoxylosus* are now all considered CoNS
* Fix for using parameter `reference_df` in `as.mo()` and `mo_*()` functions that contain old microbial codes (from previous package versions)
### Other

View File

@ -87,7 +87,7 @@ addin_insert_like <- function() {
current_row_txt <- context$contents[current_row]
pos_preceded_by <- function(txt) {
substr(current_row_txt, current_col - nchar(txt), current_col) == txt
substr(current_row_txt, current_col - nchar(txt), current_col) %like% paste0("^", txt)
}
replace_pos <- function(old, with) {
modifyRange(document_range(document_position(current_row, current_col - nchar(old)),

View File

@ -67,6 +67,11 @@
#' if (require("dplyr")) {
#' example_isolates %>%
#' filter(mo_name(mo) %like% "^ent")
#'
#' example_isolates %>%
#' mutate(group = case_when(hospital_id %like% "A|D" ~ "Group 1",
#' mo_name(mo) %not_like% "^Staph" ~ "Group 2a",
#' TRUE ~ "Group 2b"))
#' }
#' }
like <- function(x, pattern, ignore.case = TRUE) {
@ -168,7 +173,6 @@ like <- function(x, pattern, ignore.case = TRUE) {
like(x, pattern, ignore.case = FALSE)
}
#' @rdname like
#' @export
"%not_like_case%" <- function(x, pattern) {

71
R/mo.R
View File

@ -199,31 +199,16 @@ as.mo <- function(x,
uncertainty_level <- translate_allow_uncertain(allow_uncertain)
if (mo_source_isvalid(reference_df)
& isFALSE(Becker)
& isFALSE(Lancefield)
& !is.null(reference_df)
& all(x %in% reference_df[, 1][[1]])) {
&& isFALSE(Becker)
&& isFALSE(Lancefield)
&& !is.null(reference_df)
&& all(x %in% unlist(reference_df), na.rm = TRUE)) {
# has valid own reference_df
reference_df <- reference_df %pm>% pm_filter(!is.na(mo))
# keep only first two columns, second must be mo
if (colnames(reference_df)[1] == "mo") {
reference_df <- reference_df[, c(2, 1)]
} else {
reference_df <- reference_df[, c(1, 2)]
}
# some microbial codes might be old
reference_df[, 1] <- as.mo(reference_df[, 1, drop = TRUE])
colnames(reference_df)[1] <- "x"
# remove factors, just keep characters
suppressWarnings(
reference_df[] <- lapply(reference_df, as.character)
)
reference_df <- repair_reference_df(reference_df)
suppressWarnings(
y <- data.frame(x = x, stringsAsFactors = FALSE) %pm>%
pm_left_join(reference_df, by = "x") %pm>%
pm_pull("mo")
pm_pull(mo)
)
} else if (all(x[!is.na(x)] %in% MO_lookup$mo)
@ -406,22 +391,7 @@ exec_as.mo <- function(x,
# defined df to check for
if (!is.null(reference_df)) {
mo_source_isvalid(reference_df)
reference_df <- reference_df %pm>% pm_filter(!is.na(mo))
# keep only first two columns, second must be named "mo"
if (colnames(reference_df)[1] == "mo") {
reference_df <- reference_df[, c(2, 1)]
} else {
reference_df <- reference_df[, c(1, 2)]
}
# some microbial codes might be old
reference_df[, 1] <- as.mo(reference_df[, 1, drop = TRUE])
colnames(reference_df)[1] <- "x"
# remove factors, just keep characters
suppressWarnings(
reference_df[] <- lapply(reference_df, as.character)
)
reference_df <- repair_reference_df(reference_df)
}
# all empty
@ -1936,7 +1906,11 @@ replace_old_mo_codes <- function(x, property) {
if (property != "mo") {
message_(font_blue("NOTE: The input contained old microbial codes (from previous package versions). Please update your MO codes with as.mo()."))
} else {
message_(font_blue("NOTE:", length(matched), "old microbial codes (from previous package versions) were updated to current used codes."))
if (length(matched) == 1) {
message_(font_blue("NOTE: 1 old microbial code (from previous package versions) was updated to a current used code."))
} else {
message_(font_blue("NOTE:", length(matched), "old microbial codes (from previous package versions) were updated to current used codes."))
}
}
}
x
@ -1955,6 +1929,27 @@ replace_ignore_pattern <- function(x, ignore_pattern) {
x
}
repair_reference_df <- function(reference_df) {
# has valid own reference_df
reference_df <- reference_df %pm>%
pm_filter(!is.na(mo))
# keep only first two columns, second must be mo
if (colnames(reference_df)[1] == "mo") {
reference_df <- reference_df %pm>% pm_select(2, "mo")
} else {
reference_df <- reference_df %pm>% pm_select(1, "mo")
}
# some microbial codes might be old
reference_df[, 2] <- as.mo(reference_df[, 2, drop = TRUE])
# remove factors, just keep characters
suppressWarnings(
reference_df[] <- lapply(reference_df, as.character)
)
colnames(reference_df)[1] <- "x"
reference_df
}
left_join_MO_lookup <- function(x, ...) {
pm_left_join(x = x, y = MO_lookup, ...)
}

View File

@ -25,7 +25,9 @@
#' Calculate the matching score for microorganisms
#'
#' This helper function is used by [as.mo()] to determine the most probable match of taxonomic records, based on user input.
#' This algorithm is used by [as.mo()] and all the [`mo_*`][mo_property()] functions to determine the most probable match of taxonomic records based on user input.
#' @inheritSection lifecycle Stable lifecycle
#' @author Matthijs S. Berends
#' @param x Any user input value(s)
#' @param n A full taxonomic name, that exists in [`microorganisms$fullname`][microorganisms]
#' @section Matching score for microorganisms:

View File

@ -81,7 +81,7 @@
</button>
<span class="navbar-brand">
<a class="navbar-link" href="https://msberends.github.io/AMR//index.html">AMR (for R)</a>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</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.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</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.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</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.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>

View File

@ -43,7 +43,7 @@
</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.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>

View File

@ -81,7 +81,7 @@
</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.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>
@ -236,13 +236,13 @@
<small>Source: <a href='https://github.com/msberends/AMR/blob/master/NEWS.md'><code>NEWS.md</code></a></small>
</div>
<div id="amr-1409011" class="section level1">
<h1 class="page-header" data-toc-text="1.4.0.9011">
<a href="#amr-1409011" class="anchor"></a>AMR 1.4.0.9011<small> Unreleased </small>
<div id="amr-1409012" class="section level1">
<h1 class="page-header" data-toc-text="1.4.0.9012">
<a href="#amr-1409012" class="anchor"></a>AMR 1.4.0.9012<small> Unreleased </small>
</h1>
<div id="last-updated-27-october-2020" class="section level2">
<div id="last-updated-5-november-2020" class="section level2">
<h2 class="hasAnchor">
<a href="#last-updated-27-october-2020" class="anchor"></a><small>Last updated: 27 October 2020</small>
<a href="#last-updated-5-november-2020" class="anchor"></a><small>Last updated: 5 November 2020</small>
</h2>
<div id="new" class="section level3">
<h3 class="hasAnchor">
@ -259,7 +259,7 @@
<li>For all function parameters in the code, it is now defined what the exact type of user input should be (inspired by the <a href="https://github.com/moodymudskipper/typed"><code>typed</code></a> package). If the user input for a certain function does not meet the requirements for a specific parameter (such as the class or length), an informative error will be thrown. This makes the package more robust and the use of it more reproducible and reliable. In total, more than 400 arguments were defined.</li>
<li>Deprecated function <code><a href="../reference/AMR-deprecated.html">p_symbol()</a></code> that not really fits the scope of this package. It will be removed in a future version. See <a href="https://github.com/msberends/AMR/blob/v1.4.0/R/p_symbol.R">here</a> for the source code to preserve it.</li>
<li>Better determination of disk zones and MIC values when running <code><a href="../reference/as.rsi.html">as.rsi()</a></code> on a data.frame</li>
<li>Updated coagulase-negative staphylococci with Becker <em>et al.</em> 2020 (PMID 32056452), meaning that the species <em>S. argensis</em>, <em>S. caeli</em>, <em>S. debuckii</em>, <em>S. edaphicus</em> and <em>S. pseudoxylosus</em> are now all considered CoNS</li>
<li>Updated coagulase-negative staphylococci determination with Becker <em>et al.</em> 2020 (PMID 32056452), meaning that the species <em>S. argensis</em>, <em>S. caeli</em>, <em>S. debuckii</em>, <em>S. edaphicus</em> and <em>S. pseudoxylosus</em> are now all considered CoNS</li>
<li>Fix for using parameter <code>reference_df</code> in <code><a href="../reference/as.mo.html">as.mo()</a></code> and <code>mo_*()</code> functions that contain old microbial codes (from previous package versions)</li>
</ul>
</div>

View File

@ -12,7 +12,7 @@ articles:
datasets: datasets.html
resistance_predict: resistance_predict.html
welcome_to_AMR: welcome_to_AMR.html
last_built: 2020-10-27T14:41Z
last_built: 2020-11-05T00:11Z
urls:
reference: https://msberends.github.io/AMR//reference
article: https://msberends.github.io/AMR//articles

View File

@ -81,7 +81,7 @@
</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.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>

View File

@ -82,7 +82,7 @@
</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.4.0.9008</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>
@ -322,6 +322,11 @@ The <a href='lifecycle.html'>lifecycle</a> of this function is <strong>stable</s
<span class='kw'>if</span> <span class='op'>(</span><span class='kw'><a href='https://rdrr.io/r/base/library.html'>require</a></span><span class='op'>(</span><span class='st'><a href='https://dplyr.tidyverse.org'>"dplyr"</a></span><span class='op'>)</span><span class='op'>)</span> <span class='op'>{</span>
<span class='va'>example_isolates</span> <span class='op'>%&gt;%</span>
<span class='fu'><a href='https://dplyr.tidyverse.org/reference/filter.html'>filter</a></span><span class='op'>(</span><span class='fu'><a href='mo_property.html'>mo_name</a></span><span class='op'>(</span><span class='va'>mo</span><span class='op'>)</span> <span class='op'>%like%</span> <span class='st'>"^ent"</span><span class='op'>)</span>
<span class='va'>example_isolates</span> <span class='op'>%&gt;%</span>
<span class='fu'><a href='https://dplyr.tidyverse.org/reference/mutate.html'>mutate</a></span><span class='op'>(</span>group <span class='op'>=</span> <span class='fu'><a href='https://dplyr.tidyverse.org/reference/case_when.html'>case_when</a></span><span class='op'>(</span><span class='va'>hospital_id</span> <span class='op'>%like%</span> <span class='st'>"A|D"</span> <span class='op'>~</span> <span class='st'>"Group 1"</span>,
<span class='fu'><a href='mo_property.html'>mo_name</a></span><span class='op'>(</span><span class='va'>mo</span><span class='op'>)</span> <span class='op'>%not_like%</span> <span class='st'>"^Staph"</span> <span class='op'>~</span> <span class='st'>"Group 2a"</span>,
<span class='cn'>TRUE</span> <span class='op'>~</span> <span class='st'>"Group 2b"</span><span class='op'>)</span><span class='op'>)</span>
<span class='op'>}</span>
<span class='co'># }</span>
</pre>

View File

@ -49,7 +49,7 @@
<script src="../extra.js"></script>
<meta property="og:title" content="Calculate the matching score for microorganisms — mo_matching_score" />
<meta property="og:description" content="This helper function is used by as.mo() to determine the most probable match of taxonomic records, based on user input." />
<meta property="og:description" content="This algorithm is used by as.mo() and all the mo_* functions to determine the most probable match of taxonomic records based on user input." />
<meta property="og:image" content="https://msberends.github.io/AMR/logo.png" />
@ -82,7 +82,7 @@
</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.4.0.9000</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>
@ -239,7 +239,7 @@
</div>
<div class="ref-description">
<p>This helper function is used by <code><a href='as.mo.html'>as.mo()</a></code> to determine the most probable match of taxonomic records, based on user input.</p>
<p>This algorithm is used by <code><a href='as.mo.html'>as.mo()</a></code> and all the <code><a href='mo_property.html'>mo_*</a></code> functions to determine the most probable match of taxonomic records based on user input.</p>
</div>
<pre class="usage"><span class='fu'>mo_matching_score</span><span class='op'>(</span><span class='va'>x</span>, <span class='va'>n</span><span class='op'>)</span></pre>
@ -274,6 +274,16 @@
<p>The grouping into human pathogenic prevalence (\(p\)) is based on experience from several microbiological laboratories in the Netherlands in conjunction with international reports on pathogen prevalence. <strong>Group 1</strong> (most prevalent microorganisms) consists of all microorganisms where the taxonomic class is Gammaproteobacteria or where the taxonomic genus is <em>Enterococcus</em>, <em>Staphylococcus</em> or <em>Streptococcus</em>. This group consequently contains all common Gram-negative bacteria, such as <em>Pseudomonas</em> and <em>Legionella</em> and all species within the order Enterobacterales. <strong>Group 2</strong> consists of all microorganisms where the taxonomic phylum is Proteobacteria, Firmicutes, Actinobacteria or Sarcomastigophora, or where the taxonomic genus is <em>Absidia</em>, <em>Acremonium</em>, <em>Actinotignum</em>, <em>Alternaria</em>, <em>Anaerosalibacter</em>, <em>Apophysomyces</em>, <em>Arachnia</em>, <em>Aspergillus</em>, <em>Aureobacterium</em>, <em>Aureobasidium</em>, <em>Bacteroides</em>, <em>Basidiobolus</em>, <em>Beauveria</em>, <em>Blastocystis</em>, <em>Branhamella</em>, <em>Calymmatobacterium</em>, <em>Candida</em>, <em>Capnocytophaga</em>, <em>Catabacter</em>, <em>Chaetomium</em>, <em>Chryseobacterium</em>, <em>Chryseomonas</em>, <em>Chrysonilia</em>, <em>Cladophialophora</em>, <em>Cladosporium</em>, <em>Conidiobolus</em>, <em>Cryptococcus</em>, <em>Curvularia</em>, <em>Exophiala</em>, <em>Exserohilum</em>, <em>Flavobacterium</em>, <em>Fonsecaea</em>, <em>Fusarium</em>, <em>Fusobacterium</em>, <em>Hendersonula</em>, <em>Hypomyces</em>, <em>Koserella</em>, <em>Lelliottia</em>, <em>Leptosphaeria</em>, <em>Leptotrichia</em>, <em>Malassezia</em>, <em>Malbranchea</em>, <em>Mortierella</em>, <em>Mucor</em>, <em>Mycocentrospora</em>, <em>Mycoplasma</em>, <em>Nectria</em>, <em>Ochroconis</em>, <em>Oidiodendron</em>, <em>Phoma</em>, <em>Piedraia</em>, <em>Pithomyces</em>, <em>Pityrosporum</em>, <em>Prevotella</em>,\<em>Pseudallescheria</em>, <em>Rhizomucor</em>, <em>Rhizopus</em>, <em>Rhodotorula</em>, <em>Scolecobasidium</em>, <em>Scopulariopsis</em>, <em>Scytalidium</em>,<em>Sporobolomyces</em>, <em>Stachybotrys</em>, <em>Stomatococcus</em>, <em>Treponema</em>, <em>Trichoderma</em>, <em>Trichophyton</em>, <em>Trichosporon</em>, <em>Tritirachium</em> or <em>Ureaplasma</em>. <strong>Group 3</strong> consists of all other microorganisms.</p>
<p>All matches are sorted descending on their matching score and for all user input values, the top match will be returned. This will lead to the effect that e.g., <code>"E. coli"</code> will return the microbial ID of <em>Escherichia coli</em> (\(m = 0.688\), a highly prevalent microorganism found in humans) and not <em>Entamoeba coli</em> (\(m = 0.079\), a less prevalent microorganism in humans), although the latter would alphabetically come first.</p>
<h2 class="hasAnchor" id="stable-lifecycle"><a class="anchor" href="#stable-lifecycle"></a>Stable lifecycle</h2>
<p><img src='figures/lifecycle_stable.svg' style=margin-bottom:5px /> <br />
The <a href='lifecycle.html'>lifecycle</a> of this function is <strong>stable</strong>. 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.</p>
<p>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.</p>
<h2 class="hasAnchor" id="author"><a class="anchor" href="#author"></a>Author</h2>
<p>Matthijs S. Berends</p>
<h2 class="hasAnchor" id="examples"><a class="anchor" href="#examples"></a>Examples</h2>
<pre class="examples"><span class='fu'><a href='as.mo.html'>as.mo</a></span><span class='op'>(</span><span class='st'>"E. coli"</span><span class='op'>)</span>

View File

@ -81,7 +81,7 @@
</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.4.0.9011</span>
<span class="version label label-default" data-toggle="tooltip" data-placement="bottom" title="Latest development version">1.4.0.9012</span>
</span>
</div>

View File

@ -80,6 +80,11 @@ a \%like\% b
if (require("dplyr")) {
example_isolates \%>\%
filter(mo_name(mo) \%like\% "^ent")
example_isolates \%>\%
mutate(group = case_when(hospital_id \%like\% "A|D" ~ "Group 1",
mo_name(mo) \%not_like\% "^Staph" ~ "Group 2a",
TRUE ~ "Group 2b"))
}
}
}

View File

@ -12,7 +12,7 @@ mo_matching_score(x, n)
\item{n}{A full taxonomic name, that exists in \code{\link[=microorganisms]{microorganisms$fullname}}}
}
\description{
This helper function is used by \code{\link[=as.mo]{as.mo()}} to determine the most probable match of taxonomic records, based on user input.
This algorithm is used by \code{\link[=as.mo]{as.mo()}} and all the \code{\link[=mo_property]{mo_*}} functions to determine the most probable match of taxonomic records based on user input.
}
\section{Matching score for microorganisms}{
@ -35,6 +35,14 @@ The grouping into human pathogenic prevalence (\eqn{p}) is based on experience f
All matches are sorted descending on their matching score and for all user input values, the top match will be returned. This will lead to the effect that e.g., \code{"E. coli"} will return the microbial ID of \emph{Escherichia coli} (\eqn{m = 0.688}, a highly prevalent microorganism found in humans) and not \emph{Entamoeba coli} (\eqn{m = 0.079}, a less prevalent microorganism in humans), although the latter would alphabetically come first.
}
\section{Stable lifecycle}{
\if{html}{\figure{lifecycle_stable.svg}{options: style=margin-bottom:5px} \cr}
The \link[=lifecycle]{lifecycle} of this function is \strong{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.
}
\examples{
as.mo("E. coli")
mo_uncertainties()
@ -42,3 +50,6 @@ mo_uncertainties()
mo_matching_score(x = "E. coli",
n = c("Escherichia coli", "Entamoeba coli"))
}
\author{
Matthijs S. Berends
}