Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

datanames in vignettes #239

Merged
merged 22 commits into from
Jan 7, 2025
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 17 additions & 2 deletions R/qenv-constructor.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,23 @@
#'
#' @details
#'
#' `qenv()` instantiates a `qenv` with an empty environment.
#' Any changes must be made by evaluating code in it with `eval_code` or `within`, thereby ensuring reproducibility.
#' `qenv()` instantiates a with an empty `qenv` environment.
#'
#' @section `qenv` characteristics:
#'
#' A `qenv` inherits from the `environment` class, behaves like an environment, and has the
#' following characteristics:
#'
#' - `qenv` environment is locked, and data modification is only possible through the `eval_code()`
#' and `within()` functions.
#' - It stores metadata about the code used to create the data.
#' - Is immutable which means that each code evaluation does not modify the original `qenv`
#' environment directly. See the following code:
#' ```
averissimo marked this conversation as resolved.
Show resolved Hide resolved
#' q1 <- qenv()
#' q2 <- eval_code(q1, "a <- 1")
#' identical(q1, q2) # FALSE
#' ```
#'
#' @name qenv
#'
Expand Down
7 changes: 6 additions & 1 deletion R/qenv-eval_code.R
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
#' Evaluate code in `qenv`
#'
#' @details
#'
#' `eval_code()` evaluates given code in the `qenv` environment and appends it to the `code` slot.
#' Thus, if the `qenv` had been instantiated empty, contents of the environment are always a result of the stored code.
#' The `qenv` object is immutable, even though it inherits from the environment class, which is typically mutable by
#' design. This means that each code evaluation does not modify the original `qenv` object directly. Instead, every
#' code evaluation creates a new `qenv` object that reflects the result of the changes, leaving the original object
#' unchanged.
#'
#' @param object (`qenv`)
averissimo marked this conversation as resolved.
Show resolved Hide resolved
#' @param code (`character`, `language` or `expression`) code to evaluate.
#' It is possible to preserve original formatting of the `code` by providing a `character` or an
#' `expression` being a result of `parse(keep.source = TRUE)`.
#'
#' @return
#' `eval_code` returns a `qenv` object with `expr` evaluated or `qenv.error` if evaluation fails.
#' `eval_code` and `within` returns a `qenv` object with `expr` evaluated or `qenv.error` if evaluation fails.
#'
#' @examples
#' # evaluate code in qenv
Expand Down
5 changes: 3 additions & 2 deletions R/qenv-extract.R
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#'
#' @section Subsetting:
#' `x[names]` subsets objects in `qenv` environment and limit the code to the necessary needed to build limited objects.
#' @section Subsetting by the `names`:
#'
#' `x[names]` subsets `qenv` environment and limits the code to the necessary needed to build limited objects.
#' `...` passes parameters to further methods.
#'
#' @param x (`qenv`)
Expand Down
5 changes: 3 additions & 2 deletions R/qenv-get_code.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ NULL
#' @param ... see `Details`
#'
#'
#' @section Extracting dataset-specific code:
#' When `names` for `get_code` is specified, the code returned will be limited to the lines needed to _create_
#' @section Subsetting by the `names`:
#'
#' `get_code(x, names)` limits the returned code to contain only those lines needed to _create_
#' the requested objects. The code stored in the `qenv` is analyzed statically to determine
#' which lines the objects of interest depend upon. The analysis works well when objects are created
#' with standard infix assignment operators (see `?assignOps`) but it can fail in some situations.
Expand Down
38 changes: 30 additions & 8 deletions man/qenv.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 11 additions & 9 deletions vignettes/qenv.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ vignette: >

## Introduction to `qenv`

A `qenv` is an R object which contains code and an environment and can be used to create reproducible outputs.
A `qenv` inherits from the `environment` class, behaves like an environment, and has the following characteristics:

- The environment is locked, and data modification is only possible through the `eval_code()` and `within()` functions.
- It stores metadata about the code used to create the data.
- Is immutable which means that each code evaluation does not modify the original `qenv` object directly.

### Initialization

Expand All @@ -26,14 +30,12 @@ print(empty_qenv)

### `qenv` basic usage

The `eval_code()` function executes code within a `qenv` environment, yielding a new `qenv` object as the output.
To modify the data use `eval_code` to execute R code within the environment, yielding a new `qenv` object as the output.

```{r}
# evaluate code in qenv
my_qenv <- eval_code(empty_qenv, "x <- 2")
print(my_qenv)
as.environment(my_qenv)


q1 <- eval_code(my_qenv, "y <- x * 2")
q1 <- eval_code(q1, "z <- y * 2")
Expand All @@ -47,16 +49,14 @@ print(q1)
names(q1)
```

The same result can be achieved with the `within` method for the `qenv` class.
The same result can be achieved with the `within` method.

```{r}
q2 <- within(my_qenv, y <- x * 2)
q2 <- within(q2, z <- y * 2)
print(q2)
```




To extract objects from a `qenv`, use `[[`; this is particularly useful for displaying them in a `shiny` app. You can retrieve the code used to generate the `qenv` using the `get_code()` function.

```{r}
Expand All @@ -66,8 +66,10 @@ cat(get_code(q2))
```

### Substitutions

In some cases, one may want to substitute some elements of the code before evaluation.
Consider a case when a subset of `iris` is defined by an input value.

```{r}
q <- qenv()
q <- eval_code(q, quote(i <- subset(iris, Species == "setosa")))
Expand All @@ -87,6 +89,7 @@ summary(q[["iii"]]$Species)
```

A more convenient way to pass code with substitution is to use the `within` method.

```{r}
qq <- qenv()
qq <- within(qq, i <- subset(iris, Species == "setosa"))
Expand All @@ -101,7 +104,6 @@ summary(qq[["iii"]]$Species)

See `?qenv` for more details.


### Combining `qenv` objects

Given a pair of `qenv` objects, you may be able to "join" them, creating a new `qenv` object encompassing the union of both environments, along with the requisite code for reproduction:
Expand Down
2 changes: 0 additions & 2 deletions vignettes/teal-code.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,3 @@ In this context, the `qenv` object within the `teal.code` package emerges as a p
It's worth noting that there exists a public [`shinymeta`](https://github.com/rstudio/shinymeta) R package by `RStudio`, offering similar functionality. However, integrating `shinymeta` into `teal` modules poses challenges. Consequently, we recommend the use of `qenv` for teal-based applications.

For comprehensive insights, please refer to the [`qenv` vignette](https://insightsengineering.github.io/teal.code/latest-tag/articles/qenv.html).

Important Note: The legacy approach to handling reproducibility, known as `chunks`, has been deprecated. We strongly advocate for the adoption of `qenv` as its successor.
Loading