diff --git a/NAMESPACE b/NAMESPACE index 70675729..cb82921d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,7 @@ export(length_log) export(type_log) export(var_names_log) export(var_ord_msg) +export(xportr) export(xportr_df_label) export(xportr_format) export(xportr_label) diff --git a/NEWS.md b/NEWS.md index d2114c91..30c48ea1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -15,6 +15,14 @@ * It is now possible to get and set the xportr options using the helper function `xportr_options()` (#130) * Adds argument assertions to public functions using `{checkmate}` (#175) +* `xportr_metadata()` can set `verbose` for a whole pipeline, i.e. setting `verbose` in `xportr_metadata()` will populate to all `xportr` functions. (#151) + +* All `xportr` functions now have `verbose = NULL` as the default. If left `NULL`, the previous default of `getOption("xportr.[fn_name]_verbose")` is used (#151) + +* All core functions can be run together by using new function `xportr()` (#137) + +## Documentation + ## Deprecation and Breaking Changes * The `domain` argument for xportr functions will no longer be dynamically diff --git a/R/format.R b/R/format.R index 775e0e60..e59e1c08 100644 --- a/R/format.R +++ b/R/format.R @@ -18,9 +18,9 @@ #' "dataset". This is the column subset by the 'domain' argument in the #' function. #' -#' 2) Format Name - passed as the 'xportr.format_name' option. -#' Default: "format". Character values to update the '`format.sas`' attribute of -#' the column. This is passed to `haven::write` to note the format. +#' 2) Format Name - passed as the 'xportr.format_name' option. Default: +#' "format". Character values to update the '`format.sas`' attribute of the +#' column. This is passed to `haven::write` to note the format. #' #' 3) Variable Name - passed as the 'xportr.variable_name' option. Default: #' "variable". This is used to match columns in '.df' argument and the diff --git a/R/length.R b/R/length.R index d329d664..6158eeed 100644 --- a/R/length.R +++ b/R/length.R @@ -5,15 +5,9 @@ #' character columns, and 8 for non-character columns. This value is stored in #' the 'width' attribute of the column. #' -#' @param .df A data frame of CDISC standard. +#' @inheritParams xportr #' @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_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' #' @param metacore `r lifecycle::badge("deprecated")` Previously used to pass #' metadata now renamed with `metadata` #' diff --git a/R/xportr-package.R b/R/xportr-package.R index 7ffeafcb..5589c486 100644 --- a/R/xportr-package.R +++ b/R/xportr-package.R @@ -91,6 +91,7 @@ #' #' #' @keywords internal +#' @aliases xportr-package #' #' @import rlang haven #' @importFrom dplyr left_join bind_cols filter select rename rename_with n diff --git a/R/xportr.R b/R/xportr.R new file mode 100644 index 00000000..ed7c3ba1 --- /dev/null +++ b/R/xportr.R @@ -0,0 +1,69 @@ +#' Wrapper to apply all core xportr functions and write xpt +#' +#' @param .df A data frame of CDISC standard. +#' @param var_metadata A data frame containing variable level metadata +#' @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. +#' @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' +#' @param df_metadata A data frame containing dataset level metadata. +#' @param path Path where transport file will be written. File name sans will be +#' used as `xpt` name. +#' @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 +#' +#' @return Returns the input dataframe invisibly +#' @export +#' +#' @examplesIf requireNamespace("magrittr") +#' library(magrittr) +#' test_dir <- tempdir() +#' +#' pipeline_path <- file.path(test_dir, "adslpipe.xpt") +#' xportr_path <- file.path(test_dir, "adslxptr.xpt") +#' +#' dataset_spec_low <- setNames(dataset_spec, tolower(names(dataset_spec))) +#' names(dataset_spec_low)[[2]] <- "label" +#' +#' var_spec_low <- setNames(var_spec, tolower(names(var_spec))) +#' names(var_spec_low)[[5]] <- "type" +#' +#' adsl %>% +#' xportr_metadata(var_spec_low, "ADSL", verbose = "none") %>% +#' xportr_type() %>% +#' xportr_length() %>% +#' xportr_label() %>% +#' xportr_order() %>% +#' xportr_format() %>% +#' xportr_df_label(dataset_spec_low) %>% +#' xportr_write(pipeline_path) +#' +#' # `xportr()` can be used to apply a whole pipeline at once +#' xportr( +#' adsl, +#' var_metadata = var_spec_low, +#' df_metadata = dataset_spec_low, +#' domain = "ADSL", +#' verbose = "none", +#' path = xportr_path +#' ) +xportr <- function(.df, + var_metadata = NULL, + df_metadata = NULL, + domain = NULL, + verbose = NULL, + path, + strict_checks = FALSE) { + .df %>% + xportr_metadata(var_metadata, domain = domain, verbose = verbose) %>% + xportr_type() %>% + xportr_length() %>% + xportr_label() %>% + xportr_order() %>% + xportr_format() %>% + xportr_df_label(df_metadata) %>% + xportr_write(path) +} diff --git a/README.Rmd b/README.Rmd index 462f205c..8b71800d 100644 --- a/README.Rmd +++ b/README.Rmd @@ -143,7 +143,7 @@ adsl %>% 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. -```{r, message=FALSE, eval=FALSE} +```{r, warning=FALSE, message=FALSE, eval=FALSE} adsl %>% xportr_metadata(var_spec, "ADSL", verbose = "warn") %>% xportr_type() %>% @@ -155,6 +155,19 @@ adsl %>% xportr_write("adsl.xpt") ``` +Furthermore, if you're calling all xportr functions at once with common metadata and verbosity, you can shorten it by simply using `xportr()`. + +```{r, warning=FALSE, message=FALSE, eval=FALSE} +xportr( + .df = adsl, + var_metadata = var_spec, + df_metadata = dataset_spec, + domain = "ADSL", + verbose = "warn", + "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. We are in talks with other Pharma companies involved with the [`{pharmaverse}`](https://pharmaverse.org/) to enhance this package to play well with other downstream and upstream packages. diff --git a/README.md b/README.md index bebb06c8..e64b19ed 100644 --- a/README.md +++ b/README.md @@ -155,7 +155,7 @@ each function call. ``` r adsl %>% - xportr_metadata(var_spec, "ADSL") %>% + xportr_metadata(var_spec, "ADSL", verbose = "warn") %>% xportr_type() %>% xportr_length() %>% xportr_label() %>% @@ -165,6 +165,20 @@ adsl %>% xportr_write("adsl.xpt") ``` +Furthermore, if you’re calling all xportr functions at once with common +metadata and verbosity, you can shorten it by simply using `xportr()`. + +``` r +xportr( + .df = adsl, + var_metadata = var_spec, + df_metadata = dataset_spec, + domain = "ADSL", + verbose = "warn", + "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) diff --git a/_pkgdown.yml b/_pkgdown.yml index 4143179b..d98fc629 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -32,6 +32,7 @@ reference: - xportr_order - xportr_df_label - xportr_metadata + - xportr - title: xportr helper functions desc: Utility functions called within core xportr functions diff --git a/man/metadata.Rd b/man/metadata.Rd index da5de14c..30918a0c 100644 --- a/man/metadata.Rd +++ b/man/metadata.Rd @@ -13,8 +13,8 @@ xportr_metadata(.df, metadata = NULL, domain = NULL, verbose = NULL) '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_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 name of the dataset passed as +.df will be used.} \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-package.Rd b/man/xportr-package.Rd index 1d9f6571..9cef001a 100644 --- a/man/xportr-package.Rd +++ b/man/xportr-package.Rd @@ -2,8 +2,8 @@ % Please edit documentation in R/xportr-package.R \docType{package} \name{xportr-package} -\alias{xportr} \alias{xportr-package} +\alias{_PACKAGE} \title{The \code{xportr} package} \description{ \code{xportr} is designed to be a clinical workflow friendly method for outputting diff --git a/man/xportr.Rd b/man/xportr.Rd new file mode 100644 index 00000000..c810dae1 --- /dev/null +++ b/man/xportr.Rd @@ -0,0 +1,79 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/xportr.R +\name{xportr} +\alias{xportr} +\title{Wrapper to apply all core xportr functions and write xpt} +\usage{ +xportr( + .df, + var_metadata = NULL, + df_metadata = NULL, + domain = NULL, + verbose = NULL, + path, + strict_checks = FALSE +) +} +\arguments{ +\item{.df}{A data frame of CDISC standard.} + +\item{var_metadata}{A data frame containing variable level metadata} + +\item{df_metadata}{A data frame containing dataset level metadata.} + +\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{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'} + +\item{path}{Path where transport file will be written. File name sans will be +used as \code{xpt} name.} + +\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} +} +\value{ +Returns the input dataframe invisibly +} +\description{ +Wrapper to apply all core xportr functions and write xpt +} +\examples{ +\dontshow{if (requireNamespace("magrittr")) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +library(magrittr) +test_dir <- tempdir() + +pipeline_path <- file.path(test_dir, "adslpipe.xpt") +xportr_path <- file.path(test_dir, "adslxptr.xpt") + +dataset_spec_low <- setNames(dataset_spec, tolower(names(dataset_spec))) +names(dataset_spec_low)[[2]] <- "label" + +var_spec_low <- setNames(var_spec, tolower(names(var_spec))) +names(var_spec_low)[[5]] <- "type" + +adsl \%>\% + xportr_metadata(var_spec_low, "ADSL", verbose = "none") \%>\% + xportr_type() \%>\% + xportr_length() \%>\% + xportr_label() \%>\% + xportr_order() \%>\% + xportr_format() \%>\% + xportr_df_label(dataset_spec_low) \%>\% + xportr_write(pipeline_path) + +# `xportr()` can be used to apply a whole pipeline at once +xportr( + adsl, + var_metadata = var_spec_low, + df_metadata = dataset_spec_low, + domain = "ADSL", + verbose = "none", + path = xportr_path +) +\dontshow{\}) # examplesIf} +} diff --git a/man/xportr_df_label.Rd b/man/xportr_df_label.Rd index 363c59c4..691de990 100644 --- a/man/xportr_df_label.Rd +++ b/man/xportr_df_label.Rd @@ -13,8 +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_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 name of the dataset passed as +.df will be used.} \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 dd883554..e085a345 100644 --- a/man/xportr_format.Rd +++ b/man/xportr_format.Rd @@ -13,8 +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_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 name of the dataset passed as +.df will be used.} \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}} @@ -37,9 +37,9 @@ For data.frame 'metadata' arguments three columns must be present: \item Domain Name - passed as the 'xportr.domain_name' option. Default: "dataset". This is the column subset by the 'domain' argument in the function. -\item Format Name - passed as the 'xportr.format_name' option. -Default: "format". Character values to update the '\code{format.sas}' attribute of -the column. This is passed to \code{haven::write} to note the format. +\item Format Name - passed as the 'xportr.format_name' option. Default: +"format". Character values to update the '\code{format.sas}' attribute of the +column. This is passed to \code{haven::write} to note the format. \item Variable Name - passed as the 'xportr.variable_name' option. Default: "variable". This is used to match columns in '.df' argument and the metadata. diff --git a/man/xportr_label.Rd b/man/xportr_label.Rd index f408de4f..eb03df81 100644 --- a/man/xportr_label.Rd +++ b/man/xportr_label.Rd @@ -19,8 +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_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 name of the dataset passed as +.df will be used.} \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 fd8c6807..f7a7c689 100644 --- a/man/xportr_length.Rd +++ b/man/xportr_length.Rd @@ -19,8 +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_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 name of the dataset passed as +.df will be used.} \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_options.Rd b/man/xportr_options.Rd index 4194aa52..feb212cd 100644 --- a/man/xportr_options.Rd +++ b/man/xportr_options.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/options.R \name{xportr_options} \alias{xportr_options} -\title{Get or set Xportr options} +\title{Get or set xportr options} \usage{ xportr_options(...) } diff --git a/man/xportr_order.Rd b/man/xportr_order.Rd index 9cefd0fb..26b87f42 100644 --- a/man/xportr_order.Rd +++ b/man/xportr_order.Rd @@ -19,8 +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_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 name of the dataset passed as +.df will be used.} \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 cbbbbef9..21eb3583 100644 --- a/man/xportr_type.Rd +++ b/man/xportr_type.Rd @@ -19,8 +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_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 name of the dataset passed as +.df will be used.} \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 3617beec..d2be36d0 100644 --- a/man/xportr_write.Rd +++ b/man/xportr_write.Rd @@ -23,8 +23,8 @@ used as \code{xpt} name.} 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_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 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 diff --git a/tests/testthat/test-metadata.R b/tests/testthat/test-metadata.R index 55c91cde..29a9aab0 100644 --- a/tests/testthat/test-metadata.R +++ b/tests/testthat/test-metadata.R @@ -594,7 +594,7 @@ test_that("xportr_metadata: Variable ordering messaging is correct", { ) # Metadata versions - xportr_metadata(df, df_meta, verbose = "message") %>% + xportr_metadata(df, df_meta, domain = "df", verbose = "message") %>% xportr_order() %>% expect_message("All variables in specification file are in dataset") %>% expect_condition("4 reordered in dataset") %>% @@ -623,13 +623,13 @@ test_that("xportr_type: Variable types are coerced as expected and can raise mes # Metadata version of the last statement df %>% - xportr_metadata(meta_example, verbose = "warn") %>% + xportr_metadata(meta_example, domain = "df", verbose = "warn") %>% xportr_type() %>% expect_warning() # Metadata version df %>% - xportr_metadata(meta_example, verbose = "message") %>% + xportr_metadata(meta_example, domain = "df", verbose = "message") %>% xportr_type() %>% expect_message("Variable type\\(s\\) in dataframe don't match metadata") }) @@ -649,50 +649,64 @@ test_that("xportr_metadata: Check metadata interaction with other functions", { dplyr::rename(type = "Data Type") %>% rlang::set_names(tolower) + # 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 + if (requireNamespace("withr", quiet = TRUE)) { + withr::local_message_sink(withr::local_tempfile()) + } expect_equal( - structure(xportr_type(adsl, var_spec, domain = "adsl"), `_xportr.df_metadata_` = var_spec), + structure(xportr_type(adsl, var_spec, domain = "adsl"), + `_xportr.df_metadata_` = var_spec, + `_xportr.df_verbose_` = "none" + ), suppressMessages( - xportr_metadata(adsl, var_spec, domain = "adsl") %>% xportr_type() + xportr_metadata(adsl, var_spec, domain = "adsl", verbose = "none") %>% + xportr_type() ) ) expect_equal( - structure( - suppressMessages(xportr_length(adsl, var_spec, domain = "adsl")), - `_xportr.df_metadata_` = var_spec + structure(xportr_length(adsl, var_spec, domain = "adsl"), + `_xportr.df_metadata_` = var_spec, + `_xportr.df_verbose_` = "none" ), suppressMessages( - xportr_metadata(adsl, var_spec, domain = "adsl") %>% xportr_length() + xportr_metadata(adsl, var_spec, domain = "adsl", verbose = "none") %>% + xportr_length() ) ) expect_equal( - structure( - suppressMessages(xportr_label(adsl, var_spec, domain = "adsl")), - `_xportr.df_metadata_` = var_spec + structure(xportr_label(adsl, var_spec, domain = "adsl"), + `_xportr.df_metadata_` = var_spec, + `_xportr.df_verbose_` = "none" ), suppressMessages( - xportr_metadata(adsl, var_spec, domain = "adsl") %>% xportr_label() + xportr_metadata(adsl, var_spec, domain = "adsl", verbose = "none") %>% + xportr_label() ) ) expect_equal( - structure( - suppressMessages(xportr_order(adsl, var_spec, domain = "adsl")), - `_xportr.df_metadata_` = var_spec + structure(xportr_order(adsl, var_spec, domain = "adsl"), + `_xportr.df_metadata_` = var_spec, + `_xportr.df_verbose_` = "none" ), suppressMessages( - xportr_metadata(adsl, var_spec, domain = "adsl") %>% xportr_order() + xportr_metadata(adsl, var_spec, domain = "adsl", verbose = "none") %>% + xportr_order() ) ) expect_equal( - structure( - suppressMessages(xportr_format(adsl, var_spec, domain = "adsl")), - `_xportr.df_metadata_` = var_spec + structure(xportr_format(adsl, var_spec, domain = "adsl"), + `_xportr.df_metadata_` = var_spec, + `_xportr.df_verbose_` = "none" ), suppressMessages( - xportr_metadata(adsl, var_spec, domain = "adsl") %>% xportr_format() + xportr_metadata(adsl, var_spec, domain = "adsl", verbose = "none") %>% + xportr_format() ) ) }) @@ -744,10 +758,9 @@ test_that("xportr_*: Domain is kept in between calls", { test_that("`xportr_metadata()` results match traditional results", { if (require(magrittr, quietly = TRUE)) { - test_dir <- tempdir() - - trad_path <- file.path(test_dir, "adsltrad.xpt") - metadata_path <- file.path(test_dir, "adslmeta.xpt") + skip_if_not_installed("withr") + trad_path <- withr::local_file("adsltrad.xpt") + metadata_path <- withr::local_file("adslmeta.xpt") dataset_spec_low <- setNames(dataset_spec, tolower(names(dataset_spec))) names(dataset_spec_low)[[2]] <- "label" diff --git a/tests/testthat/test-type.R b/tests/testthat/test-type.R index 9d9580b3..5e8de832 100644 --- a/tests/testthat/test-type.R +++ b/tests/testthat/test-type.R @@ -83,51 +83,6 @@ test_that("xportr_type: Variable types are coerced as expected and can raise mes )) }) -test_that("xportr_metadata: Var types coerced as expected and raise messages", { - # Remove empty lines in cli theme - local_cli_theme() - - ( - df2 <- xportr_metadata(df, meta_example, domain = "df") %>% - xportr_type() - ) %>% - expect_message("Variable type mismatches found.") %>% - expect_message("[0-9+] variables coerced") - - expect_equal(purrr::map_chr(df2, class), c( - Subj = "numeric", Different = "character", - Val = "numeric", Param = "character" - )) - - suppressMessages( - xportr_metadata(df, meta_example, domain = "df") %>% xportr_type(verbose = "stop") - ) %>% - expect_error() - - suppressMessages( - df3 <- xportr_metadata(df, meta_example, domain = "df") %>% xportr_type(verbose = "warn") - ) %>% - expect_warning() - - expect_equal(purrr::map_chr(df3, class), c( - Subj = "numeric", Different = "character", - Val = "numeric", Param = "character" - )) - - suppressMessages({ - ( - df4 <- xportr_metadata(df, meta_example, domain = "df") %>% - xportr_type(verbose = "message") - ) %>% - expect_message("Variable type\\(s\\) in dataframe don't match metadata: `Subj` and `Val`") - }) - - expect_equal(purrr::map_chr(df4, class), c( - Subj = "numeric", Different = "character", - Val = "numeric", Param = "character" - )) -}) - test_that("xportr_type: Variables retain column attributes, besides class", { adsl <- dplyr::tibble( USUBJID = c(1001, 1002, 1003), diff --git a/tests/testthat/test-xportr.R b/tests/testthat/test-xportr.R new file mode 100644 index 00000000..60161a72 --- /dev/null +++ b/tests/testthat/test-xportr.R @@ -0,0 +1,44 @@ +test_that("pipeline results match `xportr()` results", { + if (require(magrittr, quietly = TRUE)) { + skip_if_not_installed("withr") + pipeline_path <- withr::local_file("adslpipe.xpt") + xportr_path <- withr::local_file("adslxptr.xpt") + + dataset_spec_low <- setNames(dataset_spec, tolower(names(dataset_spec))) + names(dataset_spec_low)[[2]] <- "label" + + var_spec_low <- setNames(var_spec, tolower(names(var_spec))) + names(var_spec_low)[[5]] <- "type" + + # 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(withr::local_tempfile()) + pipeline_df <- adsl %>% + xportr_metadata(var_spec_low, "ADSL", verbose = "none") %>% + xportr_type() %>% + xportr_length() %>% + xportr_label() %>% + xportr_order() %>% + xportr_format() %>% + xportr_df_label(dataset_spec_low) %>% + xportr_write(pipeline_path) + + # `xportr()` can be used to apply a whole pipeline at once + xportr_df <- xportr( + adsl, + var_metadata = var_spec_low, + df_metadata = dataset_spec_low, + domain = "ADSL", + verbose = "none", + path = xportr_path + ) + + expect_identical(pipeline_df, xportr_df) + + expect_identical( + haven::read_xpt(pipeline_path), + haven::read_xpt(xportr_path) + ) + } +})