Skip to content

FederatedMethods/dsROCrate

Repository files navigation

dsROCrate: ‘DataSHIELD’ RO-Crate Wrapper Functions logo

Lifecycle: experimental CRAN status Codecov test coverage

The goal of dsROCrate is to provide functions to wrap elements from a ‘DataSHIELD’ analysis into an RO-Crate.

1. Installation

You can install the development version of dsROCrate from GitHub with:

# install.packages("pak")
pak::pak("FederatedMethods/dsROCrate")

2. Creating your first RO-Crate

In this example, we will be using OBiBa’s Opal as the back-end for DataSHIELD. Another option would be MOLGENIS’ Armadillo.

2.1. Connect to an Opal Server

Setup

For instructions on how to set up a local server for DataSHIELD, see the following vignette:

vignette("deploy-local-datashield-server-with-opal")

Here we will use OBiBa’s Opal demo server: https://opal-demo.obiba.org/ which can be accessed with the following login credentials:

# define global variables
## Opal server access
USERNAME <- "administrator"
USERPASS <- "password"
SERVER <- "https://opal-demo.obiba.org"
## Credentials for `dsuser`
### NOTE: this is only used to simulate an analysis and generate logs
DSUSERPASS <- "P@ssw0rd"

Next, define global variables used in generating the RO-Crate, such as project name, table references (within the project) and user identifiers.

## Five safes variables
PEOPLE <- "dsuser"
PROJECT <- "CNSIM"
TABLES <- c("CNSIM1")

Open connection

Once the credentials and Five Safes variables are configured,we can start a new session on the opal server with the following command:

# login to local server with `USERNAME` and `USERPASS`.
o <- opalr::opal.login(
  username = USERNAME,
  password = USERPASS,
  url = SERVER
)

print(o)
#> url: https://opal-demo.obiba.org 
#> name: opal-demo.obiba.org 
#> version: 5.5.2 
#> username: administrator

2.2. Create a basic RO-Crate

To create a basic RO-Crate, we will use the {rocrateR} package. This package can be installed with the following command:

# install.packages("pak")
pak::pak("rocrateR")

Then, a basic RO-Crate can be created with the following command:

basic_rocrate <- rocrateR::rocrate_5s()

Note that this RO-Crate uses the 5s-crate profile.

print(basic_rocrate)
#> {
#>   "@context": "https://w3id.org/ro/crate/1.2/context",
#>   "@graph": [
#>     {
#>       "@id": "ro-crate-metadata.json",
#>       "@type": "CreativeWork",
#>       "about": {
#>         "@id": "./"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/ro/crate/1.2"
#>       }
#>     },
#>     {
#>       "@id": "./",
#>       "@type": "Dataset",
#>       "name": "",
#>       "description": "",
#>       "datePublished": "2026-02-27",
#>       "license": {
#>         "@id": "http://spdx.org/licenses/CC-BY-4.0"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/5s-crate/0.4"
#>       }
#>     },
#>     {
#>       "@id": "https://w3id.org/5s-crate/0.4",
#>       "@type": ["CreativeWork", "Profile"],
#>       "name": "Five Safes RO-Crate profile"
#>     }
#>   ]
#> }

2.3. Add the Five Safes Elements

Safe Data

To add details for Safe Data, use the function dsROCrate::safe_data().

basic_rocrate <- o |>
  dsROCrate::safe_data(rocrate = basic_rocrate,
                       project = PROJECT,
                       tables = TABLES)

print(basic_rocrate) # note that the output will be truncated
...
#>     {
#>       "@id": "#dataset:67adf2d8e106aca9b11de773758bd241",
#>       "@type": "Dataset",
#>       "name": "CNSIM1",
#>       "dateCreated": "2026-02-27T06:29:50.731Z",
#>       "dateModified": "2026-02-27T06:29:51.865Z",
#>       "path": "/datasource/CNSIM/table/CNSIM1"
#>     }
#>   ]
#> }

Safe Project

To add details for Safe Project, use the function dsROCrate::safe_project().

basic_rocrate <- o |>
  dsROCrate::safe_project(rocrate = basic_rocrate,
                          project = PROJECT)

print(basic_rocrate) # note that the output will be truncated
...
#>     {
#>       "@id": "#project:7ba189863f9f641196596cb28e04aa14",
#>       "@type": "Project",
#>       "name": "CNSIM",
#>       "dateCreated": "2026-02-27T06:29:49.235Z",
#>       "dateModified": "2026-02-27T06:29:54.200Z",
#>       "hasPart": [
#>         {
#>           "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>         }
#>       ]
#>     }
#>   ]
#> }

Safe People

To add details for Safe People, use the function dsROCrate::safe_people().

basic_rocrate <- o |>
  dsROCrate::safe_people(rocrate = basic_rocrate, user = PEOPLE)

print(basic_rocrate) # note that the output will be truncated
...
#>     {
#>       "@id": "#person:a0af2a94926db1b49ad7a812eef509d2",
#>       "@type": "Person",
#>       "name": "dsuser",
#>       "memberOf": [
#>         {
#>           "@id": "#project:7ba189863f9f641196596cb28e04aa14"
#>         }
#>       ]
#>     }
#>   ]
#> }

Safe Setting

To add details for Safe Setting, use the function dsROCrate::safe_setting().

⚠️NOTE: The dsROCrate::safe_setting function requires administrator privileges, so here, we will have to log in with administrator credentials (if you used a non-administrator account previously).

# close previous connection
opalr::opal.logout(o)

# open new connection as administrator
o <- opalr::opal.login(
  username = "administrator",
  password = "password",
  url = SERVER
)

Then, we can proceed as per usual:

basic_rocrate <- o |>
  dsROCrate::safe_setting(rocrate = basic_rocrate)

print(basic_rocrate) # note that the output will be truncated
...
#>     {
#>       "@id": "_:localid:datashield.privacyLevel:5",
#>       "@type": "PropertyValue",
#>       "name": "datashield.privacyLevel",
#>       "value": "5"
#>     },
#>     {
#>       "@id": "_:localid:default.datashield.privacyControlLevel:banana",
#>       "@type": "PropertyValue",
#>       "name": "default.datashield.privacyControlLevel",
#>       "value": "banana"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.glm:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.glm",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.kNN:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.kNN",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.density:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.density",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.max:40",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.max",
#>       "value": "40"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.noise:0.25",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.noise",
#>       "value": "0.25"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.string:80",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.string",
#>       "value": "80"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.stringShort:20",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.stringShort",
#>       "value": "20"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.subset:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.subset",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.tab:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.tab",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:3aaeab3631b4c9bbe7f44d60805b8f9c",
#>       "@type": "SoftwareApplication",
#>       "name": "dsBase",
#>       "version": "6.3.5",
#>       "description": "Base 'DataSHIELD' functions for the server side. 'DataSHIELD' is a software package which allows\n    you to do non-disclosive federated analysis on sensitive data. 'DataSHIELD' analytic functions have\n    been designed to only share non disclosive summary statistics, with built in automated output\n    checking based on statistical disclosure control. With data sites setting the threshold values for\n    the automated output checks. For more details, see 'citation(\"dsBase\")'."
#>     },
#>     {
#>       "@id": "_:localid:e2f7c43973c40d7a6a6731da5a0aa564",
#>       "@type": "SoftwareApplication",
#>       "name": "dsTidyverse",
#>       "version": "1.1.0",
#>       "description": "Implementation of selected 'Tidyverse' functions within 'DataSHIELD', an open-source federated analysis solution in R. Currently, DataSHIELD contains very limited tools for data manipulation, so the aim of this package is to improve the researcher experience by implementing essential functions for data manipulation, including subsetting, filtering, grouping, and renaming variables. This is the serverside package which should be installed on the server holding the data, and is used in conjuncture with the clientside package 'dsTidyverseClient' which is installed in the local R environment of the analyst. For more information, see <https://tidyverse.org/> and <https://datashield.org/>."
#>     },
#>     {
#>       "@id": "_:localid:411453e2513e6d909fe2cb8273b034dc",
#>       "@type": "SoftwareApplication",
#>       "name": "resourcer",
#>       "version": "1.5.0",
#>       "description": "A resource represents some data or a computation unit. It is \n    described by a URL and credentials. This package proposes a Resource model\n    with \"resolver\" and \"client\" classes to facilitate the access and the usage of the \n    resources."
#>     }
#>   ]
#> }

Safe Outputs

To add details for Safe Outputs, use the function dsROCrate::safe_output(). Currently, only log files from the operations executed by the user within a specific period. Set the period using logs_from and logs_to. Additionally, a list of functions executed by the user are extracted in a separate file/entity.

⚠️NOTE: Similar to dsROCrate::safe_setting, the dsROCrate::safe_output function requires of administrator rights, so here, we will have to log in with administrator credentials:

# close previous connection
opalr::opal.logout(o)

# open new connection as administrator
o <- opalr::opal.login(
  username = "administrator",
  password = "password",
  url = SERVER
)

DataSHIELD operations

⚠️NOTE: Before extracting logs, ensure there is recent activity on the server for testing purposes. This can be done using the following commands:

Setup

You will need the following packages:

pak::pak("DSI")
pak::pak("DSOpal")
pak::pak("dsBaseClient")
Open connection
# run some test commands with dsBaseClient
## needed to defined the OpalDriver class in the current environment
DSOpal::Opal()
#> An object of class "OpalDriver"
#> <S4 Type Object>
## create new login object, note that here we use the `dsuser`
builder <- DSI::newDSLoginBuilder()
builder$append(server = "study1",
               url = SERVER,
               user = "dsuser",
               password = DSUSERPASS,
               driver = "OpalDriver")
logindata <- builder$build()
conns <- DSI::datashield.login(logins = logindata)
#> 
#> Logging into the collaborating servers
Simulate some operations
## assign data
DSI::datashield.assign.table(conns["study1"], 
                             symbol = "dsROCrate_test",
                             table = paste0(PROJECT, ".", TABLES[1]),
                             errors.print = TRUE)

dsBaseClient::ds.ls(datasources = conns["study1"])
#> $study1
#> $study1$environment.searched
#> [1] "R_GlobalEnv"
#> 
#> $study1$objects.found
#> [1] "dsROCrate_test"
dsBaseClient::ds.summary("dsROCrate_test")
#> $study1
#> $study1$class
#> [1] "data.frame"
#> 
#> $study1$`number of rows`
#> [1] 2163
#> 
#> $study1$`number of columns`
#> [1] 11
#> 
#> $study1$`variables held`
#>  [1] "LAB_TSC"            "LAB_TRIG"           "LAB_HDL"           
#>  [4] "LAB_GLUC_ADJUSTED"  "PM_BMI_CONTINUOUS"  "DIS_CVA"           
#>  [7] "MEDI_LPD"           "DIS_DIAB"           "DIS_AMI"           
#> [10] "GENDER"             "PM_BMI_CATEGORICAL"

Then, we can proceed as per usual:

basic_rocrate <- o |>
  dsROCrate::safe_output(rocrate = basic_rocrate,
                         logs_from = Sys.time() - 60, # capture the last minute
                         logs_to = Sys.time())
#> opening file input connection.
#>  Found 83 records... Imported 83 records. Simplifying...
#> closing file input connection.
#> Warning: A `path` wasn't provided! The logs will be included in the RO-Crate
#> object, under the `content` tag!
print(basic_rocrate) # note that the output will be truncated
...
#>       "@type": "SoftwareApplication",
#>       "name": "resourcer",
#>       "version": "1.5.0",
#>       "description": "A resource represents some data or a computation unit. It is \n    described by a URL and credentials. This package proposes a Resource model\n    with \"resolver\" and \"client\" classes to facilitate the access and the usage of the \n    resources."
#>     },
#>     {
#>       "@id": "20260227T152405-dslogs-dsuser.log",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:05",
#>       "name": "20260227T152405-dslogs-dsuser.log",
#>       "description": "This file contains the raw logs for the user: `dsuser` , between: 2026-02-27 15:23:05 and 2026-02-27 15:24:05",
#>       "encodingFormat": "text/plain",
#>       "content": [
#>         ["[INFO][2026-02-27T15:24:02][OPEN]      created a datashield session fc258313-6846-4a8e-93d9-4809cd794fbe", "[INFO][2026-02-27T15:24:02][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:24:03][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::colnamesDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:05][AGGREGATE] evaluated 'dsBase::colnamesDS(\"dsROCrate_test\")'"]
#>       ]
#>     },
#>     {
#>       "@id": "20260227T152405-dslogs-dsuser_mappings.csv",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:05",
#>       "name": "20260227T152405-dslogs-dsuser_mappings.csv",
#>       "description": "This file contains mappings and evaluated functions",
#>       "encodingFormat": "text/csv",
#>       "content": [
#>         [
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "fx": "DSI::datashield.login",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "base::exists(\"dsROCrate_test\")",
#>             "fx": "base::exists",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::classDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::classDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::isValidDS(dsROCrate_test)",
#>             "fx": "dsBase::isValidDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::dimDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::dimDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:05",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::colnamesDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::colnamesDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           }
#>         ]
#>       ]
#>     }
#>   ]
#> }

2.4. Close connection

opalr::opal.logout(o)

2.5. Bag/Save RO-Crate

The resulting RO-Crate can be stored into an RO-Crate bag/archive with the function rocrateR::bag_rocrate:

# create temp directory
dir.create("./rocrates", showWarnings = FALSE)

NOTE: In the above example, a path to store the logs wasn’t provided when calling dsROCrate::safe_output, before creating an RO-Crate bag, we should save the contents of this file first. In addition, the contents for the entity with the list of functions executed:

logs_entity <- basic_rocrate |>
  rocrateR::get_entity(type = "File")
# write file using the path given by `@id`
## write raw logs
writeLines(
  logs_entity[[1]]$content[[1]], 
  file.path("./rocrates", logs_entity[[1]]$`@id`)
)
## write CSV with mappings and executed functions
write.csv(
  logs_entity[[2]]$content[[1]], 
  file.path("./rocrates", logs_entity[[2]]$`@id`),
  row.names = FALSE
)

# remove the section `content`
logs_entity[[1]]$content <- NULL
logs_entity[[2]]$content <- NULL
# update the RO-Crate
basic_rocrate <- basic_rocrate |>
  rocrateR::add_entity(logs_entity[[1]], overwrite = TRUE) |>
  rocrateR::add_entity(logs_entity[[2]], overwrite = TRUE)
# create RO-Crate bag
path_to_rocrate_bag <- basic_rocrate |>
  rocrateR::bag_rocrate(path = "./rocrates", overwrite = TRUE)
#> RO-Crate successfully 'bagged'!
#> For details, see: ./rocrates/rocrate-200ecad114285e36b84c12cfa3be6526.zip

We can explore the contents with the following commands:

# extract files in temporary directory
path_to_rocrate_bag |>
  # extract contents inside ./rocrates/ROC
  rocrateR::unbag_rocrate(output = "./rocrates/ROC", quiet = TRUE) |>
  # create tree with the files
  fs::dir_tree()
#> ./rocrates/ROC/
#> ├── bagit.txt
#> ├── data
#> │   ├── 20260227T152405-dslogs-dsuser.log
#> │   ├── 20260227T152405-dslogs-dsuser_mappings.csv
#> │   └── ro-crate-metadata.json
#> ├── manifest-sha512.txt
#> └── tagmanifest-sha512.txt

2.6. Clean working directory

unlink("./rocrates", recursive = TRUE, force = TRUE)

3. Auditing RO-Crates and servers

3.1. Audit People

List accessible tables within a project for an user
safe_people_crate_v1 <- opalr::opal.login(
  username = USERNAME,
  password = USERPASS,
  url = SERVER
) |>
  dsROCrate::audit_safe_people(user = "dsuser", project = "CNSIM")
#> opening file input connection.
#>  Found 83 records... Imported 83 records. Simplifying...
#> closing file input connection.

print(safe_people_crate_v1)
#> {
#>   "@context": "https://w3id.org/ro/crate/1.2/context",
#>   "@graph": [
#>     {
#>       "@id": "ro-crate-metadata.json",
#>       "@type": "CreativeWork",
#>       "about": {
#>         "@id": "./"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/ro/crate/1.2"
#>       }
#>     },
#>     {
#>       "@id": "./",
#>       "@type": "Dataset",
#>       "name": "",
#>       "description": "",
#>       "datePublished": "2026-02-27",
#>       "license": {
#>         "@id": "http://spdx.org/licenses/CC-BY-4.0"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/5s-crate/0.4"
#>       },
#>       "hasPart": [
#>         {
#>           "@id": "20260227T152406-dslogs-dsuser.log"
#>         },
#>         {
#>           "@id": "20260227T152406-dslogs-dsuser_mappings.csv"
#>         }
#>       ]
#>     },
#>     {
#>       "@id": "https://w3id.org/5s-crate/0.4",
#>       "@type": ["CreativeWork", "Profile"],
#>       "name": "Five Safes RO-Crate profile"
#>     },
#>     {
#>       "@id": "#dataset:67adf2d8e106aca9b11de773758bd241",
#>       "@type": "Dataset",
#>       "name": "CNSIM1",
#>       "dateCreated": "2026-02-27T06:29:50.731Z",
#>       "dateModified": "2026-02-27T06:29:51.865Z",
#>       "path": "/datasource/CNSIM/table/CNSIM1"
#>     },
#>     {
#>       "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9",
#>       "@type": "Dataset",
#>       "name": "CNSIM2",
#>       "dateCreated": "2026-02-27T06:29:51.872Z",
#>       "dateModified": "2026-02-27T06:29:53.057Z",
#>       "path": "/datasource/CNSIM/table/CNSIM2"
#>     },
#>     {
#>       "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492",
#>       "@type": "Dataset",
#>       "name": "CNSIM3",
#>       "dateCreated": "2026-02-27T06:29:53.064Z",
#>       "dateModified": "2026-02-27T06:29:54.200Z",
#>       "path": "/datasource/CNSIM/table/CNSIM3"
#>     },
#>     {
#>       "@id": "#project:7ba189863f9f641196596cb28e04aa14",
#>       "@type": "Project",
#>       "name": "CNSIM",
#>       "dateCreated": "2026-02-27T06:29:49.235Z",
#>       "dateModified": "2026-02-27T06:29:54.200Z",
#>       "hasPart": [
#>         {
#>           "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>         },
#>         {
#>           "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9"
#>         },
#>         {
#>           "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492"
#>         }
#>       ]
#>     },
#>     {
#>       "@id": "#person:a0af2a94926db1b49ad7a812eef509d2",
#>       "@type": "Person",
#>       "name": "dsuser"
#>     },
#>     {
#>       "@id": "#perm:9bf7f75b6c5b07d02830b95652cd39a0-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "#perm:363eb627d1e49c08933f2e26142e6d56-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "#perm:63b8097908f682bff1760e48d28c5855-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "_:localid:datashield.privacyLevel:5",
#>       "@type": "PropertyValue",
#>       "name": "datashield.privacyLevel",
#>       "value": "5"
#>     },
#>     {
#>       "@id": "_:localid:default.datashield.privacyControlLevel:banana",
#>       "@type": "PropertyValue",
#>       "name": "default.datashield.privacyControlLevel",
#>       "value": "banana"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.glm:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.glm",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.kNN:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.kNN",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.density:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.density",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.max:40",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.max",
#>       "value": "40"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.noise:0.25",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.noise",
#>       "value": "0.25"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.string:80",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.string",
#>       "value": "80"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.stringShort:20",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.stringShort",
#>       "value": "20"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.subset:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.subset",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.tab:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.tab",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:3aaeab3631b4c9bbe7f44d60805b8f9c",
#>       "@type": "SoftwareApplication",
#>       "name": "dsBase",
#>       "version": "6.3.5",
#>       "description": "Base 'DataSHIELD' functions for the server side. 'DataSHIELD' is a software package which allows\n    you to do non-disclosive federated analysis on sensitive data. 'DataSHIELD' analytic functions have\n    been designed to only share non disclosive summary statistics, with built in automated output\n    checking based on statistical disclosure control. With data sites setting the threshold values for\n    the automated output checks. For more details, see 'citation(\"dsBase\")'."
#>     },
#>     {
#>       "@id": "_:localid:e2f7c43973c40d7a6a6731da5a0aa564",
#>       "@type": "SoftwareApplication",
#>       "name": "dsTidyverse",
#>       "version": "1.1.0",
#>       "description": "Implementation of selected 'Tidyverse' functions within 'DataSHIELD', an open-source federated analysis solution in R. Currently, DataSHIELD contains very limited tools for data manipulation, so the aim of this package is to improve the researcher experience by implementing essential functions for data manipulation, including subsetting, filtering, grouping, and renaming variables. This is the serverside package which should be installed on the server holding the data, and is used in conjuncture with the clientside package 'dsTidyverseClient' which is installed in the local R environment of the analyst. For more information, see <https://tidyverse.org/> and <https://datashield.org/>."
#>     },
#>     {
#>       "@id": "_:localid:411453e2513e6d909fe2cb8273b034dc",
#>       "@type": "SoftwareApplication",
#>       "name": "resourcer",
#>       "version": "1.5.0",
#>       "description": "A resource represents some data or a computation unit. It is \n    described by a URL and credentials. This package proposes a Resource model\n    with \"resolver\" and \"client\" classes to facilitate the access and the usage of the \n    resources."
#>     },
#>     {
#>       "@id": "20260227T152406-dslogs-dsuser.log",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:06",
#>       "name": "20260227T152406-dslogs-dsuser.log",
#>       "description": "This file contains the raw logs for the user: `dsuser` , between: ALL and ALL",
#>       "encodingFormat": "text/plain",
#>       "content": [
#>         ["[INFO][2026-02-27T08:56:24][OPEN]      created a datashield session 622f2c74-9242-48e2-82d9-bc3250f8aa4b", "[INFO][2026-02-27T08:56:26][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T08:56:26][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T08:56:27][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:00:37][OPEN]      created a datashield session 7925f5e8-f7b6-416e-b05b-5ac2c19f00c1", "[INFO][2026-02-27T09:00:37][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T09:00:38][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:00:38][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:20:47][OPEN]      created a datashield session 08413766-4fa8-4eec-9392-ec30581fb48c", "[INFO][2026-02-27T09:20:48][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T09:20:48][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:20:49][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:08:39][OPEN]      created a datashield session 88a48432-61c8-4444-bb6f-1d0174d4f177", "[INFO][2026-02-27T14:08:39][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T14:08:39][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:08:40][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:18:40][OPEN]      created a datashield session e45b3573-21cc-445d-8d22-b7fc289d279a", "[INFO][2026-02-27T14:18:40][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T14:18:40][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:18:41][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:04:13][OPEN]      created a datashield session 026b4b18-c40c-4f08-8a19-75716fee1c75", "[INFO][2026-02-27T15:04:13][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:04:14][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:04:14][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:13:01][OPEN]      created a datashield session a3a6f257-79ef-443c-a110-393b1ff196f0", "[INFO][2026-02-27T15:13:01][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:13:02][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:13:03][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:02][OPEN]      created a datashield session fc258313-6846-4a8e-93d9-4809cd794fbe", "[INFO][2026-02-27T15:24:02][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:24:03][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::colnamesDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:05][AGGREGATE] evaluated 'dsBase::colnamesDS(\"dsROCrate_test\")'"]
#>       ]
#>     },
#>     {
#>       "@id": "20260227T152406-dslogs-dsuser_mappings.csv",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:06",
#>       "name": "20260227T152406-dslogs-dsuser_mappings.csv",
#>       "description": "This file contains mappings and evaluated functions",
#>       "encodingFormat": "text/csv",
#>       "content": [
#>         [
#>           {
#>             "timestamp": "2026-02-27T08:56:24",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "fx": "DSI::datashield.login",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T08:56:26",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T08:56:27",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:37",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "fx": "DSI::datashield.login",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:37",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:38",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:47",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "fx": "DSI::datashield.login",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:48",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:49",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:39",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "fx": "DSI::datashield.login",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:39",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:40",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:40",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "fx": "DSI::datashield.login",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:40",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:41",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:13",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "fx": "DSI::datashield.login",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:13",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:14",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:01",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "fx": "DSI::datashield.login",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:01",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:03",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "fx": "DSI::datashield.login",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "base::exists(\"dsROCrate_test\")",
#>             "fx": "base::exists",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::classDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::classDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::isValidDS(dsROCrate_test)",
#>             "fx": "dsBase::isValidDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::dimDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::dimDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:05",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::colnamesDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::colnamesDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           }
#>         ]
#>       ]
#>     }
#>   ]
#> }
Markdown report

A markdown report can be created with an overview and details for an RO-Crate, using the dsROCrate::rocrate_report:

Only generate .Rmd file

safe_people_crate_v1_rmd <- tempfile(fileext = ".Rmd") # temporary file

safe_people_crate_contents <- safe_people_crate_v1 |>
  dsROCrate::rocrate_report(filepath = safe_people_crate_v1_rmd, render = FALSE)
#> 1 'Author' entity was found!
#> 3 'Dataset' entities were found!
#> Warning: No entities were found with @type = 'WriteAction'!
#> Warning: No entities were found with @type = 'ControlAction'!
#> 1 'Project' entity was found!
#> 14 'PropertyValue' OR 'SoftwareApplication' entities were found!
#> 2 'File' entities were found!

# display Overview diagram
safe_people_crate_contents$overview_diagram

# display Overview data (Safe People, Safe Projects and Safe Data)
safe_people_crate_contents$overview_data |>
  knitr::kable()
Project Data Access Level People Function Timestamp
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T08:56:26
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T08:56:27
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:00:37
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:00:38
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:20:48
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:20:49
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:08:39
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:08:40
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:18:40
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:18:41
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:04:13
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:04:14
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:13:01
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:13:03
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:24:02
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser base::exists 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::classDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::isValidDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::dimDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::colnamesDS 2026-02-27T15:24:05
CNSIM CNSIM2 read dsuser
CNSIM CNSIM3 read dsuser

Render and display report (HTML)

safe_people_crate_v1 |>
  dsROCrate::rocrate_report(filepath = safe_people_crate_v1_rmd,
                            title = "DataSHIELD Safe People - Audit Report",
                            render = TRUE, 
                            overwrite = TRUE)
List all accessible projects & tables for an user
safe_people_crate_v2 <- opalr::opal.login(
  username = USERNAME,
  password = USERPASS,
  url = SERVER
) |>
  dsROCrate::audit_safe_people(user = "dsuser")
#> opening file input connection.
#>  Found 83 records... Imported 83 records. Simplifying...
#> closing file input connection.

safe_people_crate_v2_rmd <- tempfile(fileext = ".Rmd") # temporary file

safe_people_crate_contents_v2 <- safe_people_crate_v2 |>
  dsROCrate::rocrate_report(filepath = safe_people_crate_v2_rmd, render = FALSE)
#> 1 'Author' entity was found!
#> 30 'Dataset' entities were found!
#> 11 'Project' entities were found!
#> 14 'PropertyValue' OR 'SoftwareApplication' entities were found!
#> 2 'File' entities were found!

# display Overview diagram
safe_people_crate_contents_v2$overview_diagram

# display Overview data (Safe People, Safe Projects and Safe Data)
safe_people_crate_contents_v2$overview_data |>
  knitr::kable()
Project Data Access Level People Function Timestamp
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T08:56:26
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T08:56:27
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:00:37
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:00:38
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:20:48
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:20:49
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:08:39
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:08:40
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:18:40
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:18:41
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:04:13
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:04:14
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:13:01
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:13:03
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:24:02
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser base::exists 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::classDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::isValidDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::dimDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::colnamesDS 2026-02-27T15:24:05
CNSIM CNSIM2 read dsuser
CNSIM CNSIM3 read dsuser
DASIM DASIM1 read dsuser
DASIM DASIM2 read dsuser
DASIM DASIM3 read dsuser
DISCORDANT DISCORDANT_STUDY1 read dsuser
DISCORDANT DISCORDANT_STUDY2 read dsuser
DISCORDANT DISCORDANT_STUDY3 read dsuser
GREENSPACE Cohort1_exposome read dsuser
GREENSPACE Cohort2_exposome read dsuser
GREENSPACE Cohort3_exposome read dsuser
GWAS ega_phenotypes read dsuser
GWAS ega_phenotypes_1 read dsuser
GWAS ega_phenotypes_2 read dsuser
GWAS ega_phenotypes_3 read dsuser
MEDIATION UPBdata1 read dsuser
MEDIATION UPBdata2 read dsuser
MEDIATION UPBdata3 read dsuser
SURVIVAL EXPAND_WITH_MISSING1 read dsuser
SURVIVAL EXPAND_WITH_MISSING2 read dsuser
SURVIVAL EXPAND_WITH_MISSING3 read dsuser
TESTING TESTING1 read dsuser
TESTING TESTING2 read dsuser
TESTING TESTING3 read dsuser
TITANIC_NEWCOMERS_WORKSHOP titanic_server_1 read dsuser
TITANIC_NEWCOMERS_WORKSHOP titanic_server_2 read dsuser
depression growth_1 read dsuser
depression growth_2 read dsuser
serverDataKey myKey read dsuser

3.2. Audit Project

List users and dataset/table level permissions within a project
safe_project_crate_v1 <- opalr::opal.login(
  username = USERNAME,
  password = USERPASS,
  url = SERVER
) |>
  dsROCrate::audit_safe_project(project = "CNSIM")
#> opening file input connection.
#>  Found 83 records... Imported 83 records. Simplifying...
#> closing file input connection.

print(safe_project_crate_v1)
#> {
#>   "@context": "https://w3id.org/ro/crate/1.2/context",
#>   "@graph": [
#>     {
#>       "@id": "ro-crate-metadata.json",
#>       "@type": "CreativeWork",
#>       "about": {
#>         "@id": "./"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/ro/crate/1.2"
#>       }
#>     },
#>     {
#>       "@id": "./",
#>       "@type": "Dataset",
#>       "name": "",
#>       "description": "",
#>       "datePublished": "2026-02-27",
#>       "license": {
#>         "@id": "http://spdx.org/licenses/CC-BY-4.0"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/5s-crate/0.4"
#>       },
#>       "hasPart": [
#>         {
#>           "@id": "20260227T152439-dslogs-dsuser.log"
#>         },
#>         {
#>           "@id": "20260227T152439-dslogs-dsuser_mappings.csv"
#>         }
#>       ]
#>     },
#>     {
#>       "@id": "https://w3id.org/5s-crate/0.4",
#>       "@type": ["CreativeWork", "Profile"],
#>       "name": "Five Safes RO-Crate profile"
#>     },
#>     {
#>       "@id": "#dataset:67adf2d8e106aca9b11de773758bd241",
#>       "@type": "Dataset",
#>       "name": "CNSIM1",
#>       "dateCreated": "2026-02-27T06:29:50.731Z",
#>       "dateModified": "2026-02-27T06:29:51.865Z",
#>       "path": "/datasource/CNSIM/table/CNSIM1"
#>     },
#>     {
#>       "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9",
#>       "@type": "Dataset",
#>       "name": "CNSIM2",
#>       "dateCreated": "2026-02-27T06:29:51.872Z",
#>       "dateModified": "2026-02-27T06:29:53.057Z",
#>       "path": "/datasource/CNSIM/table/CNSIM2"
#>     },
#>     {
#>       "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492",
#>       "@type": "Dataset",
#>       "name": "CNSIM3",
#>       "dateCreated": "2026-02-27T06:29:53.064Z",
#>       "dateModified": "2026-02-27T06:29:54.200Z",
#>       "path": "/datasource/CNSIM/table/CNSIM3"
#>     },
#>     {
#>       "@id": "#project:7ba189863f9f641196596cb28e04aa14",
#>       "@type": "Project",
#>       "name": "CNSIM",
#>       "dateCreated": "2026-02-27T06:29:49.235Z",
#>       "dateModified": "2026-02-27T06:29:54.200Z",
#>       "hasPart": [
#>         {
#>           "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>         },
#>         {
#>           "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9"
#>         },
#>         {
#>           "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492"
#>         }
#>       ]
#>     },
#>     {
#>       "@id": "#person:a0af2a94926db1b49ad7a812eef509d2",
#>       "@type": "Person",
#>       "name": "dsuser"
#>     },
#>     {
#>       "@id": "#perm:9bf7f75b6c5b07d02830b95652cd39a0-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "#perm:363eb627d1e49c08933f2e26142e6d56-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "#perm:63b8097908f682bff1760e48d28c5855-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "_:localid:datashield.privacyLevel:5",
#>       "@type": "PropertyValue",
#>       "name": "datashield.privacyLevel",
#>       "value": "5"
#>     },
#>     {
#>       "@id": "_:localid:default.datashield.privacyControlLevel:banana",
#>       "@type": "PropertyValue",
#>       "name": "default.datashield.privacyControlLevel",
#>       "value": "banana"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.glm:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.glm",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.kNN:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.kNN",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.density:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.density",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.max:40",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.max",
#>       "value": "40"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.noise:0.25",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.noise",
#>       "value": "0.25"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.string:80",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.string",
#>       "value": "80"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.stringShort:20",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.stringShort",
#>       "value": "20"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.subset:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.subset",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.tab:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.tab",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:3aaeab3631b4c9bbe7f44d60805b8f9c",
#>       "@type": "SoftwareApplication",
#>       "name": "dsBase",
#>       "version": "6.3.5",
#>       "description": "Base 'DataSHIELD' functions for the server side. 'DataSHIELD' is a software package which allows\n    you to do non-disclosive federated analysis on sensitive data. 'DataSHIELD' analytic functions have\n    been designed to only share non disclosive summary statistics, with built in automated output\n    checking based on statistical disclosure control. With data sites setting the threshold values for\n    the automated output checks. For more details, see 'citation(\"dsBase\")'."
#>     },
#>     {
#>       "@id": "_:localid:e2f7c43973c40d7a6a6731da5a0aa564",
#>       "@type": "SoftwareApplication",
#>       "name": "dsTidyverse",
#>       "version": "1.1.0",
#>       "description": "Implementation of selected 'Tidyverse' functions within 'DataSHIELD', an open-source federated analysis solution in R. Currently, DataSHIELD contains very limited tools for data manipulation, so the aim of this package is to improve the researcher experience by implementing essential functions for data manipulation, including subsetting, filtering, grouping, and renaming variables. This is the serverside package which should be installed on the server holding the data, and is used in conjuncture with the clientside package 'dsTidyverseClient' which is installed in the local R environment of the analyst. For more information, see <https://tidyverse.org/> and <https://datashield.org/>."
#>     },
#>     {
#>       "@id": "_:localid:411453e2513e6d909fe2cb8273b034dc",
#>       "@type": "SoftwareApplication",
#>       "name": "resourcer",
#>       "version": "1.5.0",
#>       "description": "A resource represents some data or a computation unit. It is \n    described by a URL and credentials. This package proposes a Resource model\n    with \"resolver\" and \"client\" classes to facilitate the access and the usage of the \n    resources."
#>     },
#>     {
#>       "@id": "20260227T152439-dslogs-dsuser.log",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:39",
#>       "name": "20260227T152439-dslogs-dsuser.log",
#>       "description": "This file contains the raw logs for the user: `dsuser` , between: ALL and ALL",
#>       "encodingFormat": "text/plain",
#>       "content": [
#>         ["[INFO][2026-02-27T08:56:24][OPEN]      created a datashield session 622f2c74-9242-48e2-82d9-bc3250f8aa4b", "[INFO][2026-02-27T08:56:26][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T08:56:26][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T08:56:27][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:00:37][OPEN]      created a datashield session 7925f5e8-f7b6-416e-b05b-5ac2c19f00c1", "[INFO][2026-02-27T09:00:37][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T09:00:38][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:00:38][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:20:47][OPEN]      created a datashield session 08413766-4fa8-4eec-9392-ec30581fb48c", "[INFO][2026-02-27T09:20:48][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T09:20:48][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:20:49][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:08:39][OPEN]      created a datashield session 88a48432-61c8-4444-bb6f-1d0174d4f177", "[INFO][2026-02-27T14:08:39][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T14:08:39][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:08:40][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:18:40][OPEN]      created a datashield session e45b3573-21cc-445d-8d22-b7fc289d279a", "[INFO][2026-02-27T14:18:40][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T14:18:40][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:18:41][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:04:13][OPEN]      created a datashield session 026b4b18-c40c-4f08-8a19-75716fee1c75", "[INFO][2026-02-27T15:04:13][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:04:14][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:04:14][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:13:01][OPEN]      created a datashield session a3a6f257-79ef-443c-a110-393b1ff196f0", "[INFO][2026-02-27T15:13:01][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:13:02][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:13:03][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:02][OPEN]      created a datashield session fc258313-6846-4a8e-93d9-4809cd794fbe", "[INFO][2026-02-27T15:24:02][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:24:03][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::colnamesDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:05][AGGREGATE] evaluated 'dsBase::colnamesDS(\"dsROCrate_test\")'"]
#>       ]
#>     },
#>     {
#>       "@id": "20260227T152439-dslogs-dsuser_mappings.csv",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:39",
#>       "name": "20260227T152439-dslogs-dsuser_mappings.csv",
#>       "description": "This file contains mappings and evaluated functions",
#>       "encodingFormat": "text/csv",
#>       "content": [
#>         [
#>           {
#>             "timestamp": "2026-02-27T08:56:24",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "fx": "DSI::datashield.login",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T08:56:26",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T08:56:27",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:37",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "fx": "DSI::datashield.login",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:37",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:38",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:47",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "fx": "DSI::datashield.login",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:48",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:49",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:39",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "fx": "DSI::datashield.login",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:39",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:40",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:40",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "fx": "DSI::datashield.login",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:40",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:41",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:13",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "fx": "DSI::datashield.login",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:13",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:14",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:01",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "fx": "DSI::datashield.login",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:01",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:03",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "fx": "DSI::datashield.login",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "base::exists(\"dsROCrate_test\")",
#>             "fx": "base::exists",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::classDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::classDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::isValidDS(dsROCrate_test)",
#>             "fx": "dsBase::isValidDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::dimDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::dimDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:05",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::colnamesDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::colnamesDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           }
#>         ]
#>       ]
#>     }
#>   ]
#> }
Markdown report

A markdown report can be created with an overview and details for an RO-Crate, using the dsROCrate::rocrate_report:

Only generate .Rmd file

safe_project_crate_v1_rmd <- tempfile(fileext = ".Rmd") # temporary file

safe_project_crate_contents <- safe_project_crate_v1 |>
  dsROCrate::rocrate_report(filepath = safe_project_crate_v1_rmd, render = FALSE)
#> 1 'Author' entity was found!
#> 3 'Dataset' entities were found!
#> Warning: No entities were found with @type = 'WriteAction'!
#> Warning: No entities were found with @type = 'ControlAction'!
#> 1 'Project' entity was found!
#> 14 'PropertyValue' OR 'SoftwareApplication' entities were found!
#> 2 'File' entities were found!

# display Overview diagram
safe_project_crate_contents$overview_diagram

# display Overview data (Safe People, Safe Projects and Safe Data)
safe_project_crate_contents$overview_data |>
  knitr::kable()
Project Data Access Level People Function Timestamp
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T08:56:26
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T08:56:27
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:00:37
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:00:38
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:20:48
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:20:49
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:08:39
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:08:40
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:18:40
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:18:41
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:04:13
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:04:14
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:13:01
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:13:03
CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:24:02
CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser base::exists 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::classDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::isValidDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::dimDS 2026-02-27T15:24:04
CNSIM CNSIM1 read dsuser dsBase::colnamesDS 2026-02-27T15:24:05
CNSIM CNSIM2 read dsuser
CNSIM CNSIM3 read dsuser

Render and display report (HTML)

safe_project_crate_v1 |>
  dsROCrate::rocrate_report(filepath = safe_project_crate_v1_rmd, 
                            title = "DataSHIELD Safe Project - Audit Report",
                            render = TRUE, 
                            overwrite = TRUE)

3.3. Audit Study

List users and dataset/table level permissions within a study (i.e., multiple servers)
study_crate_v1 <- 
  list(
    "opal_test" = opalr::opal.login(
      username = USERNAME,
      password = USERPASS,
      url = "https://opal-test.obiba.org"
    ),
    "opal_demo" = opalr::opal.login(
      username = USERNAME,
      password = USERPASS,
      url = "https://opal-demo.obiba.org"
    )
  ) |>
  dsROCrate::audit_study(project = "CNSIM")

print(study_crate_v1)
#> $opal_test
#> {
#>   "@context": "https://w3id.org/ro/crate/1.2/context",
#>   "@graph": [
#>     {
#>       "@id": "ro-crate-metadata.json",
#>       "@type": "CreativeWork",
#>       "about": {
#>         "@id": "./"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/ro/crate/1.2"
#>       }
#>     },
#>     {
#>       "@id": "./",
#>       "@type": "Dataset",
#>       "name": "",
#>       "description": "",
#>       "datePublished": "2026-02-27",
#>       "license": {
#>         "@id": "http://spdx.org/licenses/CC-BY-4.0"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/5s-crate/0.4"
#>       }
#>     },
#>     {
#>       "@id": "https://w3id.org/5s-crate/0.4",
#>       "@type": ["CreativeWork", "Profile"],
#>       "name": "Five Safes RO-Crate profile"
#>     },
#>     {
#>       "@id": "#dataset:67adf2d8e106aca9b11de773758bd241",
#>       "@type": "Dataset",
#>       "name": "CNSIM1",
#>       "dateCreated": "2026-01-17T10:53:48.925Z",
#>       "dateModified": "2026-01-17T10:53:50.189Z",
#>       "path": "/datasource/CNSIM/table/CNSIM1"
#>     },
#>     {
#>       "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9",
#>       "@type": "Dataset",
#>       "name": "CNSIM2",
#>       "dateCreated": "2026-01-17T10:53:50.194Z",
#>       "dateModified": "2026-01-17T10:53:51.417Z",
#>       "path": "/datasource/CNSIM/table/CNSIM2"
#>     },
#>     {
#>       "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492",
#>       "@type": "Dataset",
#>       "name": "CNSIM3",
#>       "dateCreated": "2026-01-17T10:53:51.422Z",
#>       "dateModified": "2026-01-17T10:53:52.663Z",
#>       "path": "/datasource/CNSIM/table/CNSIM3"
#>     },
#>     {
#>       "@id": "#project:7ba189863f9f641196596cb28e04aa14",
#>       "@type": "Project",
#>       "name": "CNSIM",
#>       "dateCreated": "2026-01-08T17:40:46.773Z",
#>       "dateModified": "2026-01-17T10:53:52.663Z",
#>       "hasPart": [
#>         {
#>           "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>         },
#>         {
#>           "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9"
#>         },
#>         {
#>           "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492"
#>         }
#>       ]
#>     },
#>     {
#>       "@id": "#person:a0af2a94926db1b49ad7a812eef509d2",
#>       "@type": "Person",
#>       "name": "dsuser"
#>     },
#>     {
#>       "@id": "#perm:9bf7f75b6c5b07d02830b95652cd39a0-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "_:localid:datashield.privacyLevel:5",
#>       "@type": "PropertyValue",
#>       "name": "datashield.privacyLevel",
#>       "value": "5"
#>     },
#>     {
#>       "@id": "_:localid:default.datashield.privacyControlLevel:banana",
#>       "@type": "PropertyValue",
#>       "name": "default.datashield.privacyControlLevel",
#>       "value": "banana"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.glm:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.glm",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.kNN:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.kNN",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.density:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.density",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.max:40",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.max",
#>       "value": "40"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.noise:0.25",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.noise",
#>       "value": "0.25"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.string:80",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.string",
#>       "value": "80"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.stringShort:20",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.stringShort",
#>       "value": "20"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.subset:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.subset",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.tab:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.tab",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:3aaeab3631b4c9bbe7f44d60805b8f9c",
#>       "@type": "SoftwareApplication",
#>       "name": "dsBase",
#>       "version": "6.3.5",
#>       "description": "Base 'DataSHIELD' functions for the server side. 'DataSHIELD' is a software package which allows\n    you to do non-disclosive federated analysis on sensitive data. 'DataSHIELD' analytic functions have\n    been designed to only share non disclosive summary statistics, with built in automated output\n    checking based on statistical disclosure control. With data sites setting the threshold values for\n    the automated output checks. For more details, see 'citation(\"dsBase\")'."
#>     },
#>     {
#>       "@id": "_:localid:e2f7c43973c40d7a6a6731da5a0aa564",
#>       "@type": "SoftwareApplication",
#>       "name": "dsTidyverse",
#>       "version": "1.1.0",
#>       "description": "Implementation of selected 'Tidyverse' functions within 'DataSHIELD', an open-source federated analysis solution in R. Currently, DataSHIELD contains very limited tools for data manipulation, so the aim of this package is to improve the researcher experience by implementing essential functions for data manipulation, including subsetting, filtering, grouping, and renaming variables. This is the serverside package which should be installed on the server holding the data, and is used in conjuncture with the clientside package 'dsTidyverseClient' which is installed in the local R environment of the analyst. For more information, see <https://tidyverse.org/> and <https://datashield.org/>."
#>     },
#>     {
#>       "@id": "_:localid:411453e2513e6d909fe2cb8273b034dc",
#>       "@type": "SoftwareApplication",
#>       "name": "resourcer",
#>       "version": "1.5.0",
#>       "description": "A resource represents some data or a computation unit. It is \n    described by a URL and credentials. This package proposes a Resource model\n    with \"resolver\" and \"client\" classes to facilitate the access and the usage of the \n    resources."
#>     }
#>   ]
#> }
#> 
#> $opal_demo
#> {
#>   "@context": "https://w3id.org/ro/crate/1.2/context",
#>   "@graph": [
#>     {
#>       "@id": "ro-crate-metadata.json",
#>       "@type": "CreativeWork",
#>       "about": {
#>         "@id": "./"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/ro/crate/1.2"
#>       }
#>     },
#>     {
#>       "@id": "./",
#>       "@type": "Dataset",
#>       "name": "",
#>       "description": "",
#>       "datePublished": "2026-02-27",
#>       "license": {
#>         "@id": "http://spdx.org/licenses/CC-BY-4.0"
#>       },
#>       "conformsTo": {
#>         "@id": "https://w3id.org/5s-crate/0.4"
#>       },
#>       "hasPart": [
#>         {
#>           "@id": "20260227T152444-dslogs-dsuser.log"
#>         },
#>         {
#>           "@id": "20260227T152444-dslogs-dsuser_mappings.csv"
#>         }
#>       ]
#>     },
#>     {
#>       "@id": "https://w3id.org/5s-crate/0.4",
#>       "@type": ["CreativeWork", "Profile"],
#>       "name": "Five Safes RO-Crate profile"
#>     },
#>     {
#>       "@id": "#dataset:67adf2d8e106aca9b11de773758bd241",
#>       "@type": "Dataset",
#>       "name": "CNSIM1",
#>       "dateCreated": "2026-02-27T06:29:50.731Z",
#>       "dateModified": "2026-02-27T06:29:51.865Z",
#>       "path": "/datasource/CNSIM/table/CNSIM1"
#>     },
#>     {
#>       "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9",
#>       "@type": "Dataset",
#>       "name": "CNSIM2",
#>       "dateCreated": "2026-02-27T06:29:51.872Z",
#>       "dateModified": "2026-02-27T06:29:53.057Z",
#>       "path": "/datasource/CNSIM/table/CNSIM2"
#>     },
#>     {
#>       "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492",
#>       "@type": "Dataset",
#>       "name": "CNSIM3",
#>       "dateCreated": "2026-02-27T06:29:53.064Z",
#>       "dateModified": "2026-02-27T06:29:54.200Z",
#>       "path": "/datasource/CNSIM/table/CNSIM3"
#>     },
#>     {
#>       "@id": "#project:7ba189863f9f641196596cb28e04aa14",
#>       "@type": "Project",
#>       "name": "CNSIM",
#>       "dateCreated": "2026-02-27T06:29:49.235Z",
#>       "dateModified": "2026-02-27T06:29:54.200Z",
#>       "hasPart": [
#>         {
#>           "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>         },
#>         {
#>           "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9"
#>         },
#>         {
#>           "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492"
#>         }
#>       ]
#>     },
#>     {
#>       "@id": "#person:a0af2a94926db1b49ad7a812eef509d2",
#>       "@type": "Person",
#>       "name": "dsuser"
#>     },
#>     {
#>       "@id": "#perm:9bf7f75b6c5b07d02830b95652cd39a0-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:67adf2d8e106aca9b11de773758bd241"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "#perm:363eb627d1e49c08933f2e26142e6d56-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:ffb1b1adcafc024743be1b0c252787c9"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "#perm:63b8097908f682bff1760e48d28c5855-dict-summary-read",
#>       "@type": "ReadAction",
#>       "agent": {
#>         "@id": "#person:a0af2a94926db1b49ad7a812eef509d2"
#>       },
#>       "object": {
#>         "@id": "#dataset:cc3061aef69ce457358815fb9d8c6492"
#>       },
#>       "actionStatus": "PotentialActionStatus",
#>       "description": "User may view table dictionary and summary statistics only; access to individual values is restricted."
#>     },
#>     {
#>       "@id": "_:localid:datashield.privacyLevel:5",
#>       "@type": "PropertyValue",
#>       "name": "datashield.privacyLevel",
#>       "value": "5"
#>     },
#>     {
#>       "@id": "_:localid:default.datashield.privacyControlLevel:banana",
#>       "@type": "PropertyValue",
#>       "name": "default.datashield.privacyControlLevel",
#>       "value": "banana"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.glm:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.glm",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.kNN:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.kNN",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.density:0.33",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.density",
#>       "value": "0.33"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.levels.max:40",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.levels.max",
#>       "value": "40"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.noise:0.25",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.noise",
#>       "value": "0.25"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.string:80",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.string",
#>       "value": "80"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.stringShort:20",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.stringShort",
#>       "value": "20"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.subset:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.subset",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:default.nfilter.tab:3",
#>       "@type": "PropertyValue",
#>       "name": "default.nfilter.tab",
#>       "value": "3"
#>     },
#>     {
#>       "@id": "_:localid:3aaeab3631b4c9bbe7f44d60805b8f9c",
#>       "@type": "SoftwareApplication",
#>       "name": "dsBase",
#>       "version": "6.3.5",
#>       "description": "Base 'DataSHIELD' functions for the server side. 'DataSHIELD' is a software package which allows\n    you to do non-disclosive federated analysis on sensitive data. 'DataSHIELD' analytic functions have\n    been designed to only share non disclosive summary statistics, with built in automated output\n    checking based on statistical disclosure control. With data sites setting the threshold values for\n    the automated output checks. For more details, see 'citation(\"dsBase\")'."
#>     },
#>     {
#>       "@id": "_:localid:e2f7c43973c40d7a6a6731da5a0aa564",
#>       "@type": "SoftwareApplication",
#>       "name": "dsTidyverse",
#>       "version": "1.1.0",
#>       "description": "Implementation of selected 'Tidyverse' functions within 'DataSHIELD', an open-source federated analysis solution in R. Currently, DataSHIELD contains very limited tools for data manipulation, so the aim of this package is to improve the researcher experience by implementing essential functions for data manipulation, including subsetting, filtering, grouping, and renaming variables. This is the serverside package which should be installed on the server holding the data, and is used in conjuncture with the clientside package 'dsTidyverseClient' which is installed in the local R environment of the analyst. For more information, see <https://tidyverse.org/> and <https://datashield.org/>."
#>     },
#>     {
#>       "@id": "_:localid:411453e2513e6d909fe2cb8273b034dc",
#>       "@type": "SoftwareApplication",
#>       "name": "resourcer",
#>       "version": "1.5.0",
#>       "description": "A resource represents some data or a computation unit. It is \n    described by a URL and credentials. This package proposes a Resource model\n    with \"resolver\" and \"client\" classes to facilitate the access and the usage of the \n    resources."
#>     },
#>     {
#>       "@id": "20260227T152444-dslogs-dsuser.log",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:44",
#>       "name": "20260227T152444-dslogs-dsuser.log",
#>       "description": "This file contains the raw logs for the user: `dsuser` , between: ALL and ALL",
#>       "encodingFormat": "text/plain",
#>       "content": [
#>         ["[INFO][2026-02-27T08:56:24][OPEN]      created a datashield session 622f2c74-9242-48e2-82d9-bc3250f8aa4b", "[INFO][2026-02-27T08:56:26][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T08:56:26][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T08:56:27][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:00:37][OPEN]      created a datashield session 7925f5e8-f7b6-416e-b05b-5ac2c19f00c1", "[INFO][2026-02-27T09:00:37][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T09:00:38][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:00:38][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:20:47][OPEN]      created a datashield session 08413766-4fa8-4eec-9392-ec30581fb48c", "[INFO][2026-02-27T09:20:48][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T09:20:48][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T09:20:49][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:08:39][OPEN]      created a datashield session 88a48432-61c8-4444-bb6f-1d0174d4f177", "[INFO][2026-02-27T14:08:39][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T14:08:39][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:08:40][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:18:40][OPEN]      created a datashield session e45b3573-21cc-445d-8d22-b7fc289d279a", "[INFO][2026-02-27T14:18:40][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T14:18:40][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T14:18:41][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:04:13][OPEN]      created a datashield session 026b4b18-c40c-4f08-8a19-75716fee1c75", "[INFO][2026-02-27T15:04:13][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:04:14][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:04:14][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:13:01][OPEN]      created a datashield session a3a6f257-79ef-443c-a110-393b1ff196f0", "[INFO][2026-02-27T15:13:01][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:13:02][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:13:03][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:02][OPEN]      created a datashield session fc258313-6846-4a8e-93d9-4809cd794fbe", "[INFO][2026-02-27T15:24:02][ASSIGN]    created symbol 'dsROCrate_test' from: 'dsROCrate_test <- opal[CNSIM.CNSIM1]'", "[INFO][2026-02-27T15:24:03][PARSE]     parsed 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::lsDS(search.filter = NULL, 1L)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'base::exists(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::classDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::isValidDS(dsROCrate_test)'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][AGGREGATE] evaluated 'dsBase::dimDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:04][PARSE]     parsed 'dsBase::colnamesDS(\"dsROCrate_test\")'", "[INFO][2026-02-27T15:24:05][AGGREGATE] evaluated 'dsBase::colnamesDS(\"dsROCrate_test\")'"]
#>       ]
#>     },
#>     {
#>       "@id": "20260227T152444-dslogs-dsuser_mappings.csv",
#>       "@type": "File",
#>       "dateModified": "2026-02-27 15:24:44",
#>       "name": "20260227T152444-dslogs-dsuser_mappings.csv",
#>       "description": "This file contains mappings and evaluated functions",
#>       "encodingFormat": "text/csv",
#>       "content": [
#>         [
#>           {
#>             "timestamp": "2026-02-27T08:56:24",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "fx": "DSI::datashield.login",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T08:56:26",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T08:56:27",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "622f2c74-9242-48e2-82d9-bc3250f8aa4b",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:37",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "fx": "DSI::datashield.login",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:37",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:00:38",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "7925f5e8-f7b6-416e-b05b-5ac2c19f00c1",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:47",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "fx": "DSI::datashield.login",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:48",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T09:20:49",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "08413766-4fa8-4eec-9392-ec30581fb48c",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:39",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "fx": "DSI::datashield.login",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:39",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:08:40",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "88a48432-61c8-4444-bb6f-1d0174d4f177",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:40",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "fx": "DSI::datashield.login",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:40",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T14:18:41",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "e45b3573-21cc-445d-8d22-b7fc289d279a",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:13",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: 026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "fx": "DSI::datashield.login",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:13",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:04:14",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "026b4b18-c40c-4f08-8a19-75716fee1c75",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:01",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "fx": "DSI::datashield.login",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:01",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:13:03",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "a3a6f257-79ef-443c-a110-393b1ff196f0",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "OPEN",
#>             "user": "dsuser",
#>             "r_cmd": "Open session: fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "fx": "DSI::datashield.login",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:02",
#>             "action": "ASSIGN",
#>             "user": "dsuser",
#>             "r_cmd": "dsROCrate_test <- opal[CNSIM.CNSIM1]",
#>             "fx": "base::assign",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::lsDS(search.filter = NULL, 1L)",
#>             "fx": "dsBase::lsDS",
#>             "symbol": "search.filter = NULL, 1L",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "base::exists(\"dsROCrate_test\")",
#>             "fx": "base::exists",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::classDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::classDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::isValidDS(dsROCrate_test)",
#>             "fx": "dsBase::isValidDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:04",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::dimDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::dimDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           },
#>           {
#>             "timestamp": "2026-02-27T15:24:05",
#>             "action": "AGGREGATE",
#>             "user": "dsuser",
#>             "r_cmd": "dsBase::colnamesDS(\"dsROCrate_test\")",
#>             "fx": "dsBase::colnamesDS",
#>             "symbol": "dsROCrate_test",
#>             "table": "CNSIM.CNSIM1",
#>             "session": "fc258313-6846-4a8e-93d9-4809cd794fbe",
#>             "backend": "OBiBa's Opal"
#>           }
#>         ]
#>       ]
#>     }
#>   ]
#> }
#> 
#> attr(,"audit_type")
#> [1] "Study"
#> attr(,"project")
#> [1] "CNSIM"
Markdown report

A markdown report can be created with an overview and details for an RO-Crate, using the dsROCrate::rocrate_report:

Only generate .Rmd file

study_crate_v1_rmd <- tempfile(fileext = ".Rmd") # temporary file

safe_project_crate_contents <- study_crate_v1 |>
  dsROCrate::rocrate_report(filepath = study_crate_v1_rmd, render = FALSE)
#> 1 'Author' entity was found!
#> 3 'Dataset' entities were found!
#> Warning: No entities were found with @type = 'WriteAction'!
#> Warning: No entities were found with @type = 'ControlAction'!
#> 1 'Project' entity was found!
#> 14 'PropertyValue' OR 'SoftwareApplication' entities were found!
#> Warning: No entities were found with @type = 'File'!
#> 1 'Author' entity was found!
#> 3 'Dataset' entities were found!
#> Warning: No entities were found with @type = 'WriteAction'!
#> Warning: No entities were found with @type = 'ControlAction'!
#> 1 'Project' entity was found!
#> 14 'PropertyValue' OR 'SoftwareApplication' entities were found!
#> 2 'File' entities were found!

# display Overview diagram
safe_project_crate_contents$overview_diagram

# display Overview data (Safe People, Safe Projects and Safe Data)
safe_project_crate_contents$overview_data |>
  knitr::kable()
Server Project Data Access Level People Function Timestamp
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T08:56:26
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T08:56:27
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:00:37
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:00:38
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T09:20:48
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T09:20:49
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:08:39
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:08:40
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T14:18:40
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T14:18:41
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:04:13
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:04:14
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:13:01
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:13:03
opal_demo CNSIM CNSIM1 read dsuser base::assign 2026-02-27T15:24:02
opal_demo CNSIM CNSIM1 read dsuser dsBase::lsDS 2026-02-27T15:24:04
opal_demo CNSIM CNSIM1 read dsuser base::exists 2026-02-27T15:24:04
opal_demo CNSIM CNSIM1 read dsuser dsBase::classDS 2026-02-27T15:24:04
opal_demo CNSIM CNSIM1 read dsuser dsBase::isValidDS 2026-02-27T15:24:04
opal_demo CNSIM CNSIM1 read dsuser dsBase::dimDS 2026-02-27T15:24:04
opal_demo CNSIM CNSIM1 read dsuser dsBase::colnamesDS 2026-02-27T15:24:05
opal_demo CNSIM CNSIM2 read dsuser
opal_demo CNSIM CNSIM3 read dsuser
opal_test CNSIM CNSIM1 read dsuser

Render and display report (HTML)

study_crate_v1 |>
  dsROCrate::rocrate_report(filepath = study_crate_v1_rmd, 
                            title = "DataSHIELD Study audit",
                            render = TRUE, 
                            overwrite = TRUE)

4. Identity

You are welcome to use any of the following hex codes when referencing {dsROCrate}:

logo logo-white logo-black

About

R package to wrap elements from a DataSHIELD analysis inside an RO-Crate

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages