Skip to content

Incorporate resolve_delayed_datasets into resolve_delayed #255

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

Open
wants to merge 31 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
5146352
add delayed_datasets
chlebowa Feb 6, 2025
c7ca7c2
recognize delayed_datasets in get_extract_datanames
chlebowa Feb 6, 2025
9ae2204
resolve delayed_datasets in data_extract_multiple_srv
chlebowa Feb 6, 2025
389dce6
add .integrate stage in resolve_delayed_datasets
chlebowa Feb 7, 2025
b2b7e31
add unit tests for delayed_datasets
chlebowa Feb 10, 2025
6616eab
rewrite data_extract_module to create entire UI server side
chlebowa Feb 12, 2025
9f2622a
style and comment code
chlebowa Feb 12, 2025
e93f644
check data_extract_specs upon creation
chlebowa Feb 12, 2025
2fec9aa
more explicit argument checks in data_extract_spec
chlebowa Feb 12, 2025
97413b8
amend documentation
chlebowa Feb 12, 2025
69b6de0
amend NEWS
chlebowa Feb 12, 2025
2c22756
fix bug in assert_delayed_datasets
chlebowa Feb 12, 2025
cb5e366
remove parital matching b/c of testthat complaints
chlebowa Feb 12, 2025
78580ea
add tests for data_extract_spec constructor with delayed_datasets
chlebowa Feb 12, 2025
3308e76
clean up
chlebowa Feb 12, 2025
a4bb6da
update conditions in resolve_delayed_datasets to include non-delayed des
chlebowa Feb 12, 2025
06c34ea
restyle to NEST standard
chlebowa Feb 13, 2025
4e774d0
rename delayed_datasets to delayed_datanames
chlebowa Feb 17, 2025
a068f7d
move resolve_delayed call from data_extract_single to data_extract_mu…
chlebowa Feb 17, 2025
72b69ae
move resolve_delayed_datanames into resolve_delayed
chlebowa Feb 17, 2025
36a413d
skip failing unit tests
chlebowa Feb 17, 2025
e663c17
rename delayed_datasets file
chlebowa Feb 17, 2025
91e9351
rename delayed_datasets file, ctd.
chlebowa Feb 18, 2025
8b02fba
update pkgdown reference
chlebowa Feb 18, 2025
adf3fc2
rename internals properly, again
chlebowa Feb 18, 2025
d914534
amend documentation
chlebowa Feb 18, 2025
2493760
resolve to resolve
gogonzo Feb 19, 2025
0b1fac4
WIP - before tests. Some todo, asserts and decisions left
gogonzo Feb 19, 2025
9898e3c
- delayed_datanames to "all"
gogonzo Feb 20, 2025
0610d44
- add nth_choice
gogonzo Feb 20, 2025
decb456
update
gogonzo Feb 20, 2025
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
5 changes: 1 addition & 4 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ S3method(resolve,delayed_variable_choices)
S3method(resolve,list)
S3method(resolve_delayed,FilteredData)
S3method(resolve_delayed,list)
S3method(value_choices,character)
S3method(value_choices,data.frame)
S3method(variable_choices,character)
S3method(variable_choices,data.frame)
export("%>%")
export(add_no_selected_choices)
export(all_choices)
Expand Down Expand Up @@ -63,6 +59,7 @@ export(merge_datasets)
export(merge_expression_module)
export(merge_expression_srv)
export(no_selected_as_NULL)
export(nth_choice)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bad idea. What if n = 6 but there are only 3 choices?
And why not slice_choices as well?

export(resolve_delayed)
export(select_spec)
export(select_spec.default)
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# teal.transform 0.6.0.9000

### Enhancements

* Introduced defaults to all `data_extract_spec()` components to simplify the user experience. It is now possible to just call `data_extract_spec()` which will provide necessary information for `data_extract_srv()` and `data_extract_multiple_srv()` to initialize inputs for all provided datasets.
* Introduced utility function `nth_choice(n)`.

# teal.transform 0.6.0

### Enhancements
Expand Down
82 changes: 55 additions & 27 deletions R/choices_labeled.R
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ choices_labeled <- function(choices, labels, subset = NULL, types = NULL) {
#'
#' @param data (`data.frame` or `character`)
#' If `data.frame`, then data to extract labels from.
#' If `character`, then name of the dataset to extract data from once available.
#' If `character`, then name of the dataset to extract data from once available. Keyword `"all"`
#' (default) indicates that `data` will be inherited from the `data_extract_spec` `dataname`.
#' @param subset (`character` or `function`)
#' If `character`, then a vector of column names.
#' If `function`, then this function is used to determine the possible columns (e.g. all factor columns).
Expand Down Expand Up @@ -161,7 +162,10 @@ choices_labeled <- function(choices, labels, subset = NULL, types = NULL) {
#' key = default_cdisc_join_keys["ADRS", "ADRS"]
#' )
#'
#' # delayed version
#' # delayed version with unknown dataset
#' variable_choices()
#'
#' # delayed ADRS
#' variable_choices("ADRS", subset = c("USUBJID", "STUDYID"))
#'
#' # functional subset (with delayed data) - return only factor variables
Expand All @@ -171,35 +175,48 @@ choices_labeled <- function(choices, labels, subset = NULL, types = NULL) {
#' })
#' @export
#'
variable_choices <- function(data, subset = NULL, fill = FALSE, key = NULL) {
variable_choices <- function(data = "all", subset = function(data) names(data), fill = FALSE, key = NULL) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
variable_choices <- function(data = "all", subset = function(data) names(data), fill = FALSE, key = NULL) {
variable_choices <- function(data = "inherit", subset = function(data) names(data), fill = FALSE, key = NULL) {

checkmate::assert(
checkmate::check_character(subset, null.ok = TRUE, any.missing = FALSE),
checkmate::check_function(subset)
checkmate::check_function(subset, args = "data")
Comment on lines 180 to +181
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since function is now default, why allow NULL?

Suggested change
checkmate::check_character(subset, null.ok = TRUE, any.missing = FALSE),
checkmate::check_function(subset)
checkmate::check_function(subset, args = "data")
checkmate::check_character(subset, any.missing = FALSE),
checkmate::check_function(subset, args = "data")

Also remove NULL provisions in delayed_choices.

)
checkmate::assert_flag(fill)
checkmate::assert_character(key, null.ok = TRUE, any.missing = FALSE)

UseMethod("variable_choices")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not S3?

if (is.character(data)) {
variable_choices_delayed(data = data, subset = subset, fill = fill, key = key)
} else {
variable_choices_data_frame(data = data, subset = subset, fill = fill, key = key)
}
}

#' @rdname variable_choices
#' @export
variable_choices.character <- function(data, subset = NULL, fill = FALSE, key = NULL) {
#' @keywords internal
variable_choices_delayed <- function(data, subset = function(data) names(data), fill = FALSE, key = NULL) {
checkmate::assert_string(data)
structure(list(data = data, subset = subset, key = key),
class = c("delayed_variable_choices", "delayed_data", "choices_labeled")
)
}

#' @rdname variable_choices
#' @export
variable_choices.data.frame <- function(data, subset = NULL, fill = TRUE, key = NULL) {
#' @keywords internal
variable_choices_data_frame <- function(data, subset = function(data) names(data), fill = TRUE, key = NULL) {
checkmate::assert_data_frame(data, min.cols = 1)
checkmate::assert(
checkmate::check_character(subset, null.ok = TRUE),
checkmate::check_function(subset, null.ok = TRUE)
)
Comment on lines 203 to 206
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These argument checks aer performed by the caller.

Suggested change
checkmate::assert(
checkmate::check_character(subset, null.ok = TRUE),
checkmate::check_function(subset, null.ok = TRUE)
)


if (is.function(subset)) {
subset <- resolve_delayed_expr(subset, ds = data, is_value_choices = FALSE)
subset <- subset(data)
if (
!checkmate::test_character(subset, any.missing = FALSE) ||
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing values are rejected by the caller.

Suggested change
!checkmate::test_character(subset, any.missing = FALSE) ||
!checkmate::test_character(subset) ||

length(subset) > ncol(data) ||
anyDuplicated(subset)
) {
stop(
"variable_choices(subset) function in must return a character vector with unique",
"names from the available columns of the dataset"
)
Comment on lines +215 to +218
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
stop(
"variable_choices(subset) function in must return a character vector with unique",
"names from the available columns of the dataset"
)
stop("variable_choices(subset) function in must return a character vector of unique values")

}
}

checkmate::assert_subset(subset, c("", names(data)), empty.ok = TRUE)
Expand Down Expand Up @@ -283,8 +300,8 @@ variable_choices.data.frame <- function(data, subset = NULL, fill = TRUE, key =
#' })
#' @export
#'
value_choices <- function(data,
var_choices,
value_choices <- function(data = "all",
var_choices = variable_choices(data = data),
var_label = NULL,
subset = NULL,
sep = " - ") {
Expand All @@ -298,16 +315,21 @@ value_choices <- function(data,
checkmate::check_function(subset)
)
checkmate::assert_string(sep)
UseMethod("value_choices")

if (is.character(data)) {
value_choices_delayed(data = data, var_choices = var_choices, var_label = var_label, subset = subset, sep = sep)
} else {
value_choices_data_frame(data = data, var_choices = var_choices, var_label = var_label, subset = subset, sep = sep)
}
}

#' @rdname value_choices
#' @export
value_choices.character <- function(data,
var_choices,
var_label = NULL,
subset = NULL,
sep = " - ") {
#' @keywords internal
value_choices_delayed <- function(data,
var_choices,
var_label = NULL,
subset = NULL,
sep = " - ") {
checkmate::assert_string(data, null.ok = TRUE)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
checkmate::assert_string(data, null.ok = TRUE)
checkmate::assert_string(data)

structure(
list(
data = data,
Expand All @@ -320,13 +342,13 @@ value_choices.character <- function(data,
)
}

#' @rdname value_choices
#' @export
value_choices.data.frame <- function(data,
#' @keywords internal
value_choices_data_frame <- function(data,
var_choices,
var_label = NULL,
subset = NULL,
sep = " - ") {
checkmate::assert_data_frame(data, min.cols = 1)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert non-zero number of rows as well?

checkmate::assert_subset(var_choices, names(data))
checkmate::assert_subset(var_label, names(data), empty.ok = TRUE)

Expand Down Expand Up @@ -369,7 +391,13 @@ value_choices.data.frame <- function(data,
df <- unique(data.frame(choices, labels, stringsAsFactors = FALSE)) # unique combo of choices x labels

if (is.function(subset)) {
subset <- resolve_delayed_expr(subset, ds = data, is_value_choices = TRUE)
subset <- subset(data)
if (!checkmate::test_atomic(subset) || anyDuplicated(subset)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test this under different R versions, base::is.atomic(NULL) is FALSE since 4.4

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could duplicates be dropped here and not raise an error?

stop(
"value_choices(subset) function must return a vector with unique values from the ",
"respective columns of the dataset."
)
}
}
res <- choices_labeled(
choices = df$choices,
Expand Down
4 changes: 3 additions & 1 deletion R/choices_selected.R
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ no_select_keyword <- "-- no selection --"
#' @export
#'
choices_selected <- function(choices,
selected = if (inherits(choices, "delayed_data")) NULL else choices[1],
selected = first_choice(),
keep_order = FALSE,
fixed = FALSE) {
checkmate::assert(
Expand All @@ -141,6 +141,8 @@ choices_selected <- function(choices,
checkmate::assert(
checkmate::check_atomic(selected),
checkmate::check_multi_class(selected, c("delayed_data", "delayed_choices"))
# todo: only delayed_choices should be possible for delayed, otherwise it might cause different
# delayed output for choices and selected (for example two independent variable_choices)
)
checkmate::assert_flag(keep_order)
checkmate::assert_flag(fixed)
Expand Down
25 changes: 16 additions & 9 deletions R/data_extract_datanames.R
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,22 @@ get_extract_datanames <- function(data_extracts) {
all(vapply(data_extracts, function(x) checkmate::test_list(x, types = "data_extract_spec"), logical(1)))
)

datanames <- lapply(data_extracts, function(x) {
if (inherits(x, "data_extract_spec")) {
x[["dataname"]]
} else if (checkmate::test_list(x, types = "data_extract_spec")) {
lapply(x, `[[`, "dataname")
}
})
datanames <- unlist(
lapply(data_extracts, function(x) {
if (inherits(x, "data_extract_spec")) {
x[["dataname"]]
} else if (checkmate::test_list(x, types = "data_extract_spec")) {
lapply(x, `[[`, "dataname")
}
}),
use.names = FALSE
)

unique(unlist(datanames))
if (any(datanames == "all")) {
"all"
} else {
unique(datanames)
}
}

#' Verify uniform dataset source across data extract specification
Expand All @@ -82,5 +89,5 @@ get_extract_datanames <- function(data_extracts) {
is_single_dataset <- function(...) {
data_extract_spec <- list(...)
dataset_names <- get_extract_datanames(data_extract_spec)
length(dataset_names) == 1
length(dataset_names) == 1L && dataset_names != "all"
}
Loading
Loading