diff --git a/DESCRIPTION b/DESCRIPTION index 536f03c..5461ecc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -11,15 +11,17 @@ Description: Assist with management of clinical trial data in the SDTM and ADaM and verification of SDTM data. Depends: R (>= 3.5) Imports: - dplyr, - ggplot2, - labeling, - lubridate, - methods, - readr, - rio, - rlang, - tidyr + dplyr, + ggplot2, + labeling, + lifecycle, + lubridate, + metatools, + methods, + readr, + rio, + rlang, + tidyr Suggests: covr, scales, diff --git a/NAMESPACE b/NAMESPACE index d79ca56..09ff9cb 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,14 @@ # Generated by roxygen2: do not edit by hand S3method(c_to_n,character) +S3method(c_to_n,data.frame) +S3method(c_to_n,factor) +S3method(c_to_n,integer) +S3method(c_to_n,logical) +S3method(c_to_n,numeric) +S3method(sdtm_dtc_to_datetime,Date) +S3method(sdtm_dtc_to_datetime,POSIXt) +S3method(sdtm_dtc_to_datetime,character) S3method(sdtm_dtc_to_datetime,data.frame) S3method(sdtm_dtc_to_datetime,list) S3method(sdtm_first_dose,data.frame) @@ -42,22 +50,14 @@ export(sdtm_first_dose) export(sdtm_time_actual) export(simplify_sdtm_names) export(standardize_sdtm_id) -export(strip_attributes) -export(supp_reformat) -importFrom(dplyr,anti_join) importFrom(dplyr,case_when) importFrom(dplyr,group_by_at) importFrom(dplyr,is_grouped_df) -importFrom(dplyr,recode) importFrom(dplyr,rename_all) importFrom(dplyr,rename_at) importFrom(dplyr,summarize_at) importFrom(lubridate,format_ISO8601) importFrom(lubridate,is.POSIXt) importFrom(lubridate,ymd_hms) -importFrom(readr,type_convert) importFrom(rio,import) -importFrom(rlang,abort) -importFrom(rlang,inform) -importFrom(tidyr,spread) importFrom(tools,file_path_sans_ext) diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..fd164db --- /dev/null +++ b/NEWS.md @@ -0,0 +1,4 @@ +# Rsdtm 0.0.9017 + +* Added `auto_supp` and `auto_dtc` arguments to `import_sdtm()` +* Removed `merge_supp()` and related functions in favor of `metatools::combine_supp()` diff --git a/R/c_to_n.R b/R/c_to_n.R index 5f1afb7..258cb12 100644 --- a/R/c_to_n.R +++ b/R/c_to_n.R @@ -57,23 +57,27 @@ c_to_n.character <- function(x, ..., } #' @describeIn c_to_n For factors. +#' @export c_to_n.factor <- function(x, ...) { c_to_n.character(as.character(x), ...) } #' @describeIn c_to_n For numeric vectors. +#' @export c_to_n.numeric <- function(x, ...) { warning("`c_to_n` is generally not called on a numeric vector. Please verify code.") x } #' @describeIn c_to_n For integer vectors. +#' @export c_to_n.integer <- function(x, ...) { warning("`c_to_n` is generally not called on an integer vector. Please verify code.") x } #' @describeIn c_to_n For logical vectors (only handles all-NA case). +#' @export c_to_n.logical <- function(x, ...) { if (!all(is.na(x))) { warning("`c_to_n` does not set non-NA logical values to numeric.") @@ -84,6 +88,7 @@ c_to_n.logical <- function(x, ...) { #' @describeIn c_to_n For data.frames and similar, finds columns matching the #' regular expression pattern `"^..(ST|OR).*C$"`. data.frame method does not #' replace numeric columns that already exist. +#' @export c_to_n.data.frame <- function(x, ..., verbose=TRUE) { columns_named_c <- grep(pattern="^..(ST|OR).*C$", x=names(x), value=TRUE) columns_named_n <- grep(pattern="^..(ST|OR).*N$", x=names(x), value=TRUE) diff --git a/R/date_conversion.R b/R/date_conversion.R index 7ad2133..3f9c6af 100644 --- a/R/date_conversion.R +++ b/R/date_conversion.R @@ -3,8 +3,11 @@ #' #' @param x The data to convert #' @param date_col_pattern A regex to search column names for dates to convert. -#' @param truncated Passed to \code{lubridate::ymd_hms} -#' @param ... Additional arguments passed to \code{lubridate::ymd_hms} +#' @param truncated Passed to `lubridate::ymd_hms()` or `lubridate::ymd()`; the +#' `truncated` argument is always considered relative to `ymd_hms` formatting, +#' so it is used as `truncated - 3` for dates. +#' @param ... Additional arguments passed to `lubridate::ymd_hms()` or +#' `lubridate::ymd()` #' @return The data with the date converted. Note that all dates will be #' returned as POSIXct objects, so partial dates will appear as the #' @family Date management and conversion @@ -16,21 +19,51 @@ sdtm_dtc_to_datetime <- function(x, ...) { #' @rdname sdtm_dtc_to_datetime #' @export sdtm_dtc_to_datetime.list <- function(x, ...) { - lapply(X=x, - FUN=sdtm_dtc_to_datetime, - ...) + lapply(X=x, FUN=sdtm_dtc_to_datetime, ...) } #' @rdname sdtm_dtc_to_datetime #' @export -sdtm_dtc_to_datetime.data.frame <- function(x, date_col_pattern="DTC$", truncated=5, ...) { +sdtm_dtc_to_datetime.Date <- function(x, ...) { + x +} + +#' @rdname sdtm_dtc_to_datetime +#' @export +sdtm_dtc_to_datetime.POSIXt <- function(x, ...) { + x +} + +#' @rdname sdtm_dtc_to_datetime +#' @export +sdtm_dtc_to_datetime.character <- function(x, truncated=5, ...) { + # Treat empty strings as NA + x_current <- x + x_current[x_current %in% ""] <- NA_character_ + + # Detect columns that only contain dates and load them as dates rather than + # datetimes + is_date <- + grepl( + x = x_current, + pattern = paste0("^", pattern_ISO8601_calendar_date(), "$") + ) + if (all(is.na(x_current) | is_date)) { + # If it is a date + x <- lubridate::ymd(x_current, truncated=max(truncated - 3, 0), ...) + } else { + # Otherwise try to consider it a datetime + x <- lubridate::ymd_hms(x_current, truncated=truncated, ...) + } + x +} + +#' @rdname sdtm_dtc_to_datetime +#' @export +sdtm_dtc_to_datetime.data.frame <- function(x, date_col_pattern="DTC$", ...) { date_col_names <- grep(names(x), pattern=date_col_pattern, value=TRUE) for (current_name in date_col_names) { - if (!lubridate::is.POSIXt(x[[current_name]])) { - x[[current_name]] <- ymd_hms(x[[current_name]], truncated=truncated, ...) - } else { - message("Column ", current_name, " is already a datetime object.") - } + x[[current_name]] <- sdtm_dtc_to_datetime(x[[current_name]]) } x } diff --git a/R/import_sdtm.R b/R/import_sdtm.R index 901d4aa..b93a284 100644 --- a/R/import_sdtm.R +++ b/R/import_sdtm.R @@ -6,6 +6,9 @@ #' first extension in \code{extension_choice} with a usable file will be used, #' and a warning will be given for subsequent files. #' @param ignore_case Passed to \code{list.files} when loading a directory. +#' @param auto_supp Automatically combine --SUPP data with the main SDTM domain +#' and remove the --SUPP data from the returned list of data.frames. +#' @param auto_dtc Automatically convert --DTC columns to date/times? #' @param return_type When loading a single file, what type of output should be #' provided? #' @param ... Arguments passed to \code{rio::import} @@ -22,6 +25,8 @@ import_sdtm <- function(path, extension_choice = c(".sas7bdat", ".xpt"), ignore_case = TRUE, + auto_supp = FALSE, + auto_dtc = FALSE, ...) { stopifnot( is.character(path), @@ -54,6 +59,22 @@ import_sdtm <- function(path, ) ret <- append_no_duplicate_names(ret, tmp_ret, method=stop) } + + if (auto_supp) { + supp_domains <- names(ret)[startsWith(names(ret), "SUPP")] + for (current_supp in supp_domains) { + current_domain <- gsub(x = current_supp, pattern = "^SUPP", replacement = "") + if (!(current_domain %in% names(ret))) { + stop("Domain ", current_domain, " was not found when trying to auto-combine --SUPP data with ", current_supp) + } + ret[[current_domain]] <- metatools::combine_supp(ret[[current_domain]], supp = ret[[current_supp]]) + ret[[current_supp]] <- NULL + } + } + + if (auto_dtc) { + ret <- sdtm_dtc_to_datetime(ret, ...) + } ret } diff --git a/R/merge_supp.R b/R/merge_supp.R index a2b27d1..e59b402 100644 --- a/R/merge_supp.R +++ b/R/merge_supp.R @@ -1,192 +1,9 @@ #' Merge a supplementary dataset into a primary dataset #' -#' @param primary the data.frame of the primary dataset -#' @param supplementary the data.frame of the supplementary dataset -#' @param remove_attributes If \code{TRUE}, remove all attributes from all -#' columns (this will break many classes); if \code{FALSE}, remove no -#' attributes from any columns; if a character, remove those attributes from -#' the columns. -#' @inheritParams supp_reformat -#' @return \code{primary} merged with \code{supplementary} where new column -#' names come from the \code{QNAM} column in \code{supplementary} -#' @seealso \code{\link{supp_reformat}} -#' @export -#' @importFrom dplyr anti_join -#' @importFrom rlang abort inform -merge_supp <- function(primary, supplementary, remove_attributes = c("label"), auto_convert=FALSE) { - if (length(unique(supplementary$RDOMAIN)) != 1) { - stop("Only direct relationships with supplementary domains are currently supported.") - } - if (is.logical(remove_attributes) && remove_attributes) { - primary <- strip_attributes(primary, specific = NULL) - supplementary <- strip_attributes(supplementary, specific = NULL) - } else if (is.character(remove_attributes)) { - primary <- strip_attributes(primary, specific = remove_attributes) - supplementary <- strip_attributes(supplementary, specific = remove_attributes) - } - ret <- primary - supp_prep <- supp_reformat(supplementary, auto_convert=auto_convert) - for (current_supp_idx in seq_along(supp_prep)) { - current_supp <- supp_prep[[current_supp_idx]] - current_idvar <- names(supp_prep)[current_supp_idx] - if (current_idvar != "") { - # Check for a class mismatch between the original and the supp domain idvar - if (any(class(current_supp[[current_idvar]]) != class(ret[[current_idvar]]))) { - orig <- current_supp[[current_idvar]] - current_supp[[current_idvar]] <- - methods::as(current_supp[[current_idvar]], Class=class(ret[[current_idvar]])) - if (!all(is.na(orig) == is.na(current_supp[[current_idvar]]))) { - # Introduction of an NA is a problem - rlang::abort( - message=sprintf("NA introduced by coercion for supplemental merge in column %s", current_idvar), - class="Rsdtm_merge_supp_na_idvar" - ) - } else { - rlang::inform( - message= - sprintf( - "Supplemental merge column %s type converted to class: %s", - current_idvar, - class(ret[[current_idvar]])[1] - ), - class="Rsdtm_merge_supp_convert_idvar" - ) - } - } - } - current_join_vars <- setdiff(c("STUDYID", "DOMAIN", "USUBJID", current_idvar), "") - missed_rows <- dplyr::anti_join(current_supp, ret, by = current_join_vars) - if (nrow(missed_rows)) { - stop( - nrow(missed_rows), - " rows from the ", - current_idvar, - " IDVAR in the SUPP domain do not match rows in the primary ", - primary$DOMAIN[1], - " dataset." - ) - } - ret <- dplyr::left_join(ret, current_supp, by = current_join_vars) - } - ret -} - -#' Reformat a --SUPP SDTM domain into a list of data.frames ready for merging -#' into the primary domain. -#' -#' @param x a --SUPP SDTM domain object -#' @param auto_convert should the data be automatically converted using -#' `type_convert()`? -#' @return A list with length the same as \code{unique(x$IDVAR)} with -#' data.frames ready for merging into the primary dataset. -#' @seealso \code{\link{merge_supp}} -#' @export -supp_reformat <- function(x, auto_convert=FALSE) { - ret <- list() - for (current_idvar in unique(x$IDVAR)) { - ret <- append( - ret, - list( - supp_reformat_single( - x[x$IDVAR %in% current_idvar, ], - auto_convert=auto_convert - ) - ) - ) - } - names(ret) <- unique(x$IDVAR) - ret -} - -#' @importFrom dplyr rename_at recode -#' @importFrom tidyr spread -#' @importFrom readr type_convert -supp_reformat_single <- function(x, auto_convert=FALSE) { - idvar <- unique(x$IDVAR) - if (length(unique(x$RDOMAIN)) != 1) { - stop("RDOMAIN column in x must have a single value.") - } else if (length(idvar) != 1) { - stop("IDVAR column in x must have a single value.") - } else if (any(c("APID", "POOLID") %in% names(x))) { - stop("APID and POOLID are not yet supported.") - } - # Columns to drop - if (all(x$IDVAR %in% "" & x$IDVARVAL %in% "")) { - message( - "No IDVAR or IDVARVAL in SUPP", unique(x$RDOMAIN), - " data; assuming USUBJID is sufficient for merge." - ) - ret <- x[, setdiff(names(x), c("IDVAR", "IDVARVAL", "QLABEL", "QORIG", "QEVAL")), drop=FALSE] - ret <- - rename_at( - .tbl=ret, - .vars="RDOMAIN", - .funs=dplyr::recode, - RDOMAIN="DOMAIN" - ) - } else { - if (any(x$IDVAR %in% "")) { - stop("Some IDVAR values are missing (when some IDVAR or IDVARVAL are present) in SUPP", unique(x$RDOMAIN)) - } else if (any(x$IDVARVAL %in% "")) { - stop("Some IDVARVAL values are missing (when some IDVAR or IDVARVAL are present) in SUPP", unique(x$RDOMAIN)) - } - ret <- x[, setdiff(names(x), c("IDVAR", "QLABEL", "QORIG", "QEVAL")), drop=FALSE] - ret <- - rename_at( - .tbl=ret, - .vars=c("RDOMAIN", "IDVARVAL"), - .funs=recode, - RDOMAIN="DOMAIN", - IDVARVAL=idvar - ) - } - ret <- - tidyr::spread( - ret, - key="QNAM", - value="QVAL" - ) - if (auto_convert) { - ret <- type_convert(df=ret) - } - ret -} - -#' Remove attributes from an object +#' This function is defunct. Use `metatools::combine_supp()` instead. #' -#' @param x The object to remove attributes from -#' @param specific If \code{NULL}, all attributes are removed. If a character -#' vector, only the named attributes are removed. -#' @param columns_only Do not strip attributes from the data.frame; only strip -#' them from the columns of the data.frame. -#' @param ... Passed to other `strip_attributes()` methods. -#' @return \code{x} with fewer attributes. +#' @param ... Ignored #' @export -strip_attributes <- function(x, specific=NULL, ...) { - UseMethod("strip_attributes") -} - -#' @rdname strip_attributes -strip_attributes.data.frame <- function(x, specific=NULL, columns_only=TRUE, ...) { - if (columns_only) { - for (nm in seq_along(x)) { - x[[nm]] <- strip_attributes(x[[nm]], specific=specific, columns_only=columns_only, ...) - } - x - } else { - strip_attributes.default(x, specific=specific, ...) - } -} - -#' @rdname strip_attributes -strip_attributes.default <- function(x, specific=NULL, ...) { - if (is.null(specific)) { - attributes(x) <- NULL - x - } else { - for (current in specific) { - attr(x, current) <- NULL - } - x - } +merge_supp <- function(...) { + lifecycle::deprecate_stop(when = "0.0.9000", what = "merge_supp()", with = "metatools::combine_supp()") } diff --git a/inst/WORDLIST b/inst/WORDLIST index 885171f..1504941 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -25,7 +25,10 @@ datetime ddd difftime ggplots +hms https +lubridate trimws wikipedia +ymd yyyy diff --git a/man/import_sdtm.Rd b/man/import_sdtm.Rd index eac4fd3..2b8e35b 100644 --- a/man/import_sdtm.Rd +++ b/man/import_sdtm.Rd @@ -10,6 +10,8 @@ import_sdtm( path, extension_choice = c(".sas7bdat", ".xpt"), ignore_case = TRUE, + auto_supp = FALSE, + auto_dtc = FALSE, ... ) @@ -33,6 +35,11 @@ and a warning will be given for subsequent files.} \item{ignore_case}{Passed to \code{list.files} when loading a directory.} +\item{auto_supp}{Automatically combine --SUPP data with the main SDTM domain +and remove the --SUPP data from the returned list of data.frames.} + +\item{auto_dtc}{Automatically convert --DTC columns to date/times?} + \item{...}{Arguments passed to \code{rio::import}} \item{ignore_filename}{A vector of filenames not to load (case sensitive, diff --git a/man/merge_supp.Rd b/man/merge_supp.Rd index 12d058a..61e7867 100644 --- a/man/merge_supp.Rd +++ b/man/merge_supp.Rd @@ -4,33 +4,11 @@ \alias{merge_supp} \title{Merge a supplementary dataset into a primary dataset} \usage{ -merge_supp( - primary, - supplementary, - remove_attributes = c("label"), - auto_convert = FALSE -) +merge_supp(...) } \arguments{ -\item{primary}{the data.frame of the primary dataset} - -\item{supplementary}{the data.frame of the supplementary dataset} - -\item{remove_attributes}{If \code{TRUE}, remove all attributes from all -columns (this will break many classes); if \code{FALSE}, remove no -attributes from any columns; if a character, remove those attributes from -the columns.} - -\item{auto_convert}{should the data be automatically converted using -`type_convert()`?} -} -\value{ -\code{primary} merged with \code{supplementary} where new column - names come from the \code{QNAM} column in \code{supplementary} +\item{...}{Ignored} } \description{ -Merge a supplementary dataset into a primary dataset -} -\seealso{ -\code{\link{supp_reformat}} +This function is defunct. Use `metatools::combine_supp()` instead. } diff --git a/man/sdtm_dtc_to_datetime.Rd b/man/sdtm_dtc_to_datetime.Rd index 21ccd4d..8437fa4 100644 --- a/man/sdtm_dtc_to_datetime.Rd +++ b/man/sdtm_dtc_to_datetime.Rd @@ -3,6 +3,9 @@ \name{sdtm_dtc_to_datetime} \alias{sdtm_dtc_to_datetime} \alias{sdtm_dtc_to_datetime.list} +\alias{sdtm_dtc_to_datetime.Date} +\alias{sdtm_dtc_to_datetime.POSIXt} +\alias{sdtm_dtc_to_datetime.character} \alias{sdtm_dtc_to_datetime.data.frame} \title{Convert the character representation of the date in an original SDTM dataset to a POSIXct object.} @@ -11,16 +14,25 @@ sdtm_dtc_to_datetime(x, ...) \method{sdtm_dtc_to_datetime}{list}(x, ...) -\method{sdtm_dtc_to_datetime}{data.frame}(x, date_col_pattern = "DTC$", truncated = 5, ...) +\method{sdtm_dtc_to_datetime}{Date}(x, ...) + +\method{sdtm_dtc_to_datetime}{POSIXt}(x, ...) + +\method{sdtm_dtc_to_datetime}{character}(x, truncated = 5, ...) + +\method{sdtm_dtc_to_datetime}{data.frame}(x, date_col_pattern = "DTC$", ...) } \arguments{ \item{x}{The data to convert} -\item{...}{Additional arguments passed to \code{lubridate::ymd_hms}} +\item{...}{Additional arguments passed to `lubridate::ymd_hms()` or +`lubridate::ymd()`} -\item{date_col_pattern}{A regex to search column names for dates to convert.} +\item{truncated}{Passed to `lubridate::ymd_hms()` or `lubridate::ymd()`; the +`truncated` argument is always considered relative to `ymd_hms` formatting, +so it is used as `truncated - 3` for dates.} -\item{truncated}{Passed to \code{lubridate::ymd_hms}} +\item{date_col_pattern}{A regex to search column names for dates to convert.} } \value{ The data with the date converted. Note that all dates will be diff --git a/man/strip_attributes.Rd b/man/strip_attributes.Rd deleted file mode 100644 index 522824d..0000000 --- a/man/strip_attributes.Rd +++ /dev/null @@ -1,31 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/merge_supp.R -\name{strip_attributes} -\alias{strip_attributes} -\alias{strip_attributes.data.frame} -\alias{strip_attributes.default} -\title{Remove attributes from an object} -\usage{ -strip_attributes(x, specific = NULL, ...) - -\method{strip_attributes}{data.frame}(x, specific = NULL, columns_only = TRUE, ...) - -\method{strip_attributes}{default}(x, specific = NULL, ...) -} -\arguments{ -\item{x}{The object to remove attributes from} - -\item{specific}{If \code{NULL}, all attributes are removed. If a character -vector, only the named attributes are removed.} - -\item{...}{Passed to other `strip_attributes()` methods.} - -\item{columns_only}{Do not strip attributes from the data.frame; only strip -them from the columns of the data.frame.} -} -\value{ -\code{x} with fewer attributes. -} -\description{ -Remove attributes from an object -} diff --git a/man/supp_reformat.Rd b/man/supp_reformat.Rd deleted file mode 100644 index 29f58f9..0000000 --- a/man/supp_reformat.Rd +++ /dev/null @@ -1,26 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/merge_supp.R -\name{supp_reformat} -\alias{supp_reformat} -\title{Reformat a --SUPP SDTM domain into a list of data.frames ready for merging -into the primary domain.} -\usage{ -supp_reformat(x, auto_convert = FALSE) -} -\arguments{ -\item{x}{a --SUPP SDTM domain object} - -\item{auto_convert}{should the data be automatically converted using -`type_convert()`?} -} -\value{ -A list with length the same as \code{unique(x$IDVAR)} with - data.frames ready for merging into the primary dataset. -} -\description{ -Reformat a --SUPP SDTM domain into a list of data.frames ready for merging -into the primary domain. -} -\seealso{ -\code{\link{merge_supp}} -} diff --git a/tests/testthat/example-sdtm/dm.xpt b/tests/testthat/example-sdtm/dm.xpt new file mode 100644 index 0000000..a0b79cc Binary files /dev/null and b/tests/testthat/example-sdtm/dm.xpt differ diff --git a/tests/testthat/example-sdtm/suppdm.xpt b/tests/testthat/example-sdtm/suppdm.xpt new file mode 100644 index 0000000..342704d Binary files /dev/null and b/tests/testthat/example-sdtm/suppdm.xpt differ diff --git a/tests/testthat/test-date_conversion.R b/tests/testthat/test-date_conversion.R index ccb3a22..56a5509 100644 --- a/tests/testthat/test-date_conversion.R +++ b/tests/testthat/test-date_conversion.R @@ -1,3 +1,12 @@ +test_that("sdtm_dtc_to_datetime", { + expect_message( + ld_sdtm <- import_sdtm(path = test_path("example-sdtm"), auto_dtc = TRUE), + regexp = "Detected domain SUPPDM from data." + ) + expect_s3_class(ld_sdtm$DM$RFPENDTC, "POSIXt") + expect_s3_class(ld_sdtm$DM$RFSTDTC, "Date") +}) + test_that("generate_dtc works", { expect_equal( generate_dtc(datetime="2020-05-01T01:02:03"), diff --git a/tests/testthat/test-defunct.R b/tests/testthat/test-defunct.R new file mode 100644 index 0000000..4b970ba --- /dev/null +++ b/tests/testthat/test-defunct.R @@ -0,0 +1,3 @@ +test_that("Defunct function notifications", { + lifecycle::expect_defunct(merge_supp()) +}) diff --git a/tests/testthat/test-import_sdtm.R b/tests/testthat/test-import_sdtm.R new file mode 100644 index 0000000..6107919 --- /dev/null +++ b/tests/testthat/test-import_sdtm.R @@ -0,0 +1,43 @@ +# This is how the example SDTM data were created +# rio::export(x = pharmaversesdtm::dm, file = test_path("example-sdtm/dm.xpt")) +# rio::export(x = pharmaversesdtm::suppdm, file = test_path("example-sdtm/suppdm.xpt")) + +test_that("import_sdtm", { + # Automatically import a directory + expect_message( + import_sdtm(path = test_path("example-sdtm")), + regexp = "Detected domain SUPPDM from data." + ) + + # Import a single file + expect_message( + import_sdtm(path = test_path("example-sdtm/dm.xpt")), + regexp = "Detected domain DM from data." + ) +}) + +test_that("import_sdtm expected errors", { + expect_error( + import_sdtm(path = "foo"), + regexp = 'The following were not found as directories or files: "foo"' + ) + expect_error( + suppressMessages(import_sdtm(path = test_path("example-sdtm/suppdm.xpt"), auto_supp = TRUE)), + regexp = "Domain DM was not found when trying to auto-combine --SUPP data with SUPPDM" + ) +}) + +test_that("import_sdtm auto_supp automatically merges --SUPP domains", { + expect_message( + ld_sdtm <- import_sdtm(path = test_path("example-sdtm")), + regexp = "Detected domain SUPPDM from data." + ) + expect_named(ld_sdtm, c("DM", "SUPPDM")) + + expect_message( + ld_sdtm <- import_sdtm(path = test_path("example-sdtm"), auto_supp = TRUE), + regexp = "Detected domain SUPPDM from data." + ) + expect_named(ld_sdtm, "DM") +}) +