Skip to content

Commit

Permalink
feat: initial support for names(teal_data)
Browse files Browse the repository at this point in the history
  • Loading branch information
averissimo committed Oct 28, 2024
1 parent eca9695 commit eb24644
Show file tree
Hide file tree
Showing 17 changed files with 234 additions and 202 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ Collate:
'join_keys.R'
'teal.data.R'
'teal_data-class.R'
'teal_data-datanames.R'
'teal_data-get_code.R'
'teal_data-names.R'
'teal_data-show.R'
'teal_data.R'
'testhat-helpers.R'
Expand Down
3 changes: 2 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@ S3method(format,join_keys)
S3method(join_keys,default)
S3method(join_keys,join_keys)
S3method(join_keys,teal_data)
S3method(names,"teal_data<-")
S3method(names,teal_data)
S3method(parents,join_keys)
S3method(parents,teal_data)
S3method(print,join_keys)
export("col_labels<-")
export("datanames<-")
export("get_join_keys<-")
export("join_keys<-")
export("parents<-")
Expand Down
10 changes: 6 additions & 4 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
### Breaking changes

- soft deprecate `datanames` argument of `get_code()`. Use `names` instead.
- Soft deprecate of `datanames()` and `datanames(x) <- value` functions.
Use `names()` and `names(x) <- value` instead.

### Enhancements

- `datanames()`
- if `join_keys` are provided, the `datanames()` are now sorted in topological way (`Kahn` algorithm),
- `names()` function is introduced replacing `datanames`.
- if `join_keys` are provided, the `names()` are now sorted in topological way (`Kahn` algorithm),
which means the parent dataset always precedes the child dataset.
- are extended by the parent dataset name, if one of the child dataset exist in `datanames()` and
- are extended by the parent dataset name, if one of the child dataset exist in `names()` and
the connection between child-parent is set through `join_keys` and `parent` exist in `teal_data` environment.
- do not allow to set a dataset name that do not exist in `teal_data` environment.
- `teal_data` no longer set default `datanames()` based on `join_keys` names - it uses only data names.
- `teal_data` no longer set default `names()` based on `join_keys` names - it uses only data names.

### Miscellaneous

Expand Down
35 changes: 35 additions & 0 deletions R/deprecated.R
Original file line number Diff line number Diff line change
Expand Up @@ -343,3 +343,38 @@ get_join_keys <- function(...) {
get_labels <- function(...) {
.deprecate_function("get_labels()", "Use col_labels(data)")
}

#' Names of data sets in `teal_data` object
#'
#' @description
#' `r lifecycle::badge("deprecated")`
#'
#' Use `names()` instead of `datanames()`.
#'
#' `datanames()` is deprecated. If object should be hidden, then use a `.` (dot)
#' prefix for the object's name.
#'
#' @param x (`teal_data` or `qenv_error`) object to access or modify
#' @param ... (`character`) new value for `@datanames`; all elements must be names of variables existing in `@env`
#'
#' @return The contents of `@datanames` or `teal_data` object with updated `@datanames`.
#'
#'
#' @name datanames

#' @rdname datanames
#' @export
datanames <- function(x, ...) {
lifecycle::deprecate_soft("0.6.1", "datanames()", details = "names()")
names(x)
}

#' @rdname datanames
`datanames<-` <- function(x, value, ...) {
lifecycle::deprecate_soft(
"0.6.1",
"`datanames<-`()",
details = "Function has no effect. Use a `.` (dot) prefix to hide objects instead in `teal_data`. See the documentation for more details."
)
names(x)
}
1 change: 0 additions & 1 deletion R/join_keys.R
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ join_keys.teal_data <- function(...) {
#' join_keys(td)
`join_keys<-.teal_data` <- function(x, value) {
join_keys(x@join_keys) <- value
datanames(x) <- x@datanames # datanames fun manages some exceptions
x
}

Expand Down
16 changes: 2 additions & 14 deletions R/teal_data-class.R
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ setOldClass("join_keys")
#' @slot messages (`character`) vector of messages raised when evaluating code.
#' @slot join_keys (`join_keys`) object specifying joining keys for data sets in `@env`.
#' Access or modify with [join_keys()].
#' @slot datanames (`character`) vector of names of data sets in `@env`.
#' Used internally to distinguish them from auxiliary variables.
#' Access or modify with [datanames()].
#' @slot verified (`logical(1)`) flag signifying that code in `@code` has been proven to yield contents of `@env`.
#' Used internally. See [`verify()`] for more details.
#'
Expand All @@ -37,10 +34,9 @@ setOldClass("join_keys")
setClass(
Class = "teal_data",
contains = "qenv",
slots = c(join_keys = "join_keys", datanames = "character", verified = "logical"),
slots = c(join_keys = "join_keys", verified = "logical"),
prototype = list(
join_keys = join_keys(),
datanames = character(0),
verified = logical(0)
)
)
Expand All @@ -53,18 +49,13 @@ setClass(
#' @param code (`character` or `language`) code to reproduce the `data`.
#' Accepts and stores comments also.
#' @param join_keys (`join_keys`) object
#' @param datanames (`character`) names of datasets passed to `data`.
#' Needed when non-dataset objects are needed in the `env` slot.
#' @rdname new_teal_data
#' @keywords internal
new_teal_data <- function(data,
code = character(0),
join_keys = join_keys(),
datanames = names(data)) {
join_keys = join_keys()) {
checkmate::assert_list(data)
checkmate::assert_class(join_keys, "join_keys")
if (is.null(datanames)) datanames <- character(0) # todo: allow to specify
checkmate::assert_character(datanames)
if (!any(is.language(code), is.character(code))) {
stop("`code` must be a character or language object.")
}
Expand All @@ -82,8 +73,6 @@ new_teal_data <- function(data,
new_env <- rlang::env_clone(list2env(data), parent = parent.env(.GlobalEnv))
lockEnvironment(new_env, bindings = TRUE)

datanames <- .get_sorted_datanames(datanames = datanames, join_keys = join_keys, env = new_env)

methods::new(
"teal_data",
env = new_env,
Expand All @@ -92,7 +81,6 @@ new_teal_data <- function(data,
messages = rep("", length(code)),
id = id,
join_keys = join_keys,
datanames = datanames,
verified = verified
)
}
68 changes: 0 additions & 68 deletions R/teal_data-datanames.R

This file was deleted.

53 changes: 53 additions & 0 deletions R/teal_data-names.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#' Names of data sets in `teal_data` object
#'
#' Functions to get the names of a `teal_data` object.
#' The names are extrapolated from the objects in the `qenv` environment and
#' are not stored statically, unlike the normal behavior of `names()` function.
#'
#' Objects named with a `.` (dot) prefix will be ignored and not returned,
#' unless `all.names` parameter is set to `TRUE`.
#'
#' @param x A (`teal_data`) object to access or modify.
#' @param all.names (`logical(1)`) that specifies whether to include hidden
#' objects.
#' @param value Does nothing as the names assignment is not supported.
#'
#' @return A character vector of names.
#'
#' @examples
#' td <- teal_data(iris = iris)
#' td <- within(td, mtcars <- mtcars)
#' names(td)
#'
#' td <- within(td, .CO2 <- CO2)
#' names(td)
#'
#' @export
names.teal_data <- function(x, all.names = FALSE) {
checkmate::assert_flag(all.names)
# Call method on qenv class
names_x <- utils::getS3method("names", class = "qenv")(x, all.names)
.get_sorted_names(names_x, join_keys(x), teal.code::get_env(x))
}

#' @rdname names.teal_data
#' @export
`names.teal_data<-` <- function(x, value) {
warning("`names(x) <- value` assignment does nothing for teal_data objects")
x
}

#' @keywords internal
.get_sorted_names <- function(datanames, join_keys, env) {
child_parent <- sapply(
datanames,
function(name) parent(join_keys, name),
USE.NAMES = TRUE,
simplify = FALSE
)

union(
intersect(unlist(topological_sort(child_parent)), ls(env, all.names = TRUE)),
datanames
)
}
33 changes: 9 additions & 24 deletions man/datanames.Rd

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

40 changes: 40 additions & 0 deletions man/names.teal_data.Rd

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

10 changes: 1 addition & 9 deletions man/new_teal_data.Rd

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

Loading

0 comments on commit eb24644

Please sign in to comment.