From 6c58cdf7e77815245afe3578d436f4adf8e4218f Mon Sep 17 00:00:00 2001 From: vedhav Date: Thu, 16 Nov 2023 12:03:38 +0530 Subject: [PATCH 01/43] feat: extend `xportr_write` to accept `metadata` and deprecate `label` --- DESCRIPTION | 2 +- NEWS.md | 8 +++++++ R/df_label.R | 4 ++++ R/write.R | 43 +++++++++++++++++++++++++------------ man/xportr_write.Rd | 19 ++++++++++++++-- tests/testthat/test-write.R | 9 -------- 6 files changed, 59 insertions(+), 26 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 61e81239..28b9ff0b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1 +Version: 0.3.1.9001 Authors@R: c( person(given = "Eli", diff --git a/NEWS.md b/NEWS.md index c066e5e7..ad0b607b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,11 @@ +# xportr 0.3.1.9001 + +## New Features and Bug Fixes +* `xportr_write()` now accepts `metadata` argument which can be used to set the dataset label to stay consistent with the other `xportr_*` functions. It is noteworthy that the dataset label set using the `xportr_df_label()` function will be retained during the `xportr_write()`. + +## Deprecation and Breaking Changes +* The `label` argument from the `xportr_write()` function is deprecated with the `metadata` argument. + # xportr 0.3.0 ## New Features and Bug Fixes diff --git a/R/df_label.R b/R/df_label.R index 0b3b7194..df9d6b75 100644 --- a/R/df_label.R +++ b/R/df_label.R @@ -83,6 +83,10 @@ xportr_df_label <- function(.df, abort("Length of dataset label must be 40 characters or less.") } + if (stringr::str_detect(label, "[^[:ascii:]]")) { + abort("`label` cannot contain any non-ASCII, symbol or special characters.") + } + attr(.df, "label") <- label .df diff --git a/R/write.R b/R/write.R index 57367fc2..3921b803 100644 --- a/R/write.R +++ b/R/write.R @@ -7,10 +7,12 @@ #' @param .df A data frame to write. #' @param path Path where transport file will be written. File name sans will be #' used as `xpt` name. -#' @param label Dataset label. It must be <=40 characters. +#' @param label `r lifecycle::badge("deprecated")` Previously used to to set the Dataset label. +#' Use the `metadata` to set the dataset label. #' @param strict_checks If TRUE, xpt validation will report errors and not write #' out the dataset. If FALSE, xpt validation will report warnings and continue #' with writing out the dataset. Defaults to FALSE +#' @inheritParams xportr_length #' #' @details #' * Variable and dataset labels are stored in the "label" attribute. @@ -38,11 +40,36 @@ #' strict_checks = FALSE #' ) #' -xportr_write <- function(.df, path, label = NULL, strict_checks = FALSE) { +xportr_write <- function(.df, + path, + metadata = NULL, + domain = NULL, + strict_checks = FALSE, + label = deprecated()) { path <- normalizePath(path, mustWork = FALSE) name <- tools::file_path_sans_ext(basename(path)) + ## Common section to detect domain from argument or pipes + + df_arg <- tryCatch(as_name(enexpr(.df)), error = function(err) NULL) + domain <- get_domain(.df, df_arg, domain) + if (!is.null(domain)) attr(.df, "_xportr.df_arg_") <- domain + + ## End of common section + + if (!missing(label)) { + lifecycle::deprecate_warn( + when = "0.3.2", + what = "xportr_write(label = )", + with = "xportr_write(metadata = )" + ) + metadata <- data.frame(dataset = domain, label = label) + } + if (!is.null(metadata)) { + .df <- xportr_df_label(.df, metadata = metadata, domain = domain) + } + if (nchar(name) > 8) { abort("`.df` file name must be 8 characters or less.") } @@ -51,18 +78,6 @@ xportr_write <- function(.df, path, label = NULL, strict_checks = FALSE) { abort("`.df` cannot contain any non-ASCII, symbol or underscore characters.") } - if (!is.null(label)) { - if (nchar(label) > 40) { - abort("`label` must be 40 characters or less.") - } - - if (stringr::str_detect(label, "[^[:ascii:]]")) { - abort("`label` cannot contain any non-ASCII, symbol or special characters.") - } - - attr(.df, "label") <- label - } - checks <- xpt_validate(.df) if (length(checks) > 0) { diff --git a/man/xportr_write.Rd b/man/xportr_write.Rd index f1b89fc9..2387baf3 100644 --- a/man/xportr_write.Rd +++ b/man/xportr_write.Rd @@ -4,7 +4,14 @@ \alias{xportr_write} \title{Write xpt v5 transport file} \usage{ -xportr_write(.df, path, label = NULL, strict_checks = FALSE) +xportr_write( + .df, + path, + metadata = NULL, + domain = NULL, + strict_checks = FALSE, + label = deprecated() +) } \arguments{ \item{.df}{A data frame to write.} @@ -12,11 +19,19 @@ xportr_write(.df, path, label = NULL, strict_checks = FALSE) \item{path}{Path where transport file will be written. File name sans will be used as \code{xpt} name.} -\item{label}{Dataset label. It must be <=40 characters.} +\item{metadata}{A data frame containing variable level metadata. See +'Metadata' section for details.} + +\item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset +the metadata object. If none is passed, then name of the dataset passed as +.df will be used.} \item{strict_checks}{If TRUE, xpt validation will report errors and not write out the dataset. If FALSE, xpt validation will report warnings and continue with writing out the dataset. Defaults to FALSE} + +\item{label}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Previously used to to set the Dataset label. +Use the \code{metadata} to set the dataset label.} } \value{ A data frame. \code{xportr_write()} returns the input data invisibly. diff --git a/tests/testthat/test-write.R b/tests/testthat/test-write.R index ba165e3c..51b569b6 100644 --- a/tests/testthat/test-write.R +++ b/tests/testthat/test-write.R @@ -85,15 +85,6 @@ test_that("xportr_write: expect warning when an xpt validation fails with strict expect_warning(xportr_write(data_to_save, tmp, label = "label", strict_checks = FALSE)) }) -test_that("xportr_write: expect warning when an xpt validation fails with strict_checks set to FALSE", { - tmpdir <- tempdir() - tmp <- file.path(tmpdir, "xyz.xpt") - attr(data_to_save$X, "format.sas") <- "foo" - - on.exit(unlink(tmpdir)) - - expect_warning(xportr_write(data_to_save, tmp, label = "label", strict_checks = FALSE)) -}) test_that("xportr_write: Capture errors by haven and report them as such", { tmpdir <- tempdir() From 399a4fd176e8383ac38e7a463db159353ac5a8b6 Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 21 Nov 2023 22:40:33 +0530 Subject: [PATCH 02/43] chore: update tests with metadata instead of label --- tests/testthat/test-write.R | 116 ++++++++++++++++++++++++++++++++---- 1 file changed, 106 insertions(+), 10 deletions(-) diff --git a/tests/testthat/test-write.R b/tests/testthat/test-write.R index 51b569b6..4229c06e 100644 --- a/tests/testthat/test-write.R +++ b/tests/testthat/test-write.R @@ -10,13 +10,48 @@ test_that("xportr_write: exported data can be saved to a file", { expect_equal(read_xpt(tmp), data_to_save) }) -test_that("xportr_write: exported data can be saved to a file with a label", { +test_that("xportr_write: exported data can still be saved to a file with a label", { tmpdir <- tempdir() tmp <- file.path(tmpdir, "xyz.xpt") on.exit(unlink(tmpdir)) - xportr_write(data_to_save, path = tmp, label = "Lorem ipsum dolor sit amet") + suppressWarnings(xportr_write(data_to_save, path = tmp, label = "Lorem ipsum dolor sit amet")) + expect_output(str(read_xpt(tmp)), "Lorem ipsum dolor sit amet") +}) + +test_that("xportr_write: exported data can be saved to a file with a metadata", { + tmpdir <- tempdir() + tmp <- file.path(tmpdir, "xyz.xpt") + + on.exit(unlink(tmpdir)) + + xportr_write( + data_to_save, + path = tmp, + metadata = data.frame( + dataset = "data_to_save", + label = "Lorem ipsum dolor sit amet" + ) + ) + expect_output(str(read_xpt(tmp)), "Lorem ipsum dolor sit amet") +}) + +test_that("xportr_write: exported data can be saved to a file with a existing metadata", { + tmpdir <- tempdir() + tmp <- file.path(tmpdir, "xyz.xpt") + + on.exit(unlink(tmpdir)) + + df <- xportr_df_label( + data_to_save, + data.frame( + dataset = "data_to_save", + label = "Lorem ipsum dolor sit amet" + ) + ) + + xportr_write(df, path = tmp) expect_output(str(read_xpt(tmp)), "Lorem ipsum dolor sit amet") }) @@ -26,7 +61,16 @@ test_that("xportr_write: expect error when invalid multibyte string is passed in on.exit(unlink(tmpdir)) - expect_error(xportr_write(data_to_save, tmp, label = "Lorizzle ipsizzle dolizzl\xe7 pizzle")) + expect_error( + xportr_write( + data_to_save, + tmp, + metadata = data.frame( + dataset = "data_to_save", + label = "Lorizzle ipsizzle dolizzl\xe7 pizzle" + ) + ) + ) }) test_that("xportr_write: expect error when file name is over 8 characters long", { @@ -35,7 +79,7 @@ test_that("xportr_write: expect error when file name is over 8 characters long", on.exit(unlink(tmpdir)) - expect_error(xportr_write(data_to_save, tmp, label = "asdf")) + expect_error(xportr_write(data_to_save, tmp)) }) test_that("xportr_write: expect error when file name contains non-ASCII symbols or special characters", { @@ -44,7 +88,7 @@ test_that("xportr_write: expect error when file name contains non-ASCII symbols on.exit(unlink(tmpdir)) - expect_error(xportr_write(data_to_save, tmp, label = "asdf")) + expect_error(xportr_write(data_to_save, tmp)) }) test_that("xportr_write: expect error when label contains non-ASCII symbols or special characters", { @@ -53,7 +97,22 @@ test_that("xportr_write: expect error when label contains non-ASCII symbols or s on.exit(unlink(tmpdir)) - expect_error(xportr_write(data_to_save, tmp, label = "çtestç")) + expect_error( + xportr_write( + data_to_save, + tmp, + expect_error( + xportr_write( + data_to_save, + tmp, + metadata = data.frame( + dataset = "data_to_save", + label = "çtestç" + ) + ) + ) + ) + ) }) test_that("xportr_write: expect error when label is over 40 characters", { @@ -62,7 +121,16 @@ test_that("xportr_write: expect error when label is over 40 characters", { on.exit(unlink(tmpdir)) - expect_error(xportr_write(data_to_save, tmp, label = paste(rep("a", 41), collapse = ""))) + expect_error( + xportr_write( + data_to_save, + tmp, + metadata = data.frame( + dataset = "data_to_save", + label = paste(rep("a", 41), collapse = "") + ) + ) + ) }) test_that("xportr_write: expect error when an xpt validation fails with strict_checks set to TRUE", { @@ -72,7 +140,16 @@ test_that("xportr_write: expect error when an xpt validation fails with strict_c on.exit(unlink(tmpdir)) - expect_error(xportr_write(data_to_save, tmp, label = "label", strict_checks = TRUE)) + expect_error( + xportr_write( + data_to_save, tmp, + metadata = data.frame( + dataset = "data_to_save", + label = "label" + ), + strict_checks = TRUE + ) + ) }) test_that("xportr_write: expect warning when an xpt validation fails with strict_checks set to FALSE", { @@ -82,7 +159,16 @@ test_that("xportr_write: expect warning when an xpt validation fails with strict on.exit(unlink(tmpdir)) - expect_warning(xportr_write(data_to_save, tmp, label = "label", strict_checks = FALSE)) + expect_warning( + xportr_write( + data_to_save, tmp, + metadata = data.frame( + dataset = "data_to_save", + label = "label" + ), + strict_checks = FALSE + ) + ) }) @@ -93,8 +179,18 @@ test_that("xportr_write: Capture errors by haven and report them as such", { on.exit(unlink(tmpdir)) + expect_error( - suppressWarnings(xportr_write(data_to_save, tmp, label = "label", strict_checks = FALSE)), + suppressWarnings( + xportr_write( + data_to_save, tmp, + metadata = data.frame( + dataset = "data_to_save", + label = "label" + ), + strict_checks = FALSE + ) + ), "Error reported by haven" ) }) From 1fa2b56b77e9c189d857a40ee47365da049cc89a Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 21 Nov 2023 22:57:40 +0530 Subject: [PATCH 03/43] docs: replace the docs where label is used --- R/write.R | 3 ++- README.Rmd | 4 ++-- README.md | 4 ++-- man/xportr_write.Rd | 3 ++- vignettes/deepdive.Rmd | 10 +++++----- vignettes/xportr.Rmd | 2 +- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/R/write.R b/R/write.R index 3921b803..f16f08cc 100644 --- a/R/write.R +++ b/R/write.R @@ -34,9 +34,10 @@ #' Param = c("param1", "param2", "param3") #' ) #' +#' var_spec <- data.frame(dataset = "adsl", label = "Subject-Level Analysis Dataset") #' xportr_write(adsl, #' path = paste0(tempdir(), "/adsl.xpt"), -#' label = "Subject-Level Analysis", +#' metadata = var_spec, #' strict_checks = FALSE #' ) #' diff --git a/README.Rmd b/README.Rmd index 6536ac6d..6c2830a7 100644 --- a/README.Rmd +++ b/README.Rmd @@ -133,7 +133,7 @@ adsl %>% xportr_label(var_spec, "ADSL", verbose = "warn") %>% xportr_order(var_spec, "ADSL", verbose = "warn") %>% xportr_format(var_spec, "ADSL") %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` The `xportr_metadata()` function can reduce duplication by setting the variable specification and domain explicitly at the top of a pipeline. If you would like to use the `verbose` argument, you will need to set in each function call. @@ -146,7 +146,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` That's it! We now have a xpt file created in R with all appropriate types, lengths, labels, ordering and formats. Please check out the [Get Started](https://atorus-research.github.io/xportr/articles/xportr.html) for more information and detailed walk through of each `xportr_` function. diff --git a/README.md b/README.md index bbd581f9..675ca401 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,7 @@ adsl %>% xportr_label(var_spec, "ADSL", verbose = "warn") %>% xportr_order(var_spec, "ADSL", verbose = "warn") %>% xportr_format(var_spec, "ADSL") %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` The `xportr_metadata()` function can reduce duplication by setting the @@ -156,7 +156,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` That’s it! We now have a xpt file created in R with all appropriate diff --git a/man/xportr_write.Rd b/man/xportr_write.Rd index 2387baf3..8e19147b 100644 --- a/man/xportr_write.Rd +++ b/man/xportr_write.Rd @@ -57,9 +57,10 @@ adsl <- data.frame( Param = c("param1", "param2", "param3") ) +var_spec <- data.frame(dataset = "adsl", label = "Subject-Level Analysis Dataset") xportr_write(adsl, path = paste0(tempdir(), "/adsl.xpt"), - label = "Subject-Level Analysis", + metadata = var_spec, strict_checks = FALSE ) diff --git a/vignettes/deepdive.Rmd b/vignettes/deepdive.Rmd index 8f1ccac0..72af4bca 100644 --- a/vignettes/deepdive.Rmd +++ b/vignettes/deepdive.Rmd @@ -171,7 +171,7 @@ adsl %>% xportr_label(var_spec, "ADSL", "message") %>% xportr_order(var_spec, "ADSL", "message") %>% xportr_format(var_spec, "ADSL") %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` To help reduce these repetitive calls, we have created `xportr_metadata()`. A user can just **set** the _metadata object_ and the Domain name in the first call, and this will be passed on to the other functions. Much cleaner! @@ -185,7 +185,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` @@ -410,7 +410,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% - xportr_write(path = "adsl.xpt", label = "Subject-Level Analysis Dataset", strict_checks = FALSE) + xportr_write(path = "adsl.xpt", strict_checks = FALSE) ``` Success! We have applied types, lengths, labels, ordering and formats to our dataset. Note the messages written out to the console. Remember the `TRTDUR` and `DCREASCD` and how these are not present in the metadata, but in the dataset. This impacts the messaging for lengths and labels where `{xportr}` is printing out some feedback to us on the two issues. 5 types are coerced, as well as 36 variables re-ordered. Note that `strict_checks` was set to `FALSE`. @@ -419,7 +419,7 @@ The next two examples showcase the `strict_checks = TRUE` option in `xportr_writ ```{r, echo = TRUE, error = TRUE} adsl %>% - xportr_write(path = "adsl.xpt", label = "Subject-Level Analysis Dataset", strict_checks = TRUE) + xportr_write(path = "adsl.xpt", strict_checks = TRUE) ``` @@ -439,7 +439,7 @@ adsl %>% xportr_label() %>% xportr_type() %>% xportr_format() %>% - xportr_write(path = "adsl.xpt", label = "Subject-Level Analysis Dataset", strict_checks = TRUE) + xportr_write(path = "adsl.xpt", strict_checks = TRUE) ``` diff --git a/vignettes/xportr.Rmd b/vignettes/xportr.Rmd index 1c6acdb0..2e39f386 100644 --- a/vignettes/xportr.Rmd +++ b/vignettes/xportr.Rmd @@ -278,7 +278,7 @@ adsl %>% xportr_label(var_spec, "ADSL", "message") %>% xportr_order(var_spec, "ADSL", "message") %>% xportr_format(var_spec, "ADSL") %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` That's it! We now have a `xpt` file created in R with all appropriate types, lengths, labels, ordering and formats from our specification file. If you are interested in exploring more of the custom From d75aefa74b844d138ace5dce62ded01a42ec6b05 Mon Sep 17 00:00:00 2001 From: Vedha Viyash <49812166+vedhav@users.noreply.github.com> Date: Tue, 28 Nov 2023 03:44:44 +0530 Subject: [PATCH 04/43] Update NEWS.md Co-authored-by: Eli Miller --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index ad0b607b..b1ef4a4d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,7 @@ * `xportr_write()` now accepts `metadata` argument which can be used to set the dataset label to stay consistent with the other `xportr_*` functions. It is noteworthy that the dataset label set using the `xportr_df_label()` function will be retained during the `xportr_write()`. ## Deprecation and Breaking Changes -* The `label` argument from the `xportr_write()` function is deprecated with the `metadata` argument. +* The `label` argument from the `xportr_write()` function is deprecated in favor of the `metadata` argument. # xportr 0.3.0 From c6725b1fa9039c44c350e4f62dbc46b8ee56dfc7 Mon Sep 17 00:00:00 2001 From: Vedha Viyash <49812166+vedhav@users.noreply.github.com> Date: Tue, 28 Nov 2023 03:44:51 +0530 Subject: [PATCH 05/43] Update R/write.R Co-authored-by: Eli Miller --- R/write.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/write.R b/R/write.R index f16f08cc..0dd13541 100644 --- a/R/write.R +++ b/R/write.R @@ -8,7 +8,7 @@ #' @param path Path where transport file will be written. File name sans will be #' used as `xpt` name. #' @param label `r lifecycle::badge("deprecated")` Previously used to to set the Dataset label. -#' Use the `metadata` to set the dataset label. +#' Use the `metadata` argument to set the dataset label. #' @param strict_checks If TRUE, xpt validation will report errors and not write #' out the dataset. If FALSE, xpt validation will report warnings and continue #' with writing out the dataset. Defaults to FALSE From 25c7bc4cb1d99cf34151e0b091c09f8b8184959e Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 28 Nov 2023 03:46:43 +0530 Subject: [PATCH 06/43] docs: update roxygen docs --- man/xportr_write.Rd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/xportr_write.Rd b/man/xportr_write.Rd index 8e19147b..b59e61bd 100644 --- a/man/xportr_write.Rd +++ b/man/xportr_write.Rd @@ -31,7 +31,7 @@ out the dataset. If FALSE, xpt validation will report warnings and continue with writing out the dataset. Defaults to FALSE} \item{label}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Previously used to to set the Dataset label. -Use the \code{metadata} to set the dataset label.} +Use the \code{metadata} argument to set the dataset label.} } \value{ A data frame. \code{xportr_write()} returns the input data invisibly. From 2404325e24f71dbbe805eaf10384ce27bbe0f837 Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 28 Nov 2023 04:16:20 +0530 Subject: [PATCH 07/43] docs: make some minor corrections to the deep dive vignette --- vignettes/deepdive.Rmd | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/vignettes/deepdive.Rmd b/vignettes/deepdive.Rmd index 8f1ccac0..ab900da0 100644 --- a/vignettes/deepdive.Rmd +++ b/vignettes/deepdive.Rmd @@ -143,20 +143,19 @@ options( One final note on `options()`. 4 of the core `{xportr}` functions have the ability to set messaging as `"none", "message", "warn", "stop"`. Setting each of these in all your calls can be a bit repetitive. You can use `options()` to set these at a higher level and avoid this repetition. ```{r, eval = FALSE} -# Default +# Default verbose is set to `none` options( xportr.format_verbose = "none", xportr.label_verbose = "none", xportr.length_verbose = "none", - xportr.type_verbose = "none", + xportr.type_verbose = "none" ) -# Will send Warning Message to Console options( - xportr.format_verbose = "warn", - xportr.label_verbose = "warn", - xportr.length_verbose = "warn", - xportr.type_verbose = "warn", + xportr.format_verbose = "none", # Disables any messaging, keeping the console output clean + xportr.label_verbose = "message", # Sends a standard message to the console + xportr.length_verbose = "warn", # Sends a warning message to the console + xportr.type_verbose = "stop" # Stops execution and sends an error message to the console ) ``` @@ -279,7 +278,7 @@ glimpse(adsl_type_glimpse) Note that `xportr_type(verbose = "warn")` was set so the function has provided feedback, which would show up in the console, on which variables were converted as a warning message. However, you can set `verbose = "stop"` so that the types are not applied if the data does not match what is in the specification file. Using `verbose = "stop"` will instantly stop the processing of this function and not create the object. A user will need to alter the variables in their R script before using `xportr_type()` ```{r, echo = TRUE, error = TRUE} -adsl_type <- xportr_type(.df = adsl, metadata = var_spec, domain = "ADSL", verbose = "stop") +adsl_type <- xportr_type(.df = adsl_fct, metadata = var_spec, domain = "ADSL", verbose = "stop") ``` ## `xportr_length()` From f490414accf48a8764fdec02176256fdb909e6eb Mon Sep 17 00:00:00 2001 From: Kangjie Zhang Date: Tue, 28 Nov 2023 00:11:14 +0000 Subject: [PATCH 08/43] add length check <=200 bytes --- NEWS.md | 5 +++++ R/utils-xportr.R | 10 ++++++++++ tests/testthat/test-utils-xportr.R | 8 ++++++++ 3 files changed, 23 insertions(+) diff --git a/NEWS.md b/NEWS.md index c066e5e7..83d5529a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +# xportr 0.3.1.9001 + +## New Features and Bug Fixes +* Added a check for character variable lengths up to 200 bytes in `xpt_validate()`(#91, #189). + # xportr 0.3.0 ## New Features and Bug Fixes diff --git a/R/utils-xportr.R b/R/utils-xportr.R index 06e1684f..8086ffa4 100644 --- a/R/utils-xportr.R +++ b/R/utils-xportr.R @@ -302,6 +302,16 @@ xpt_validate <- function(data) { glue("{fmt_fmts(names(chk_formats))} must have a valid format.") ) } + + # 4.0 max length of Character variables <= 200 bytes + max_nchar <- data %>% + summarise(across(where(is.character), ~ max(nchar(., type = "bytes")))) + nchar_gt_200 <- max_nchar[which(max_nchar > 200)] + err_cnd <- c( + err_cnd, + glue("Character variables must have lengths <= 200 bytes, max length of {names(nchar_gt_200)} is {nchar_gt_200} bytes.") + ) + return(err_cnd) } diff --git a/tests/testthat/test-utils-xportr.R b/tests/testthat/test-utils-xportr.R index 4167b698..0a679e46 100644 --- a/tests/testthat/test-utils-xportr.R +++ b/tests/testthat/test-utils-xportr.R @@ -111,3 +111,11 @@ test_that("xpt_validate: Get error message when the label contains non-ASCII, sy "Label 'A=fooçbar' cannot contain any non-ASCII, symbol or special characters." ) }) + +test_that("xpt_validate: Get error message when the length of a character variable is > 200 bytes ", { + df <- data.frame(A = paste(rep("A", 201), collapse = "")) + expect_equal( + xpt_validate(df), + "Character variables must have lengths <= 200 bytes, max length of A is 201 bytes." + ) +}) From bf1fc3e1cf0c60ef54adece227920e5a23e8f48a Mon Sep 17 00:00:00 2001 From: Kangjie Zhang Date: Tue, 28 Nov 2023 00:27:18 +0000 Subject: [PATCH 09/43] update length check --- R/utils-xportr.R | 4 ++-- tests/testthat/test-utils-xportr.R | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/R/utils-xportr.R b/R/utils-xportr.R index 8086ffa4..5e21c7e9 100644 --- a/R/utils-xportr.R +++ b/R/utils-xportr.R @@ -305,11 +305,11 @@ xpt_validate <- function(data) { # 4.0 max length of Character variables <= 200 bytes max_nchar <- data %>% - summarise(across(where(is.character), ~ max(nchar(., type = "bytes")))) + dplyr::summarise(across(where(is.character), ~ max(nchar(., type = "bytes")))) nchar_gt_200 <- max_nchar[which(max_nchar > 200)] err_cnd <- c( err_cnd, - glue("Character variables must have lengths <= 200 bytes, max length of {names(nchar_gt_200)} is {nchar_gt_200} bytes.") + glue("Length of {names(nchar_gt_200)} must be 200 bytes or less.") ) return(err_cnd) diff --git a/tests/testthat/test-utils-xportr.R b/tests/testthat/test-utils-xportr.R index 0a679e46..7c272fe0 100644 --- a/tests/testthat/test-utils-xportr.R +++ b/tests/testthat/test-utils-xportr.R @@ -116,6 +116,6 @@ test_that("xpt_validate: Get error message when the length of a character variab df <- data.frame(A = paste(rep("A", 201), collapse = "")) expect_equal( xpt_validate(df), - "Character variables must have lengths <= 200 bytes, max length of A is 201 bytes." + "Length of A must be 200 bytes or less." ) }) From a0d653fe9e8864fdc3a3423ae9a01b4e36fe7484 Mon Sep 17 00:00:00 2001 From: EeethB Date: Tue, 28 Nov 2023 19:26:09 +0000 Subject: [PATCH 10/43] Add test --- tests/testthat/test-type.R | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/testthat/test-type.R b/tests/testthat/test-type.R index d5841a63..c593fdb1 100644 --- a/tests/testthat/test-type.R +++ b/tests/testthat/test-type.R @@ -280,3 +280,23 @@ test_that("xportr_type: Gets warning when metadata has multiple rows with same v # Checks that message doesn't appear when xportr.domain_name is valid multiple_vars_in_spec_helper2(xportr_type) }) + +test_that("xportr_type: Drops factor levels", { + metadata <- data.frame( + dataset = "test", + variable = c("Subj", "Param", "Val", "NotUsed"), + type = c("numeric", "character", "numeric", "character"), + format = NA + ) + + .df <- data.frame( + Subj = as.character(123, 456, 789), + Different = c("a", "b", "c"), + Val = factor(c("1", "2", "3")), + Param = c("param1", "param2", "param3") + ) + + df2 <- xportr_type(.df, metadata, "test") + + expect_null(attributes(df2$Val)) +}) From 338739eed385b7b6bf98498eb96bfa7176db7916 Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 5 Dec 2023 06:00:30 +0530 Subject: [PATCH 11/43] fix: use `xportr_df_label` to set the dataset label before writing it --- README.Rmd | 6 ++++++ README.md | 5 +++++ vignettes/deepdive.Rmd | 14 ++++++++++++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index 2d41e159..89d6e94b 100644 --- a/README.Rmd +++ b/README.Rmd @@ -19,6 +19,7 @@ library(fontawesome) # xportr +[](https://RValidationHub.slack.com) [![R build status](https://github.com/atorus-research/xportr/workflows/R-CMD-check/badge.svg)](https://github.com/atorus-research/xportr/actions?workflow=R-CMD-check) [](https://app.codecov.io/gh/atorus-research/xportr) [](https://github.com/atorus-research/xportr/blob/master/LICENSE) @@ -121,6 +122,9 @@ spec_path <- system.file(paste0("specs/", "ADaM_admiral_spec.xlsx"), package = " var_spec <- readxl::read_xlsx(spec_path, sheet = "Variables") %>% dplyr::rename(type = "Data Type") %>% rlang::set_names(tolower) +dataset_spec <- readxl::read_xlsx(spec_path, sheet = "Datasets") %>% + dplyr::rename(label = "Description") %>% + rlang::set_names(tolower) ``` Each `xportr_` function has been written in a way to take in a part of the specification file and apply that piece to the dataset. Setting `verbose = "warn"` will send appropriate warning message to the console. We have suppressed the warning for the sake of brevity. @@ -132,6 +136,7 @@ adsl %>% xportr_label(var_spec, "ADSL", verbose = "warn") %>% xportr_order(var_spec, "ADSL", verbose = "warn") %>% xportr_format(var_spec, "ADSL") %>% + xportr_df_label(dataset_spec, "ADSL") %>% xportr_write("adsl.xpt") ``` @@ -145,6 +150,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% + xportr_df_label(dataset_spec) %>% xportr_write("adsl.xpt") ``` diff --git a/README.md b/README.md index 675ca401..147964b2 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,9 @@ spec_path <- system.file(paste0("specs/", "ADaM_admiral_spec.xlsx"), package = " var_spec <- readxl::read_xlsx(spec_path, sheet = "Variables") %>% dplyr::rename(type = "Data Type") %>% rlang::set_names(tolower) +dataset_spec <- readxl::read_xlsx(spec_path, sheet = "Datasets") %>% + dplyr::rename(label = "Description") %>% + rlang::set_names(tolower) ``` Each `xportr_` function has been written in a way to take in a part of @@ -140,6 +143,7 @@ adsl %>% xportr_label(var_spec, "ADSL", verbose = "warn") %>% xportr_order(var_spec, "ADSL", verbose = "warn") %>% xportr_format(var_spec, "ADSL") %>% + xportr_df_label(dataset_spec, "ADSL") %>% xportr_write("adsl.xpt") ``` @@ -156,6 +160,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% + xportr_df_label(dataset_spec) %>% xportr_write("adsl.xpt") ``` diff --git a/vignettes/deepdive.Rmd b/vignettes/deepdive.Rmd index 72af4bca..5567e14f 100644 --- a/vignettes/deepdive.Rmd +++ b/vignettes/deepdive.Rmd @@ -171,6 +171,7 @@ adsl %>% xportr_label(var_spec, "ADSL", "message") %>% xportr_order(var_spec, "ADSL", "message") %>% xportr_format(var_spec, "ADSL") %>% + xportr_df_label(dataset_spec, "ADSL") %>% xportr_write("adsl.xpt") ``` @@ -185,6 +186,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% + xportr_df_label(dataset_spec) %>% xportr_write("adsl.xpt") ``` @@ -198,11 +200,16 @@ For the next six sections, we are going to explore the Warnings and Errors messa ### Setting up our metadata object First, let's read in the specification file and call it `var_spec`. Note that we are not using `options()` here. We will do some slight manipulation to the column names by doing all lower case, and changing `Data Type` to `type` and making the Order column numeric. You can also use `options()` for this step as well. The `var_spec` object has five dataset specification files stacked on top of each other. We will make use of the `ADSL` subset of `var_spec`. You can make use of the Search field above the dataset column to subset the specification file for `ADSL` +Similarly, we can read the Dataset spec file and call it `dataset_spec`. ```{r} var_spec <- var_spec %>% rename(type = "Data Type") %>% set_names(tolower) + +dataset_spec <- readxl::read_xlsx(spec_path, sheet = "Datasets") %>% + rename(label = "Description") %>% + set_names(tolower) ``` ```{r, echo = FALSE} @@ -400,7 +407,8 @@ At the time of `{xportr} v0.3.0` we have not implemented any warnings or error m Finally, we want to write out an `xpt` dataset with all our metadata applied. -We will make use of `xportr_metadata()` to reduce repetitive metadata and domain specifications. We will use default option for verbose, which is just `message` and so not set anything for `verbose`. In `xportr_write()` we will specify the path, which will just be our current working directory, set the dataset label and toggle the `strict_checks` to be `FALSE`. +We will make use of `xportr_metadata()` to reduce repetitive metadata and domain specifications. We will use default option for verbose, which is just `message` and so not set anything for `verbose`. In `xportr_write()` we will specify the path, which will just be our current working directory, set the dataset label and toggle the `strict_checks` to be `FALSE`. +It is also note worthy that you can set the dataset label using the `xportr_df_label` and a `dataset_spec` which will be used by the `xportr_write()` ```{r, echo = TRUE, error = TRUE} adsl %>% @@ -410,6 +418,7 @@ adsl %>% xportr_label() %>% xportr_order() %>% xportr_format() %>% + xportr_df_label(dataset_spec) %>% xportr_write(path = "adsl.xpt", strict_checks = FALSE) ``` @@ -419,7 +428,7 @@ The next two examples showcase the `strict_checks = TRUE` option in `xportr_writ ```{r, echo = TRUE, error = TRUE} adsl %>% - xportr_write(path = "adsl.xpt", strict_checks = TRUE) + xportr_write(path = "adsl.xpt", metadata = dataset_spec, domain = "ADSL", strict_checks = TRUE) ``` @@ -439,6 +448,7 @@ adsl %>% xportr_label() %>% xportr_type() %>% xportr_format() %>% + xportr_df_label(dataset_spec) %>% xportr_write(path = "adsl.xpt", strict_checks = TRUE) ``` From 4c2f3766469c35d9278e3faaeb421c5ea389bb15 Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 5 Dec 2023 06:03:51 +0530 Subject: [PATCH 12/43] chore: use the proper version numbers --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 28b9ff0b..4e813ef9 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9001 +Version: 0.3.1.9000 Authors@R: c( person(given = "Eli", diff --git a/NEWS.md b/NEWS.md index b1ef4a4d..53462ac2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# xportr 0.3.1.9001 +# xportr 0.3.1.9000 ## New Features and Bug Fixes * `xportr_write()` now accepts `metadata` argument which can be used to set the dataset label to stay consistent with the other `xportr_*` functions. It is noteworthy that the dataset label set using the `xportr_df_label()` function will be retained during the `xportr_write()`. From 907e91b0ab351931468d6428d73c8300b3cd94c0 Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 5 Dec 2023 06:23:26 +0530 Subject: [PATCH 13/43] feat: exporting the `dataset_spec` similar to `var_spec` --- NEWS.md | 1 + R/data.R | 19 ++++++++++++++++++- _pkgdown.yml | 1 + data/dataset_spec.rda | Bin 0 -> 310 bytes vignettes/deepdive.Rmd | 2 +- 5 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 data/dataset_spec.rda diff --git a/NEWS.md b/NEWS.md index 00cbce19..1800f0d5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,7 @@ ## New Features and Bug Fixes * `xportr_write()` now accepts `metadata` argument which can be used to set the dataset label to stay consistent with the other `xportr_*` functions. It is noteworthy that the dataset label set using the `xportr_df_label()` function will be retained during the `xportr_write()`. +* Exporting a new dataset `dataset_spec` that contains the Dataset Specification for ADSL. ## Deprecation and Breaking Changes * The `label` argument from the `xportr_write()` function is deprecated in favor of the `metadata` argument. diff --git a/R/data.R b/R/data.R index 96e24de2..ca83a2a6 100644 --- a/R/data.R +++ b/R/data.R @@ -56,7 +56,7 @@ #' } "adsl" -#' Example Dataset Specification +#' Example Dataset Variable Specification #' #' @format ## `var_spec` #' A data frame with 216 rows and 19 columns: @@ -82,3 +82,20 @@ #' \item{Developer Notes}{Developer Notes} #' } "var_spec" + +#' Example Dataset Specification +#' +#' @format ## `dataset_spec` +#' A data frame with 1 row and 9 columns: +#' \describe{ +#' \item{Dataset}{ Dataset} +#' \item{Description}{ Dataset description} +#' \item{Class}{ Dataset class} +#' \item{Structure}{ Logical, indicating if there's a specific structure} +#' \item{Purpose}{ Purpose of the dataset} +#' \item{Key, Variables}{ Join Key variables in the dataset} +#' \item{Repeating}{ Indicates if the dataset is repeating} +#' \item{Reference Data}{ Regerence Data} +#' \item{Comment}{ Additional comment} +#' } +"dataset_spec" diff --git a/_pkgdown.yml b/_pkgdown.yml index b3a5cde5..29b72472 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -45,6 +45,7 @@ reference: - contents: - adsl - var_spec + - dataset_spec articles: - title: ~ diff --git a/data/dataset_spec.rda b/data/dataset_spec.rda new file mode 100644 index 0000000000000000000000000000000000000000..be9c31c4d8dd8a0c495a96c953fb55d3abc34e2d GIT binary patch literal 310 zcmV-60m=R!iwFP!000001AS4?PlGTR?FMLuKeEKT;Sbn$@#1yTn4mit3TB>`!afY9 z6w(&WZvN$J3)Czm+Ju(xeXp;tuQA@<_*)+#_ znSfS>pcRaCW}^OBag7_T3**H&_|{{5pe4<_aC`97Ce@c`7-TNWri;Lu?|cr25hdDO zwF2z^r&ctzwB_X^92UVd6(!9W{O*dO0UaxUwX_%t5WsWjUdn2PbyWd3ul8lWAISs% I2|xk>0OjA7% rename(type = "Data Type") %>% set_names(tolower) -dataset_spec <- readxl::read_xlsx(spec_path, sheet = "Datasets") %>% +dataset_spec <- dataset_spec %>% rename(label = "Description") %>% set_names(tolower) ``` From c36bb5f8c798c2af171096055c06228563e7275b Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 5 Dec 2023 06:30:48 +0530 Subject: [PATCH 14/43] docs: update docs --- man/dataset_spec.Rd | 30 ++++++++++++++++++++++++++++++ man/var_spec.Rd | 4 ++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 man/dataset_spec.Rd diff --git a/man/dataset_spec.Rd b/man/dataset_spec.Rd new file mode 100644 index 00000000..7ab0d370 --- /dev/null +++ b/man/dataset_spec.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{dataset_spec} +\alias{dataset_spec} +\title{Example Dataset Specification} +\format{ +\subsection{\code{dataset_spec}}{ + +A data frame with 1 row and 9 columns: +\describe{ +\item{Dataset}{\if{html}{\out{}} Dataset} +\item{Description}{\if{html}{\out{}} Dataset description} +\item{Class}{\if{html}{\out{}} Dataset class} +\item{Structure}{\if{html}{\out{}} Logical, indicating if there's a specific structure} +\item{Purpose}{\if{html}{\out{}} Purpose of the dataset} +\item{Key, Variables}{\if{html}{\out{}} Join Key variables in the dataset} +\item{Repeating}{\if{html}{\out{}} Indicates if the dataset is repeating} +\item{Reference Data}{\if{html}{\out{}} Regerence Data} +\item{Comment}{\if{html}{\out{}} Additional comment} +} +} +} +\usage{ +dataset_spec +} +\description{ +Example Dataset Specification +} +\keyword{datasets} diff --git a/man/var_spec.Rd b/man/var_spec.Rd index 1b688c9c..5460c33d 100644 --- a/man/var_spec.Rd +++ b/man/var_spec.Rd @@ -3,7 +3,7 @@ \docType{data} \name{var_spec} \alias{var_spec} -\title{Example Dataset Specification} +\title{Example Dataset Variable Specification} \format{ \subsection{\code{var_spec}}{ @@ -35,6 +35,6 @@ A data frame with 216 rows and 19 columns: var_spec } \description{ -Example Dataset Specification +Example Dataset Variable Specification } \keyword{datasets} From 40a1dd4d0cb02b0b9858d5987b6d0c8d8af584b3 Mon Sep 17 00:00:00 2001 From: elimillera Date: Thu, 7 Dec 2023 16:57:31 +0000 Subject: [PATCH 15/43] [skip actions] Bump version to 0.3.1.9001 --- DESCRIPTION | 114 +++++++++++++++++++++------------------------------- 1 file changed, 45 insertions(+), 69 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 4e813ef9..29842a22 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,85 +1,61 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9000 -Authors@R: - c( - person(given = "Eli", - family = "Miller", - role = c("aut", "cre"), - email = "Eli.Miller@AtorusResearch.com", +Version: 0.3.1.9001 +Authors@R: c( + person("Eli", "Miller", , "Eli.Miller@AtorusResearch.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-2127-9456")), - person(given = "Vignesh ", - family = "Thanikachalam", - role = c("aut")), - person(given = "Ben", - family = "Straub", - role = ("aut")), - person(given = "Ross", - family = "Didenko", - role = ("aut")), - person(given = "Zelos", - family = "Zhu", - role = ("aut")), - person(given = "Ethan", - family = "Brockmann", - role = ("aut")), - person(given = "Vedha", - family = "Viyash", - role = ("aut")), - person(given = "Andre", - family = "Verissimo", - role = ("aut")), - person(given = "Sophie", - family = "Shapcott", - role = ("aut")), - person(given = "Celine", - family = "Piraux", - role = ("aut")), - person(given = "Adrian", - family = "Chan", - role = ("aut")), - person(given = "Sadchla", - family = "Mascary", - role = ("aut")), - person(given = "Atorus/GSK JPT", - role = "cph")) -Description: Tools to build CDISC compliant data sets and check for CDISC compliance. + person("Vignesh ", "Thanikachalam", role = "aut"), + person("Ben", "Straub", role = "aut"), + person("Ross", "Didenko", role = "aut"), + person("Zelos", "Zhu", role = "aut"), + person("Ethan", "Brockmann", role = "aut"), + person("Vedha", "Viyash", role = "aut"), + person("Andre", "Verissimo", role = "aut"), + person("Sophie", "Shapcott", role = "aut"), + person("Celine", "Piraux", role = "aut"), + person("Adrian", "Chan", role = "aut"), + person("Sadchla", "Mascary", role = "aut"), + person("Atorus/GSK JPT", role = "cph") + ) +Description: Tools to build CDISC compliant data sets and check for CDISC + compliance. +License: MIT + file LICENSE URL: https://github.com/atorus-research/xportr BugReports: https://github.com/atorus-research/xportr/issues +Depends: + R (>= 3.5) Imports: + cli, dplyr (>= 1.0.2), - purrr (>= 0.3.4), - stringr (>= 1.4.0), - magrittr, glue (>= 1.4.2), + haven (>= 2.5.0), + janitor, + lifecycle, + magrittr, + purrr (>= 0.3.4), + readr, rlang (>= 0.4.10), - cli, + stringr (>= 1.4.0), tidyselect, - readr, - janitor, - tm, - haven (>= 2.5.0), - lifecycle -License: MIT + file LICENSE -Encoding: UTF-8 -LazyData: true -Roxygen: list(markdown = TRUE) -RoxygenNote: 7.2.3 + tm Suggests: - testthat (>= 3.0.0), - withr, - knitr, - rmarkdown, - readxl, - DT, - labelled, admiral, devtools, + DT, + knitr, + labelled, + lintr, + metacore, + readxl, + rmarkdown, spelling, + testthat (>= 3.0.0), usethis, - lintr, - metacore + withr +VignetteBuilder: + knitr Config/testthat/edition: 3 -VignetteBuilder: knitr -Depends: - R (>= 3.5) +Encoding: UTF-8 +LazyData: true +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.2.3 From 7dd04d0a3a32afdc3ffb0feeff7df5d5e1c38d4e Mon Sep 17 00:00:00 2001 From: vedhav Date: Thu, 7 Dec 2023 17:16:40 +0000 Subject: [PATCH 16/43] [skip actions] Bump version to 0.3.1.9002 --- DESCRIPTION | 2 +- NEWS.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 29842a22..1f3a1a59 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9001 +Version: 0.3.1.9002 Authors@R: c( person("Eli", "Miller", , "Eli.Miller@AtorusResearch.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-2127-9456")), diff --git a/NEWS.md b/NEWS.md index 86f99365..a4fc0187 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# xportr 0.3.1.9001 +# xportr 0.3.1.9002 ## New Features and Bug Fixes * `xportr_write()` now accepts `metadata` argument which can be used to set the dataset label to stay consistent with the other `xportr_*` functions. It is noteworthy that the dataset label set using the `xportr_df_label()` function will be retained during the `xportr_write()`. From b09805e4499204f370b847645de613e96f9ad1bc Mon Sep 17 00:00:00 2001 From: Ben Straub Date: Thu, 7 Dec 2023 14:30:03 -0500 Subject: [PATCH 17/43] docs: #81 added new blurb --- NEWS.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index a4fc0187..dbbab276 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,14 +1,19 @@ -# xportr 0.3.1.9002 +# xportr (development version) ## New Features and Bug Fixes + * `xportr_write()` now accepts `metadata` argument which can be used to set the dataset label to stay consistent with the other `xportr_*` functions. It is noteworthy that the dataset label set using the `xportr_df_label()` function will be retained during the `xportr_write()`. -* Exporting a new dataset `dataset_spec` that contains the Dataset Specification for ADSL. +* Exporting a new dataset `dataset_spec` that contains the Dataset Specification for ADSL. (#179) ## Deprecation and Breaking Changes -* The `label` argument from the `xportr_write()` function is deprecated in favor of the `metadata` argument. + +* The `label` argument from the `xportr_write()` function is deprecated in favor of the `metadata` argument. (#179) ## Documentation +* Created development version of the website (#187) +* Additional guidance for options added in deep dive vignette (#81) + # xportr 0.3.1 ## New Features and Bug Fixes From c090ea5db800a3976adfa45925a9e066980e6272 Mon Sep 17 00:00:00 2001 From: bms63 Date: Thu, 7 Dec 2023 19:47:20 +0000 Subject: [PATCH 18/43] [skip actions] Bump version to 0.3.1.9003 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 1f3a1a59..065cf316 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9002 +Version: 0.3.1.9003 Authors@R: c( person("Eli", "Miller", , "Eli.Miller@AtorusResearch.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-2127-9456")), From 2851f70e43c334e47ea25ba96fea934205113cd8 Mon Sep 17 00:00:00 2001 From: Kangjie Zhang Date: Thu, 7 Dec 2023 21:36:41 +0000 Subject: [PATCH 19/43] add a test for non-acsii character >200 bytes, <200 characters --- tests/testthat/test-utils-xportr.R | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/testthat/test-utils-xportr.R b/tests/testthat/test-utils-xportr.R index 7c272fe0..41f6adb8 100644 --- a/tests/testthat/test-utils-xportr.R +++ b/tests/testthat/test-utils-xportr.R @@ -119,3 +119,11 @@ test_that("xpt_validate: Get error message when the length of a character variab "Length of A must be 200 bytes or less." ) }) + +test_that("xpt_validate: Get error message when the length of a non-ASCII character variable is > 200 bytes", { + df <- data.frame(A = paste(rep("一", 67), collapse = "")) + expect_equal( + xpt_validate(df), + "Length of A must be 200 bytes or less." + ) +}) From 362a505b2665968233905066e221753b6ec1c3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9line=20Piraux?= Date: Mon, 11 Dec 2023 13:42:11 +0100 Subject: [PATCH 20/43] include filename check in strict_checks --- R/write.R | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/R/write.R b/R/write.R index 0dd13541..84bea9c1 100644 --- a/R/write.R +++ b/R/write.R @@ -75,12 +75,12 @@ xportr_write <- function(.df, abort("`.df` file name must be 8 characters or less.") } + checks <- xpt_validate(.df) + if (stringr::str_detect(name, "[^a-zA-Z0-9]")) { - abort("`.df` cannot contain any non-ASCII, symbol or underscore characters.") + checks <- c(checks, "`.df` cannot contain any non-ASCII, symbol or underscore characters.") } - checks <- xpt_validate(.df) - if (length(checks) > 0) { if (!strict_checks) { warn(c("The following validation checks failed:", checks)) From 90a691449e321583608c9c32f5749716f43b23bb Mon Sep 17 00:00:00 2001 From: Kangjie Zhang <47867131+kaz462@users.noreply.github.com> Date: Wed, 13 Dec 2023 21:22:58 -0800 Subject: [PATCH 21/43] Update R/utils-xportr.R MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: André Veríssimo <211358+averissimo@users.noreply.github.com> --- R/utils-xportr.R | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/R/utils-xportr.R b/R/utils-xportr.R index 5e21c7e9..860d2cf6 100644 --- a/R/utils-xportr.R +++ b/R/utils-xportr.R @@ -307,10 +307,12 @@ xpt_validate <- function(data) { max_nchar <- data %>% dplyr::summarise(across(where(is.character), ~ max(nchar(., type = "bytes")))) nchar_gt_200 <- max_nchar[which(max_nchar > 200)] - err_cnd <- c( - err_cnd, - glue("Length of {names(nchar_gt_200)} must be 200 bytes or less.") - ) + if (length(nchar_gt_200) > 0) { + err_cnd <- c( + err_cnd, + glue("Length of {names(nchar_gt_200)} must be 200 bytes or less.") + ) + } return(err_cnd) } From 5ff189a45f5ddaea932b178aea37af813de66934 Mon Sep 17 00:00:00 2001 From: Kangjie Zhang <47867131+kaz462@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:56:44 -0500 Subject: [PATCH 22/43] Update R/utils-xportr.R MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: André Veríssimo <211358+averissimo@users.noreply.github.com> --- R/utils-xportr.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/utils-xportr.R b/R/utils-xportr.R index 860d2cf6..feb31195 100644 --- a/R/utils-xportr.R +++ b/R/utils-xportr.R @@ -305,7 +305,7 @@ xpt_validate <- function(data) { # 4.0 max length of Character variables <= 200 bytes max_nchar <- data %>% - dplyr::summarise(across(where(is.character), ~ max(nchar(., type = "bytes")))) + summarize(across(where(is.character), ~ max(nchar(., type = "bytes")))) nchar_gt_200 <- max_nchar[which(max_nchar > 200)] if (length(nchar_gt_200) > 0) { err_cnd <- c( From 6a74578bb5698e3d094ce6c8cfbc656e4bfaf5f9 Mon Sep 17 00:00:00 2001 From: Kangjie Zhang Date: Thu, 14 Dec 2023 18:06:30 +0000 Subject: [PATCH 23/43] add across/where to import --- NAMESPACE | 2 ++ R/xportr-package.R | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 2b7d1412..d2f10378 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -23,6 +23,7 @@ importFrom(cli,cli_alert_success) importFrom(cli,cli_div) importFrom(cli,cli_h2) importFrom(cli,cli_text) +importFrom(dplyr,across) importFrom(dplyr,arrange) importFrom(dplyr,bind_cols) importFrom(dplyr,case_when) @@ -61,6 +62,7 @@ importFrom(stringr,str_replace) importFrom(stringr,str_replace_all) importFrom(tidyselect,all_of) importFrom(tidyselect,any_of) +importFrom(tidyselect,where) importFrom(tm,stemDocument) importFrom(utils,capture.output) importFrom(utils,packageVersion) diff --git a/R/xportr-package.R b/R/xportr-package.R index 701c4a52..197ad5be 100644 --- a/R/xportr-package.R +++ b/R/xportr-package.R @@ -95,11 +95,11 @@ #' @import rlang haven #' @importFrom dplyr left_join bind_cols filter select rename rename_with n #' everything arrange group_by summarize mutate ungroup case_when distinct -#' tribble if_else +#' tribble if_else across #' @importFrom glue glue glue_collapse #' @importFrom cli cli_alert_info cli_h2 cli_alert_success cli_div cli_text #' cli_alert_danger -#' @importFrom tidyselect all_of any_of +#' @importFrom tidyselect all_of any_of where #' @importFrom utils capture.output str tail packageVersion #' @importFrom stringr str_detect str_extract str_replace str_replace_all #' @importFrom readr parse_number From 71f59959c07d6974067e782a5d4b77c00cd18600 Mon Sep 17 00:00:00 2001 From: bms63 Date: Fri, 15 Dec 2023 16:36:54 +0000 Subject: [PATCH 24/43] [skip actions] Bump version to 0.3.1.9004 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 065cf316..0288c86c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9003 +Version: 0.3.1.9004 Authors@R: c( person("Eli", "Miller", , "Eli.Miller@AtorusResearch.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-2127-9456")), From 8747e76d721505e247df06b8886b163e2eefc116 Mon Sep 17 00:00:00 2001 From: Celine Date: Mon, 18 Dec 2023 04:27:35 -0500 Subject: [PATCH 25/43] Add test for underscore in filename --- tests/testthat/test-write.R | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/testthat/test-write.R b/tests/testthat/test-write.R index 4229c06e..953a6939 100644 --- a/tests/testthat/test-write.R +++ b/tests/testthat/test-write.R @@ -91,6 +91,15 @@ test_that("xportr_write: expect error when file name contains non-ASCII symbols expect_error(xportr_write(data_to_save, tmp)) }) +test_that("xportr_write: expect warning when file name contains underscore and strict_checks = FALSE", { + tmpdir <- tempdir() + tmp <- file.path(tmpdir, "test_.xpt") + + on.exit(unlink(tmpdir)) + + expect_warning(xportr_write(data_to_save, tmp, strict_checks = FALSE)) +}) + test_that("xportr_write: expect error when label contains non-ASCII symbols or special characters", { tmpdir <- tempdir() tmp <- file.path(tmpdir, "xyz.xpt") From 49b44e834031de0b64d5e15080009463ee1fd29a Mon Sep 17 00:00:00 2001 From: elimillera Date: Mon, 18 Dec 2023 21:36:22 +0000 Subject: [PATCH 26/43] Add news entry --- NEWS.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index 27f14385..aa4049f2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,10 @@ ## Deprecation and Breaking Changes +* The `domain` argument for xportr functions will no longer be dynamically +determined by the name of the data frame passed as the .df argument. This was +done to make the use of xportr functions more explicit. (#182) + # xportr 0.3.1 ## New Features and Bug Fixes From 9da5288947dd80197aec48c191158f6d21220674 Mon Sep 17 00:00:00 2001 From: elimillera Date: Mon, 18 Dec 2023 21:45:55 +0000 Subject: [PATCH 27/43] Remove unneeded tests --- tests/testthat/test-metadata.R | 37 ++++++ tests/testthat/test-pipe.R | 202 --------------------------------- 2 files changed, 37 insertions(+), 202 deletions(-) delete mode 100644 tests/testthat/test-pipe.R diff --git a/tests/testthat/test-metadata.R b/tests/testthat/test-metadata.R index 9841ae0d..20a4aa63 100644 --- a/tests/testthat/test-metadata.R +++ b/tests/testthat/test-metadata.R @@ -607,4 +607,41 @@ test_that("xportr_metadata: Check metadata interaction with other functions", { ) ) }) + +test_that("xportr_*: Domain is kept in between calls", { + # Divert all messages to tempfile, instead of printing them + # note: be aware as this should only be used in tests that don't track + # messages + withr::local_message_sink(tempfile()) + + adsl <- minimal_table(30) + + metadata <- minimal_metadata( + dataset = TRUE, length = TRUE, label = TRUE, type = TRUE, format = TRUE, + order = TRUE + ) + + df2 <- adsl %>% + xportr_domain_name("adsl") %>% + xportr_type(metadata) + + df3 <- df2 %>% + xportr_label(metadata) %>% + xportr_length(metadata) %>% + xportr_order(metadata) %>% + xportr_format(metadata) + + expect_equal(attr(df3, "_xportr.df_arg_"), "adsl") + + df4 <- adsl %>% + xportr_type(metadata, domain = "adsl") + + df5 <- df4 %>% + xportr_label(metadata) %>% + xportr_length(metadata) %>% + xportr_order(metadata) %>% + xportr_format(metadata) + + expect_equal(attr(df5, "_xportr.df_arg_"), "adsl") +}) # end diff --git a/tests/testthat/test-pipe.R b/tests/testthat/test-pipe.R deleted file mode 100644 index 90876763..00000000 --- a/tests/testthat/test-pipe.R +++ /dev/null @@ -1,202 +0,0 @@ -test_that("xportr_*: Domain is kept in between calls", { - # Divert all messages to tempfile, instead of printing them - # note: be aware as this should only be used in tests that don't track - # messages - withr::local_message_sink(tempfile()) - - adsl <- minimal_table(30) - - metadata <- minimal_metadata( - dataset = TRUE, length = TRUE, label = TRUE, type = TRUE, format = TRUE, - order = TRUE - ) - - df2 <- adsl %>% - xportr_domain_name("adsl") %>% - xportr_type(metadata) - - df3 <- df2 %>% - xportr_label(metadata) %>% - xportr_length(metadata) %>% - xportr_order(metadata) %>% - xportr_format(metadata) - - expect_equal(attr(df3, "_xportr.df_arg_"), "adsl") - - df4 <- adsl %>% - xportr_type(metadata, domain = "adsl") - - df5 <- df4 %>% - xportr_label(metadata) %>% - xportr_length(metadata) %>% - xportr_order(metadata) %>% - xportr_format(metadata) - - expect_equal(attr(df5, "_xportr.df_arg_"), "adsl") -}) - -test_that("xportr_*: Can use magrittr pipe and aquire domain from call", { - # Divert all messages to tempfile, instead of printing them - # note: be aware as this should only be used in tests that don't track - # messages - withr::local_message_sink(tempfile()) - - adsl <- minimal_table(30) - - metadata <- minimal_metadata( - dataset = TRUE, length = TRUE, label = TRUE, type = TRUE, format = TRUE, - order = TRUE - ) - - non_standard_name <- adsl - result <- non_standard_name %>% - xportr_domain_name("non_standard_name") %>% - xportr_type(metadata) %>% - xportr_label(metadata) %>% - xportr_length(metadata) %>% - xportr_order(metadata) %>% - xportr_format(metadata) %>% - xportr_df_label(metadata) - - expect_equal(attr(result, "_xportr.df_arg_"), "non_standard_name") - - # Different sequence call by moving first and last around - result2 <- non_standard_name %>% - xportr_domain_name("non_standard_name") %>% - xportr_label(metadata) %>% - xportr_length(metadata) %>% - xportr_order(metadata) %>% - xportr_df_label(metadata) %>% - xportr_type(metadata) %>% - xportr_format(metadata) - - expect_equal(attr(result2, "_xportr.df_arg_"), "non_standard_name") -}) - -test_that("xportr_*: Can use magrittr pipe and aquire domain from call (metadata)", { - # Divert all messages to tempfile, instead of printing them - # note: be aware as this should only be used in tests that don't track - # messages - withr::local_message_sink(tempfile()) - - adsl <- minimal_table(30) - - metadata <- minimal_metadata( - dataset = TRUE, length = TRUE, label = TRUE, type = TRUE, format = TRUE, - order = TRUE - ) - - non_standard_name <- adsl - result <- non_standard_name %>% - xportr_domain_name("non_standard_name") %>% - xportr_metadata(metadata) %>% - xportr_type() %>% - xportr_label() %>% - xportr_length() %>% - xportr_order() %>% - xportr_format() %>% - xportr_df_label() - - expect_equal(attr(result, "_xportr.df_arg_"), "non_standard_name") - - # Different sequence call by moving first and last around - result2 <- non_standard_name %>% - xportr_domain_name("non_standard_name") %>% - xportr_metadata(metadata) %>% - xportr_label() %>% - xportr_length() %>% - xportr_order() %>% - xportr_df_label() %>% - xportr_type() %>% - xportr_format() - - expect_equal(attr(result2, "_xportr.df_arg_"), "non_standard_name") -}) - -test_that("xportr_*: Can use R native pipe (R>4.1) and aquire domain from call", { - skip_if( - compareVersion(glue("{R.version$major}.{R.version$minor}"), "4.1.0") < 0, - "R Version doesn't support native pipe (<4.1)" - ) - - # Divert all messages to tempfile, instead of printing them - # note: be aware as this should only be used in tests that don't track - # messages - withr::local_message_sink(tempfile()) - - adsl <- minimal_table(30) - - metadata <- minimal_metadata( - dataset = TRUE, length = TRUE, label = TRUE, type = TRUE, format = TRUE, - order = TRUE - ) - - non_standard_name_native <- adsl - result <- non_standard_name_native |> - xportr_domain_name("non_standard_name_native") |> - xportr_type(metadata) |> - xportr_label(metadata) |> - xportr_length(metadata) |> - xportr_order(metadata) |> - xportr_format(metadata) |> - xportr_df_label(metadata) - - expect_equal(attr(result, "_xportr.df_arg_"), "non_standard_name_native") - - # Different sequence call by moving first and last around - result2 <- non_standard_name_native |> - xportr_domain_name("non_standard_name_native") |> - xportr_label(metadata) |> - xportr_length(metadata) |> - xportr_order(metadata) |> - xportr_df_label(metadata) |> - xportr_type(metadata) |> - xportr_format(metadata) - - expect_equal(attr(result2, "_xportr.df_arg_"), "non_standard_name_native") -}) - -test_that("xportr_*: Can use R native pipe (R>4.1) and aquire domain from call (metadata)", { - skip_if( - compareVersion(glue("{R.version$major}.{R.version$minor}"), "4.1.0") < 0, - "R Version doesn't support native pipe (<4.1)" - ) - - # Divert all messages to tempfile, instead of printing them - # note: be aware as this should only be used in tests that don't track - # messages - withr::local_message_sink(tempfile()) - - adsl <- minimal_table(30) - - metadata <- minimal_metadata( - dataset = TRUE, length = TRUE, label = TRUE, type = TRUE, format = TRUE, - order = TRUE - ) - - non_standard_name_native <- adsl - result <- non_standard_name_native |> - xportr_domain_name("non_standard_name_native") |> - xportr_metadata(metadata) |> - xportr_type() |> - xportr_label() |> - xportr_length() |> - xportr_order() |> - xportr_format() |> - xportr_df_label() - - expect_equal(attr(result, "_xportr.df_arg_"), "non_standard_name_native") - - # Different sequence call by moving first and last around - result2 <- non_standard_name_native |> - xportr_domain_name("non_standard_name_native") |> - xportr_metadata(metadata) |> - xportr_label() |> - xportr_length() |> - xportr_order() |> - xportr_df_label() |> - xportr_type() |> - xportr_format() - - expect_equal(attr(result2, "_xportr.df_arg_"), "non_standard_name_native") -}) From e7d96c992b20614e2d0ab744bcd57d00f5f4dd8c Mon Sep 17 00:00:00 2001 From: elimillera Date: Mon, 18 Dec 2023 21:50:24 +0000 Subject: [PATCH 28/43] doc update for domain argument --- R/length.R | 5 +++-- man/metadata.Rd | 5 +++-- man/xportr_df_label.Rd | 5 +++-- man/xportr_format.Rd | 5 +++-- man/xportr_label.Rd | 5 +++-- man/xportr_length.Rd | 5 +++-- man/xportr_order.Rd | 5 +++-- man/xportr_type.Rd | 5 +++-- 8 files changed, 24 insertions(+), 16 deletions(-) diff --git a/R/length.R b/R/length.R index ec4e191a..46a6f7a7 100644 --- a/R/length.R +++ b/R/length.R @@ -9,8 +9,9 @@ #' @param metadata A data frame containing variable level metadata. See #' 'Metadata' section for details. #' @param domain Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -#' the metadata object. If none is passed, then name of the dataset passed as -#' .df will be used. +#' the metadata object. If none is passed, then [xportr_domain()] or +#' [xportr_metadata()] must be called before hand to set the domain as an +#' attribute of `.df`. #' @param verbose The action this function takes when an action is taken on the #' dataset or function validation finds an issue. See 'Messaging' section for #' details. Options are 'stop', 'warn', 'message', and 'none' diff --git a/man/metadata.Rd b/man/metadata.Rd index 2a7d0af0..e429b91d 100644 --- a/man/metadata.Rd +++ b/man/metadata.Rd @@ -16,8 +16,9 @@ xportr_domain_name(.df, domain) 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} } \value{ \code{.df} dataset with metadata and domain attributes set diff --git a/man/xportr_df_label.Rd b/man/xportr_df_label.Rd index 691de990..64c1aebb 100644 --- a/man/xportr_df_label.Rd +++ b/man/xportr_df_label.Rd @@ -13,8 +13,9 @@ xportr_df_label(.df, metadata = NULL, domain = NULL, metacore = deprecated()) details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} \item{metacore}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Previously used to pass metadata now renamed with \code{metadata}} diff --git a/man/xportr_format.Rd b/man/xportr_format.Rd index c6fd6e85..0bef1798 100644 --- a/man/xportr_format.Rd +++ b/man/xportr_format.Rd @@ -13,8 +13,9 @@ xportr_format(.df, metadata = NULL, domain = NULL, metacore = deprecated()) 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} \item{metacore}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Previously used to pass metadata now renamed with \code{metadata}} diff --git a/man/xportr_label.Rd b/man/xportr_label.Rd index 4cd7d18c..ecad5b4d 100644 --- a/man/xportr_label.Rd +++ b/man/xportr_label.Rd @@ -19,8 +19,9 @@ xportr_label( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for diff --git a/man/xportr_length.Rd b/man/xportr_length.Rd index 4c4dd224..d4a0b252 100644 --- a/man/xportr_length.Rd +++ b/man/xportr_length.Rd @@ -19,8 +19,9 @@ xportr_length( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for diff --git a/man/xportr_order.Rd b/man/xportr_order.Rd index 44f283cf..ef10eab0 100644 --- a/man/xportr_order.Rd +++ b/man/xportr_order.Rd @@ -19,8 +19,9 @@ xportr_order( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for diff --git a/man/xportr_type.Rd b/man/xportr_type.Rd index abfa41d8..8dfdfa1e 100644 --- a/man/xportr_type.Rd +++ b/man/xportr_type.Rd @@ -19,8 +19,9 @@ xportr_type( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for From 49bfdfbf299fe7343731e39b2e103acfe7f4079d Mon Sep 17 00:00:00 2001 From: Celine Date: Tue, 19 Dec 2023 08:41:58 -0500 Subject: [PATCH 29/43] Update New.md for #126 --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index 56a921e3..9dfa7fdc 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,7 @@ * Exporting a new dataset `dataset_spec` that contains the Dataset Specification for ADSL. (#179) * Added a check for character variable lengths up to 200 bytes in `xpt_validate()`(#91, #189). +* File name check is moved to strict_checks condition to allow underscores in the file name. Underscores are allowed in xpt but not per FDA requirements. (#126) ## Deprecation and Breaking Changes From da3fe758874cc8c82c5f2d4d405e17a5617e6846 Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 19 Dec 2023 21:33:23 +0530 Subject: [PATCH 30/43] chore: hard deprecate the `metacore` argument --- NEWS.md | 1 + R/df_label.R | 5 ++--- R/format.R | 5 ++--- R/label.R | 5 ++--- R/length.R | 5 ++--- R/order.R | 5 ++--- R/type.R | 5 ++--- 7 files changed, 13 insertions(+), 18 deletions(-) diff --git a/NEWS.md b/NEWS.md index 56a921e3..0adb7867 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,6 +10,7 @@ ## Deprecation and Breaking Changes * The `label` argument from the `xportr_write()` function is deprecated in favor of the `metadata` argument. (#179) +* The `metacore` argument, which was renamed to `metadata` in the following six xportr functions: (`xportr_df_label()`, `xportr_format()`, `xportr_label()`, `xportr_length()`, `xportr_order()`, and `xportr_type()`) in version `0.3.0` with a soft deprecation warning, has now been hard deprecated. Please update your code to use the new `metadata` argument in place of `metacore`. ## Documentation diff --git a/R/df_label.R b/R/df_label.R index 0621428a..91ba0c36 100644 --- a/R/df_label.R +++ b/R/df_label.R @@ -44,12 +44,11 @@ xportr_df_label <- function(.df, domain = NULL, metacore = deprecated()) { if (!missing(metacore)) { - lifecycle::deprecate_warn( - when = "0.3.0", + lifecycle::deprecate_stop( + when = "0.3.1.9005", what = "xportr_df_label(metacore = )", with = "xportr_df_label(metadata = )" ) - metadata <- metacore } domain_name <- getOption("xportr.df_domain_name") label_name <- getOption("xportr.df_label") diff --git a/R/format.R b/R/format.R index 17e15183..1b1a627d 100644 --- a/R/format.R +++ b/R/format.R @@ -46,12 +46,11 @@ xportr_format <- function(.df, domain = NULL, metacore = deprecated()) { if (!missing(metacore)) { - lifecycle::deprecate_warn( - when = "0.3.0", + lifecycle::deprecate_stop( + when = "0.3.1.9005", what = "xportr_format(metacore = )", with = "xportr_format(metadata = )" ) - metadata <- metacore } domain_name <- getOption("xportr.domain_name") format_name <- getOption("xportr.format_name") diff --git a/R/label.R b/R/label.R index e412e9fc..03a09348 100644 --- a/R/label.R +++ b/R/label.R @@ -62,12 +62,11 @@ xportr_label <- function(.df, verbose = getOption("xportr.label_verbose", "none"), metacore = deprecated()) { if (!missing(metacore)) { - lifecycle::deprecate_warn( - when = "0.3.0", + lifecycle::deprecate_stop( + when = "0.3.1.9005", what = "xportr_label(metacore = )", with = "xportr_label(metadata = )" ) - metadata <- metacore } domain_name <- getOption("xportr.domain_name") variable_name <- getOption("xportr.variable_name") diff --git a/R/length.R b/R/length.R index 17627268..1cd10980 100644 --- a/R/length.R +++ b/R/length.R @@ -69,12 +69,11 @@ xportr_length <- function(.df, verbose = getOption("xportr.length_verbose", "none"), metacore = deprecated()) { if (!missing(metacore)) { - lifecycle::deprecate_warn( - when = "0.3.0", + lifecycle::deprecate_stop( + when = "0.3.1.9005", what = "xportr_length(metacore = )", with = "xportr_length(metadata = )" ) - metadata <- metacore } domain_name <- getOption("xportr.domain_name") variable_length <- getOption("xportr.length") diff --git a/R/order.R b/R/order.R index 0f7e1b30..0c8d322f 100644 --- a/R/order.R +++ b/R/order.R @@ -65,12 +65,11 @@ xportr_order <- function(.df, verbose = getOption("xportr.order_verbose", "none"), metacore = deprecated()) { if (!missing(metacore)) { - lifecycle::deprecate_warn( - when = "0.3.0", + lifecycle::deprecate_stop( + when = "0.3.1.9005", what = "xportr_order(metacore = )", with = "xportr_order(metadata = )" ) - metadata <- metacore } domain_name <- getOption("xportr.domain_name") order_name <- getOption("xportr.order_name") diff --git a/R/type.R b/R/type.R index 78cf6dca..86d6bd15 100644 --- a/R/type.R +++ b/R/type.R @@ -82,12 +82,11 @@ xportr_type <- function(.df, verbose = getOption("xportr.type_verbose", "none"), metacore = deprecated()) { if (!missing(metacore)) { - lifecycle::deprecate_warn( - when = "0.3.0", + lifecycle::deprecate_stop( + when = "0.3.1.9005", what = "xportr_type(metacore = )", with = "xportr_type(metadata = )" ) - metadata <- metacore } # Name of the columns for working with metadata domain_name <- getOption("xportr.domain_name") From e9a3e997f04840c31a546baadfa162de4f425301 Mon Sep 17 00:00:00 2001 From: vedhav Date: Tue, 19 Dec 2023 21:48:16 +0530 Subject: [PATCH 31/43] chore: fix tests --- tests/testthat/test-depreciation.R | 65 ++++++------------------------ tests/testthat/test-length.R | 1 - tests/testthat/test-metadata.R | 1 + tests/testthat/test-order.R | 1 - 4 files changed, 13 insertions(+), 55 deletions(-) diff --git a/tests/testthat/test-depreciation.R b/tests/testthat/test-depreciation.R index 157f59b1..2679ecc9 100644 --- a/tests/testthat/test-depreciation.R +++ b/tests/testthat/test-depreciation.R @@ -1,16 +1,12 @@ -test_that("xportr_df_label: deprecated metacore argument still works and gives warning", { +test_that("xportr_df_label: deprecated metacore gives an error", { withr::local_options(lifecycle_verbosity = "quiet") df <- data.frame(x = "a", y = "b") df_meta <- data.frame(dataset = "df", label = "Label") - df_spec_labeled_df <- xportr_df_label(df, metacore = df_meta) - - expect_equal(attr(df_spec_labeled_df, "label"), "Label") - xportr_df_label(df, metacore = df_meta) %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") + expect_error(xportr_df_label(df, metacore = df_meta)) }) -test_that("xportr_format: deprecated metacore argument still works and gives warning", { +test_that("xportr_format: deprecated metacore gives an error", { withr::local_options(lifecycle_verbosity = "quiet") df <- data.frame(x = 1, y = 2) df_meta <- data.frame( @@ -19,33 +15,19 @@ test_that("xportr_format: deprecated metacore argument still works and gives war format = "date9." ) - formatted_df <- xportr_format(df, metacore = df_meta) - - expect_equal(attr(formatted_df$x, "format.sas"), "DATE9.") - xportr_format(df, metacore = df_meta) %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") + expect_error(xportr_format(df, metacore = df_meta)) }) -test_that("xportr_label: deprecated metacore argument still works and gives warning", { +test_that("xportr_label: using the deprecated metacore argument gives an error", { withr::local_options(lifecycle_verbosity = "quiet") df <- data.frame(x = "a", y = "b") df_meta <- data.frame(dataset = "df", variable = "x", label = "foo") - df_labeled_df <- suppressMessages( - xportr_label(df, metacore = df_meta) - ) - - expect_equal(attr(df_labeled_df$x, "label"), "foo") - - # Note that only the deprecated message should be caught (others are ignored) - suppressMessages( - xportr_label(df, metacore = df_meta) %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") - ) + expect_error(xportr_label(df, metacore = df_meta)) }) -test_that("xportr_length: deprecated metacore argument still works and gives warning", { +test_that("xportr_length: using the deprecated metacore argument gives an error", { withr::local_options(lifecycle_verbosity = "quiet") df <- data.frame(x = "a", y = "b") df_meta <- data.frame( @@ -55,15 +37,10 @@ test_that("xportr_length: deprecated metacore argument still works and gives war length = c(1, 2) ) - df_with_width <- xportr_length(df, metacore = df_meta) - - expect_equal(c(x = 1, y = 2), map_dbl(df_with_width, attr, "width")) - - xportr_length(df, metacore = df_meta) %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") + expect_error(xportr_length(df, metacore = df_meta)) }) -test_that("xportr_order: deprecated metacore argument still works and gives warning", { +test_that("xportr_order: using the deprecated metacore argument gives an error", { withr::local_options(lifecycle_verbosity = "quiet") df <- data.frame(c = 1:5, a = "a", d = 5:1, b = LETTERS[1:5]) @@ -73,20 +50,10 @@ test_that("xportr_order: deprecated metacore argument still works and gives warn order = 1:4 ) - ordered_df <- suppressMessages( - xportr_order(df, metacore = df_meta, domain = "DOMAIN") - ) - - expect_equal(names(ordered_df), df_meta$variable) - - # Note that only the deprecated message should be caught (others are ignored) - suppressMessages( - xportr_order(df, metacore = df_meta) %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") - ) + expect_error(xportr_order(df, metacore = df_meta, domain = "DOMAIN")) }) -test_that("xportr_type: deprecated metacore argument still works and gives warning", { +test_that("xportr_type: using the deprecated metacore argument gives an error", { withr::local_options(lifecycle_verbosity = "quiet") df <- data.frame( Subj = as.character(c(123, 456, 789, "", NA, NA_integer_)), @@ -101,13 +68,5 @@ test_that("xportr_type: deprecated metacore argument still works and gives warni format = NA ) - df2 <- suppressMessages( - xportr_type(df, metacore = df_meta) - ) - - # Note that only the deprecated message should be caught (others are ignored) - suppressMessages( - xportr_type(df, metacore = df_meta) %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") - ) + expect_error(xportr_type(df, metacore = df_meta)) }) diff --git a/tests/testthat/test-length.R b/tests/testthat/test-length.R index e749684d..35761d84 100644 --- a/tests/testthat/test-length.R +++ b/tests/testthat/test-length.R @@ -181,7 +181,6 @@ test_that("xportr_length: Metacore instance can be used", { }) test_that("xportr_length: Domain not in character format", { - skip_if_not_installed("haven") skip_if_not_installed("readxl") require(haven, quietly = TRUE) diff --git a/tests/testthat/test-metadata.R b/tests/testthat/test-metadata.R index b232ea2d..465d0de5 100644 --- a/tests/testthat/test-metadata.R +++ b/tests/testthat/test-metadata.R @@ -547,6 +547,7 @@ test_that("xportr_length: Expect error if domain is not a character", { # tests for `xportr_metadata()` basic functionality # start test_that("xportr_metadata: Check metadata interaction with other functions", { + skip_if_not_installed("admiral") adsl <- admiral::admiral_adsl var_spec <- diff --git a/tests/testthat/test-order.R b/tests/testthat/test-order.R index 801108c4..4caba77d 100644 --- a/tests/testthat/test-order.R +++ b/tests/testthat/test-order.R @@ -110,7 +110,6 @@ test_that("xportr_order: error when metadata is not set", { }) test_that("xportr_order: Variable ordering messaging is correct", { - skip_if_not_installed("haven") skip_if_not_installed("readxl") require(haven, quietly = TRUE) From a5bd5271e2c1c5e3e0ce9a2df32b1fd6358d1df3 Mon Sep 17 00:00:00 2001 From: Eli Miller Date: Tue, 19 Dec 2023 10:28:10 -0600 Subject: [PATCH 32/43] Update R/metadata.R Co-authored-by: Ben Straub --- R/metadata.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/metadata.R b/R/metadata.R index 325a3ff4..2db7d1b5 100644 --- a/R/metadata.R +++ b/R/metadata.R @@ -54,7 +54,7 @@ xportr_metadata <- function(.df, metadata, domain = NULL) { #' Update Metadata Domain Name #' -#' Similar to `xportr_metadata`, but just added the domain and not the metadata. +#' Similar to `xportr_metadata()`, but just adds the domain and not the metadata. #' #' @inheritParams xportr_length #' From dc832f3be650a5bcbd28a6fdf700fb90ed488635 Mon Sep 17 00:00:00 2001 From: elimillera Date: Tue, 19 Dec 2023 16:29:41 +0000 Subject: [PATCH 33/43] Update with PR comments --- R/length.R | 2 +- README.Rmd | 4 ++-- README.md | 3 ++- man/metadata.Rd | 2 +- man/xportr_df_label.Rd | 2 +- man/xportr_format.Rd | 2 +- man/xportr_label.Rd | 2 +- man/xportr_length.Rd | 2 +- man/xportr_order.Rd | 2 +- man/xportr_type.Rd | 2 +- 10 files changed, 12 insertions(+), 11 deletions(-) diff --git a/R/length.R b/R/length.R index 46a6f7a7..1b007970 100644 --- a/R/length.R +++ b/R/length.R @@ -9,7 +9,7 @@ #' @param metadata A data frame containing variable level metadata. See #' 'Metadata' section for details. #' @param domain Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -#' the metadata object. If none is passed, then [xportr_domain()] or +#' the metadata object. If none is passed, then [xportr_domain_name()] or #' [xportr_metadata()] must be called before hand to set the domain as an #' attribute of `.df`. #' @param verbose The action this function takes when an action is taken on the diff --git a/README.Rmd b/README.Rmd index 5f8431f5..1541a21b 100644 --- a/README.Rmd +++ b/README.Rmd @@ -137,8 +137,8 @@ adsl %>% xportr_label(var_spec, verbose = "warn") %>% xportr_order(var_spec, verbose = "warn") %>% xportr_format(var_spec) %>% - xportr_df_label(dataset_spec, "ADSL") %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_df_label(dataset_spec, "ADSL") %>% + xportr_write("adsl.xpt") ``` The `xportr_metadata()` function can reduce duplication by setting the variable specification and domain explicitly at the top of a pipeline. If you would like to use the `verbose` argument, you will need to set in each function call. diff --git a/README.md b/README.md index 646d0b45..cc83fae4 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ +[](https://RValidationHub.slack.com) [![R build status](https://github.com/atorus-research/xportr/workflows/R-CMD-check/badge.svg)](https://github.com/atorus-research/xportr/actions?workflow=R-CMD-check) [](https://app.codecov.io/gh/atorus-research/xportr) @@ -144,7 +145,7 @@ adsl %>% xportr_order(var_spec, verbose = "warn") %>% xportr_format(var_spec) %>% xportr_df_label(dataset_spec, "ADSL") %>% - xportr_write("adsl.xpt", label = "Subject-Level Analysis Dataset") + xportr_write("adsl.xpt") ``` The `xportr_metadata()` function can reduce duplication by setting the diff --git a/man/metadata.Rd b/man/metadata.Rd index e429b91d..d6171414 100644 --- a/man/metadata.Rd +++ b/man/metadata.Rd @@ -16,7 +16,7 @@ xportr_domain_name(.df, domain) 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or \code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an attribute of \code{.df}.} } diff --git a/man/xportr_df_label.Rd b/man/xportr_df_label.Rd index 64c1aebb..6d4764b4 100644 --- a/man/xportr_df_label.Rd +++ b/man/xportr_df_label.Rd @@ -13,7 +13,7 @@ xportr_df_label(.df, metadata = NULL, domain = NULL, metacore = deprecated()) details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or \code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an attribute of \code{.df}.} diff --git a/man/xportr_format.Rd b/man/xportr_format.Rd index 0bef1798..b7825fc4 100644 --- a/man/xportr_format.Rd +++ b/man/xportr_format.Rd @@ -13,7 +13,7 @@ xportr_format(.df, metadata = NULL, domain = NULL, metacore = deprecated()) 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or \code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an attribute of \code{.df}.} diff --git a/man/xportr_label.Rd b/man/xportr_label.Rd index ecad5b4d..87d648da 100644 --- a/man/xportr_label.Rd +++ b/man/xportr_label.Rd @@ -19,7 +19,7 @@ xportr_label( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or \code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an attribute of \code{.df}.} diff --git a/man/xportr_length.Rd b/man/xportr_length.Rd index d4a0b252..1d5100df 100644 --- a/man/xportr_length.Rd +++ b/man/xportr_length.Rd @@ -19,7 +19,7 @@ xportr_length( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or \code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an attribute of \code{.df}.} diff --git a/man/xportr_order.Rd b/man/xportr_order.Rd index ef10eab0..72bda30d 100644 --- a/man/xportr_order.Rd +++ b/man/xportr_order.Rd @@ -19,7 +19,7 @@ xportr_order( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or \code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an attribute of \code{.df}.} diff --git a/man/xportr_type.Rd b/man/xportr_type.Rd index 8dfdfa1e..3c67c4c7 100644 --- a/man/xportr_type.Rd +++ b/man/xportr_type.Rd @@ -19,7 +19,7 @@ xportr_type( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain]{xportr_domain()}} or +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or \code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an attribute of \code{.df}.} From e378cbdcb80233a2e9605fcbe322d1f17ea15857 Mon Sep 17 00:00:00 2001 From: elimillera Date: Tue, 19 Dec 2023 16:46:30 +0000 Subject: [PATCH 34/43] passing R CMD Check --- R/write.R | 6 +++--- man/metadata.Rd | 2 +- man/xportr_write.Rd | 6 ++++-- tests/testthat/test-write.R | 8 ++++++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/R/write.R b/R/write.R index 0dd13541..c9005471 100644 --- a/R/write.R +++ b/R/write.R @@ -37,6 +37,7 @@ #' var_spec <- data.frame(dataset = "adsl", label = "Subject-Level Analysis Dataset") #' xportr_write(adsl, #' path = paste0(tempdir(), "/adsl.xpt"), +#' domain = "adsl", #' metadata = var_spec, #' strict_checks = FALSE #' ) @@ -51,10 +52,9 @@ xportr_write <- function(.df, name <- tools::file_path_sans_ext(basename(path)) - ## Common section to detect domain from argument or pipes + ## Common section to detect domain from argument or attribute - df_arg <- tryCatch(as_name(enexpr(.df)), error = function(err) NULL) - domain <- get_domain(.df, df_arg, domain) + domain <- get_domain(.df, domain) if (!is.null(domain)) attr(.df, "_xportr.df_arg_") <- domain ## End of common section diff --git a/man/metadata.Rd b/man/metadata.Rd index d6171414..f3c497de 100644 --- a/man/metadata.Rd +++ b/man/metadata.Rd @@ -31,7 +31,7 @@ functions. If used at the start of an xportr pipeline, it removes the need to set metadata and domain at each step individually. For details on the format of the metadata, see the 'Metadata' section for each function in question. -Similar to \code{xportr_metadata}, but just added the domain and not the metadata. +Similar to \code{xportr_metadata()}, but just adds the domain and not the metadata. } \examples{ diff --git a/man/xportr_write.Rd b/man/xportr_write.Rd index b59e61bd..9ecbd3a4 100644 --- a/man/xportr_write.Rd +++ b/man/xportr_write.Rd @@ -23,8 +23,9 @@ used as \code{xpt} name.} 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then name of the dataset passed as -.df will be used.} +the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or +\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an +attribute of \code{.df}.} \item{strict_checks}{If TRUE, xpt validation will report errors and not write out the dataset. If FALSE, xpt validation will report warnings and continue @@ -60,6 +61,7 @@ adsl <- data.frame( var_spec <- data.frame(dataset = "adsl", label = "Subject-Level Analysis Dataset") xportr_write(adsl, path = paste0(tempdir(), "/adsl.xpt"), + domain = "adsl", metadata = var_spec, strict_checks = FALSE ) diff --git a/tests/testthat/test-write.R b/tests/testthat/test-write.R index 4229c06e..e45abce0 100644 --- a/tests/testthat/test-write.R +++ b/tests/testthat/test-write.R @@ -16,7 +16,7 @@ test_that("xportr_write: exported data can still be saved to a file with a label on.exit(unlink(tmpdir)) - suppressWarnings(xportr_write(data_to_save, path = tmp, label = "Lorem ipsum dolor sit amet")) + suppressWarnings(xportr_write(data_to_save, path = tmp, label = "Lorem ipsum dolor sit amet", domain = "data_to_save")) expect_output(str(read_xpt(tmp)), "Lorem ipsum dolor sit amet") }) @@ -29,6 +29,7 @@ test_that("xportr_write: exported data can be saved to a file with a metadata", xportr_write( data_to_save, path = tmp, + domain = "data_to_save", metadata = data.frame( dataset = "data_to_save", label = "Lorem ipsum dolor sit amet" @@ -45,13 +46,14 @@ test_that("xportr_write: exported data can be saved to a file with a existing me df <- xportr_df_label( data_to_save, + domain = "data_to_save", data.frame( dataset = "data_to_save", label = "Lorem ipsum dolor sit amet" ) ) - xportr_write(df, path = tmp) + xportr_write(df, path = tmp, domain = "data_to_save") expect_output(str(read_xpt(tmp)), "Lorem ipsum dolor sit amet") }) @@ -162,6 +164,7 @@ test_that("xportr_write: expect warning when an xpt validation fails with strict expect_warning( xportr_write( data_to_save, tmp, + domain = "data_to_save", metadata = data.frame( dataset = "data_to_save", label = "label" @@ -184,6 +187,7 @@ test_that("xportr_write: Capture errors by haven and report them as such", { suppressWarnings( xportr_write( data_to_save, tmp, + domain = "data_to_save", metadata = data.frame( dataset = "data_to_save", label = "label" From 8c5e0ceadd83c7e623c54f3ae359320ed2fa598e Mon Sep 17 00:00:00 2001 From: elimillera Date: Tue, 19 Dec 2023 16:57:39 +0000 Subject: [PATCH 35/43] fix coverage --- tests/testthat/test-write.R | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-write.R b/tests/testthat/test-write.R index e45abce0..e6e35ca5 100644 --- a/tests/testthat/test-write.R +++ b/tests/testthat/test-write.R @@ -16,7 +16,12 @@ test_that("xportr_write: exported data can still be saved to a file with a label on.exit(unlink(tmpdir)) - suppressWarnings(xportr_write(data_to_save, path = tmp, label = "Lorem ipsum dolor sit amet", domain = "data_to_save")) + suppressWarnings( + xportr_write(data_to_save, + path = tmp, + label = "Lorem ipsum dolor sit amet", + domain = "data_to_save") + ) expect_output(str(read_xpt(tmp)), "Lorem ipsum dolor sit amet") }) @@ -106,6 +111,7 @@ test_that("xportr_write: expect error when label contains non-ASCII symbols or s expect_error( xportr_write( data_to_save, + domain = "data_to_save", tmp, metadata = data.frame( dataset = "data_to_save", @@ -126,6 +132,7 @@ test_that("xportr_write: expect error when label is over 40 characters", { expect_error( xportr_write( data_to_save, + domain = "data_to_save", tmp, metadata = data.frame( dataset = "data_to_save", @@ -145,6 +152,7 @@ test_that("xportr_write: expect error when an xpt validation fails with strict_c expect_error( xportr_write( data_to_save, tmp, + domain = "data_to_save", metadata = data.frame( dataset = "data_to_save", label = "label" From 9a451f74843e21fbd98e17a29037bbbb5e8217ae Mon Sep 17 00:00:00 2001 From: EeethB Date: Thu, 21 Dec 2023 16:35:35 +0000 Subject: [PATCH 36/43] [skip actions] Bump version to 0.3.1.9005 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0288c86c..315b2810 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9004 +Version: 0.3.1.9005 Authors@R: c( person("Eli", "Miller", , "Eli.Miller@AtorusResearch.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-2127-9456")), From 6138a14730f07cc6ec5e01c51b6dcdc106e218d0 Mon Sep 17 00:00:00 2001 From: elimillera Date: Fri, 29 Dec 2023 20:27:35 +0000 Subject: [PATCH 37/43] Updates with PR comment --- R/format.R | 2 +- R/label.R | 2 +- R/length.R | 2 +- R/order.R | 2 +- R/type.R | 2 +- _pkgdown.yml | 1 + tests/testthat/test-format.R | 15 +++++++++++++++ tests/testthat/test-label.R | 16 ++++++++++++++++ tests/testthat/test-length.R | 16 ++++++++++++++++ tests/testthat/test-order.R | 16 ++++++++++++++++ tests/testthat/test-type.R | 17 +++++++++++++++++ tests/testthat/test-write.R | 7 ++++--- 12 files changed, 90 insertions(+), 8 deletions(-) diff --git a/R/format.R b/R/format.R index 1249ac4e..798c7e18 100644 --- a/R/format.R +++ b/R/format.R @@ -72,7 +72,7 @@ xportr_format <- function(.df, metadata <- metadata$var_spec } - if (domain_name %in% names(metadata)) { + if (domain_name %in% names(metadata) && !is.null(domain)) { metadata <- metadata %>% dplyr::filter(!!sym(domain_name) == domain & !is.na(!!sym(format_name))) } else { diff --git a/R/label.R b/R/label.R index ad6c339a..15a386f4 100644 --- a/R/label.R +++ b/R/label.R @@ -88,7 +88,7 @@ xportr_label <- function(.df, metadata <- metadata$var_spec } - if (domain_name %in% names(metadata)) { + if (domain_name %in% names(metadata) && !is.null(domain)) { metadata <- metadata %>% dplyr::filter(!!sym(domain_name) == domain) } else { diff --git a/R/length.R b/R/length.R index 1b007970..5ee823b4 100644 --- a/R/length.R +++ b/R/length.R @@ -96,7 +96,7 @@ xportr_length <- function(.df, metadata <- metadata$var_spec } - if (domain_name %in% names(metadata)) { + if (domain_name %in% names(metadata) && !is.null(domain)) { metadata <- metadata %>% filter(!!sym(domain_name) == domain) } else { diff --git a/R/order.R b/R/order.R index 8f01ee78..e5f5a822 100644 --- a/R/order.R +++ b/R/order.R @@ -91,7 +91,7 @@ xportr_order <- function(.df, metadata <- metadata$ds_vars } - if (domain_name %in% names(metadata)) { + if (domain_name %in% names(metadata) && !is.null(domain)) { metadata <- metadata %>% dplyr::filter(!!sym(domain_name) == domain & !is.na(!!sym(order_name))) } else { diff --git a/R/type.R b/R/type.R index f75395f1..d01ad078 100644 --- a/R/type.R +++ b/R/type.R @@ -113,7 +113,7 @@ xportr_type <- function(.df, metadata <- metadata$var_spec } - if (domain_name %in% names(metadata)) { + if (domain_name %in% names(metadata) && !is.null(domain)) { metadata <- metadata %>% filter(!!sym(domain_name) == domain) } diff --git a/_pkgdown.yml b/_pkgdown.yml index dbeae1cc..8082901f 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -32,6 +32,7 @@ reference: - xportr_order - xportr_df_label - xportr_metadata + - xportr_domain_name - title: xportr helper functions desc: Utility functions called within core xportr functions diff --git a/tests/testthat/test-format.R b/tests/testthat/test-format.R index 76b65e1d..a311a8c4 100644 --- a/tests/testthat/test-format.R +++ b/tests/testthat/test-format.R @@ -19,3 +19,18 @@ test_that("xportr_format: Gets warning when metadata has multiple rows with same # Checks that message doesn't appear when xportr.domain_name is valid multiple_vars_in_spec_helper2(xportr_format) }) + +test_that("xportr_format: Works as expected with only one domain in metadata", { + adsl <- data.frame( + USUBJID = c(1001, 1002, 1003), + BRTHDT = c(1, 1, 2) + ) + + metadata <- data.frame( + dataset = c("adsl", "adsl"), + variable = c("USUBJID", "BRTHDT"), + format = c(NA, "DATE9.") + ) + + expect_silent(xportr_format(adsl, metadata)) +}) diff --git a/tests/testthat/test-label.R b/tests/testthat/test-label.R index 8030a826..cd0fc30b 100644 --- a/tests/testthat/test-label.R +++ b/tests/testthat/test-label.R @@ -21,3 +21,19 @@ test_that("xportr_label: Gets warning when metadata has multiple rows with same # Checks that message doesn't appear when xportr.domain_name is valid multiple_vars_in_spec_helper2(xportr_label) }) + + +test_that("xportr_label: Works as expected with only one domain in metadata", { + adsl <- data.frame( + USUBJID = c(1001, 1002, 1003), + BRTHDT = c(1, 1, 2) + ) + + metadata <- data.frame( + dataset = c("adsl", "adsl"), + variable = c("USUBJID", "BRTHDT"), + label = c("Hello", "Hello2") + ) + + expect_silent(xportr_label(adsl, metadata)) +}) diff --git a/tests/testthat/test-length.R b/tests/testthat/test-length.R index dd8b531f..f0045ead 100644 --- a/tests/testthat/test-length.R +++ b/tests/testthat/test-length.R @@ -193,3 +193,19 @@ test_that("xportr_length: Gets warning when metadata has multiple rows with same # Checks that message doesn't appear when xportr.domain_name is valid multiple_vars_in_spec_helper2(xportr_length) }) + + +test_that("xportr_length: Works as expected with only one domain in metadata", { + adsl <- data.frame( + USUBJID = c(1001, 1002, 1003), + BRTHDT = c(1, 1, 2) + ) + + metadata <- data.frame( + dataset = c("adsl", "adsl"), + variable = c("USUBJID", "BRTHDT"), + length = c(1, 1) + ) + + expect_silent(xportr_length(adsl, metadata)) +}) diff --git a/tests/testthat/test-order.R b/tests/testthat/test-order.R index 941a7d04..431db805 100644 --- a/tests/testthat/test-order.R +++ b/tests/testthat/test-order.R @@ -170,3 +170,19 @@ test_that("xportr_order: Gets warning when metadata has multiple rows with same expect_message("All variables in specification file are in dataset") %>% expect_message("All variables in dataset are ordered") }) + + +test_that("xportr_order: Works as expected with only one domain in metadata", { + adsl <- data.frame( + USUBJID = c(1001, 1002, 1003), + BRTHDT = c(1, 1, 2) + ) + + metadata <- data.frame( + dataset = c("adsl", "adsl"), + variable = c("USUBJID", "BRTHDT"), + order = c(1, 2) + ) + + expect_equal(xportr_order(adsl, metadata), adsl) +}) diff --git a/tests/testthat/test-type.R b/tests/testthat/test-type.R index 2287198e..f53271cc 100644 --- a/tests/testthat/test-type.R +++ b/tests/testthat/test-type.R @@ -304,3 +304,20 @@ test_that("xportr_type: Drops factor levels", { expect_null(attributes(df2$Val)) }) + + +test_that("xportr_type: Works as expected with only one domain in metadata", { + adsl <- data.frame( + USUBJID = c(1001, 1002, 1003), + BRTHDT = c(1, 1, 2) + ) + + metadata <- data.frame( + dataset = c("adsl", "adsl"), + variable = c("USUBJID", "BRTHDT"), + type = c("numeric", "numeric"), + format = c(NA, "DATE9.") + ) + + expect_equal(xportr_type(adsl, metadata), adsl) +}) diff --git a/tests/testthat/test-write.R b/tests/testthat/test-write.R index e6e35ca5..44e4718a 100644 --- a/tests/testthat/test-write.R +++ b/tests/testthat/test-write.R @@ -18,10 +18,11 @@ test_that("xportr_write: exported data can still be saved to a file with a label suppressWarnings( xportr_write(data_to_save, - path = tmp, - label = "Lorem ipsum dolor sit amet", - domain = "data_to_save") + path = tmp, + label = "Lorem ipsum dolor sit amet", + domain = "data_to_save" ) + ) expect_output(str(read_xpt(tmp)), "Lorem ipsum dolor sit amet") }) From 8db698ee1b659141a0489d9cdfcb4397d6c49666 Mon Sep 17 00:00:00 2001 From: elimillera Date: Fri, 29 Dec 2023 20:48:07 +0000 Subject: [PATCH 38/43] Revert bad merge --- tests/testthat/test-depreciation.R | 53 ++++-------------------------- 1 file changed, 6 insertions(+), 47 deletions(-) diff --git a/tests/testthat/test-depreciation.R b/tests/testthat/test-depreciation.R index b967c27e..2679ecc9 100644 --- a/tests/testthat/test-depreciation.R +++ b/tests/testthat/test-depreciation.R @@ -3,11 +3,7 @@ test_that("xportr_df_label: deprecated metacore gives an error", { df <- data.frame(x = "a", y = "b") df_meta <- data.frame(dataset = "df", label = "Label") - df_spec_labeled_df <- xportr_df_label(df, metacore = df_meta, domain = "df") - - expect_equal(attr(df_spec_labeled_df, "label"), "Label") - xportr_df_label(df, metacore = df_meta, domain = "df") %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") + expect_error(xportr_df_label(df, metacore = df_meta)) }) test_that("xportr_format: deprecated metacore gives an error", { @@ -19,11 +15,7 @@ test_that("xportr_format: deprecated metacore gives an error", { format = "date9." ) - formatted_df <- xportr_format(df, metacore = df_meta, domain = "df") - - expect_equal(attr(formatted_df$x, "format.sas"), "DATE9.") - xportr_format(df, metacore = df_meta, domain = "df") %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") + expect_error(xportr_format(df, metacore = df_meta)) }) test_that("xportr_label: using the deprecated metacore argument gives an error", { @@ -32,17 +24,7 @@ test_that("xportr_label: using the deprecated metacore argument gives an error", df <- data.frame(x = "a", y = "b") df_meta <- data.frame(dataset = "df", variable = "x", label = "foo") - df_labeled_df <- suppressMessages( - xportr_label(df, metacore = df_meta, domain = "df") - ) - - expect_equal(attr(df_labeled_df$x, "label"), "foo") - - # Note that only the deprecated message should be caught (others are ignored) - suppressMessages( - xportr_label(df, metacore = df_meta, domain = "df") %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") - ) + expect_error(xportr_label(df, metacore = df_meta)) }) test_that("xportr_length: using the deprecated metacore argument gives an error", { @@ -55,12 +37,7 @@ test_that("xportr_length: using the deprecated metacore argument gives an error" length = c(1, 2) ) - df_with_width <- xportr_length(df, metacore = df_meta, domain = "df") - - expect_equal(c(x = 1, y = 2), map_dbl(df_with_width, attr, "width")) - - xportr_length(df, metacore = df_meta, domain = "df") %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") + expect_error(xportr_length(df, metacore = df_meta)) }) test_that("xportr_order: using the deprecated metacore argument gives an error", { @@ -73,17 +50,7 @@ test_that("xportr_order: using the deprecated metacore argument gives an error", order = 1:4 ) - ordered_df <- suppressMessages( - xportr_order(df, metacore = df_meta, domain = "DOMAIN") - ) - - expect_equal(names(ordered_df), df_meta$variable) - - # Note that only the deprecated message should be caught (others are ignored) - suppressMessages( - xportr_order(df, metacore = df_meta, domain = "df") %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") - ) + expect_error(xportr_order(df, metacore = df_meta, domain = "DOMAIN")) }) test_that("xportr_type: using the deprecated metacore argument gives an error", { @@ -101,13 +68,5 @@ test_that("xportr_type: using the deprecated metacore argument gives an error", format = NA ) - df2 <- suppressMessages( - xportr_type(df, metacore = df_meta, domain = "df") - ) - - # Note that only the deprecated message should be caught (others are ignored) - suppressMessages( - xportr_type(df, metacore = df_meta, domain = "df") %>% - lifecycle::expect_deprecated("Please use the `metadata` argument instead.") - ) + expect_error(xportr_type(df, metacore = df_meta)) }) From 466d7efe8c18e0444d68055ca26f22786f1edf2e Mon Sep 17 00:00:00 2001 From: elimillera Date: Wed, 10 Jan 2024 17:15:58 +0000 Subject: [PATCH 39/43] Remove function and update xportr_metadata to allow for domain setting --- NAMESPACE | 1 - R/length.R | 5 ++--- R/metadata.R | 32 +++++++++----------------------- R/support-test.R | 2 +- _pkgdown.yml | 1 - man/metadata.Rd | 24 ++++++++---------------- man/xportr_df_label.Rd | 5 ++--- man/xportr_format.Rd | 5 ++--- man/xportr_label.Rd | 5 ++--- man/xportr_length.Rd | 5 ++--- man/xportr_order.Rd | 5 ++--- man/xportr_type.Rd | 5 ++--- man/xportr_write.Rd | 5 ++--- tests/testthat/test-length.R | 2 +- tests/testthat/test-metadata.R | 4 ++-- tests/testthat/test-order.R | 2 +- tests/testthat/test-type.R | 4 ++-- 17 files changed, 40 insertions(+), 72 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index dd495905..d2f10378 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,7 +6,6 @@ export(type_log) export(var_names_log) export(var_ord_msg) export(xportr_df_label) -export(xportr_domain_name) export(xportr_format) export(xportr_label) export(xportr_length) diff --git a/R/length.R b/R/length.R index 3039218f..21ea95d4 100644 --- a/R/length.R +++ b/R/length.R @@ -9,9 +9,8 @@ #' @param metadata A data frame containing variable level metadata. See #' 'Metadata' section for details. #' @param domain Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -#' the metadata object. If none is passed, then [xportr_domain_name()] or -#' [xportr_metadata()] must be called before hand to set the domain as an -#' attribute of `.df`. +#' the metadata object. If none is passed, then [xportr_metadata()] must be +#' called before hand to set the domain as an attribute of `.df`. #' @param verbose The action this function takes when an action is taken on the #' dataset or function validation finds an issue. See 'Messaging' section for #' details. Options are 'stop', 'warn', 'message', and 'none' diff --git a/R/metadata.R b/R/metadata.R index 2db7d1b5..df206ef2 100644 --- a/R/metadata.R +++ b/R/metadata.R @@ -1,9 +1,10 @@ #' Set variable specifications and domain #' -#' Sets metadata for a dataset in a way that can be accessed by other xportr -#' functions. If used at the start of an xportr pipeline, it removes the need to -#' set metadata and domain at each step individually. For details on the format -#' of the metadata, see the 'Metadata' section for each function in question. +#' Sets metadata and/or domain for a dataset in a way that can be accessed by +#' other xportr functions. If used at the start of an xportr pipeline, it +#' removes the need to set metadata and domain at each step individually. For +#' details on the format of the metadata, see the 'Metadata' section for each +#' function in question. #' #' @inheritParams xportr_length #' @@ -35,12 +36,14 @@ #' library(magrittr) #' #' adlb %>% -#' xportr_domain_name("adlb") %>% #' xportr_metadata(metadata, "test") %>% #' xportr_type() %>% #' xportr_order() #' } -xportr_metadata <- function(.df, metadata, domain = NULL) { +xportr_metadata <- function(.df, metadata = NULL, domain = NULL) { + if (is.null(metadata) && is.null(domain)) { + stop("Must provide either metadata or domain argument") + } ## Common section to detect domain from argument or attribute domain <- get_domain(.df, domain) @@ -50,20 +53,3 @@ xportr_metadata <- function(.df, metadata, domain = NULL) { structure(.df, `_xportr.df_metadata_` = metadata) } - - -#' Update Metadata Domain Name -#' -#' Similar to `xportr_metadata()`, but just adds the domain and not the metadata. -#' -#' @inheritParams xportr_length -#' -#' @return `.df` dataset with domain argument set -#' @export -#' -#' @rdname metadata -xportr_domain_name <- function(.df, domain) { - attr(.df, "_xportr.df_arg_") <- domain - - .df -} diff --git a/R/support-test.R b/R/support-test.R index b81fba3d..d223a6d6 100644 --- a/R/support-test.R +++ b/R/support-test.R @@ -180,7 +180,7 @@ multiple_vars_in_spec_helper2 <- function(FUN) { local_cli_theme() adsl %>% - xportr_domain_name("adsl") %>% + xportr_metadata(domain = "adsl") %>% FUN(metadata) %>% testthat::expect_no_message(message = "There are multiple specs for the same variable name") } diff --git a/_pkgdown.yml b/_pkgdown.yml index 8082901f..dbeae1cc 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -32,7 +32,6 @@ reference: - xportr_order - xportr_df_label - xportr_metadata - - xportr_domain_name - title: xportr helper functions desc: Utility functions called within core xportr functions diff --git a/man/metadata.Rd b/man/metadata.Rd index f3c497de..658fe0a4 100644 --- a/man/metadata.Rd +++ b/man/metadata.Rd @@ -2,12 +2,9 @@ % Please edit documentation in R/metadata.R \name{xportr_metadata} \alias{xportr_metadata} -\alias{xportr_domain_name} \title{Set variable specifications and domain} \usage{ -xportr_metadata(.df, metadata, domain = NULL) - -xportr_domain_name(.df, domain) +xportr_metadata(.df, metadata = NULL, domain = NULL) } \arguments{ \item{.df}{A data frame of CDISC standard.} @@ -16,22 +13,18 @@ xportr_domain_name(.df, domain) 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} } \value{ \code{.df} dataset with metadata and domain attributes set - -\code{.df} dataset with domain argument set } \description{ -Sets metadata for a dataset in a way that can be accessed by other xportr -functions. If used at the start of an xportr pipeline, it removes the need to -set metadata and domain at each step individually. For details on the format -of the metadata, see the 'Metadata' section for each function in question. - -Similar to \code{xportr_metadata()}, but just adds the domain and not the metadata. +Sets metadata and/or domain for a dataset in a way that can be accessed by +other xportr functions. If used at the start of an xportr pipeline, it +removes the need to set metadata and domain at each step individually. For +details on the format of the metadata, see the 'Metadata' section for each +function in question. } \examples{ @@ -56,7 +49,6 @@ if (rlang::is_installed("magrittr")) { library(magrittr) adlb \%>\% - xportr_domain_name("adlb") \%>\% xportr_metadata(metadata, "test") \%>\% xportr_type() \%>\% xportr_order() diff --git a/man/xportr_df_label.Rd b/man/xportr_df_label.Rd index 6d4764b4..363c59c4 100644 --- a/man/xportr_df_label.Rd +++ b/man/xportr_df_label.Rd @@ -13,9 +13,8 @@ xportr_df_label(.df, metadata = NULL, domain = NULL, metacore = deprecated()) details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} \item{metacore}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Previously used to pass metadata now renamed with \code{metadata}} diff --git a/man/xportr_format.Rd b/man/xportr_format.Rd index b7825fc4..059fe168 100644 --- a/man/xportr_format.Rd +++ b/man/xportr_format.Rd @@ -13,9 +13,8 @@ xportr_format(.df, metadata = NULL, domain = NULL, metacore = deprecated()) 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} \item{metacore}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Previously used to pass metadata now renamed with \code{metadata}} diff --git a/man/xportr_label.Rd b/man/xportr_label.Rd index 87d648da..6af7ad9a 100644 --- a/man/xportr_label.Rd +++ b/man/xportr_label.Rd @@ -19,9 +19,8 @@ xportr_label( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for diff --git a/man/xportr_length.Rd b/man/xportr_length.Rd index 1d5100df..b7f3e818 100644 --- a/man/xportr_length.Rd +++ b/man/xportr_length.Rd @@ -19,9 +19,8 @@ xportr_length( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for diff --git a/man/xportr_order.Rd b/man/xportr_order.Rd index 72bda30d..de8ec9cd 100644 --- a/man/xportr_order.Rd +++ b/man/xportr_order.Rd @@ -19,9 +19,8 @@ xportr_order( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for diff --git a/man/xportr_type.Rd b/man/xportr_type.Rd index 3c67c4c7..440cf535 100644 --- a/man/xportr_type.Rd +++ b/man/xportr_type.Rd @@ -19,9 +19,8 @@ xportr_type( 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} \item{verbose}{The action this function takes when an action is taken on the dataset or function validation finds an issue. See 'Messaging' section for diff --git a/man/xportr_write.Rd b/man/xportr_write.Rd index 9ecbd3a4..31c91c1e 100644 --- a/man/xportr_write.Rd +++ b/man/xportr_write.Rd @@ -23,9 +23,8 @@ used as \code{xpt} name.} 'Metadata' section for details.} \item{domain}{Appropriate CDSIC dataset name, e.g. ADAE, DM. Used to subset -the metadata object. If none is passed, then \code{\link[=xportr_domain_name]{xportr_domain_name()}} or -\code{\link[=xportr_metadata]{xportr_metadata()}} must be called before hand to set the domain as an -attribute of \code{.df}.} +the metadata object. If none is passed, then \code{\link[=xportr_metadata]{xportr_metadata()}} must be +called before hand to set the domain as an attribute of \code{.df}.} \item{strict_checks}{If TRUE, xpt validation will report errors and not write out the dataset. If FALSE, xpt validation will report warnings and continue diff --git a/tests/testthat/test-length.R b/tests/testthat/test-length.R index 7fa87f53..e3adce3f 100644 --- a/tests/testthat/test-length.R +++ b/tests/testthat/test-length.R @@ -14,7 +14,7 @@ test_that("xportr_length: Accepts valid domain names in metadata object", { # Test minimal call with valid data and without domain adsl %>% - xportr_domain_name("adsl") %>% + xportr_metadata(domain = "adsl") %>% xportr_length(metadata) %>% expect_silent() %>% expect_attr_width(metadata$length) diff --git a/tests/testthat/test-metadata.R b/tests/testthat/test-metadata.R index b3041018..fc4a3b74 100644 --- a/tests/testthat/test-metadata.R +++ b/tests/testthat/test-metadata.R @@ -178,7 +178,7 @@ test_that("xportr_df_label: Correctly applies label when data is piped", { df_meta <- data.frame(dataset = "df", label = "Label") df_spec_labeled_df <- df %>% - xportr_domain_name("df") %>% + xportr_metadata(domain = "df") %>% xportr_df_label(df_meta) %>% xportr_df_label(df_meta) @@ -621,7 +621,7 @@ test_that("xportr_*: Domain is kept in between calls", { ) df2 <- adsl %>% - xportr_domain_name("adsl") %>% + xportr_metadata(domain = "adsl") %>% xportr_type(metadata) df3 <- df2 %>% diff --git a/tests/testthat/test-order.R b/tests/testthat/test-order.R index 3450ba10..1c68feef 100644 --- a/tests/testthat/test-order.R +++ b/tests/testthat/test-order.R @@ -21,7 +21,7 @@ test_that("xportr_order: Variable are ordered correctly when data is piped", { ordered_df <- suppressMessages( df %>% - xportr_domain_name("df") %>% + xportr_metadata(domain = "df") %>% xportr_order(df_meta) %>% xportr_order(df_meta) ) diff --git a/tests/testthat/test-type.R b/tests/testthat/test-type.R index f53271cc..aa31baf1 100644 --- a/tests/testthat/test-type.R +++ b/tests/testthat/test-type.R @@ -155,14 +155,14 @@ test_that("xportr_type: Variables retain column attributes, besides class", { withr::local_message_sink(tempfile()) df_type_label <- adsl %>% - xportr_domain_name("adsl") %>% + xportr_metadata(domain = "adsl") %>% xportr_type(metadata) %>% xportr_label(metadata) %>% xportr_length(metadata) %>% xportr_format(metadata) df_label_type <- adsl %>% - xportr_domain_name("adsl") %>% + xportr_metadata(domain = "adsl") %>% xportr_label(metadata) %>% xportr_length(metadata) %>% xportr_format(metadata) %>% From e3a31b1e2e5dd76e87a66f702ff6807056fc307a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Ver=C3=ADssimo?= <211358+averissimo@users.noreply.github.com> Date: Tue, 16 Jan 2024 16:40:18 +0100 Subject: [PATCH 40/43] tests: add missing coverage --- tests/testthat/test-metadata.R | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/testthat/test-metadata.R b/tests/testthat/test-metadata.R index fc4a3b74..e50a0741 100644 --- a/tests/testthat/test-metadata.R +++ b/tests/testthat/test-metadata.R @@ -607,6 +607,13 @@ test_that("xportr_metadata: Check metadata interaction with other functions", { ) }) +test_that("xportr_metadata: must throw error if both metadata and domain are null", { + expect_error( + xportr_metadata(data.frame(), metadata = NULL, domain = NULL), + "Must provide either metadata or domain argument" + ) +}) + test_that("xportr_*: Domain is kept in between calls", { # Divert all messages to tempfile, instead of printing them # note: be aware as this should only be used in tests that don't track From 601209fdb6d72725f50b53dd4d6f1aa746d1c8e1 Mon Sep 17 00:00:00 2001 From: elimillera Date: Tue, 16 Jan 2024 15:58:34 +0000 Subject: [PATCH 41/43] Update readme per comments --- README.Rmd | 12 ++++++------ README.md | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/README.Rmd b/README.Rmd index 1541a21b..2f422c1c 100644 --- a/README.Rmd +++ b/README.Rmd @@ -131,12 +131,12 @@ Each `xportr_` function has been written in a way to take in a part of the speci ```{r, warning = FALSE, message=FALSE, eval=TRUE} adsl %>% - xportr_domain_name("ADSL") %>% - xportr_type(var_spec, verbose = "warn") %>% - xportr_length(var_spec, verbose = "warn") %>% - xportr_label(var_spec, verbose = "warn") %>% - xportr_order(var_spec, verbose = "warn") %>% - xportr_format(var_spec) %>% + xportr_metadata(var_spec, "ADSL") %>% + xportr_type(verbose = "warn") %>% + xportr_length(verbose = "warn") %>% + xportr_label(verbose = "warn") %>% + xportr_order(verbose = "warn") %>% + xportr_format() %>% xportr_df_label(dataset_spec, "ADSL") %>% xportr_write("adsl.xpt") ``` diff --git a/README.md b/README.md index cc83fae4..bebb06c8 100644 --- a/README.md +++ b/README.md @@ -138,12 +138,12 @@ We have suppressed the warning for the sake of brevity. ``` r adsl %>% - xportr_domain_name("ADSL") %>% - xportr_type(var_spec, verbose = "warn") %>% - xportr_length(var_spec, verbose = "warn") %>% - xportr_label(var_spec, verbose = "warn") %>% - xportr_order(var_spec, verbose = "warn") %>% - xportr_format(var_spec) %>% + xportr_metadata(var_spec, "ADSL") %>% + xportr_type(verbose = "warn") %>% + xportr_length(verbose = "warn") %>% + xportr_label(verbose = "warn") %>% + xportr_order(verbose = "warn") %>% + xportr_format() %>% xportr_df_label(dataset_spec, "ADSL") %>% xportr_write("adsl.xpt") ``` From 6fc3451a7a4e56767c0bc8e4df2f81f5e0a33667 Mon Sep 17 00:00:00 2001 From: elimillera Date: Tue, 16 Jan 2024 16:00:00 +0000 Subject: [PATCH 42/43] [skip actions] Bump version to 0.3.1.9006 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 315b2810..424b59cb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9005 +Version: 0.3.1.9006 Authors@R: c( person("Eli", "Miller", , "Eli.Miller@AtorusResearch.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-2127-9456")), From bcf4c88d1e4b0a900410c309993ee23c3b2111fe Mon Sep 17 00:00:00 2001 From: bms63 Date: Tue, 16 Jan 2024 16:46:42 +0000 Subject: [PATCH 43/43] [skip actions] Bump version to 0.3.1.9007 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 424b59cb..d247be32 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: xportr Title: Utilities to Output CDISC SDTM/ADaM XPT Files -Version: 0.3.1.9006 +Version: 0.3.1.9007 Authors@R: c( person("Eli", "Miller", , "Eli.Miller@AtorusResearch.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-2127-9456")),