From d0d846f92a2d3fdaeca7757d032acb05fbb27d0c Mon Sep 17 00:00:00 2001 From: Stuart Lee Date: Thu, 5 Dec 2019 10:32:30 +1100 Subject: [PATCH] beginning refactor of nse semantics for #74 --- R/nse.R | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 R/nse.R diff --git a/R/nse.R b/R/nse.R new file mode 100644 index 0000000..7534672 --- /dev/null +++ b/R/nse.R @@ -0,0 +1,45 @@ +#' Create a data mask rectangular data structures in Bioconductor +#' +#' @description Tidy evaluation for rectangular +#' data structures in Bioconductor. +#' @details This is the backend for non-standard evaluation +#' in `plyranges` and is used to provide semantics for non-standard +#' evaluation used throughout the grammar. Generally, +#' you will not need to interact with this function directly, +#' but it can be useful if you're planning on extending +#' `plyranges` functionality. +#' +#' @seealso [rlang::new_data_mask()], [rlang::eval_tidy()] +bc_data_mask <- function(data) { + # extract the namespace of the class + pkg_scope <- rlang::pkg_env(packageSlot(class(data))) + + # place the generics at the top of the mask + top <- bioc_generics() + top <- rlang::new_environment(top) + # enclose the mcols as middle + mcols_names <- names(mcols(data)) + mcols_fn <- lapply(mcols_names, + function(nm) { + function() mcols(data)[[nm]] + }) + names(mcols_fn) <- mcols_names + + mid <- rlang::env(top) + rlang::env_bind_active(mid, !!!mcols_fn) + # bottom is the vector + vec_names <- parallelVectorNames(data) + vec_fn <- lapply(vec_names, + function(nm) { + getter <- rlang::env_get(pkg_scope, nm) + function() getter(data) + }) + names(vec_fn) <- vec_names + bottom <- rlang::env(mid) + rlang::env_bind_active(bottom, !!!vec_fn) + + mask <- rlang::new_data_mask(bottom, top = top) + mask$.data <- rlang::as_data_pronoun(mask) + mask +} +