Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitHub issue #3, #16, #17, #18, #20 #19

Merged
merged 12 commits into from
Sep 29, 2023
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
Depends: R (>= 3.5)
Imports:
jsonlite (>= 1.8.7),
jsonvalidate (>= 1.3.2)
jsonlite (>= 1.8.0),
jsonvalidate (>= 1.3.1)
Suggests:
testthat (>= 2.1.0),
knitr,
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# datasetjson 0.0.1.9000

- Capability to read and validate Dataset JSON files from URLs has been added (#8)
- Remove autoset of fileOID using output path (#3)
- Don't auto-populate optional attributes with NA (#16)
- Push dependency versions back (#18)
- Default `pretty` parameter on `write_dataset_json()` to false (#20)

# datasetjson 0.0.1

Expand Down
2 changes: 1 addition & 1 deletion R/data_metadata.R
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
#' data_meta_updated <- set_metadata_version(data_meta_updated, "MDV.MSGv2.0.SDTMIG.3.3.SDTM.1.7")
#' data_meta_updated <- set_study_oid(data_meta_updated, "SOMESTUDY")
#'
data_metadata <- function(study = "NA", metadata_version = "NA", metadata_ref = "NA") {
data_metadata <- function(study = NULL, metadata_version = NULL, metadata_ref = NULL) {

x <- list(
studyOID = study,
Expand Down
26 changes: 19 additions & 7 deletions R/file_metadata.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#' file."
#' @param sys_version sourceSystemVersion, defined as "The version of the
#' sourceSystem"
#' @param file_oid fileOID parameter, defined as "A unique identifier for this
#' file."
#' @param version Dataset JSON schema version being used
#'
#' @return file_metadata object
Expand All @@ -26,17 +28,17 @@
#' file_meta_updated <- set_file_oid(file_meta, "/some/path")
#' file_meta_updated <- set_originator(file_meta_updated, "Some Org")
#' file_meta_updated <- set_source_system(file_meta_updated, "source system", "1.0")
file_metadata <- function(originator="NA", sys = "NA", sys_version = "NA", version = "1.0.0") {
file_metadata <- function(originator=NULL, sys = NULL, sys_version = NULL, file_oid = NULL, version = "1.0.0") {

if (!(version %in% c("1.0.0"))) {
stop("Unsupported version specified - currently only version 1.0.0 is supported", call.=FALSE)
}

x <- list(
"creationDateTime"= get_datetime(),
"creationDateTime"= character(),
"datasetJSONVersion"= version,
"fileOID" = character(),
"asOfDateTime" = character(),
"fileOID" = file_oid,
"asOfDateTime" = NULL, # Not sure we want this to exist?
"originator" = originator,
"sourceSystem" = sys,
"sourceSystemVersion" = sys_version
Expand All @@ -59,10 +61,20 @@ get_datetime <- function() {
format(Sys.time(), "%Y-%m-%dT%H:%M:%S")
}

#' Set source system information
#' File Metadata Setters
#'
#' Set information about the file and source system used to generate the Dataset
#' JSON object.
#'
#' @details
#'
#' Set information about the source system used to generate the Dataset JSON
#' object.
#' The fileOID parameter should be structured following description outlined in
#' the ODM V2.0 specification. "FileOIDs should be universally unique if at all
#' possible. One way to ensure this is to prefix every FileOID with an internet
#' domain name owned by the creator of the ODM file or database (followed by a
#' forward slash, "/"). For example,
#' FileOID="BestPharmaceuticals.com/Study5894/1" might be a good way to denote
#' the first file in a series for study 5894 from Best Pharmaceuticals."
#'
#' @param x datasetjson object
#' @param sys sourceSystem parameter, defined as "The computer system or
Expand Down
35 changes: 35 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,41 @@ set_col_attr <- function(nm, d, attr, items) {
x
}

#' Get the index of nulls in a list
#'
#' @param x A list
#'
#' @return Integer vector of indices
#' @noRd
get_null_inds <- function(x) {
which(vapply(x, is.null, FUN.VALUE = TRUE))
}

#' Remove nulls from a Dataset JSON object
#'
#' Only targets the file and data metadata to pull off optional elements
#'
#' @param x A Dataset JSON object
#'
#' @return A Dataset JSON object
#' @noRd
remove_nulls <- function(x) {

# Specifically target the data metadata
dm_nulls <- get_null_inds(x[[get_data_type(x)]])
if (length(dm_nulls) > 0) {
x[[get_data_type(x)]] <- x[[get_data_type(x)]][-dm_nulls]
}

# Top level
fm_nulls <- get_null_inds(x)
if (length(fm_nulls) > 0) {
x <- x[-fm_nulls]
}

x
}

#' Check if given path is a URL
#'
#' @param path character string
Expand Down
13 changes: 5 additions & 8 deletions R/write_dataset_json.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,19 @@
#' \dontrun{
#' write_dataset_json(ds_json, "path/to/file.json")
#' }
write_dataset_json <- function(x, file, pretty=TRUE) {
write_dataset_json <- function(x, file, pretty=FALSE) {
stopifnot_datasetjson(x)

# Populate the as-of datetime
x[['asOfDateTime']] <- get_datetime()
# Populate the creation datetime
x[['creationDateTime']] <- get_datetime()

x <- remove_nulls(x)

if (!missing(file)) {
# Make sure the output path exists
if(!dir.exists(dirname(file))) {
stop("Folder supplied to `file` does not exist", call.=FALSE)
}

# Attach the file OID
x <- set_file_oid(x, tools::file_path_sans_ext(file))
} else{
x <- set_file_oid(x, "NA")
}

# Create the JSON text
Expand Down
10 changes: 4 additions & 6 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,7 @@ knitr::opts_chunk$set(echo = TRUE)
library(datasetjson)
```

# datasetjson

<!-- Please do not edit the README.md file as it is auto-generated after PR merges. Only edit the README.Rmd file -->
<!-- The purpose of this is to enable dynamic links using dyn_link function above to access devel/main admiral homepage respectively -->
<!-- To test this in your feature branch use code: rmarkdown::render("README.Rmd", output_format ="md_document") -->
# **datasetjson** <img src="man/figures/logo.svg" align="right" alt="" width="120" />

<!-- badges: start -->
[<img src="https://img.shields.io/codecov/c/github/atorus-research/datasetjson">](https://app.codecov.io/gh/atorus-research/datasetjson)
Expand Down Expand Up @@ -67,7 +63,7 @@ write_dataset_json(ds_updated, file = "./iris.json")
Or if you don't provide a file path, the JSON text will return directly.

```{r write_print}
js_text <- write_dataset_json(ds_updated)
js_text <- write_dataset_json(ds_updated, pretty=TRUE)
cat(js_text)
```

Expand All @@ -87,6 +83,8 @@ print(attr(dat$Sepal.Width, "type"))
```
Note that Dataset JSON is an early CDISC standard and is still subject to change, as as such this package will be updated. Backwards compatibility will be enforced once the standard itself is more stable. Until then, it is not recommended to use this package within production activities.

# [<img src="man/figures/cdisc.png" alt="" width="120" />](https://www.cdisc.org/)

## Acknowledgements

Thank you to Ben Straub and Eric Simms (GSK) for help and input during the original CDISC Dataset JSON hackathon that motivated this work.
Expand Down
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

# datasetjson
# **datasetjson** <img src="man/figures/logo.svg" align="right" alt="" width="120" />

<!-- Please do not edit the README.md file as it is auto-generated after PR merges. Only edit the README.Rmd file -->
<!-- The purpose of this is to enable dynamic links using dyn_link function above to access devel/main admiral homepage respectively -->
<!-- To test this in your feature branch use code: rmarkdown::render("README.Rmd", output_format ="md_document") -->
<!-- badges: start -->

[<img src="https://img.shields.io/codecov/c/github/atorus-research/datasetjson">](https://app.codecov.io/gh/atorus-research/datasetjson)
Expand Down Expand Up @@ -73,15 +70,14 @@ write_dataset_json(ds_updated, file = "./iris.json")
Or if you don’t provide a file path, the JSON text will return directly.

``` r
js_text <- write_dataset_json(ds_updated)
js_text <- write_dataset_json(ds_updated, pretty=TRUE)
cat(js_text)
```

## {
## "creationDateTime": "2023-09-15T17:57:31",
## "creationDateTime": "2023-09-25T12:20:23",
## "datasetJSONVersion": "1.0.0",
## "fileOID": "NA",
## "asOfDateTime": "2023-09-15T17:57:31",
## "fileOID": "/some/path",
## "originator": "Some Org",
## "sourceSystem": "source system",
## "sourceSystemVersion": "1.0",
Expand Down Expand Up @@ -174,7 +170,7 @@ attached as attributes on the data frame itself:
print(attr(dat, "creationDateTime"))
```

## [1] "2023-09-15T17:57:31"
## [1] "2023-09-25T12:20:23"

``` r
print(attr(dat$Sepal.Length, "OID"))
Expand All @@ -194,6 +190,8 @@ compatibility will be enforced once the standard itself is more stable.
Until then, it is not recommended to use this package within production
activities.

# [<img src="man/figures/cdisc.png" alt="" width="120" />](https://www.cdisc.org/)

## Acknowledgements

Thank you to Ben Straub and Eric Simms (GSK) for help and input during
Expand Down
2 changes: 1 addition & 1 deletion man/data_metadata.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added man/figures/cdisc.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
164 changes: 164 additions & 0 deletions man/figures/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions man/file_metadata.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 12 additions & 3 deletions man/file_metadata_setters.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion man/write_dataset_json.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified pkgdown/favicon/apple-touch-icon-120x120.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/apple-touch-icon-152x152.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/apple-touch-icon-180x180.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/apple-touch-icon-60x60.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/apple-touch-icon-76x76.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/apple-touch-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/favicon-16x16.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/favicon-32x32.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified pkgdown/favicon/favicon.ico
Binary file not shown.
6 changes: 3 additions & 3 deletions tests/testthat/test-data_metadata.R
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
data_meta <- data_metadata()

test_that("Default data_metadata object produces correctly", {
expect_equal(data_meta$studyOID, "NA")
expect_equal(data_meta$metaDataVersionOID, "NA")
expect_equal(data_meta$metaDataRef, "NA")
expect_null(data_meta$studyOID)
expect_null(data_meta$metaDataVersionOID)
expect_null(data_meta$metaDataRef)
})

test_that("data_metadata setters work properly", {
Expand Down
18 changes: 9 additions & 9 deletions tests/testthat/test-datasetjson.R
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,23 @@ test_that("datasetjson object builds with minimal defaults", {

# I just want to remove the potential for a corner case
# where the call to system time splits across a second
expect_equal(grep("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}", ds_json$creationDateTime), 1)
# expect_equal(grep("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}", ds_json$creationDateTime), 1)

# File metadata
expect_equal(ds_json$datasetJSONVersion, "1.0.0")
expect_equal(ds_json$fileOID, character())
expect_equal(ds_json$asOfDateTime, character())
expect_equal(ds_json$originator, "NA")
expect_equal(ds_json$sourceSystem, "NA")
expect_equal(ds_json$sourceSystemVersion, "NA")
expect_null(ds_json$fileOID)
expect_null(ds_json$asOfDateTime)
expect_null(ds_json$originator)
expect_null(ds_json$sourceSystem)
expect_null(ds_json$sourceSystemVersion)

# Data type is correct
expect_equal(tail(names(ds_json), 1), "clinicalData")

# Data metadata
expect_equal(ds_json$clinicalData$studyOID, "NA")
expect_equal(ds_json$clinicalData$metaDataVersionOID, "NA")
expect_equal(ds_json$clinicalData$metaDataRef, "NA")
expect_null(ds_json$clinicalData$studyOID)
expect_null(ds_json$clinicalData$metaDataVersionOID)
expect_null(ds_json$clinicalData$metaDataRef)

# item_id passes through
expect_equal(names(ds_json$clinicalData$itemGroupData), "IG.IRIS")
Expand Down
10 changes: 5 additions & 5 deletions tests/testthat/test-file_metadata.R
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ test_that("Default file_metadata object produces correctly", {
file_meta <- file_metadata()

expect_equal(file_meta$datasetJSONVersion, "1.0.0")
expect_equal(file_meta$fileOID, character())
expect_equal(file_meta$asOfDateTime, character())
expect_equal(file_meta$originator, "NA")
expect_equal(file_meta$sourceSystem, "NA")
expect_equal(file_meta$sourceSystemVersion, "NA")
expect_null(file_meta$fileOID, character())
expect_null(file_meta$asOfDateTime)
expect_null(file_meta$originator)
expect_null(file_meta$sourceSystem)
expect_null(file_meta$sourceSystemVersion)
})

test_that("Parameters pass through on file_metadata call", {
Expand Down
Loading