[med-svn] [r-bioc-annotationfilter] 01/04: New upstream version 1.2.0

Andreas Tille tille at debian.org
Thu Nov 9 09:06:50 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository r-bioc-annotationfilter.

commit 05c889e0bf7c379aea2b761d1fac3a86dd7f2514
Author: Andreas Tille <tille at debian.org>
Date:   Thu Nov 9 10:02:35 2017 +0100

    New upstream version 1.2.0
---
 DESCRIPTION                                |  28 ++--
 NAMESPACE                                  |   5 +
 NEWS                                       |   8 ++
 R/AllGenerics.R                            |  12 ++
 R/AnnotationFilter.R                       | 175 ++++++++++++++++++------
 R/AnnotationFilterList.R                   | 213 +++++++++++++++++++++++++----
 R/translate-utils.R                        |  82 +++++++++--
 build/vignette.rds                         | Bin 272 -> 274 bytes
 inst/doc/AnnotationFilter.R                |   2 +-
 inst/doc/AnnotationFilter.Rmd              |   8 +-
 inst/doc/AnnotationFilter.html             | 139 ++++++++-----------
 man/AnnotationFilter.Rd                    |  90 +++++++-----
 man/AnnotationFilterList.Rd                |  75 +++++++++-
 tests/testthat/test_AnnotationFilter.R     |  55 +++++++-
 tests/testthat/test_AnnotationFilterList.R |  39 ++++--
 tests/testthat/test_translate-utils.R      |  18 +--
 vignettes/AnnotationFilter.Rmd             |   8 +-
 17 files changed, 716 insertions(+), 241 deletions(-)

diff --git a/DESCRIPTION b/DESCRIPTION
index e24bcf3..77eac7b 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,18 +1,22 @@
 Package: AnnotationFilter
 Title: Facilities for Filtering Bioconductor Annotation Resources
-Version: 1.0.0
-Authors at R: c( person("Martin", "Morgan", email =
-        "martin.morgan at roswellpark.org", role = "aut"),
-        person("Johannes", "Rainer", email =
-        "johannes.rainer at eurac.edu", role = "aut"),
-        person("Bioconductor", "Maintainer",
-        email="maintainer at bioconductor.org", role = "cre"))
+Version: 1.2.0
+Authors at R: c(
+    person("Martin", "Morgan", email = "martin.morgan at roswellpark.org",
+        role = "aut"),
+    person("Johannes", "Rainer", email = "johannes.rainer at eurac.edu",
+        role = "aut"),
+    person("Joachim", "Bargsten", email = "jw at bargsten.org", role = "ctb"),
+    person("Daniel", "Van Twisk", email = "daniel.vantwisk at roswellpark.org",
+        role = "ctb"),
+    person("Bioconductor", "Maintainer", email="maintainer at bioconductor.org",
+        role = "cre"))
 URL: https://github.com/Bioconductor/AnnotationFilter
 BugReports: https://github.com/Bioconductor/AnnotationFilter/issues
 Description: This package provides class and other infrastructure to
-        implement filters for manipulating Bioconductor annotation
-        resources. The filters will be used by ensembldb,
-        Organism.dplyr, and other packages.
+    implement filters for manipulating Bioconductor annotation
+    resources. The filters will be used by ensembldb, Organism.dplyr,
+    and other packages.
 Depends: R (>= 3.4.0)
 Imports: utils, methods, GenomicRanges, lazyeval
 Suggests: BiocStyle, knitr, testthat, RSQLite, org.Hs.eg.db
@@ -25,8 +29,10 @@ RoxygenNote: 6.0.1
 Collate: 'AllGenerics.R' 'AnnotationFilter.R' 'AnnotationFilterList.R'
         'translate-utils.R'
 NeedsCompilation: no
-Packaged: 2017-04-25 01:05:17 UTC; biocbuild
+Packaged: 2017-10-31 01:20:26 UTC; biocbuild
 Author: Martin Morgan [aut],
   Johannes Rainer [aut],
+  Joachim Bargsten [ctb],
+  Daniel Van Twisk [ctb],
   Bioconductor Maintainer [cre]
 Maintainer: Bioconductor Maintainer <maintainer at bioconductor.org>
diff --git a/NAMESPACE b/NAMESPACE
index c17b25f..12e2115 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -27,6 +27,8 @@ export(TxNameFilter)
 export(TxStartFilter)
 export(UniprotFilter)
 export(feature)
+export(logicOp)
+export(not)
 exportClasses(AnnotationFilter)
 exportClasses(AnnotationFilterList)
 exportClasses(CdsEndFilter)
@@ -56,7 +58,10 @@ exportClasses(TxNameFilter)
 exportClasses(TxStartFilter)
 exportClasses(UniprotFilter)
 exportMethods(condition)
+exportMethods(convertFilter)
+exportMethods(distributeNegation)
 exportMethods(field)
+exportMethods(not)
 exportMethods(show)
 exportMethods(supportedFilters)
 exportMethods(value)
diff --git a/NEWS b/NEWS
index 43d5934..a8ae1db 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,11 @@
+CHANGES IN VERSION 1.1.2
+------------------------
+
+NEW FEATURES
+
+    o supportFilters returns a data.frame with filter class name and field.
+
+
 CHANGES IN VERSION 0.99.5
 --------------------------
 
diff --git a/R/AllGenerics.R b/R/AllGenerics.R
index 71be13d..36838f2 100644
--- a/R/AllGenerics.R
+++ b/R/AllGenerics.R
@@ -5,5 +5,17 @@ setGeneric("field", function(object, ...) standardGeneric("field"))
 
 setGeneric("value", function(object, ...) standardGeneric("value"))
 
+setGeneric("logicOp", function(object, ...) standardGeneric("logicOp"))
+
+setGeneric("not", function(object, ...) standardGeneric("not"))
+
+setGeneric("simplify", function(object, ...) standardGeneric("simplify"))
+
+setGeneric("convertFilter", function(object, db, ...)
+    standardGeneric("convertFilter"))
+
+setGeneric("distributeNegation", function(object, ...)
+    standardGeneric("distributeNegation"))
+
 setGeneric("supportedFilters", function(object, ...)
     standardGeneric("supportedFilters"))
diff --git a/R/AnnotationFilter.R b/R/AnnotationFilter.R
index a5390ca..8053db3 100644
--- a/R/AnnotationFilter.R
+++ b/R/AnnotationFilter.R
@@ -31,11 +31,12 @@
 #' Filter instances created using the constructor functions (e.g.
 #' \code{GeneIdFilter}).
 #'
-#' \code{supportedFilters()} lists all defined filters. Packages using
-#' \code{AnnotationFilter} should implement the \code{supportedFilters} for
-#' their annotation resource object (e.g. for \code{object = "EnsDb"} in the
-#' \code{ensembldb} package) to list all supported filters for the specific
-#' resource.
+#' \code{supportedFilters()} lists all defined filters. It returns a two column
+#' \code{data.frame} with the filter class name and its default field.
+#' Packages using \code{AnnotationFilter} should implement the
+#' \code{supportedFilters} for their annotation resource object (e.g. for
+#' \code{object = "EnsDb"} in the \code{ensembldb} package) to list all
+#' supported filters for the specific resource.
 #'
 #' @details
 #'
@@ -48,29 +49,29 @@
 #'
 #' @usage
 #'
-#' CdsStartFilter(value, condition = "==")
-#' CdsEndFilter(value, condition = "==")
-#' ExonIdFilter(value, condition = "==")
-#' ExonNameFilter(value, condition = "==")
-#' ExonRankFilter(value, condition = "==")
-#' ExonStartFilter(value, condition = "==")
-#' ExonEndFilter(value, condition = "==")
-#' GeneIdFilter(value, condition = "==")
-#' GenenameFilter(value, condition = "==")
-#' GeneBiotypeFilter(value, condition = "==")
-#' GeneStartFilter(value, condition = "==")
-#' GeneEndFilter(value, condition = "==")
-#' EntrezFilter(value, condition = "==")
-#' SymbolFilter(value, condition = "==")
-#' TxIdFilter(value, condition = "==")
-#' TxNameFilter(value, condition = "==")
-#' TxBiotypeFilter(value, condition = "==")
-#' TxStartFilter(value, condition = "==")
-#' TxEndFilter(value, condition = "==")
-#' ProteinIdFilter(value, condition = "==")
-#' UniprotFilter(value, condition = "==")
-#' SeqNameFilter(value, condition = "==")
-#' SeqStrandFilter(value, condition = "==")
+#' CdsStartFilter(value, condition = "==", not = FALSE)
+#' CdsEndFilter(value, condition = "==", not = FALSE)
+#' ExonIdFilter(value, condition = "==", not = FALSE)
+#' ExonNameFilter(value, condition = "==", not = FALSE)
+#' ExonRankFilter(value, condition = "==", not = FALSE)
+#' ExonStartFilter(value, condition = "==", not = FALSE)
+#' ExonEndFilter(value, condition = "==", not = FALSE)
+#' GeneIdFilter(value, condition = "==", not = FALSE)
+#' GenenameFilter(value, condition = "==", not = FALSE)
+#' GeneBiotypeFilter(value, condition = "==", not = FALSE)
+#' GeneStartFilter(value, condition = "==", not = FALSE)
+#' GeneEndFilter(value, condition = "==", not = FALSE)
+#' EntrezFilter(value, condition = "==", not = FALSE)
+#' SymbolFilter(value, condition = "==", not = FALSE)
+#' TxIdFilter(value, condition = "==", not = FALSE)
+#' TxNameFilter(value, condition = "==", not = FALSE)
+#' TxBiotypeFilter(value, condition = "==", not = FALSE)
+#' TxStartFilter(value, condition = "==", not = FALSE)
+#' TxEndFilter(value, condition = "==", not = FALSE)
+#' ProteinIdFilter(value, condition = "==", not = FALSE)
+#' UniprotFilter(value, condition = "==", not = FALSE)
+#' SeqNameFilter(value, condition = "==", not = FALSE)
+#' SeqStrandFilter(value, condition = "==", not = FALSE)
 #'
 #' @param value \code{character()}, \code{integer()}, or
 #'     \code{GRanges()} value for the filter
@@ -79,8 +80,12 @@
 #'     used in the filter. For \code{IntegerFilter}, one of
 #'     \code{"=="}, \code{"!="}, \code{">"}, \code{"<"}, \code{">="}
 #'     or \code{"<="}. For \code{CharacterFilter}, one of \code{"=="},
-#'     \code{"!="}, \code{"startsWith"} or \code{"endsWith"}. Default
-#'     condition is \code{"=="}.
+#'     \code{"!="}, \code{"startsWith"}, \code{"endsWith"} or \code{"contains"}.
+#'     Default condition is \code{"=="}.
+#'
+#' @param not \code{logical(1)} whether the \code{AnnotationFilter} is negated.
+#'     \code{TRUE} indicates is negated (!). \code{FALSE} indicates not
+#'     negated. Default not is \code{FALSE}.
 #'
 #' @return The constructor function return an object extending
 #'     \code{AnnotationFilter}. For the return value of the other methods see
@@ -92,7 +97,7 @@ NULL
 
 .CONDITION <- list(
     IntegerFilter = c("==", "!=", ">", "<", ">=", "<="),
-    CharacterFilter =  c("==", "!=", "startsWith", "endsWith"),
+    CharacterFilter =  c("==", "!=", "startsWith", "endsWith", "contains"),
     GRangesFilter = c("any", "start", "end", "within", "equal")
 )
 
@@ -133,10 +138,12 @@ NULL
     slots = c(
         field="character",
         condition="character",
-        value="ANY"
+        value="ANY",
+        not="logical"
     ),
     prototype=list(
-        condition= "=="
+        condition= "==",
+        not= FALSE
     )
 )
 
@@ -145,6 +152,7 @@ setValidity("AnnotationFilter", function(object) {
 
     value <- .value(object)
     condition <- .condition(object)
+    not <- .not(object)
     test_len <- length(condition) == 1L
     test_NA <- !any(is.na(condition))
 
@@ -152,10 +160,14 @@ setValidity("AnnotationFilter", function(object) {
         txt <- c(txt, "'condition' can not be NA")
     test0 <- test_len && test_NA
 
-    test1 <- condition  %in% c("startsWith", "endsWith", ">", "<", ">=", "<=")
+    test1 <- condition  %in% c("startsWith", "endsWith", "contains", ">",
+                               "<", ">=", "<=")
     if (test0 && test1 && length(value) > 1L)
         txt <- c(txt, paste0("'", condition, "' requires length 1 'value'"))
 
+    if(length(not) != 1)
+        txt <- c(txt, '"not" value must be of length 1.')
+
     if (any(is.na(value)))
         txt <- c(txt, "'value' can not be NA")
 
@@ -168,6 +180,8 @@ setValidity("AnnotationFilter", function(object) {
 
 .value <- function(object) object at value
 
+.not <- function(object) object at not
+
 #' @rdname AnnotationFilter
 #'
 #' @aliases condition
@@ -200,10 +214,18 @@ setMethod("value", "AnnotationFilter", .value)
 #' @export
 setMethod("field", "AnnotationFilter", .field)
 
+#' @rdname AnnotationFilter
+#'
+#' @description \code{not()} get the \code{not} for the filter \code{object}.
+#'
+#' @export
+setMethod("not", "AnnotationFilter", .not)
+
 #' @importFrom methods show
 #'
 #' @export
 setMethod("show", "AnnotationFilter", function(object){
+    if(.not(object)) cat("NOT\n")
     cat("class:", class(object),
         "\ncondition:", .condition(object), "\n")
 })
@@ -376,18 +398,26 @@ NULL
     force(field); force(class)          # watch for lazy evaluation
     as.value <-
         if (field %in% .FIELD[["CharacterFilter"]]) {
-            as.character
+            function(x) {
+#               if(!is.character(x))
+#                  stop("Input to a ", field,
+#                       "filter must be a character vector.")
+                as.character(x)
+            }
         } else {
             function(x) {
-                stopifnot(is.numeric(x))
+                if(!is.numeric(x))
+                    stop("Input to a ", field,
+                         "filter must be a numeric vector.")
                 as.integer(x)
             }
         }
 
-    function(value, condition = "==") {
+    function(value, condition = "==", not = FALSE) {
         value <- as.value(value)
         condition <- as.character(condition)
-        new(class, field=field, condition = condition, value=value)
+        not <- as.logical(not)
+        new(class, field=field, condition = condition, value=value, not=not)
     }
 }
 
@@ -409,11 +439,76 @@ local({
 })
 
 ############################################################
-## Utilities - supportedFilters
+## Utilities 
 ##
 
+.convertFilter <- function(object) {
+    field <- field(object)
+    if (field == "granges")
+        stop("GRangesFilter cannot be converted using convertFilter().")
+    value <- value(object)
+    condition <- condition(object)
+    not <- not(object)
+
+    op <- switch(
+        condition,
+        "==" = if (length(value) == 1) "==" else "%in%",
+        "!=" = if (length(value) == 1) "!=" else "%in%",
+        "startsWith" = "%like%",
+        "endsWith" = "%like%",
+        "contains" = "%like%"
+    )
+
+    not_val <- ifelse(not, '!', '')
+
+    if (condition %in% c("==", "!="))
+        value <- paste0("'", value, "'", collapse=", ")
+
+    if (!is.null(op) && op %in% c("==", "!="))
+        sprintf("%s%s %s %s", not_val, field, op, value)
+    else if ((condition == "==") && op == "%in%")
+        sprintf("%s%s %s c(%s)", not_val, field, op, value)
+    else if ((condition == "!=") && op == "%in%")
+        if(not) sprintf("%s %s c(%s)", field, op, value)
+        else sprintf("!%s%s %s c(%s)", not_val, field, op, value)
+    else if (condition == "startsWith")
+        sprintf("%s%s %s '%s%%'", not_val, field, op, value)
+    else if (condition == "endsWith")
+        sprintf("%s%s %s '%%%s'", not_val, field, op, value)
+    else if (condition == "contains")
+        sprintf("%s%s %s '%s'", not_val, field, op, value)
+    else if (condition %in% c(">", "<", ">=", "<=")) {
+        sprintf("%s%s %s %s", not_val, field, condition, as.integer(value))
+    }
+}
+
+#' @rdname AnnotationFilter
+#'
+#' @description Converts an \code{AnnotationFilter} object to a 
+#'      \code{character(1)} giving an equation that can be used as input to
+#'      a \code{dplyr} filter.
+#'
+#' @return \code{character(1)} that can be used as input to a \code{dplyr} 
+#'      filter.
+#'
+#' @examples
+#' filter <- SymbolFilter("ADA", "==")
+#' result <- convertFilter(filter)
+#' result
+#' @export
+setMethod("convertFilter", signature(object = "AnnotationFilter",
+                                     db = "missing"), .convertFilter)
+
+.FILTERS_WO_FIELD <- c("GRangesFilter")
+
 .supportedFilters <- function() {
-    sort(c(.fieldToClass(unlist(.FIELD, use.names=FALSE)), "GRangesFilter"))
+    fields <- unlist(.FIELD, use.names=FALSE)
+    filters <- .fieldToClass(fields)
+    d <- data.frame(
+      filter=c(filters, .FILTERS_WO_FIELD),
+      field=c(fields, "granges") #rep(NA, length(.FILTERS_WO_FIELD)))
+    )
+    d[order(d$filter),]
 }
 
 #' @rdname AnnotationFilter
diff --git a/R/AnnotationFilterList.R b/R/AnnotationFilterList.R
index 734c93f..5df04d7 100644
--- a/R/AnnotationFilterList.R
+++ b/R/AnnotationFilterList.R
@@ -26,7 +26,9 @@ NULL
 .AnnotationFilterList <- setClass(
     "AnnotationFilterList",
     contains = "list",
-    slots = c(logOp = "character")
+    slots = c(logOp = "character",
+              not = "logical",
+              .groupingFlag = "logical")
 )
 
 .LOG_OPS <- c("&", "|")
@@ -37,9 +39,10 @@ setValidity("AnnotationFilterList",
     txt <- character()
     filters <- .aflvalue(object)
     logOp <- .logOp(object)
+    not <- .not(object)
     if (length(filters) == 0 && length(logOp)) {
         txt <- c(
-            txt, "'logOp' can not have length > 0 if the object is empty"
+            txt, "'logicOp' can not have length > 0 if the object is empty"
         )
     } else if (length(filters) != 0) {
         ## Note: we allow length of filters being 1, but then logOp has
@@ -52,17 +55,17 @@ setValidity("AnnotationFilterList",
                 txt, "only 'AnnotationFilter' or 'AnnotationFilterList' allowed"
             )
         }
-        ## Check that all elements are non-empty (issue #17). Doing this
+        # Check that all elements are non-empty (issue #17). Doing this
         ## separately from the check above to ensure we get a different error
         ## message.
         if (!all(lengths(filters) > 0))
             txt <- c(txt, "Lengths of all elements have to be > 0")
         ## Check that logOp has length object -1
         if (length(logOp) != length(filters) - 1)
-            txt <- c(txt, "length of 'logOp' has to be length of the object -1")
+            txt <- c(txt, "length of 'logicOp' has to be length of the object -1")
         ## Check content of logOp.
         if (!all(logOp %in% .LOG_OPS))
-            txt <- c(txt, "'logOp' can only contain '&' and '|'")
+            txt <- c(txt, "'logicOp' can only contain '&' and '|'")
     }
 
     if (length(txt)) txt else TRUE
@@ -77,8 +80,8 @@ setValidity("AnnotationFilterList",
 #'     mixture of \code{AnnotationFilter} and
 #'     \code{AnnotationFilterList} objects.
 #'
-#' @param logOp \code{character} of length being equal to the numner
-#'     of submitted \code{AnnotationFilter} objects -1. Each value
+#' @param logicOp \code{character} of length equal to the number
+#'     of submitted \code{AnnotationFilter} objects - 1. Each value
 #'     representing the logical operation to combine consecutive
 #'     filters, i.e. the first element being the logical operation to
 #'     combine the first and second \code{AnnotationFilter}, the
@@ -87,6 +90,13 @@ setValidity("AnnotationFilterList",
 #'     values are \code{"&"} and \code{"|"}. The function assumes a
 #'     logical \emph{and} between all elements by default.
 #'
+#' @param logOp Deprecated; use \code{logicOp=}.
+#'
+#' @param .groupingFlag Flag desginated for internal use only.
+#'
+#' @param not \code{logical} of length one. Indicates whether the grouping
+#'      of \code{AnnotationFilters} are to be negated.
+#'
 #' @seealso \code{\link{supportedFilters}} for available
 #'     \code{\link{AnnotationFilter}} objects
 #'
@@ -113,60 +123,203 @@ setValidity("AnnotationFilterList",
 #' ## also found by the previous AnnotationFilterList and returns also all
 #' ## features on chromosome Y.
 #' afl <- AnnotationFilterList(gf, tbtf, SeqNameFilter("Y"),
-#'                             logOp = c("&", "|"))
+#'                             logicOp = c("&", "|"))
 #' afl
 #'
 #' @export
 AnnotationFilterList <-
-    function(..., logOp = character())
+    function(..., logicOp = character(), logOp = character(), not = FALSE,
+        .groupingFlag=FALSE)
 {
+    if (!missing(logOp) && missing(logicOp)) {
+        logicOp <- logOp
+        .Deprecated(msg = "'logOp' deprecated, use 'logicOp'")
+    }
     filters <- list(...)
-    ## Remove empty elements (issue #17)
-    filters <- filters[lengths(filters) > 0]
-    ## By default we're assuming & between elements.
-    if (length(filters) > 1 & length(logOp) == 0)
-        logOp <- rep("&", (length(filters) - 1))
-    .AnnotationFilterList(filters, logOp = logOp)
+
+    ## Remove empty nested lists and AnnotationFilterLists
+    removal <- lengths(filters) != 0
+    filters <- filters[removal]
+
+    if (length(filters) > 1 & length(logicOp) == 0)
+        ## By default we're assuming & between elements.
+        logicOp <- rep("&", (length(filters) - 1))
+    .AnnotationFilterList(filters, logOp = logicOp, not = not,
+        .groupingFlag=.groupingFlag)
 }
 
 .logOp <- function(object) object at logOp
 
 .aflvalue <- function(object) object at .Data
 
+.not <- function(object) object at not
+
 #' @rdname AnnotationFilterList
 #'
 #' @description \code{value()} get a \code{list} with the
 #'     \code{AnnotationFilter} objects. Use \code{[[} to access
 #'     individual filters.
 #'
-#' @return \code{value} returns a \code{list} with \code{AnnotationFilter}
+#' @return \code{value()} returns a \code{list} with \code{AnnotationFilter}
 #'     objects.
 #' 
 #' @export
 setMethod("value", "AnnotationFilterList", .aflvalue)
 
+#' @rdname AnnotationFilterList
+#'
+#' @aliases logicOp
+#'
+#' @description \code{logicOp()} gets the logical operators separating
+#'     successive \code{AnnotationFilter}.
+#'
+#' @return \code{logicOp()} returns a \code{character()} vector of
+#'     \dQuote{&} or \dQuote{|} symbols.
+#'
+#' @export logicOp
+setMethod("logicOp", "AnnotationFilterList", .logOp)
 
 #' @rdname AnnotationFilterList
 #'
-#' @param object An object of class \code{AnnotationFilterList}.
+#' @aliases not
 #'
-#' @importFrom utils tail
-#' @export
-setMethod("show", "AnnotationFilterList",
-    function(object)
+#' @description \code{not()} gets the logical operators separating
+#'     successive \code{AnnotationFilter}.
+#'
+#' @return \code{not()} returns a \code{character()} vector of
+#'     \dQuote{&} or \dQuote{|} symbols.
+#'
+#' @export not
+setMethod("not", "AnnotationFilterList", .not)
+
+.distributeNegation <- function(object, .prior_negation=FALSE)
 {
-    cat("class:", class(object),
-        "\nlength:", length(object)
+    if(.not(object))
+        .prior_negation <- ifelse(.prior_negation, FALSE, TRUE)
+    filters <- lapply(object, function(x){
+        if(is(x, "AnnotationFilterList"))
+            distributeNegation(x, .prior_negation)   
+        else{
+            if(.prior_negation) x at not <- ifelse(x at not, FALSE, TRUE)
+            x
+        }
+    })
+    ops <- vapply(logicOp(object), function(x) {
+        if(.prior_negation){
+            if(x == '&')
+                '|'
+            else
+                '&'
+        }
+        else
+            x
+    }
+        ,character(1)
     )
+    ops <- unname(ops)
+    filters[['logicOp']] <- ops
+    do.call("AnnotationFilterList", filters)
+}
 
-    if (length(object) == 0L)
-        return()
+#' @rdname AnnotationFilterList
+#'
+#' @aliases distributeNegation
+#'
+#' @description
+#'
+#' @param .prior_negation \code{logical(1)} unused argument.
+#'
+#' @return \code{AnnotationFilterList} object with DeMorgan's law applied to
+#'      it such that it is equal to the original \code{AnnotationFilterList}
+#'      object but all \code{!}'s are distributed out of the
+#'      \code{AnnotationFilterList} object and to the nested
+#'      \code{AnnotationFilter} objects.
+#'
+#' @examples
+#' afl <- AnnotationFilter(~!(symbol == 'ADA' | symbol %startsWith% 'SNORD'))
+#' afl <- distributeNegation(afl)
+#' afl
+#' @export
+setMethod("distributeNegation", "AnnotationFilterList", .distributeNegation)
 
-    cat("\nfilters:\n\n")
-    show(object[[1L]])
-    for (i in tail(seq_along(object), -1L)) {
-        cat("\n", .logOp(object)[i - 1L], "\n\n")
-        show(object[[i]])
+.convertFilterList <- function(object, show, granges=list(), nested=FALSE)
+{
+    filters <- value(object)
+    result <- character(length(filters))
+    for (i in seq_len(length(filters))) {
+        if (is(filters[[i]], "AnnotationFilterList")) {
+            res <- .convertFilterList(filters[[i]], show=show, granges=granges,
+                nested=TRUE)
+            granges <- c(granges, res[[2]])
+            result[i] <- res[[1]]
+        }
+        else if (field(filters[[i]]) == "granges") {
+            if(!show)
+                result[i] <- .convertFilter(filters[[i]])
+            else {
+                nam <- paste0("GRangesFilter_", length(granges) + 1)
+                granges <- c(granges, list(filters[[i]]))
+                result[i] <- nam
+            }
+        }
+        else
+            result[i] <- .convertFilter(filters[[i]])
     }
+
+    result_last <- tail(result, 1)
+    result <- head(result, -1)
+    result <- c(rbind(result, logicOp(object)))
+    result <- c(result, result_last)
+    result <- paste(result, collapse=" ")
+    if(nested || object at not)
+        result <- paste0("(", result, ")")
+    if(object at not)
+        result <- paste0("!", result)
+        
+    list(result, granges)
+}
+
+#' @rdname AnnotationFilterList
+#'
+#' @aliases convertFilter
+#'
+#' @description Converts an \code{AnnotationFilterList} object to a
+#'      \code{character(1)} giving an equation that can be used as input to
+#'      a \code{dplyr} filter.
+#'
+#' @return \code{character(1)} that can be used as input to a \code{dplyr}
+#'      filter.
+#'
+#' @examples
+#' afl <- AnnotationFilter(~symbol=="ADA" & tx_start > "400000")
+#' result <- convertFilter(afl)
+#' result
+#' @export
+setMethod("convertFilter", signature(object = "AnnotationFilterList",
+                                     db = "missing") , function(object)
+{
+    result <- .convertFilterList(object, show=FALSE)
+    result[[1]]
 })
 
+#' @rdname AnnotationFilterList
+#'
+#' @param object An object of class \code{AnnotationFilterList}.
+#'
+#' @importFrom utils tail
+#' @export
+setMethod("show", "AnnotationFilterList", function(object)
+{
+    result <- .convertFilterList(object, show=TRUE)
+    granges <- result[[2]]
+    result <- result[[1]]
+    cat("AnnotationFilterList of length", length(object), "\n")
+    cat(result)
+    cat("\n")
+    for(i in seq_len(length(granges))) {
+        cat("\n")
+        cat("Symbol: GRangesFilter_", i, "\n", sep="")
+        show(granges[[1]])
+        cat("\n")
+    }
+})
diff --git a/R/translate-utils.R b/R/translate-utils.R
index 5232554..87e4002 100644
--- a/R/translate-utils.R
+++ b/R/translate-utils.R
@@ -31,26 +31,65 @@
     }
 }
 
+#' Functionality to translate a unary operation into an AnnotationFilter.
+#'
+#' @noRd
+.not_op <- function(sep) {
+    force(sep)
+    function(x) {
+        if(is(x, "AnnotationFilterList") || is(x, "AnnotationFilter")) {
+            if(x at not)
+                x at not <- FALSE
+            else
+                x at not <- TRUE
+            if(is(x, "AnnotationFilterList"))
+                x at .groupingFlag <- FALSE
+            return(x)
+        }
+#       else if (is(x, "AnnotationFilter")) 
+#           AnnotationFilterList(x, logicOp=character(), not=TRUE)
+        else
+            stop('Arguments to "!" must be an AnnotationFilter or AnnotationFilerList.')
+    }
+}
+
+.parenthesis_op <- function(sep) {
+    force(sep)
+    function(x) {
+        if (is(x, "AnnotationFilterList")) {
+            x at .groupingFlag <- FALSE
+            x
+        }
+        else
+            AnnotationFilterList(x, .groupingFlag=FALSE)
+    }
+}
+
+
 #' Combine filters into a AnnotationFilterList combbined with \code{sep}
 #'
 #' @noRd
 .combine_op <- function(sep) {
     force(sep)
     function(e1, e2) {
-        ## Avoid implicit nesting of AnnotationFilterList - should be done
-        ## eventually
-        if (is(e1, "AnnotationFilterList")) {
-            sep <- c(.logOp(e1), sep)
+        op1 <- character()
+        op2 <- character()
+        if (is(e1, "AnnotationFilterList") && e1 at .groupingFlag) {
+            op1 <- logicOp(e1)
             e1 <- .aflvalue(e1)
-        } else
+        } else {
             e1 <- list(e1)
-        if (is(e2, "AnnotationFilterList")) {
-            sep <- c(.logOp(e2), sep)
+        }
+        if (is(e2, "AnnotationFilterList") && e2 at .groupingFlag) {
+            op2 <- logicOp(e2)
             e2 <- .aflvalue(e2)
-        } else
+        } else {
             e2 <- list(e2)
-        ## Don't use the constructor here.
-        new("AnnotationFilterList", c(e1, e2), logOp = sep)
+        }
+        input <- c(e1, e2)
+        input[['logicOp']] <- c(op1, sep, op2)
+        input[['.groupingFlag']] <- TRUE
+        do.call("AnnotationFilterList", input)
     }
 }
 
@@ -68,10 +107,22 @@
 .LOG_OP_REG$`<` <- .binary_op("<")
 .LOG_OP_REG$`>=` <- .binary_op(">=")
 .LOG_OP_REG$`<=` <- .binary_op("<=")
+## Custom binary operators 
+.LOG_OP_REG$`%startsWith%` <- .binary_op("startsWith")
+.LOG_OP_REG$`%endsWith%` <- .binary_op("endsWith")
+.LOG_OP_REG$`%contains%` <- .binary_op("contains")
+## not conditional.
+.LOG_OP_REG$`!` <- .not_op("!")
+## parenthesis
+.LOG_OP_REG$`(` <- .parenthesis_op("(")
 ## combine filters
 .LOG_OP_REG$`&` <- .combine_op("&")
 .LOG_OP_REG$`|` <- .combine_op("|")
 
+`%startsWith%` <- function(e1, e2){}
+`%endsWith%` <- function(e1, e2){}
+`%contains%` <- function(e1, e2){}
+
 #' @rdname AnnotationFilter
 #'
 #' @description \code{AnnotationFilter} \emph{translates} a filter
@@ -79,7 +130,12 @@
 #'     extending the \code{\link{AnnotationFilter}} class (in the example a
 #'     \code{\link{GeneIdFilter}} object) or an
 #'     \code{\link{AnnotationFilterList}} if the expression contains multiple
-#'     conditions (see examples below).
+#'     conditions (see examples below). Filter expressions have to be written
+#'     in the form \code{~ <field> <condition> <value>}, with \code{<field>}
+#'     being the default field of the filter class (use the
+#'     \code{supportedFilter} function to list all fields and filter classes),
+#'     \code{<condition>} the logical expression and \code{<value>} the value
+#'     for the filter.
 #'
 #' @details Filter expressions for the \code{AnnotationFilter} class have to be
 #'     written as formulas, i.e. starting with a \code{~}.
@@ -116,5 +172,7 @@
 #' 
 #' @export
 AnnotationFilter <- function(expr) {
-    f_eval(expr, data = .LOG_OP_REG)
+    res <- f_eval(expr, data = .LOG_OP_REG)
+    if(is(res, "AnnotationFilterList")) res at .groupingFlag <- FALSE
+    res
 }
diff --git a/build/vignette.rds b/build/vignette.rds
index ec7ec6d..32a8595 100644
Binary files a/build/vignette.rds and b/build/vignette.rds differ
diff --git a/inst/doc/AnnotationFilter.R b/inst/doc/AnnotationFilter.R
index 18b925e..7cf0dcc 100644
--- a/inst/doc/AnnotationFilter.R
+++ b/inst/doc/AnnotationFilter.R
@@ -32,7 +32,7 @@ afl1 <- AnnotationFilterList(SymbolFilter("BCL2L11"),
 afl2 <- AnnotationFilterList(SymbolFilter("BCL2"),
                              TxBiotypeFilter("protein_coding"))
 ## Now combine both with a logical OR
-afl <- AnnotationFilterList(afl1, afl2, logOp = "|")
+afl <- AnnotationFilterList(afl1, afl2, logicOp = "|")
 
 afl
 
diff --git a/inst/doc/AnnotationFilter.Rmd b/inst/doc/AnnotationFilter.Rmd
index 0dddd45..446e81b 100644
--- a/inst/doc/AnnotationFilter.Rmd
+++ b/inst/doc/AnnotationFilter.Rmd
@@ -134,9 +134,9 @@ smbl
 
 Individual `AnnotationFilter` objects can be combined in an
 `AnnotationFilterList`. This class extends `list` and provides an additional
-`logOp` slot that defines how its individual filters are supposed to be
-combined. The length of `logOp` has to be 1 less than the number of filter
-objects. Each element in `logOp` defines how two consecutive filters should
+`logicOp()` that defines how its individual filters are supposed to be
+combined. The length of `logicOp()` has to be 1 less than the number of filter
+objects. Each element in `logicOp()` defines how two consecutive filters should
 be combined. Below we create a `AnnotationFilterList` containing two filter
 objects to be combined with a logical *AND*.
 
@@ -160,7 +160,7 @@ afl1 <- AnnotationFilterList(SymbolFilter("BCL2L11"),
 afl2 <- AnnotationFilterList(SymbolFilter("BCL2"),
                              TxBiotypeFilter("protein_coding"))
 ## Now combine both with a logical OR
-afl <- AnnotationFilterList(afl1, afl2, logOp = "|")
+afl <- AnnotationFilterList(afl1, afl2, logicOp = "|")
 
 afl
 ```
diff --git a/inst/doc/AnnotationFilter.html b/inst/doc/AnnotationFilter.html
index 790b545..4889daf 100644
--- a/inst/doc/AnnotationFilter.html
+++ b/inst/doc/AnnotationFilter.html
@@ -10,7 +10,7 @@
 
 
 
-<meta name="date" content="2017-04-24" />
+<meta name="date" content="2017-10-30" />
 
 <title>Facilities for Filtering Bioconductor Annotation Resources</title>
 
@@ -68,7 +68,7 @@ h6 {
 }
 </style>
 
-<link href="data:text/css;charset=utf-8,body%20%7B%0Amargin%3A%200px%20auto%3B%0Amax%2Dwidth%3A%201134px%3B%0A%7D%0Abody%2C%20td%20%7B%0Afont%2Dfamily%3A%20sans%2Dserif%3B%0Afont%2Dsize%3A%2010pt%3B%0A%7D%0A%0Adiv%23TOC%20ul%20%7B%0Apadding%3A%200px%200px%200px%2045px%3B%0Alist%2Dstyle%3A%20none%3B%0Abackground%2Dimage%3A%20none%3B%0Abackground%2Drepeat%3A%20none%3B%0Abackground%2Dposition%3A%200%3B%0Afont%2Dsize%3A%2010pt%3B%0Afont%2Dfamily%3A%20Helvetica%2C%20Arial%2C%20sans%2Dserif%3B [...]
+<link href="data:text/css;charset=utf-8,body%20%7B%0Amargin%3A%200px%20auto%3B%0Amax%2Dwidth%3A%201134px%3B%0Afont%2Dfamily%3A%20sans%2Dserif%3B%0Afont%2Dsize%3A%2010pt%3B%0A%7D%0A%0Adiv%23TOC%20ul%20%7B%0Apadding%3A%200px%200px%200px%2045px%3B%0Alist%2Dstyle%3A%20none%3B%0Abackground%2Dimage%3A%20none%3B%0Abackground%2Drepeat%3A%20none%3B%0Abackground%2Dposition%3A%200%3B%0Afont%2Dsize%3A%2010pt%3B%0Afont%2Dfamily%3A%20Helvetica%2C%20Arial%2C%20sans%2Dserif%3B%0A%7D%0Adiv%23TOC%20%3E%20 [...]
 
 </head>
 
@@ -208,7 +208,7 @@ div.tocify {
 
 
 <h1 class="title toc-ignore">Facilities for Filtering Bioconductor Annotation Resources</h1>
-<h4 class="date"><em>24 April 2017</em></h4>
+<h4 class="date"><em>30 October 2017</em></h4>
 
 </div>
 
@@ -226,7 +226,7 @@ document.addEventListener("DOMContentLoaded", function() {
       links[i].target = '_blank';
 });
 </script>
-<p><strong>Package</strong>: <em><a href="http://bioconductor.org/packages/AnnotationFilter">AnnotationFilter</a></em><br /> <strong>Authors</strong>: Martin Morgan [aut], Johannes Rainer [aut], Bioconductor Maintainer [cre]<br /> <strong>Last modified:</strong> 2017-04-24 16:35:20<br /> <strong>Compiled</strong>: Mon Apr 24 21:05:12 2017</p>
+<p><strong>Package</strong>: <em><a href="http://bioconductor.org/packages/AnnotationFilter">AnnotationFilter</a></em><br /> <strong>Authors</strong>: Martin Morgan [aut], Johannes Rainer [aut], Joachim Bargsten [ctb], Daniel Van Twisk [ctb], Bioconductor Maintainer [cre]<br /> <strong>Last modified:</strong> 2017-10-30 17:37:05<br /> <strong>Compiled</strong>: Mon Oct 30 21:20:21 2017</p>
 <div id="introduction" class="section level1">
 <h1><span class="header-section-number">1</span> Introduction</h1>
 <p>A large variety of annotation resources are available in Bioconductor. Accessing the full content of these databases or even of single tables is computationally expensive and in many instances not required, as users may want to extract only sub-sets of the data e.g. genomic coordinates of a single gene. In that respect, filtering annotation resources before data extraction has a major impact on performance and increases the usability of such genome-scale databases.</p>
@@ -244,14 +244,31 @@ document.addEventListener("DOMContentLoaded", function() {
 <p>The <code>supportedFilters</code> method can be used to get an overview of all available filter objects defined in <code>AnnotationFilter</code>.</p>
 <pre class="r"><code>library(AnnotationFilter)
 supportedFilters()</code></pre>
-<pre><code>##  [1] "CdsEndFilter"      "CdsStartFilter"    "EntrezFilter"     
-##  [4] "ExonEndFilter"     "ExonIdFilter"      "ExonNameFilter"   
-##  [7] "ExonRankFilter"    "ExonStartFilter"   "GRangesFilter"    
-## [10] "GeneBiotypeFilter" "GeneEndFilter"     "GeneIdFilter"     
-## [13] "GeneStartFilter"   "GenenameFilter"    "ProteinIdFilter"  
-## [16] "SeqNameFilter"     "SeqStrandFilter"   "SymbolFilter"     
-## [19] "TxBiotypeFilter"   "TxEndFilter"       "TxIdFilter"       
-## [22] "TxNameFilter"      "TxStartFilter"     "UniprotFilter"</code></pre>
+<pre><code>##               filter        field
+## 16      CdsEndFilter      cds_end
+## 15    CdsStartFilter    cds_start
+## 6       EntrezFilter       entrez
+## 19     ExonEndFilter     exon_end
+## 1       ExonIdFilter      exon_id
+## 2     ExonNameFilter    exon_name
+## 18    ExonRankFilter    exon_rank
+## 17   ExonStartFilter   exon_start
+## 24     GRangesFilter      granges
+## 5  GeneBiotypeFilter gene_biotype
+## 21     GeneEndFilter     gene_end
+## 3       GeneIdFilter      gene_id
+## 20   GeneStartFilter   gene_start
+## 4     GenenameFilter     genename
+## 11   ProteinIdFilter   protein_id
+## 13     SeqNameFilter     seq_name
+## 14   SeqStrandFilter   seq_strand
+## 7       SymbolFilter       symbol
+## 10   TxBiotypeFilter   tx_biotype
+## 23       TxEndFilter       tx_end
+## 8         TxIdFilter        tx_id
+## 9       TxNameFilter      tx_name
+## 22     TxStartFilter     tx_start
+## 12     UniprotFilter      uniprot</code></pre>
 <p>Note that the <code>AnnotationFilter</code> package does provides only the filter classes but not the functionality to apply the filtering. Such functionality is annotation resource and database layout dependent and needs thus to be implemented in the packages providing access to annotation resources.</p>
 </div>
 <div id="usage" class="section level1">
@@ -278,23 +295,12 @@ smbl</code></pre>
 <pre><code>## class: SymbolFilter 
 ## condition: == 
 ## value: BCL2</code></pre>
-<p>Individual <code>AnnotationFilter</code> objects can be combined in an <code>AnnotationFilterList</code>. This class extends <code>list</code> and provides an additional <code>logOp</code> slot that defines how its individual filters are supposed to be combined. The length of <code>logOp</code> has to be 1 less than the number of filter objects. Each element in <code>logOp</code> defines how two consecutive filters should be combined. Below we create a <code>AnnotationFilterList</code [...]
+<p>Individual <code>AnnotationFilter</code> objects can be combined in an <code>AnnotationFilterList</code>. This class extends <code>list</code> and provides an additional <code>logicOp()</code> that defines how its individual filters are supposed to be combined. The length of <code>logicOp()</code> has to be 1 less than the number of filter objects. Each element in <code>logicOp()</code> defines how two consecutive filters should be combined. Below we create a <code>AnnotationFilterLis [...]
 <pre class="r"><code>flt <- AnnotationFilter(~ symbol == "BCL2" &
                             tx_biotype == "protein_coding")
 flt</code></pre>
-<pre><code>## class: AnnotationFilterList 
-## length: 2
-## filters:
-## 
-## class: SymbolFilter 
-## condition: == 
-## value: BCL2 
-## 
-##  & 
-## 
-## class: TxBiotypeFilter 
-## condition: == 
-## value: protein_coding</code></pre>
+<pre><code>## AnnotationFilterList of length 2 
+## symbol == 'BCL2' & tx_biotype == 'protein_coding'</code></pre>
 <p>Note that the <code>AnnotationFilter</code> function does not (yet) support translation of nested expressions, such as <code>(symbol == "BCL2L11" & tx_biotype == "nonsense_mediated_decay") | (symbol == "BCL2" & tx_biotype == "protein_coding")</code>. Such queries can however be build by nesting <code>AnnotationFilterList</code> classes.</p>
 <pre class="r"><code>## Define the filter query for the first pair of filters.
 afl1 <- AnnotationFilterList(SymbolFilter("BCL2L11"),
@@ -303,42 +309,11 @@ afl1 <- AnnotationFilterList(SymbolFilter("BCL2L11"),
 afl2 <- AnnotationFilterList(SymbolFilter("BCL2"),
                              TxBiotypeFilter("protein_coding"))
 ## Now combine both with a logical OR
-afl <- AnnotationFilterList(afl1, afl2, logOp = "|")
+afl <- AnnotationFilterList(afl1, afl2, logicOp = "|")
 
 afl</code></pre>
-<pre><code>## class: AnnotationFilterList 
-## length: 2
-## filters:
-## 
-## class: AnnotationFilterList 
-## length: 2
-## filters:
-## 
-## class: SymbolFilter 
-## condition: == 
-## value: BCL2L11 
-## 
-##  & 
-## 
-## class: TxBiotypeFilter 
-## condition: == 
-## value: nonsense_mediated_decay 
-## 
-##  | 
-## 
-## class: AnnotationFilterList 
-## length: 2
-## filters:
-## 
-## class: SymbolFilter 
-## condition: == 
-## value: BCL2 
-## 
-##  & 
-## 
-## class: TxBiotypeFilter 
-## condition: == 
-## value: protein_coding</code></pre>
+<pre><code>## AnnotationFilterList of length 2 
+## (symbol == 'BCL2L11' & tx_biotype == 'nonsense_mediated_decay') | (symbol == 'BCL2' & tx_biotype == 'protein_coding')</code></pre>
 <p>This <code>AnnotationFilterList</code> would now select all entries for all transcripts of the gene <em>BCL2L11</em> with the biotype <em>nonsense_mediated_decay</em> or for all protein coding transcripts of the gene <em>BCL2</em>.</p>
 </div>
 <div id="using-annotationfilter-in-other-packages" class="section level1">
@@ -422,8 +397,8 @@ dbListTables(dbcon)</code></pre>
 ## [22] "kegg"                  "map_counts"            "map_metadata"         
 ## [25] "metadata"              "ncbi2ensembl"          "omim"                 
 ## [28] "pfam"                  "prosite"               "pubmed"               
-## [31] "refseq"                "sqlite_stat1"          "ucsc"                 
-## [34] "unigene"               "uniprot"</code></pre>
+## [31] "refseq"                "sqlite_stat1"          "sqlite_stat4"         
+## [34] "ucsc"                  "unigene"               "uniprot"</code></pre>
 <p><code>org.Hs.eg.db</code> provides many different tables, one for each identifier or annotation resource. We will use the <em>gene_info</em> table and determine which <em>fields</em> (i.e. columns) the table provides.</p>
 <pre class="r"><code>## What fields are there in the gene_info table?
 dbListFields(dbcon, "gene_info")</code></pre>
@@ -477,23 +452,23 @@ bcl2</code></pre>
 <p>Below we compare the performance of both approaches.</p>
 <pre class="r"><code>system.time(doExtractGene(dbcon, ~ symbol == "BCL2"))</code></pre>
 <pre><code>##    user  system elapsed 
-##   0.100   0.000   0.099</code></pre>
+##   0.096   0.000   0.095</code></pre>
 <pre class="r"><code>system.time(doExtractGene2(dbcon, ~ symbol == "BCL2"))</code></pre>
 <pre><code>##    user  system elapsed 
-##   0.016   0.000   0.013</code></pre>
+##   0.012   0.000   0.011</code></pre>
 <p>Not surprisingly, the second approach is much faster.</p>
 <p>Be aware that the examples shown here are only for illustration purposes. In a real world situation additional factors, like combinations of filters, which database tables to join, which columns to be returned etc would have to be considered too.</p>
 </div>
 <div id="session-information" class="section level1">
 <h1><span class="header-section-number">5</span> Session information</h1>
 <pre class="r"><code>sessionInfo()</code></pre>
-<pre><code>## R version 3.4.0 (2017-04-21)
+<pre><code>## R version 3.4.2 (2017-09-28)
 ## Platform: x86_64-pc-linux-gnu (64-bit)
-## Running under: Ubuntu 16.04.2 LTS
+## Running under: Ubuntu 16.04.3 LTS
 ## 
 ## Matrix products: default
-## BLAS: /home/biocbuild/bbs-3.5-bioc/R/lib/libRblas.so
-## LAPACK: /home/biocbuild/bbs-3.5-bioc/R/lib/libRlapack.so
+## BLAS: /home/biocbuild/bbs-3.6-bioc/R/lib/libRblas.so
+## LAPACK: /home/biocbuild/bbs-3.6-bioc/R/lib/libRlapack.so
 ## 
 ## locale:
 ##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
@@ -508,20 +483,22 @@ bcl2</code></pre>
 ## [8] methods   base     
 ## 
 ## other attached packages:
-## [1] RSQLite_1.1-2          org.Hs.eg.db_3.4.1     AnnotationDbi_1.38.0  
-## [4] IRanges_2.10.0         S4Vectors_0.14.0       Biobase_2.36.0        
-## [7] BiocGenerics_0.22.0    AnnotationFilter_1.0.0 BiocStyle_2.4.0       
+## [1] RSQLite_2.0            org.Hs.eg.db_3.4.2     AnnotationDbi_1.40.0  
+## [4] IRanges_2.12.0         S4Vectors_0.16.0       Biobase_2.38.0        
+## [7] BiocGenerics_0.24.0    AnnotationFilter_1.2.0 BiocStyle_2.6.0       
 ## 
 ## loaded via a namespace (and not attached):
-##  [1] Rcpp_0.12.10            knitr_1.15.1            XVector_0.16.0         
-##  [4] magrittr_1.5            GenomicRanges_1.28.0    zlibbioc_1.22.0        
-##  [7] stringr_1.2.0           GenomeInfoDb_1.12.0     tools_3.4.0            
-## [10] DBI_0.6-1               htmltools_0.3.5         lazyeval_0.2.0         
-## [13] yaml_2.1.14             rprojroot_1.2           digest_0.6.12          
-## [16] bookdown_0.3            GenomeInfoDbData_0.99.0 bitops_1.0-6           
-## [19] RCurl_1.95-4.8          memoise_1.1.0           evaluate_0.10          
-## [22] rmarkdown_1.4           stringi_1.1.5           compiler_3.4.0         
-## [25] backports_1.0.5</code></pre>
+##  [1] Rcpp_0.12.13            knitr_1.17              XVector_0.18.0         
+##  [4] magrittr_1.5            GenomicRanges_1.30.0    zlibbioc_1.24.0        
+##  [7] bit_1.1-12              rlang_0.1.2             blob_1.1.0             
+## [10] stringr_1.2.0           GenomeInfoDb_1.14.0     tools_3.4.2            
+## [13] DBI_0.7                 htmltools_0.3.6         bit64_0.9-7            
+## [16] lazyeval_0.2.1          yaml_2.1.14             rprojroot_1.2          
+## [19] digest_0.6.12           tibble_1.3.4            bookdown_0.5           
+## [22] GenomeInfoDbData_0.99.1 bitops_1.0-6            RCurl_1.95-4.8         
+## [25] memoise_1.1.0           evaluate_0.10.1         rmarkdown_1.6          
+## [28] stringi_1.1.5           compiler_3.4.2          backports_1.1.1        
+## [31] pkgconfig_2.0.1</code></pre>
 </div>
 
 
@@ -562,7 +539,7 @@ $(document).ready(function () {
   (function () {
     var script = document.createElement("script");
     script.type = "text/javascript";
-    script.src  = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
+    script.src  = "https://mathjax.rstudio.com/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML";
     document.getElementsByTagName("head")[0].appendChild(script);
   })();
 </script>
diff --git a/man/AnnotationFilter.Rd b/man/AnnotationFilter.Rd
index f7492d9..8508a18 100644
--- a/man/AnnotationFilter.Rd
+++ b/man/AnnotationFilter.Rd
@@ -63,38 +63,40 @@
 \alias{value}
 \alias{field,AnnotationFilter-method}
 \alias{field}
+\alias{not,AnnotationFilter-method}
 \alias{GRangesFilter-class}
 \alias{.GRangesFilter}
 \alias{GRangesFilter}
 \alias{feature}
 \alias{AnnotationFilter}
+\alias{convertFilter,AnnotationFilter,missing-method}
 \alias{supportedFilters,missing-method}
 \alias{AnnotationFilter}
 \title{Filters for annotation objects}
 \usage{
-CdsStartFilter(value, condition = "==")
-CdsEndFilter(value, condition = "==")
-ExonIdFilter(value, condition = "==")
-ExonNameFilter(value, condition = "==")
-ExonRankFilter(value, condition = "==")
-ExonStartFilter(value, condition = "==")
-ExonEndFilter(value, condition = "==")
-GeneIdFilter(value, condition = "==")
-GenenameFilter(value, condition = "==")
-GeneBiotypeFilter(value, condition = "==")
-GeneStartFilter(value, condition = "==")
-GeneEndFilter(value, condition = "==")
-EntrezFilter(value, condition = "==")
-SymbolFilter(value, condition = "==")
-TxIdFilter(value, condition = "==")
-TxNameFilter(value, condition = "==")
-TxBiotypeFilter(value, condition = "==")
-TxStartFilter(value, condition = "==")
-TxEndFilter(value, condition = "==")
-ProteinIdFilter(value, condition = "==")
-UniprotFilter(value, condition = "==")
-SeqNameFilter(value, condition = "==")
-SeqStrandFilter(value, condition = "==")
+CdsStartFilter(value, condition = "==", not = FALSE)
+CdsEndFilter(value, condition = "==", not = FALSE)
+ExonIdFilter(value, condition = "==", not = FALSE)
+ExonNameFilter(value, condition = "==", not = FALSE)
+ExonRankFilter(value, condition = "==", not = FALSE)
+ExonStartFilter(value, condition = "==", not = FALSE)
+ExonEndFilter(value, condition = "==", not = FALSE)
+GeneIdFilter(value, condition = "==", not = FALSE)
+GenenameFilter(value, condition = "==", not = FALSE)
+GeneBiotypeFilter(value, condition = "==", not = FALSE)
+GeneStartFilter(value, condition = "==", not = FALSE)
+GeneEndFilter(value, condition = "==", not = FALSE)
+EntrezFilter(value, condition = "==", not = FALSE)
+SymbolFilter(value, condition = "==", not = FALSE)
+TxIdFilter(value, condition = "==", not = FALSE)
+TxNameFilter(value, condition = "==", not = FALSE)
+TxBiotypeFilter(value, condition = "==", not = FALSE)
+TxStartFilter(value, condition = "==", not = FALSE)
+TxEndFilter(value, condition = "==", not = FALSE)
+ProteinIdFilter(value, condition = "==", not = FALSE)
+UniprotFilter(value, condition = "==", not = FALSE)
+SeqNameFilter(value, condition = "==", not = FALSE)
+SeqStrandFilter(value, condition = "==", not = FALSE)
 
 \S4method{condition}{AnnotationFilter}(object)
 
@@ -102,11 +104,15 @@ SeqStrandFilter(value, condition = "==")
 
 \S4method{field}{AnnotationFilter}(object)
 
+\S4method{not}{AnnotationFilter}(object)
+
 GRangesFilter(value, feature = "gene", type = c("any", "start", "end",
   "within", "equal"))
 
 feature(object)
 
+\S4method{convertFilter}{AnnotationFilter,missing}(object)
+
 \S4method{supportedFilters}{missing}(object)
 
 AnnotationFilter(expr)
@@ -133,14 +139,21 @@ class. See below for examples.}
 used in the filter. For \code{IntegerFilter}, one of
 \code{"=="}, \code{"!="}, \code{">"}, \code{"<"}, \code{">="}
 or \code{"<="}. For \code{CharacterFilter}, one of \code{"=="},
-\code{"!="}, \code{"startsWith"} or \code{"endsWith"}. Default
-condition is \code{"=="}.}
+\code{"!="}, \code{"startsWith"}, \code{"endsWith"} or \code{"contains"}.
+Default condition is \code{"=="}.}
+
+\item{not}{\code{logical(1)} whether the \code{AnnotationFilter} is negated.
+\code{TRUE} indicates is negated (!). \code{FALSE} indicates not
+negated. Default not is \code{FALSE}.}
 }
 \value{
 The constructor function return an object extending
     \code{AnnotationFilter}. For the return value of the other methods see
     the methods' descriptions.
 
+\code{character(1)} that can be used as input to a \code{dplyr} 
+     filter.
+
 \code{AnnotationFilter} returns an
     \code{\link{AnnotationFilter}} or an \code{\link{AnnotationFilterList}}.
 }
@@ -153,11 +166,12 @@ table column using the provided values and the defined condition.
 Filter instances created using the constructor functions (e.g.
 \code{GeneIdFilter}).
 
-\code{supportedFilters()} lists all defined filters. Packages using
-\code{AnnotationFilter} should implement the \code{supportedFilters} for
-their annotation resource object (e.g. for \code{object = "EnsDb"} in the
-\code{ensembldb} package) to list all supported filters for the specific
-resource.
+\code{supportedFilters()} lists all defined filters. It returns a two column
+\code{data.frame} with the filter class name and its default field.
+Packages using \code{AnnotationFilter} should implement the
+\code{supportedFilters} for their annotation resource object (e.g. for
+\code{object = "EnsDb"} in the \code{ensembldb} package) to list all
+supported filters for the specific resource.
 
 \code{condition()} get the \code{condition} value for
     the filter \code{object}.
@@ -168,15 +182,26 @@ resource.
 \code{field()} get the \code{field} for the filter
     \code{object}.
 
+\code{not()} get the \code{not} for the filter \code{object}.
+
 \code{feature()} get the \code{feature} for the
     \code{GRangesFilter} \code{object}.
 
+Converts an \code{AnnotationFilter} object to a 
+     \code{character(1)} giving an equation that can be used as input to
+     a \code{dplyr} filter.
+
 \code{AnnotationFilter} \emph{translates} a filter
     expression such as \code{~ gene_id == "BCL2"} into a filter object
     extending the \code{\link{AnnotationFilter}} class (in the example a
     \code{\link{GeneIdFilter}} object) or an
     \code{\link{AnnotationFilterList}} if the expression contains multiple
-    conditions (see examples below).
+    conditions (see examples below). Filter expressions have to be written
+    in the form \code{~ <field> <condition> <value>}, with \code{<field>}
+    being the default field of the filter class (use the
+    \code{supportedFilter} function to list all fields and filter classes),
+    \code{<condition>} the logical expression and \code{<value>} the value
+    for the filter.
 }
 \details{
 By default filters are only available for tables containing the
@@ -205,6 +230,9 @@ sf
 gsf <- GeneStartFilter(10000, condition = ">")
 gsf
 
+filter <- SymbolFilter("ADA", "==")
+result <- convertFilter(filter)
+result
 supportedFilters()
 
 ## Convert a filter expression based on a gene ID to a GeneIdFilter
diff --git a/man/AnnotationFilterList.Rd b/man/AnnotationFilterList.Rd
index 0f95296..17b3cd6 100644
--- a/man/AnnotationFilterList.Rd
+++ b/man/AnnotationFilterList.Rd
@@ -6,13 +6,31 @@
 \alias{AnnotationFilterList-class}
 \alias{AnnotationFilterList}
 \alias{value,AnnotationFilterList-method}
+\alias{logicOp,AnnotationFilterList-method}
+\alias{logicOp}
+\alias{not,AnnotationFilterList-method}
+\alias{not}
+\alias{distributeNegation,AnnotationFilterList-method}
+\alias{distributeNegation}
+\alias{convertFilter,AnnotationFilterList,missing-method}
+\alias{convertFilter}
 \alias{show,AnnotationFilterList-method}
 \title{Combining annotation filters}
 \usage{
-AnnotationFilterList(..., logOp = character())
+AnnotationFilterList(..., logicOp = character(), logOp = character(),
+  not = FALSE, .groupingFlag = FALSE)
 
 \S4method{value}{AnnotationFilterList}(object)
 
+\S4method{logicOp}{AnnotationFilterList}(object)
+
+\S4method{not}{AnnotationFilterList}(object)
+
+\S4method{distributeNegation}{AnnotationFilterList}(object,
+  .prior_negation = FALSE)
+
+\S4method{convertFilter}{AnnotationFilterList,missing}(object)
+
 \S4method{show}{AnnotationFilterList}(object)
 }
 \arguments{
@@ -20,8 +38,8 @@ AnnotationFilterList(..., logOp = character())
 mixture of \code{AnnotationFilter} and
 \code{AnnotationFilterList} objects.}
 
-\item{logOp}{\code{character} of length being equal to the numner
-of submitted \code{AnnotationFilter} objects -1. Each value
+\item{logicOp}{\code{character} of length equal to the number
+of submitted \code{AnnotationFilter} objects - 1. Each value
 representing the logical operation to combine consecutive
 filters, i.e. the first element being the logical operation to
 combine the first and second \code{AnnotationFilter}, the
@@ -30,13 +48,37 @@ second and third \code{AnnotationFilter} and so on. Allowed
 values are \code{"&"} and \code{"|"}. The function assumes a
 logical \emph{and} between all elements by default.}
 
+\item{logOp}{Deprecated; use \code{logicOp=}.}
+
+\item{not}{\code{logical} of length one. Indicates whether the grouping
+of \code{AnnotationFilters} are to be negated.}
+
+\item{.groupingFlag}{Flag desginated for internal use only.}
+
 \item{object}{An object of class \code{AnnotationFilterList}.}
+
+\item{.prior_negation}{\code{logical(1)} unused argument.}
 }
 \value{
 \code{AnnotationFilterList} returns an \code{AnnotationFilterList}.
 
-\code{value} returns a \code{list} with \code{AnnotationFilter}
+\code{value()} returns a \code{list} with \code{AnnotationFilter}
     objects.
+
+\code{logicOp()} returns a \code{character()} vector of
+    \dQuote{&} or \dQuote{|} symbols.
+
+\code{not()} returns a \code{character()} vector of
+    \dQuote{&} or \dQuote{|} symbols.
+
+\code{AnnotationFilterList} object with DeMorgan's law applied to
+     it such that it is equal to the original \code{AnnotationFilterList}
+     object but all \code{!}'s are distributed out of the
+     \code{AnnotationFilterList} object and to the nested
+     \code{AnnotationFilter} objects.
+
+\code{character(1)} that can be used as input to a \code{dplyr}
+     filter.
 }
 \description{
 The \code{AnnotationFilterList} allows to combine
@@ -50,6 +92,23 @@ The \code{AnnotationFilterList} allows to combine
 \code{value()} get a \code{list} with the
     \code{AnnotationFilter} objects. Use \code{[[} to access
     individual filters.
+
+\code{logicOp()} gets the logical operators separating
+    successive \code{AnnotationFilter}.
+
+\code{not()} gets the logical operators separating
+    successive \code{AnnotationFilter}.
+
+
+
+Converts an \code{AnnotationFilterList} object to a
+     \code{character(1)} giving an equation that can be used as input to
+     a \code{dplyr} filter.
+}
+\note{
+The \code{AnnotationFilterList} does not support containing empty
+    elements, hence all elements of \code{length == 0} are removed in
+    the constructor function.
 }
 \examples{
 ## Create some AnnotationFilters
@@ -72,9 +131,15 @@ afl[[1]]
 ## also found by the previous AnnotationFilterList and returns also all
 ## features on chromosome Y.
 afl <- AnnotationFilterList(gf, tbtf, SeqNameFilter("Y"),
-                            logOp = c("&", "|"))
+                            logicOp = c("&", "|"))
 afl
 
+afl <- AnnotationFilter(~!(symbol == 'ADA' | symbol \%startsWith\% 'SNORD'))
+afl <- distributeNegation(afl)
+afl
+afl <- AnnotationFilter(~symbol=="ADA" & tx_start > "400000")
+result <- convertFilter(afl)
+result
 }
 \seealso{
 \code{\link{supportedFilters}} for available
diff --git a/tests/testthat/test_AnnotationFilter.R b/tests/testthat/test_AnnotationFilter.R
index 400cac8..a159575 100644
--- a/tests/testthat/test_AnnotationFilter.R
+++ b/tests/testthat/test_AnnotationFilter.R
@@ -1,10 +1,11 @@
 context("AnnotationFilter")
 
 test_that("supportedFilters() works", {
-    expect_true(inherits(supportedFilters(), "character"))
+    expect_true(inherits(supportedFilters(), "data.frame"))
     expect_identical(
-        length(supportedFilters()),
-        length(unlist(AnnotationFilter:::.FIELD, use.names=FALSE)) + 1L
+        nrow(supportedFilters()),
+        length(unlist(AnnotationFilter:::.FIELD, use.names=FALSE)) +
+            length(AnnotationFilter:::.FILTERS_WO_FIELD)
     )
 })
 
@@ -73,3 +74,51 @@ test_that("fieldToClass works", {
     expect_identical(AnnotationFilter:::.fieldToClass("gene_seq_start"),
                      "GeneSeqStartFilter")
 })
+
+test_that("convertFilter Works", {
+    expect_identical(convertFilter(SymbolFilter("ADA")), "symbol == 'ADA'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "!=")),
+        "symbol != 'ADA'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "startsWith")),
+        "symbol %like% 'ADA%'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "endsWith")),
+        "symbol %like% '%ADA'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "contains")),
+        "symbol %like% 'ADA'")
+    
+    expect_identical(convertFilter(TxStartFilter(1000)), "tx_start == '1000'")
+    expect_identical(convertFilter(TxStartFilter(1000, "!=")),
+        "tx_start != '1000'")
+    expect_identical(convertFilter(TxStartFilter(1000, ">")), "tx_start > 1000")
+    expect_identical(convertFilter(TxStartFilter(1000, "<")), "tx_start < 1000")
+    expect_identical(convertFilter(TxStartFilter(1000, ">=")),
+        "tx_start >= 1000")
+    expect_identical(convertFilter(TxStartFilter(1000, "<=")),
+        "tx_start <= 1000")
+
+    ## check NOT works    
+
+    expect_identical(convertFilter(SymbolFilter("ADA", not=TRUE)),
+        "!symbol == 'ADA'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "!=", not=TRUE)),
+        "!symbol != 'ADA'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "startsWith", not=TRUE)),
+        "!symbol %like% 'ADA%'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "endsWith", not=TRUE)),
+        "!symbol %like% '%ADA'")
+    expect_identical(convertFilter(SymbolFilter("ADA", "contains", not=TRUE)),
+        "!symbol %like% 'ADA'")
+    
+    expect_identical(convertFilter(TxStartFilter(1000, not=TRUE)),
+        "!tx_start == '1000'")
+    expect_identical(convertFilter(TxStartFilter(1000, "!=", not=TRUE)),
+        "!tx_start != '1000'")
+    expect_identical(convertFilter(TxStartFilter(1000, ">", not=TRUE)),
+        "!tx_start > 1000")
+    expect_identical(convertFilter(TxStartFilter(1000, "<", not=TRUE)),
+        "!tx_start < 1000")
+    expect_identical(convertFilter(TxStartFilter(1000, ">=", not=TRUE)),
+        "!tx_start >= 1000")
+    expect_identical(convertFilter(TxStartFilter(1000, "<=", not=TRUE)),
+        "!tx_start <= 1000")
+})
diff --git a/tests/testthat/test_AnnotationFilterList.R b/tests/testthat/test_AnnotationFilterList.R
index c56c904..732a65d 100644
--- a/tests/testthat/test_AnnotationFilterList.R
+++ b/tests/testthat/test_AnnotationFilterList.R
@@ -1,7 +1,6 @@
 context("AnnotationFilterList")
 
 test_that("AnnotationFilterList() works", {
-    logOp <- AnnotationFilter:::.logOp
     f1 <- GeneIdFilter("somegene")
     f2 <- SeqNameFilter("chr3")
     f3 <- GeneBiotypeFilter("protein_coding", "!=")
@@ -10,27 +9,27 @@ test_that("AnnotationFilterList() works", {
     expect_true(length(fL) == 2)
     expect_equal(fL[[1]], f1)
     expect_equal(fL[[2]], f2)
-    expect_true(all(logOp(fL) == "&"))
+    expect_true(all(logicOp(fL) == "&"))
     
     fL <- AnnotationFilter:::AnnotationFilterList(f1, f2, f3,
-                                                  logOp = c("&", "|"))
+                                                  logicOp = c("&", "|"))
     expect_true(length(fL) == 3)
     expect_equal(fL[[1]], f1)
     expect_equal(fL[[2]], f2)
     expect_equal(fL[[3]], f3)
-    expect_equal(fL at logOp, c("&", "|"))
+    expect_equal(logicOp(fL), c("&", "|"))
 
     ## A AnnotationFilterList with and AnnotationFilterList
-    fL <- AnnotationFilter:::AnnotationFilterList(f1, f2, logOp = "|")
-    fL2 <- AnnotationFilter:::AnnotationFilterList(f3, fL, logOp = "&")
+    fL <- AnnotationFilter:::AnnotationFilterList(f1, f2, logicOp = "|")
+    fL2 <- AnnotationFilter:::AnnotationFilterList(f3, fL, logicOp = "&")
     expect_true(length(fL) == 2)
     expect_true(length(fL2) == 2)
     expect_true(is(value(fL2)[[1]], "GeneBiotypeFilter"))
     expect_true(is(value(fL2)[[2]], "AnnotationFilterList"))
     expect_equal(value(fL2)[[2]], fL)
     expect_equal(fL2[[2]], fL)
-    expect_equal(logOp(fL2), c("&"))
-    expect_equal(logOp(fL2[[2]]), c("|"))
+    expect_equal(logicOp(fL2), "&")
+    expect_equal(logicOp(fL2[[2]]), "|")
 })
 
 test_that("empty elements in AnnotationFilterList", {
@@ -41,8 +40,7 @@ test_that("empty elements in AnnotationFilterList", {
     afl <- AnnotationFilterList(GeneIdFilter(4), empty_afl)
     expect_true(length(afl) == 1)
     afl <- AnnotationFilterList(GeneIdFilter(4),
-                                AnnotationFilter(~ gene_id == 3 | seq_name == 4),
-                                empty_afl)
+        AnnotationFilter(~ gene_id == 3 | seq_name == 4),empty_afl)
     expect_true(length(afl) == 2)
     ## Check validate.
     afl at .Data <- c(afl at .Data, list(empty_afl))
@@ -50,3 +48,24 @@ test_that("empty elements in AnnotationFilterList", {
     afl at logOp <- c(afl at logOp, "|")
     expect_error(validObject(afl))
 })
+
+test_that("convertFilter works", {
+    smbl <- SymbolFilter("ADA")
+    txid <- TxIdFilter(1000)
+    gr <- GRangesFilter(GenomicRanges::GRanges("chr15:25062333-25065121"))
+
+    expect_identical(convertFilter(AnnotationFilter(~smbl | txid)),
+        "symbol == 'ADA' | tx_id == '1000'")
+    expect_identical(convertFilter(AnnotationFilter(~smbl & (smbl | txid))),
+        "symbol == 'ADA' & (symbol == 'ADA' | tx_id == '1000')")
+    expect_identical(convertFilter(AnnotationFilter(~smbl & !(smbl | txid))),
+        "symbol == 'ADA' & !(symbol == 'ADA' | tx_id == '1000')")
+    expect_error(convertFilter(AnnotationFilter(smbl | (txid & gr))))
+    
+})
+
+test_that("distributeNegation works", {
+    afl <- AnnotationFilter(~!(symbol == 'ADA' | symbol %startsWith% 'SNORD'))
+    afl2 <- AnnotationFilter(~!symbol == 'ADA' & !symbol %startsWith% 'SNORD')
+    expect_identical(distributeNegation(afl), afl2)
+})
diff --git a/tests/testthat/test_translate-utils.R b/tests/testthat/test_translate-utils.R
index 0fd31c0..248be96 100644
--- a/tests/testthat/test_translate-utils.R
+++ b/tests/testthat/test_translate-utils.R
@@ -41,7 +41,7 @@ test_that("translation of combined expressions works", {
     expect_equal(res, cmp)
     res <- AnnotationFilter(~ exon_id == "EX1" | genename != "BCL2")
     cmp <- AnnotationFilterList(ExonIdFilter("EX1"),
-                                GenenameFilter("BCL2", "!="), logOp = "|")
+                                GenenameFilter("BCL2", "!="), logicOp = "|")
     expect_equal(res, cmp)
     ## 3 filters.
     res <- AnnotationFilter(~ exon_id == "EX1" & genename == "BCL2" |
@@ -49,7 +49,7 @@ test_that("translation of combined expressions works", {
     ## Expect an AnnotationFilterList of length 3.
     expect_equal(length(res), 3)
     cmp <- AnnotationFilterList(ExonIdFilter("EX1"), GenenameFilter("BCL2"),
-                                SeqNameFilter(3, "!="), logOp = c("&", "|"))
+                                SeqNameFilter(3, "!="), logicOp = c("&", "|"))
     expect_equal(res, cmp)
     ## 4 filters.
     res <- AnnotationFilter(~ exon_id == "EX1" & genename == "BCL2" |
@@ -57,7 +57,7 @@ test_that("translation of combined expressions works", {
     expect_equal(length(res), 4)
     cmp <- AnnotationFilterList(ExonIdFilter("EX1"), GenenameFilter("BCL2"),
                                 SeqNameFilter(3, "!="), SeqNameFilter("Y"),
-                                logOp = c("&", "|",  "|"))
+                                logicOp = c("&", "|",  "|"))
     expect_equal(res, cmp)
 })
 
@@ -74,15 +74,15 @@ test_that("translation works from within other functions", {
 ## test_that("translation of nested expressions works" {
 ##     res <- convertFilterExpression((exon_id == "EX1" & gene_id == "BCL2") |
 ##                                    (exon_id == "EX3" & gene_id == "BCL2L11"))
-##     expect_equal(logOp(res), "|")
+##     expect_equal(logicOp(res), "|")
 ##     expect_true(is(res[[1]], "AnnotationFilterList"))
 ##     expect_equal(res[[1]][[1]], ExonIdFilter("EX1"))
 ##     expect_equal(res[[1]][[2]], GeneIdFilter("BCL2"))
-##     expect_equal(logOp(res[[1]]), "&")
+##     expect_equal(logicOp(res[[1]]), "&")
 ##     expect_true(is(res[[2]], "AnnotationFilterList"))
 ##     expect_equal(res[[2]][[1]], ExonIdFilter("EX3"))
 ##     expect_equal(res[[2]][[2]], GeneIdFilter("BCL2L11"))
-##     expect_equal(logOp(res[[2]]), "&")
+##     expect_equal(logicOp(res[[2]]), "&")
 ##     ##
 ##     res <- convertFilterExpression(seq_name == "Y" |
 ##                                    (exon_id == "EX1" & gene_id == "BCL2") &
@@ -90,15 +90,15 @@ test_that("translation works from within other functions", {
 ##     ## Expect: length 3, first being a SeqNameFilter, second an
 ##     ## AnnotationFilterList, third a AnnotationFilterList.
 ##     expect_equal(res[[1]], SeqNameFilter("Y"))
-##     expect_equal(logOp(res), "|")
+##     expect_equal(logicOp(res), "|")
 ##     expect_true(is(res[[2]], "AnnotationFilterList"))
 ##     expect_equal(res[[1]][[1]], ExonIdFilter("EX1"))
 ##     expect_equal(res[[1]][[2]], GeneIdFilter("BCL2"))
-##     expect_equal(logOp(res[[1]]), "&")
+##     expect_equal(logicOp(res[[1]]), "&")
 ##     expect_true(is(res[[2]], "AnnotationFilterList"))
 ##     expect_equal(res[[2]][[1]], ExonIdFilter("EX3"))
 ##     expect_equal(res[[2]][[2]], GeneIdFilter("BCL2L11"))
-##     expect_equal(logOp(res[[2]]), "&")
+##     expect_equal(logicOp(res[[2]]), "&")
 
 ##     expect_true(is(res[[1]], "AnnotationFilterList"))
 ##     expect_true(is(res[[2]], "AnnotationFilterList"))
diff --git a/vignettes/AnnotationFilter.Rmd b/vignettes/AnnotationFilter.Rmd
index 0dddd45..446e81b 100644
--- a/vignettes/AnnotationFilter.Rmd
+++ b/vignettes/AnnotationFilter.Rmd
@@ -134,9 +134,9 @@ smbl
 
 Individual `AnnotationFilter` objects can be combined in an
 `AnnotationFilterList`. This class extends `list` and provides an additional
-`logOp` slot that defines how its individual filters are supposed to be
-combined. The length of `logOp` has to be 1 less than the number of filter
-objects. Each element in `logOp` defines how two consecutive filters should
+`logicOp()` that defines how its individual filters are supposed to be
+combined. The length of `logicOp()` has to be 1 less than the number of filter
+objects. Each element in `logicOp()` defines how two consecutive filters should
 be combined. Below we create a `AnnotationFilterList` containing two filter
 objects to be combined with a logical *AND*.
 
@@ -160,7 +160,7 @@ afl1 <- AnnotationFilterList(SymbolFilter("BCL2L11"),
 afl2 <- AnnotationFilterList(SymbolFilter("BCL2"),
                              TxBiotypeFilter("protein_coding"))
 ## Now combine both with a logical OR
-afl <- AnnotationFilterList(afl1, afl2, logOp = "|")
+afl <- AnnotationFilterList(afl1, afl2, logicOp = "|")
 
 afl
 ```

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-bioc-annotationfilter.git



More information about the debian-med-commit mailing list