Skip to content

Commit

Permalink
Merge pull request #74 from atorus-research/rename-na-fmts
Browse files Browse the repository at this point in the history
Add logic to convert any null or NA formats to "" for haven.
  • Loading branch information
bms63 authored Feb 23, 2023
2 parents b1e84c5 + 93cacb8 commit 5bd830d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 10 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# xportr 0.2.0
* Added a new validation test that errors when users pass invalid formats (#60 #64). Thanks to @zdz2101!
* Fixed an issue where xportr_format could pass invalid formats to haven::write_xpt.

# xportr 0.1.0

Expand Down
17 changes: 13 additions & 4 deletions R/format.R
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,27 @@ xportr_format <- function(.df, metacore, domain = NULL, verbose = getOption("xpo
} else {
metadata <- metacore
}

filtered_metadata <- metadata %>%
filter(!!sym(variable_name) %in% names(.df))

format <- metadata %>%

format <- filtered_metadata %>%
select(!!sym(format_name)) %>%
unlist() %>%
toupper()
names(format) <- metadata[[variable_name]]

names(format) <- filtered_metadata[[variable_name]]

for (i in names(format)) {
attr(.df[[i]], "format.sas") <- format[[i]]
}

# Convert NA formats to "" for haven
for (i in seq_len(ncol(.df))) {
if (is.na(attr(.df[[i]], "format.sas")) || is.null(attr(.df[[i]], "format.sas")))
attr(.df[[i]], "format.sas") <- ""
}

.df
}
35 changes: 29 additions & 6 deletions tests/testthat/test-metadata.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@

extract_format <- function(.x) {
format_ <- character(length(.x))
for (i in 1:length(.x)) {
format_[i] <- attr(.x[[i]], "format.sas")
}
format_
}

test_that("Variable label", {
df <- data.frame(x = "a", y = "b")
varmeta <- data.frame(dataset = rep("df", 2),
Expand Down Expand Up @@ -53,15 +62,13 @@ test_that("Expect error if any label exceeds 40 character", {
"dataset label must be 40 characters or less")
})

test_that("SAS format", {
test_that("xportr_format will set formats as expected", {
df <- data.frame(x = 1, y = 2)
varmeta <- data.frame(dataset = rep("df", 2),
variable = c("x", "y"),
format = c("date9.", "datetime20."))
variable = c("x", "y"),
format = c("date9.", "datetime20."))

extract_format <- function(.x) {
vapply(.x, function(.x) attr(.x, "format.sas"), character(1), USE.NAMES = FALSE)
}


out <- xportr_format(df, varmeta)

Expand All @@ -71,6 +78,22 @@ test_that("SAS format", {
row.names = c(NA, -1L), class = "data.frame"))
})

test_that("xportr_format will handle NA values and won't error", {
df <- data.frame(x = 1, y = 2, z = 3, a = 4)
varmeta <- data.frame(dataset = rep("df", 4),
variable = c("x", "y", "z", "abc"),
format = c("date9.", "datetime20.", NA, "text"))

out <- xportr_format(df, varmeta)

expect_equal(extract_format(out), c("DATE9.", "DATETIME20.", "", ""))
expect_equal(dput(out), structure(list(x = structure(1, format.sas = "DATE9."),
y = structure(2, format.sas = "DATETIME20."),
z = structure(3, format.sas = ""),
a = structure(4, format.sas = "")),
row.names = c(NA, -1L), class = "data.frame"))
})

test_that("Error ", {
df1 <- data.frame(x = 1, y = 2)
df2 <- data.frame(x = 3, y = 4)
Expand Down

0 comments on commit 5bd830d

Please sign in to comment.