diff --git a/.Rbuildignore b/.Rbuildignore
index 561a653e..59863e10 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -9,4 +9,5 @@
^pkgdown$
^\.circleci$
^\.circleci/config\.yml$
-^\.github$
\ No newline at end of file
+^\.github$
+^cran-comments\.md$
diff --git a/.github/workflows/dsBase_test_suite.yaml b/.github/workflows/dsBase_test_suite.yaml
new file mode 100755
index 00000000..bea80e31
--- /dev/null
+++ b/.github/workflows/dsBase_test_suite.yaml
@@ -0,0 +1,210 @@
+################################################################################
+# DataSHIELD GHA test suite - dsBase
+# Adapted from `azure-pipelines.yml` by Roberto Villegas-Diaz
+#
+# Inside the root directory $(Pipeline.Workspace) will be a file tree like:
+# /dsBase <- Checked out version of datashield/dsBase
+# /dsBase/logs <- Where results of tests and logs are collated
+# /testStatus <- Checked out version of datashield/testStatus
+#
+# As of Jul 2025 this takes ~ 9 mins to run.
+################################################################################
+name: dsBase tests' suite
+
+on:
+ push:
+ schedule:
+ - cron: '0 0 * * 0' # Weekly
+
+jobs:
+ dsBase_test_suite:
+ runs-on: ubuntu-latest
+ timeout-minutes: 120
+ permissions:
+ contents: write
+
+ # These should all be constant, except TEST_FILTER. This can be used to test
+ # subsets of test files in the testthat directory. Options are like:
+ # '*' <- Run all tests.
+ # 'asNumericDS*' <- Run all asNumericDS tests, i.e. all the arg, etc. tests.
+ # '*_smk_*' <- Run all the smoke tests for all functions.
+ env:
+ TEST_FILTER: '*'
+ _r_check_system_clock_: 0
+ WORKFLOW_ID: ${{ github.run_id }}-${{ github.run_attempt }}
+ PROJECT_NAME: dsBase
+ BRANCH_NAME: ${{ github.ref_name }}
+ REPO_OWNER: ${{ github.repository_owner }}
+ R_KEEP_PKG_SOURCE: yes
+ GITHUB_TOKEN: ${{ github.token || 'placeholder-token' }}
+
+ steps:
+ - name: Checkout dsBase
+ uses: actions/checkout@v4
+ with:
+ path: dsBase
+
+ - name: Checkout testStatus
+ if: ${{ github.actor != 'nektos/act' }} # for local deployment only
+ uses: actions/checkout@v4
+ with:
+ repository: ${{ env.REPO_OWNER }}/testStatus
+ ref: master
+ path: testStatus
+ persist-credentials: false
+ token: ${{ env.GITHUB_TOKEN }}
+
+ - uses: r-lib/actions/setup-pandoc@v2
+
+ - uses: r-lib/actions/setup-r@v2
+ with:
+ r-version: release
+ http-user-agent: release
+ use-public-rspm: true
+
+ - name: Install dsBase
+ run: |
+ Rscript -e 'install.packages(c("RANN", "stringr", "lme4", "dplyr", "reshape2", "polycor", "gamlss", "gamlss.dist", "mice", "childsds", "usethis", "devtools"), dependencies = TRUE)'
+ R CMD INSTALL ./dsBase
+
+ - uses: r-lib/actions/setup-r-dependencies@v2
+ with:
+ dependencies: 'c("Imports")'
+ extra-packages: |
+ any::rcmdcheck
+ cran::devtools
+ cran::git2r
+ cran::RCurl
+ cran::readr
+ cran::magrittr
+ cran::xml2
+ cran::purrr
+ cran::dplyr
+ cran::stringr
+ cran::tidyr
+ cran::quarto
+ cran::knitr
+ cran::kableExtra
+ cran::rmarkdown
+ cran::downlit
+ needs: check
+
+ - name: Check man files up-to-date
+ run: |
+ orig_sum=$(find man -type f | sort -u | xargs cat | md5sum)
+ R -e "devtools::document()"
+ new_sum=$(find man -type f | sort -u | xargs cat | md5sum)
+ if [ "$orig_sum" != "$new_sum" ]; then
+ echo "Your committed manual files (man/*.Rd) are out of sync with the R files. Run devtools::document() locally then commit."
+ exit 1
+ else
+ echo "Documentation up-to-date."
+ fi
+ working-directory: dsBase
+ continue-on-error: true
+
+ - name: Run devtools::check
+ run: |
+ R -q -e "library('devtools'); devtools::check(args = c('--no-tests', '--no-examples'))" | tee ../check.Rout
+ grep -q "^0 errors" ../check.Rout && grep -q " 0 warnings" ../check.Rout && grep -q " 0 notes" ../check.Rout
+ working-directory: dsBase
+ continue-on-error: true
+
+ - name: Run tests with coverage & JUnit report
+ run: |
+ mkdir -p logs
+ R -q -e "devtools::reload();"
+ R -q -e '
+ write.csv(
+ covr::coverage_to_list(
+ covr::package_coverage(
+ type = c("none"),
+ code = c('"'"'
+ output_file <- file("test_console_output.txt");
+ sink(output_file);
+ sink(output_file, type = "message");
+ junit_rep <- testthat::JunitReporter$new(file = file.path(getwd(), "test_results.xml"));
+ progress_rep <- testthat::ProgressReporter$new(max_failures = 999999);
+ multi_rep <- testthat::MultiReporter$new(reporters = list(progress_rep, junit_rep));
+ testthat::test_package("${{ env.PROJECT_NAME }}", filter = "${{ env.TEST_FILTER }}", reporter = multi_rep, stop_on_failure = FALSE)'"'"'
+ )
+ )
+ ),
+ "coveragelist.csv"
+ )'
+
+ mv coveragelist.csv logs/
+ mv test_* logs/
+ grep -q " FAIL 0 " logs/test_console_output.txt
+ working-directory: dsBase
+
+ - name: Check for JUnit errors
+ run: |
+ issue_count=$(sed 's/failures="0" errors="0"//' test_results.xml | grep -c errors= || true)
+ echo "Number of testsuites with issues: $issue_count"
+ sed 's/failures="0" errors="0"//' test_results.xml | grep errors= > issues.log || true
+ cat issues.log || true
+ exit $issue_count
+ working-directory: dsBase/logs
+
+ - name: Write versions to file
+ run: |
+ echo "branch:${{ env.BRANCH_NAME }}" > ${{ env.WORKFLOW_ID }}.txt
+ echo "os:$(lsb_release -ds)" >> ${{ env.WORKFLOW_ID }}.txt
+ echo "R:$(R --version | head -n1)" >> ${{ env.WORKFLOW_ID }}.txt
+ Rscript --vanilla -e 'sessionInfo()' >> session_info_${{ env.WORKFLOW_ID }}.txt
+ working-directory: dsBase/logs
+
+ - name: Parse results from testthat and covr
+ run: |
+ Rscript --verbose --vanilla ../testStatus/source/parse_test_report.R logs/ logs/ https://github.com/datashield/${{ env.PROJECT_NAME }}/blob/${{ env.BRANCH_NAME }} '[^-:.]+' '(?<=::)[^:]+(?=::)'
+ working-directory: dsBase
+ env:
+ PROJECT_NAME: ${{ env.PROJECT_NAME }}
+ BRANCH_NAME: ${{ env.BRANCH_NAME }}
+
+ - name: Render report
+ run: |
+ cd testStatus
+
+ mkdir -p new/logs/${{ env.PROJECT_NAME }}/${{ env.BRANCH_NAME }}/${{ env.WORKFLOW_ID }}/
+ mkdir -p new/docs/${{ env.PROJECT_NAME }}/${{ env.BRANCH_NAME }}/latest/
+
+ # Copy logs to new logs directory location
+ cp -rv ../${{ env.PROJECT_NAME }}/logs/* new/logs/${{ env.PROJECT_NAME }}/${{ env.BRANCH_NAME }}/${{ env.WORKFLOW_ID }}/
+ cp -rv ../${{ env.PROJECT_NAME }}/logs/${{ env.WORKFLOW_ID }}.txt new/logs/${{ env.PROJECT_NAME }}/${{ env.BRANCH_NAME }}/${{ env.WORKFLOW_ID }}/
+
+ R -e 'input_dir <- file.path("../new/logs", Sys.getenv("PROJECT_NAME"), Sys.getenv("BRANCH_NAME"), Sys.getenv("WORKFLOW_ID")); quarto::quarto_render("source/test_report.qmd", execute_params = list(input_dir = input_dir))'
+ mv source/test_report.html new/docs/${{ env.PROJECT_NAME }}/${{ env.BRANCH_NAME }}/latest/index.html
+
+ env:
+ PROJECT_NAME: ${{ env.PROJECT_NAME }}
+ BRANCH_NAME: ${{ env.BRANCH_NAME }}
+ WORKFLOW_ID: ${{ env.WORKFLOW_ID }}
+
+ - name: Upload test logs
+ uses: actions/upload-artifact@v4
+ with:
+ name: dsbase-logs
+ path: testStatus/new
+
+ - name: Dump environment info
+ run: |
+ echo -e "\n#############################"
+ echo -e "ls /: ######################"
+ ls -al .
+ echo -e "\n#############################"
+ echo -e "lscpu: ######################"
+ lscpu
+ echo -e "\n#############################"
+ echo -e "memory: #####################"
+ free -m
+ echo -e "\n#############################"
+ echo -e "env: ########################"
+ env
+ echo -e "\n#############################"
+ echo -e "R sessionInfo(): ############"
+ R -e 'sessionInfo()'
+ sudo apt install tree -y
+ tree .
+
diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml
new file mode 100644
index 00000000..bfc9f4db
--- /dev/null
+++ b/.github/workflows/pkgdown.yaml
@@ -0,0 +1,49 @@
+# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
+# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
+on:
+ push:
+ branches: [main, master]
+ pull_request:
+ release:
+ types: [published]
+ workflow_dispatch:
+
+name: pkgdown.yaml
+
+permissions: read-all
+
+jobs:
+ pkgdown:
+ runs-on: ubuntu-latest
+ # Only restrict concurrency for non-PR jobs
+ concurrency:
+ group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }}
+ env:
+ GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
+ permissions:
+ contents: write
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: r-lib/actions/setup-pandoc@v2
+
+ - uses: r-lib/actions/setup-r@v2
+ with:
+ use-public-rspm: true
+
+ - uses: r-lib/actions/setup-r-dependencies@v2
+ with:
+ extra-packages: any::pkgdown, local::.
+ needs: website
+
+ - name: Build site
+ run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
+ shell: Rscript {0}
+
+ - name: Deploy to GitHub pages 🚀
+ if: github.event_name != 'pull_request'
+ uses: JamesIves/github-pages-deploy-action@v4.5.0
+ with:
+ clean: false
+ branch: gh-pages
+ folder: docs
diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml
new file mode 100644
index 00000000..0ab748d6
--- /dev/null
+++ b/.github/workflows/test-coverage.yaml
@@ -0,0 +1,62 @@
+# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
+# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
+on:
+ push:
+ branches: [main, master]
+ pull_request:
+
+name: test-coverage.yaml
+
+permissions: read-all
+
+jobs:
+ test-coverage:
+ runs-on: ubuntu-latest
+ env:
+ GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - uses: r-lib/actions/setup-r@v2
+ with:
+ use-public-rspm: true
+
+ - uses: r-lib/actions/setup-r-dependencies@v2
+ with:
+ extra-packages: any::covr, any::xml2
+ needs: coverage
+
+ - name: Test coverage
+ run: |
+ cov <- covr::package_coverage(
+ quiet = FALSE,
+ clean = FALSE,
+ install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package")
+ )
+ print(cov)
+ covr::to_cobertura(cov)
+ shell: Rscript {0}
+
+ - uses: codecov/codecov-action@v5
+ with:
+ # Fail if error if not on PR, or if on PR and token is given
+ fail_ci_if_error: ${{ github.event_name != 'pull_request' || secrets.CODECOV_TOKEN }}
+ files: ./cobertura.xml
+ plugins: noop
+ disable_search: true
+ token: ${{ secrets.CODECOV_TOKEN }}
+
+ - name: Show testthat output
+ if: always()
+ run: |
+ ## --------------------------------------------------------------------
+ find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true
+ shell: bash
+
+ - name: Upload test results
+ if: failure()
+ uses: actions/upload-artifact@v4
+ with:
+ name: coverage-test-failures
+ path: ${{ runner.temp }}/package
diff --git a/DESCRIPTION b/DESCRIPTION
index 3943a07f..bc5e3973 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,23 +1,27 @@
Package: dsBase
-Title: 'DataSHIELD' Server Site Base Functions
+Title: 'DataSHIELD' Server Side Base Functions
Description: Base 'DataSHIELD' functions for the server side. 'DataSHIELD' is a software package which allows
you to do non-disclosive federated analysis on sensitive data. 'DataSHIELD' analytic functions have
been designed to only share non disclosive summary statistics, with built in automated output
checking based on statistical disclosure control. With data sites setting the threshold values for
- the automated output checks.
-Version: 6.3.3
+ the automated output checks. For more details, see 'citation("dsBase")'.
+Version: 6.3.5.9000
Authors@R: c(person(given = "Paul",
family = "Burton",
- role = c("aut")),
+ role = c("aut"),
+ comment = c(ORCID = "0000-0001-5799-9634")),
person(given = "Rebecca",
family = "Wilson",
- role = c("aut")),
+ role = c("aut"),
+ comment = c(ORCID = "0000-0003-2294-593X")),
person(given = "Olly",
family = "Butters",
- role = c("aut")),
+ role = c("aut"),
+ comment = c(ORCID = "0000-0003-0354-8461")),
person(given = "Patricia",
family = "Ryser-Welch",
- role = c("aut")),
+ role = c("aut"),
+ comment = c(ORCID = "0000-0002-0070-0264")),
person(given = "Alex",
family = "Westerberg",
role = c("aut")),
@@ -37,6 +41,17 @@ Authors@R: c(person(given = "Paul",
role = c("aut"),
email = "yannick.marcon@obiba.org",
comment = c(ORCID = "0000-0003-0138-2023")),
+ person(given = "Tom",
+ family = "Bishop",
+ role = c("aut")),
+ person(given = "Amadou",
+ family = "Gaye",
+ role = c("aut"),
+ comment = c(ORCID = "0000-0002-1180-2792")),
+ person(given = "Xavier",
+ family = "Escribà-Montagut",
+ role = c("aut"),
+ comment = c(ORCID = "0000-0003-2888-8948")),
person(given = "Stuart",
family = "Wheater",
role = c("aut", "cre"),
@@ -58,6 +73,8 @@ Imports:
mice,
childsds
Suggests:
+ spelling,
testthat
-RoxygenNote: 7.3.2
+RoxygenNote: 7.3.3
Encoding: UTF-8
+Language: en-GB
diff --git a/NAMESPACE b/NAMESPACE
index 897148d1..e52e5d10 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -82,6 +82,7 @@ export(matrixDimnamesDS)
export(matrixInvertDS)
export(matrixMultDS)
export(matrixTransposeDS)
+export(mdPatternDS)
export(meanDS)
export(meanSdGpDS)
export(mergeDS)
diff --git a/R/BooleDS.R b/R/BooleDS.R
index 1ad5e14f..0f54dfca 100644
--- a/R/BooleDS.R
+++ b/R/BooleDS.R
@@ -28,7 +28,7 @@
BooleDS <- function(V1.name=NULL, V2.name=NULL, Boolean.operator.n=NULL, na.assign.text, numeric.output=TRUE){
# Check Permissive Privacy Control Level.
- dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
+ dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
#########################################################################
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS #
diff --git a/R/asDataMatrixDS.R b/R/asDataMatrixDS.R
index 5b4e5d71..3fff528b 100644
--- a/R/asDataMatrixDS.R
+++ b/R/asDataMatrixDS.R
@@ -3,7 +3,7 @@
#' class for all columns in data.frames.
#' @details This assign function is based on the native R function \code{data.matrix}
#' If applied to a data.frame, the native R function \code{as.matrix}
-#' coverts all columns into character class. In contrast, if applied to
+#' converts all columns into character class. In contrast, if applied to
#' a data.frame the native R function \code{data.matrix} converts
#' the data.frame to a matrix but maintains all data columns in their
#' original class
diff --git a/R/blackBoxDS.R b/R/blackBoxDS.R
index 8e7e33f1..63cf0160 100644
--- a/R/blackBoxDS.R
+++ b/R/blackBoxDS.R
@@ -67,8 +67,11 @@ blackBoxDS <- function(input.var.name=NULL,
########################################################
# back-up current .Random.seed and revert on.exit
- old_seed <- .Random.seed
- on.exit(.Random.seed <- old_seed, add = TRUE)
+ if (exists(x = ".Random.seed", envir = globalenv())) {
+ assign(x = ".old_seed", value = .Random.seed, envir = parent.frame());
+ on.exit({ assign(x = ".Random.seed", value = parent.frame()$.old_seed, envir = globalenv()); remove(".old_seed", envir = parent.frame()) }, add = TRUE)
+ } else
+ on.exit(if (exists(x = ".Random.seed", envir = globalenv())) remove(".Random.seed", envir = globalenv()), add = TRUE)
input.var <- eval(parse(text=input.var.name), envir = parent.frame())
diff --git a/R/blackBoxRanksDS.R b/R/blackBoxRanksDS.R
index cb2fc21f..522307a8 100644
--- a/R/blackBoxRanksDS.R
+++ b/R/blackBoxRanksDS.R
@@ -62,8 +62,11 @@ blackBoxRanksDS <- function(input.var.name=NULL, shared.seedval){ #START FUNC
########################################################
# back-up current .Random.seed and revert on.exit
- old_seed <- .Random.seed
- on.exit(.Random.seed <- old_seed, add = TRUE)
+ if (exists(x = ".Random.seed", envir = globalenv())) {
+ assign(x = ".old_seed", value = .Random.seed, envir = parent.frame());
+ on.exit({ assign(x = ".Random.seed", value = parent.frame()$.old_seed, envir = globalenv()); remove(".old_seed", envir = parent.frame()) }, add = TRUE)
+ } else
+ on.exit(if (exists(x = ".Random.seed", envir = globalenv())) remove(".Random.seed", envir = globalenv()), add = TRUE)
input.var <- eval(parse(text=input.var.name), envir = parent.frame())
input.global.ranks<-input.var
diff --git a/R/cbindDS.R b/R/cbindDS.R
index 5d5464e7..b7864864 100644
--- a/R/cbindDS.R
+++ b/R/cbindDS.R
@@ -24,7 +24,7 @@
cbindDS <- function(x.names.transmit=NULL, colnames.transmit=NULL){
# Check Permissive Privacy Control Level.
- dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
+ dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
x.names.input <- x.names.transmit
x.names.act1 <- unlist(strsplit(x.names.input, split=","))
diff --git a/R/checkNegValueDS.R b/R/checkNegValueDS.R
index 3f46f3fa..48629138 100644
--- a/R/checkNegValueDS.R
+++ b/R/checkNegValueDS.R
@@ -1,7 +1,7 @@
#'
#' @title Checks if a numeric variable has negative values
#' @description this function is only called by the client function \code{ds.glm}.
-#' @details if a user sets the parameter 'weights' on the client site function \code{ds.glm} this
+#' @details if a user sets the parameter 'weights' on the client side function \code{ds.glm} this
#' server side function is called to verify that the 'weights' vector does not have negative values
#' because no negative are allowed in weights.
#' @param weights a numeric vector
diff --git a/R/dataFrameDS.R b/R/dataFrameDS.R
index a3e06f4c..7a2b36be 100644
--- a/R/dataFrameDS.R
+++ b/R/dataFrameDS.R
@@ -40,7 +40,7 @@
dataFrameDS <- function(vectors=NULL, r.names=NULL, ch.rows=FALSE, ch.names=TRUE, clnames=NULL, strAsFactors=TRUE, completeCases=FALSE){
# Check Permissive Privacy Control Level.
- dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
+ dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
#########################################################################
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS
diff --git a/R/dataFrameSortDS.R b/R/dataFrameSortDS.R
index 0ea3b3c1..a398a70b 100644
--- a/R/dataFrameSortDS.R
+++ b/R/dataFrameSortDS.R
@@ -36,7 +36,7 @@
dataFrameSortDS <- function(df.name=NULL,sort.key.name=NULL,sort.descending,sort.method){
# Check Permissive Privacy Control Level.
- dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
+ dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
#########################################################################
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS
diff --git a/R/dataFrameSubsetDS1.R b/R/dataFrameSubsetDS1.R
index 232e405c..4b3c9476 100644
--- a/R/dataFrameSubsetDS1.R
+++ b/R/dataFrameSubsetDS1.R
@@ -50,7 +50,7 @@
dataFrameSubsetDS1 <- function(df.name=NULL,V1.name=NULL,V2.name=NULL,Boolean.operator.n=NULL,keep.cols=NULL,rm.cols=NULL,keep.NAs=NULL){
# Check Permissive Privacy Control Level.
- dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
+ dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
#########################################################################
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS
diff --git a/R/dataFrameSubsetDS2.R b/R/dataFrameSubsetDS2.R
index 3a59602f..05938a60 100644
--- a/R/dataFrameSubsetDS2.R
+++ b/R/dataFrameSubsetDS2.R
@@ -59,7 +59,7 @@
dataFrameSubsetDS2<-function(df.name=NULL,V1.name=NULL, V2.name=NULL, Boolean.operator.n=NULL,keep.cols=NULL, rm.cols=NULL, keep.NAs=NULL){
# Check Permissive Privacy Control Level.
- dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
+ dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
#########################################################################
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS #
diff --git a/R/densityGridDS.R b/R/densityGridDS.R
index 786302f7..1569d5c1 100644
--- a/R/densityGridDS.R
+++ b/R/densityGridDS.R
@@ -1,6 +1,6 @@
#'
#' @title Generates a density grid with or without a priori defined limits
-#' @description Generates a density grid that can then be used for heatmap or countour plots.
+#' @description Generates a density grid that can then be used for heatmap or contour plots.
#' @details Invalid cells (cells with count < to the set filter value for the minimum allowed
#' counts in table cells) are turn to 0.
#' @param xvect a numerical vector
diff --git a/R/dmtC2SDS.R b/R/dmtC2SDS.R
index 5d315e3d..9b4329ad 100644
--- a/R/dmtC2SDS.R
+++ b/R/dmtC2SDS.R
@@ -22,10 +22,10 @@
#' @param ncols.transmit specifies the number of columns in the matrix to be created.
#' Fixed by the clientside function as equal to the number of columns in
#' the clientside DMT to be transferred.
-#' @param colnames.transmit a parser-transmissable vector specifying the name of each column
+#' @param colnames.transmit a parser-transmissible vector specifying the name of each column
#' in the DMT being transferred from clientside to serverside.
#' Generated automatically by clientside function from colnames of clientside DMT.
-#' @param colclass.transmit a parser-transmissable vector specifying the class of the
+#' @param colclass.transmit a parser-transmissible vector specifying the class of the
#' vector representing each individual column in the DMT to be transferred.
#' Generated automatically by clientside function. This allows the transmission of DMTs
#' containing columns with different classes.If something is going to go wrong with
diff --git a/R/dsBase-package.R b/R/dsBase-package.R
new file mode 100644
index 00000000..a65cf643
--- /dev/null
+++ b/R/dsBase-package.R
@@ -0,0 +1,6 @@
+#' @keywords internal
+"_PACKAGE"
+
+## usethis namespace: start
+## usethis namespace: end
+NULL
diff --git a/R/gamlssDS.R b/R/gamlssDS.R
index 322f0661..533da0e1 100644
--- a/R/gamlssDS.R
+++ b/R/gamlssDS.R
@@ -1,5 +1,5 @@
#'
-#' @title gamlssDS an aggregate function called by ds.galmss
+#' @title gamlssDS an aggregate function called by ds.gamlss
#' @description This function calls the gamlssDS that is a wrapper function from
#' the gamlss R package. The function returns an object of class "gamlss", which
#' is a generalized additive model for location, scale and shape (GAMLSS). The
diff --git a/R/glmerSLMADS.assign.R b/R/glmerSLMADS.assign.R
index 9e39c72b..df367ea1 100644
--- a/R/glmerSLMADS.assign.R
+++ b/R/glmerSLMADS.assign.R
@@ -5,7 +5,7 @@
#' The analytic work engine is the glmer function in R which sits in the lme4 package.
#' glmerSLMADS.assign fits a generalized linear mixed effects model (glme) - e.g. a logistic or
#' Poisson regression model including both fixed and random effects - on data
-#' from each single data source and saves the regression outcomes on the serveside.
+#' from each single data source and saves the regression outcomes on the serverside.
#' @param formula see help for ds.glmerSLMA
#' @param offset see help for ds.glmerSLMA
#' @param weights see help for ds.glmerSLMA
diff --git a/R/global.R b/R/global.R
index 89970bc0..a3c9454e 100644
--- a/R/global.R
+++ b/R/global.R
@@ -2,5 +2,4 @@
utils::globalVariables(c('offset.to.use', 'weights.to.use', 'out.table.real', 'out.table.dim', 'out.table.dimnames', 'list.obj', 'mg',
'blackbox.output.df', 'blackbox.ranks.df', 'global.bounds.df', 'global.ranks.quantiles.df', 'sR4.df',
- 'min.max.df','sR5.df','input.mean.sd.df','input.ranks.sd.df','RS','CG','mixed', 'x','y'))
-
+ 'min.max.df','sR5.df','input.mean.sd.df','input.ranks.sd.df','RS','CG','mixed','x','y','.old_seed','.Random.seed'))
diff --git a/R/heatmapPlotDS.R b/R/heatmapPlotDS.R
index 6dccbd5b..349f57b9 100644
--- a/R/heatmapPlotDS.R
+++ b/R/heatmapPlotDS.R
@@ -39,8 +39,11 @@ heatmapPlotDS <- function(x, y, k, noise, method.indicator){
###################################################################
# back-up current .Random.seed and revert on.exit
- old_seed <- .Random.seed
- on.exit(.Random.seed <- old_seed, add = TRUE)
+ if (exists(x = ".Random.seed", envir = globalenv())) {
+ assign(x = ".old_seed", value = .Random.seed, envir = parent.frame());
+ on.exit({ assign(x = ".Random.seed", value = parent.frame()$.old_seed, envir = globalenv()); remove(".old_seed", envir = parent.frame()) }, add = TRUE)
+ } else
+ on.exit(if (exists(x = ".Random.seed", envir = globalenv())) remove(".Random.seed", envir = globalenv()), add = TRUE)
# Cbind the columns of the two variables and remove any rows that include NAs
data.table <- cbind.data.frame(x, y)
diff --git a/R/hetcorDS.R b/R/hetcorDS.R
index 3cf57366..d561ce30 100644
--- a/R/hetcorDS.R
+++ b/R/hetcorDS.R
@@ -1,7 +1,7 @@
#'
#' @title Heterogeneous Correlation Matrix
#' @description This function is based on the hetcor function from the R package \code{polycor}.
-#' @details Computes a heterogenous correlation matrix, consisting of Pearson product-moment
+#' @details Computes a heterogeneous correlation matrix, consisting of Pearson product-moment
#' correlations between numeric variables, polyserial correlations between numeric and ordinal
#' variables, and polychoric correlations between ordinal variables.
#' @param data the name of a data frame consisting of factors, ordered factors, logical variables,
diff --git a/R/histogramDS1.R b/R/histogramDS1.R
index a79d2f52..71ffc439 100644
--- a/R/histogramDS1.R
+++ b/R/histogramDS1.R
@@ -37,8 +37,11 @@ histogramDS1 <- function(xvect, method.indicator, k, noise){
##################################################################
# back-up current .Random.seed and revert on.exit
- old_seed <- .Random.seed
- on.exit(.Random.seed <- old_seed, add = TRUE)
+ if (exists(x = ".Random.seed", envir = globalenv())) {
+ assign(x = ".old_seed", value = .Random.seed, envir = parent.frame());
+ on.exit({ assign(x = ".Random.seed", value = parent.frame()$.old_seed, envir = globalenv()); remove(".old_seed", envir = parent.frame()) }, add = TRUE)
+ } else
+ on.exit(if (exists(x = ".Random.seed", envir = globalenv())) remove(".Random.seed", envir = globalenv()), add = TRUE)
# print an error message if the input vector is not a numeric
if(!(is.numeric(xvect))){
diff --git a/R/histogramDS2.R b/R/histogramDS2.R
index 1f7a8acc..001ab0dd 100644
--- a/R/histogramDS2.R
+++ b/R/histogramDS2.R
@@ -39,8 +39,11 @@ histogramDS2 <- function (xvect, num.breaks, min, max, method.indicator, k, nois
##################################################################
# back-up current .Random.seed and revert on.exit
- old_seed <- .Random.seed
- on.exit(.Random.seed <- old_seed, add = TRUE)
+ if (exists(x = ".Random.seed", envir = globalenv())) {
+ assign(x = ".old_seed", value = .Random.seed, envir = parent.frame());
+ on.exit({ assign(x = ".Random.seed", value = parent.frame()$.old_seed, envir = globalenv()); remove(".old_seed", envir = parent.frame()) }, add = TRUE)
+ } else
+ on.exit(if (exists(x = ".Random.seed", envir = globalenv())) remove(".Random.seed", envir = globalenv()), add = TRUE)
if (method.indicator==1){
diff --git a/R/levelsDS.R b/R/levelsDS.R
index 9bb54401..bdb374d5 100644
--- a/R/levelsDS.R
+++ b/R/levelsDS.R
@@ -10,7 +10,7 @@
levelsDS <- function(x){
# Check Permissive Privacy Control Level.
- dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
+ dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
##################################################################
#MODULE 1: CAPTURE THE nfilter SETTINGS #
diff --git a/R/lexisDS2.R b/R/lexisDS2.R
index e4c08117..d63989d2 100644
--- a/R/lexisDS2.R
+++ b/R/lexisDS2.R
@@ -3,7 +3,7 @@
#' @description The second serverside function called by ds.lexis.
#' @details This is the assign
#' function which actually creates
-#' the expanded dataframe containing surival data for a piecewise exponential
+#' the expanded dataframe containing survival data for a piecewise exponential
#' regression. lexisDS2 also
#' carries out a series of disclosure checks and if the arguments or data fail any of
#' those tests,
diff --git a/R/lmerSLMADS.assign.R b/R/lmerSLMADS.assign.R
index 526818a1..06b2bcd1 100644
--- a/R/lmerSLMADS.assign.R
+++ b/R/lmerSLMADS.assign.R
@@ -1,10 +1,10 @@
#' @title Fitting linear mixed effect models - serverside function
-#' @description lmerSLMADS.assing is the same as lmerSLMADS2 which fits a linear
+#' @description lmerSLMADS.assign is the same as lmerSLMADS2 which fits a linear
#' mixed effects model (lme) per study and saves the outcomes in each study
#' @details lmerSLMADS.assign is a serverside function called by ds.lmerSLMA on the clientside.
#' The analytic work engine is the lmer function in R which sits in the lme4 package.
#' lmerSLMADS.assign fits a linear mixed effects model (lme) including both fixed and random
-#' effects - on data from each single data source and saves the regression outcomes on the serveside.
+#' effects - on data from each single data source and saves the regression outcomes on the serverside.
#' @param formula see help for ds.lmerSLMA
#' @param offset see help for ds.lmerSLMA
#' @param weights see help for ds.lmerSLMA
diff --git a/R/mdPatternDS.R b/R/mdPatternDS.R
new file mode 100644
index 00000000..0f817034
--- /dev/null
+++ b/R/mdPatternDS.R
@@ -0,0 +1,121 @@
+#'
+#' @title Missing data pattern with disclosure control
+#' @description This function is a serverside aggregate function that computes the
+#' missing data pattern using mice::md.pattern and applies disclosure control to
+#' prevent revealing small cell counts.
+#' @details This function calls the mice::md.pattern function to generate a matrix
+#' showing the missing data patterns in the input data. To ensure disclosure control,
+#' any pattern counts that are below the threshold (nfilter.tab, default=3) are
+#' suppressed.
+#'
+#' \strong{Suppression Method:}
+#'
+#' When a pattern count is below threshold:
+#' - Row name is changed to "suppressed( Paul Burton. Author.
+ Rebecca Wilson. Author.
+ Olly Butters. Author.
+ Patricia Ryser-Welch. Author.
+ Tom Bishop. Author.
+ Stuart Wheater. Author, maintainer.
Burton P, Wilson R, Butters O, Ryser-Welch P, Westerberg A, Abarrategui L, Villegas-Diaz R, Avraam D, Marcon Y, Wheater S (2025).
-dsBase: DataSHIELD Server Site Base Functions.
-R package version 6.3.3.
+ Burton P, Wilson R, Butters O, Ryser-Welch P, Westerberg A, Abarrategui L, Villegas-Diaz R, Avraam D, Marcon Y, Bishop T, Gaye A, Escribà-Montagut X, Wheater S (????).
+dsBase: 'DataSHIELD' Server Side Base Functions.
+R package version 6.3.5.9000.
Gaye A, Marcon Y, Isaeva J, LaFlamme P, Turner A, Jones E, Minion J, Boyd A, Newby C, Nuotio M, Wilson R, Butters O, Murtagh B, Demir I, Doiron D, Giepmans L, Wallace S, Budin-Ljøsne I, Schmidt C, Boffetta P, Boniol M, Bota M, Carter K, deKlerk N, Dibben C, Francis R, Hiekkalinna T, Hveem K, Kvaløy K, Millar S, Perry I, Peters A, Phillips C, Popham F, Raab G, Reischl E, Sheehan N, Waldenberger M, Perola M, van den Heuvel E, Macleod J, Knoppers B, Stolk R, Fortier I, Harris J, Woffenbuttel B, Murtagh M, Ferretti V, Burton P (2014).
+“DataSHIELD: taking the analysis to the data, not the data to the analysis.”
+International Journal of Epidemiology, 43(6), 1929–1944.
+doi:10.1093/ije/dyu188.
+ Wilson R, Butters O, Avraam D, Baker J, Tedds J, Turner A, Murtagh M, Burton P (2017).
+“DataSHIELD – New Directions and Dimensions.”
+Data Science Journal, 16(21), 1–21.
+doi:10.5334/dsj-2017-021.
+ Avraam D, Wilson R, Aguirre Chan N, Banerjee S, Bishop T, Butters O, Cadman T, Cederkvist L, Duijts L, Escribà Montagut X, Garner H, Gonçalves G, González J, Haakma S, Hartlev M, Hasenauer J, Huth M, Hyde E, Jaddoe V, Marcon Y, Mayrhofer M, Molnar-Gabor F, Morgan A, Murtagh M, Nestor M, Nybo Andersen A, Parker S, Pinot de Moira A, Schwarz F, Strandberg-Larsen K, Swertz M, Welten M, Wheater S, Burton P (2024).
+“DataSHIELD: mitigating disclosure risk in a multi-site federated analysis platform.”
+Bioinformatics Advances, 5(1), 1–21.
+doi:10.1093/bioadv/vbaf046.
+Page not found (404)
diff --git a/docs/LICENSE.html b/docs/LICENSE.html
index 158c5efe..5faa2d0e 100644
--- a/docs/LICENSE.html
+++ b/docs/LICENSE.html
@@ -1,5 +1,5 @@
-NA
diff --git a/docs/authors.html b/docs/authors.html
index cc06044e..a1aec549 100644
--- a/docs/authors.html
+++ b/docs/authors.html
@@ -1,5 +1,5 @@
-Authors and Citation
Authors and Citation
Citation
- @Manual{,
- title = {dsBase: DataSHIELD Server Site Base Functions},
- author = {Paul Burton and Rebecca Wilson and Olly Butters and Patricia Ryser-Welch and Alex Westerberg and Leire Abarrategui and Roberto Villegas-Diaz and Demetris Avraam and Yannick Marcon and Stuart Wheater},
- year = {2025},
- note = {R package version 6.3.3},
+ title = {dsBase: 'DataSHIELD' Server Side Base Functions},
+ author = {Paul Burton and Rebecca Wilson and Olly Butters and Patricia Ryser-Welch and Alex Westerberg and Leire Abarrategui and Roberto Villegas-Diaz and Demetris Avraam and Yannick Marcon and Tom Bishop and Amadou Gaye and Xavier Escribà-Montagut and Stuart Wheater},
+ note = {R package version 6.3.5.9000},
+}
+ @Article{,
+ title = {{DataSHIELD: taking the analysis to the data, not the data to the analysis}},
+ author = {Amadou Gaye and Yannick Marcon and Julia Isaeva and Philippe {LaFlamme} and Andrew Turner and Elinor M Jones and Joel Minion and Andrew W Boyd and Christopher J Newby and Marja-Liisa Nuotio and Rebecca Wilson and Oliver Butters and Barnaby Murtagh and Ipek Demir and Dany Doiron and Lisette Giepmans and Susan E Wallace and Isabelle Budin-Lj{\o}sne and Carsten O. Schmidt and Paolo Boffetta and Mathieu Boniol and Maria Bota and Kim W Carter and Nick {deKlerk} and Chris Dibben and Richard W Francis and Tero Hiekkalinna and Kristian Hveem and Kirsti Kval{\o}y and Sean Millar and Ivan J Perry and Annette Peters and Catherine M Phillips and Frank Popham and Gillian Raab and Eva Reischl and Nuala Sheehan and Melanie Waldenberger and Markus Perola and Edwin {{van den Heuvel}} and John Macleod and Bartha M Knoppers and Ronald P Stolk and Isabel Fortier and Jennifer R Harris and Bruce H R Woffenbuttel and Madeleine J Murtagh and Vincent Ferretti and Paul R Burton},
+ journal = {International Journal of Epidemiology},
+ year = {2014},
+ volume = {43},
+ number = {6},
+ pages = {1929--1944},
+ doi = {10.1093/ije/dyu188},
+}
+ @Article{,
+ title = {{DataSHIELD – New Directions and Dimensions}},
+ author = {Rebecca C. Wilson and Oliver W. Butters and Demetris Avraam and James Baker and Jonathan A. Tedds and Andrew Turner and Madeleine Murtagh and Paul R. Burton},
+ journal = {Data Science Journal},
+ year = {2017},
+ volume = {16},
+ number = {21},
+ pages = {1--21},
+ doi = {10.5334/dsj-2017-021},
+}
+ @Article{,
+ title = {{DataSHIELD: mitigating disclosure risk in a multi-site federated analysis platform}},
+ author = {Demetris Avraam and Rebecca C Wilson and Noemi {{Aguirre Chan}} and Soumya Banerjee and Tom R P Bishop and Olly Butters and Tim Cadman and Luise Cederkvist and Liesbeth Duijts and Xavier {{Escrib{\a`a} Montagut}} and Hugh Garner and Gon{\c c}alo {Gon{\c c}alves} and Juan R Gonz{\a'a}lez and Sido Haakma and Mette Hartlev and Jan Hasenauer and Manuel Huth and Eleanor Hyde and Vincent W V Jaddoe and Yannick Marcon and Michaela Th Mayrhofer and Fruzsina Molnar-Gabor and Andrei Scott Morgan and Madeleine Murtagh and Marc Nestor and Anne-Marie {{Nybo Andersen}} and Simon Parker and Angela {{Pinot de Moira}} and Florian Schwarz and Katrine Strandberg-Larsen and Morris A Swertz and Marieke Welten and Stuart Wheater and Paul R Burton},
+ journal = {Bioinformatics Advances},
+ year = {2024},
+ volume = {5},
+ number = {1},
+ pages = {1--21},
+ doi = {10.1093/bioadv/vbaf046},
+ editor = {Thomas Lengauer},
+ publisher = {Oxford University Press (OUP)},
}
@@ -106,11 +164,11 @@ Citation
diff --git a/docs/index.html b/docs/index.html
index 54bbe6e5..1f70741d 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -1,18 +1,18 @@
-
+
-
+install.packages("remotes")
+remotes::install_github("datashield/dsBase", "<BRANCH>")
+
+# Install v6.3.4 with the following
+remotes::install_github("datashield/dsBase", "6.3.4")For a full list of development branches, checkout https://github.com/datashield/dsBase/branches
+ +DataSHIELD is a software package which allows you to do non-disclosive federated analysis on sensitive data. Our website (https://www.datashield.org) has in depth descriptions of what it is, how it works and how to install it. A key point to highlight is that DataSHIELD has a client-server infrastructure, so the dsBase package (https://github.com/datashield/dsBase) needs to be used in conjunction with the dsBaseClient package (https://github.com/datashield/dsBaseClient) - trying to use one without the other makes no sense.
Detailed instructions on how to install DataSHIELD are at https://wiki.datashield.org/. The code here is organised as:
[1] Burton P, Wilson R, Butters O, Ryser-Welch P, Westerberg A, Abarrategui L, Villegas-Diaz R, Avraam D, Marcon Y, Bishop T, Gaye A, Escribà Montagut X, Wheater S (2025). dsBase: ‘DataSHIELD’ Server Side Base Functions. R package version 6.3.4. https://doi.org/10.32614/CRAN.package.dsBase.
+[2] Gaye A, Marcon Y, Isaeva J, LaFlamme P, Turner A, Jones E, Minion J, Boyd A, Newby C, Nuotio M, Wilson R, Butters O, Murtagh B, Demir I, Doiron D, Giepmans L, Wallace S, Budin-Ljøsne I, Oliver Schmidt C, Boffetta P, Boniol M, Bota M, Carter K, deKlerk N, Dibben C, Francis R, Hiekkalinna T, Hveem K, Kvaløy K, Millar S, Perry I, Peters A, Phillips C, Popham F, Raab G, Reischl E, Sheehan N, Waldenberger M, Perola M, van den Heuvel E, Macleod J, Knoppers B, Stolk R, Fortier I, Harris J, Woffenbuttel B, Murtagh M, Ferretti V, Burton P (2014). “DataSHIELD: taking the analysis to the data, not the data to the analysis.” International Journal of Epidemiology, 43(6), 1929-1944. https://doi.org/10.1093/ije/dyu188.
+[3] Wilson R, W. Butters O, Avraam D, Baker J, Tedds J, Turner A, Murtagh M, R. Burton P (2017). “DataSHIELD – New Directions and Dimensions.” Data Science Journal, 16(21), 1-21. https://doi.org/10.5334/dsj-2017-021.
+[4] Avraam D, Wilson R, Aguirre Chan N, Banerjee S, Bishop T, Butters O, Cadman T, Cederkvist L, Duijts L, Escribà Montagut X, Garner H, Gonçalves G, González J, Haakma S, Hartlev M, Hasenauer J, Huth M, Hyde E, Jaddoe V, Marcon Y, Mayrhofer M, Molnar-Gabor F, Morgan A, Murtagh M, Nestor M, Nybo Andersen A, Parker S, Pinot de Moira A, Schwarz F, Strandberg-Larsen K, Swertz M, Welten M, Wheater S, Burton P (2024). “DataSHIELD: mitigating disclosure risk in a multi-site federated analysis platform.” Bioinformatics Advances, 5(1), 1-21. https://doi.org/10.1093/bioadv/vbaf046.
++Note: Apple Mx architecture users, please be aware that there are some numerical limitations on this platform, which leads to unexpected results when using base R packages, like stats.
+x <- c(0, 3, 7)
+1 - cor(x, x)
+The above should result in a value of zero.
+Also See: For more details see https://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f and the bug report: https://bugs.r-project.org/show_bug.cgi?id=18941
+
if a user sets the parameter 'weights' on the client site function ds.glm this
+
if a user sets the parameter 'weights' on the client side function ds.glm this
server side function is called to verify that the 'weights' vector does not have negative values
because no negative are allowed in weights.
This serverside function check that the server is running in "permissive" privacy control level.
+This server-side function check that the server is running in "permissive" privacy control level.
is a vector of strings which contains the privacy control level names which are permitted by the calling method.
No return value, called for side effects
+Tests whether the R option "datashield.privacyControlLevel" is set to "permissive", if it isn't @@ -63,7 +67,7 @@
Generates a density grid that can then be used for heatmap or countour plots.
+Generates a density grid that can then be used for heatmap or contour plots.
dsBase-package.RdBase 'DataSHIELD' functions for the server side. 'DataSHIELD' is a software package which allows you to do non-disclosive federated analysis on sensitive data. 'DataSHIELD' analytic functions have been designed to only share non disclosive summary statistics, with built in automated output checking based on statistical disclosure control. With data sites setting the threshold values for the automated output checks. For more details, see 'citation("dsBase")'.
+gamlssDS.RdThis is the first serverside aggregate function called by ds.glm
+This is the first server-side aggregate function called by ds.glm
List with values from GLM model.
+It is an @@ -96,11 +100,11 @@
This is the second serverside aggregate function called by ds.glm.
+This is the second server-side aggregate function called by ds.glm.
List with values from GLM model
+It is an aggregate function that uses the model structure and starting @@ -102,11 +106,11 @@
the number of the nearest neghbours for which their centroid is calculated if the +
the number of the nearest neighbours for which their centroid is calculated if the
method.indicator is equal to 1 (i.e. deterministic method).
Computes a heterogenous correlation matrix, consisting of Pearson product-moment +
Computes a heterogeneous correlation matrix, consisting of Pearson product-moment correlations between numeric variables, polyserial correlations between numeric and ordinal variables, and polychoric correlations between ordinal variables.
the number of the nearest neghbours for which their centroid is calculated if the +
the number of the nearest neighbours for which their centroid is calculated if the
method.indicator is equal to 2 (i.e. deterministic method).
gamlssDS an aggregate function called by ds.galmss
gamlssDS an aggregate function called by ds.gamlss
matrixTransposeDS()
matrixTransposeDS serverside assign function called by ds.matrixTranspose
Missing data pattern with disclosure control
Computes statistical mean of a vectores
Computes statistical mean of a vector
Developed by Paul Burton, Rebecca Wilson, Olly Butters, Patricia Ryser-Welch, Alex Westerberg, Leire Abarrategui, Roberto Villegas-Diaz, Demetris Avraam, Yannick Marcon, Stuart Wheater.
+Developed by Paul Burton, Rebecca Wilson, Olly Butters, Patricia Ryser-Welch, Alex Westerberg, Leire Abarrategui, Roberto Villegas-Diaz, Demetris Avraam, Yannick Marcon, Tom Bishop, Amadou Gaye, Xavier Escribà-Montagut, Stuart Wheater.
The first serverside function called by ds.lexis.
+The first server-side function called by ds.lexis.
a character string specifying the variable holding the time that each individual is censored or fails
List with `max.time`
+This is an aggregate function. @@ -73,11 +77,11 @@
a clientside generated character string specifying the variable -holding the IDs of indivuals in the data set to be expanded
List with `expanded.table`
+This is the assign function which actually creates -the expanded dataframe containing surival data for a piecewise exponential +the expanded dataframe containing survival data for a piecewise exponential regression. lexisDS2 also carries out a series of disclosure checks and if the arguments or data fail any of those tests, -creation of the exapanded dataframe is blocked and an appropriate serverside error +creation of the expanded dataframe is blocked and an appropriate serverside error message is stored. For more details see the extensive header for ds.lexis.
lexisDS3()Data frame with `messageobj` object
+This is an assign function that simplifies the @@ -63,11 +67,11 @@
Undertakes standard matrix multiplication where with input matrices A and B with -dimensions A: mxn and B: nxp the output C has dimensions mxp and each elemnt C[i,j] has +dimensions A: mxn and B: nxp the output C has dimensions mxp and each element C[i,j] has value equal to the dot product of row i of A and column j of B where the dot product is obtained as sum(A[i,1]*B[1,j] + A[i,2]*B[2,j] + .... + A[i,n]*B[n,j]). This calculation is only valid if the number of columns of A is the same as the number of rows of B
@@ -87,11 +87,11 @@mdPatternDS.RdThis function is a serverside aggregate function that computes the +missing data pattern using mice::md.pattern and applies disclosure control to +prevent revealing small cell counts.
+mdPatternDS(x)A list containing:
+The missing data pattern matrix with disclosure control applied
Logical indicating if all patterns meet disclosure requirements
A message describing the validity status
This function calls the mice::md.pattern function to generate a matrix +showing the missing data patterns in the input data. To ensure disclosure control, +any pattern counts that are below the threshold (nfilter.tab, default=3) are +suppressed.
+Suppression Method:
+When a pattern count is below threshold: +- Row name is changed to "suppressed(<N>)" where N is the threshold +- All pattern values in that row are set to NA +- Summary row is also set to NA (prevents back-calculation)
+Output Matrix Structure:
+- Rows represent different missing data patterns (plus a summary row at the bottom) +- Row names contain pattern counts (or "suppressed(<N>)" for invalid patterns) +- Columns show 1 if variable is observed, 0 if missing +- Last column shows total number of missing values per pattern +- Last row shows total number of missing values per variable
+Note for Pooling:
+When this function is called from ds.mdPattern with type='combine', suppressed +patterns are excluded from pooling to prevent disclosure through subtraction. +This means pooled counts may underestimate the true total when patterns are +suppressed in some studies.
+meanDS.RdServerside function called by ds.meanSdGp
+Server-side function called by ds.meanSdGp
a clientside supplied character string identifying the variable for which +
a client-side supplied character string identifying the variable for which means/SDs are to be calculated
a clientside supplied character string identifying the factor across +
a client-side supplied character string identifying the factor across which means/SDs are to be calculated
List with results from the group statistics
+Computes the mean and standard deviation across groups defined by one @@ -79,11 +83,11 @@
a list containing the metadata. The elements of the list will depend -on the meatadata available.
+on the metadata available.This argument fixes the length of
-the output repetive sequence vector
+the output repetitive sequence vector
For behaviour see help for ds.rep and "details from native R
help for <rep>" (see above). This parameter is usually fully defined by
the argument <length.out> in the call to ds.rep that itself calls repDS.
the names of the objects to be deleted converted -into transmissable form, a comma seperated list of character string. The +into transmissible form, a comma separated list of character string. The argument is specified via the <x.names> argument of ds.rm
The function uses the R classical subsetting with squared brackets '[]' and allows also to -subset using a logical oprator and a threshold. The object to subset from must be a vector (factor, numeric -or charcater) or a table (data.frame or matrix).
+subset using a logical operator and a threshold. The object to subset from must be a vector (factor, numeric +or character) or a table (data.frame or matrix).a character, if the input data is a table, if this parameter is provided along with the 'logical' and 'threshold' -parameters, a subtable is based the threshold applied to the speicified variable. This parameter is however ignored if the parameter +parameters, a subtable is based the threshold applied to the specified variable. This parameter is however ignored if the parameter 'rows' and/or 'cols' are provided.
a subset of the vector, matric or dataframe as specified is stored on the server side
+a subset of the vector, matrix or dataframe as specified is stored on the server side
If the input data is a table: The user specifies the rows and/or columns to include in the subset if the input -object is a table; the columns can be refered to by their names. The name of a vector (i.e. a variable) can also be provided +object is a table; the columns can be referred to by their names. The name of a vector (i.e. a variable) can also be provided with a logical operator and a threshold (see example 3). If the input data is a vector: when the parameters 'rows', 'logical' and 'threshold' are all provided the last two are ignored ( 'rows' has precedence over the other two parameters then). @@ -124,11 +124,11 @@
The serverside function called by ds.testObjExists
+The server-side function called by ds.testObjExists
List with `test.obj.exists` and `test.obj.class`
+Tests whether a given object exists in @@ -76,11 +80,11 @@