Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
fbdfa42
Permit perf test duration to be set, seconds, by environment variable…
StuartWheater Apr 10, 2026
1f12d53
Permit perf test duration to be set, seconds, by environment variable…
StuartWheater Apr 10, 2026
e75797b
Refactor perf test duration obtaining
StuartWheater Apr 13, 2026
6a1b21f
Merge pull request #468 from StuartWheater/v6.3.6-dev_feat-perf-support
StuartWheater Apr 14, 2026
c4ff561
feat: add server-side functions for ds.standardiseDf
timcadman Apr 21, 2026
dd6133f
Added libuv1-dev to deployment
StuartWheater Apr 21, 2026
3b7b9d4
export functions
timcadman Apr 22, 2026
9f94f63
Merge branch 'datashield:v6.3.6-dev' into v6.3.6-dev
StuartWheater Apr 22, 2026
90b6f86
Update to perf test suppoer and 'libuv1'
StuartWheater Apr 22, 2026
d40d899
Add 'libuv1'
StuartWheater Apr 22, 2026
b01c923
Updated version to 'v6.3.6-dev'
StuartWheater Apr 22, 2026
baab62b
Merge pull request #476 from StuartWheater/v6.3.6-dev
StuartWheater Apr 23, 2026
1ce10e8
Merge branch 'v6.3.6-dev' into v6.3.6-dev-feat/standardise-df
StuartWheater Apr 23, 2026
3c64965
Switched to 'RoxygenNote: 8.0.0'
StuartWheater May 13, 2026
a71a4c0
feat: standardise-df
timcadman May 14, 2026
15dd8c4
Merge branch 'datashield:v6.3.6-dev' into v6.3.6-dev
StuartWheater May 14, 2026
69a7c12
Merge pull request #481 from StuartWheater/v6.3.6-dev
StuartWheater May 14, 2026
9692ef8
Update to documentation
StuartWheater Jul 6, 2026
b288a3a
Updates due to testthats removal of context(...)
StuartWheater Jul 6, 2026
d6c761e
Merge pull request #491 from StuartWheater/v6.3.6-dev
StuartWheater Jul 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
sudo apt-get install -y r-base-core cmake
- run:
command: |
sudo apt-get install -y libxml2-dev
sudo apt-get install -y libxml2-dev libuv1-dev
- run:
command: |
echo "options(Ncpus=4)" >> ~/.Rprofile
Expand Down
11 changes: 7 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Description: Base 'DataSHIELD' functions for the server side. 'DataSHIELD' is a
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")'.
Version: 6.3.5
Version: 6.3.6.9000
Authors@R: c(person(given = "Paul",
family = "Burton",
role = c("aut"),
Expand Down Expand Up @@ -59,12 +59,15 @@ Authors@R: c(person(given = "Paul",
comment = c(ORCID = "0009-0003-2419-1964")))
License: GPL-3
Depends:
R (>= 4.0.0)
R (>= 4.1.0)
Imports:
RANN,
stringr,
lme4,
dplyr,
tibble,
purrr,
tidyselect,
reshape2,
polycor (>= 0.8),
splines,
Expand All @@ -74,7 +77,7 @@ Imports:
childsds
Suggests:
spelling,
testthat
RoxygenNote: 7.3.3
testthat (>= 3.0.0)
RoxygenNote: 8.0.0
Encoding: UTF-8
Language: en-GB
15 changes: 15 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ export(dmtC2SDS)
export(elsplineDS)
export(extractQuantilesDS1)
export(extractQuantilesDS2)
export(fixClassDS)
export(fixColsDS)
export(fixLevelsDS)
export(gamlssDS)
export(getAllLevelsDS)
export(getClassAllColsDS)
export(getWGSRDS)
export(glmDS1)
export(glmDS2)
Expand Down Expand Up @@ -139,5 +144,15 @@ import(dplyr)
import(gamlss)
import(gamlss.dist)
import(mice)
importFrom(dplyr,"%>%")
importFrom(dplyr,across)
importFrom(dplyr,mutate)
importFrom(dplyr,select)
importFrom(gamlss.dist,pST3)
importFrom(gamlss.dist,qST3)
importFrom(purrr,imap)
importFrom(purrr,map)
importFrom(purrr,set_names)
importFrom(tibble,as_tibble)
importFrom(tidyselect,all_of)
importFrom(tidyselect,peek_vars)
133 changes: 133 additions & 0 deletions R/standardiseDfDS.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#' Get the Class of All Columns in a Data Frame
#' @param df.name A string representing the name of the data frame.
#' @return A tibble with the class of each column in the data frame.
#' @importFrom dplyr %>%
#' @importFrom tibble as_tibble
#' @importFrom purrr map
#' @export
getClassAllColsDS <- function(df.name){
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))

df.name <- eval(parse(text = df.name), envir = parent.frame())
all_classes <- map(df.name, class) %>% as_tibble()
return(all_classes)
}

#' Change Class of Target Variables in a Data Frame
#' @param df.name A string representing the name of the data frame.
#' @param target_vars A character vector specifying the columns to be modified.
#' @param target_class A character vector specifying the new classes for each column (1 = factor,
#' 2 = integer, 3 = numeric, 4 = character, 5 = logical).
#' @return A modified data frame with the specified columns converted to the target classes.
#' @importFrom dplyr mutate across
#' @importFrom tidyselect all_of
#' @export
fixClassDS <- function(df.name, target_vars, target_class) {
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))

df <- eval(parse(text = df.name), envir = parent.frame())
df_transformed <- df %>%
mutate(
across(all_of(target_vars),
~ .convertClass(.x, target_class[which(target_vars == cur_column())])))
return(df_transformed)
}

#' Convert a Vector to a Specified Class
#' @param x The vector to be converted.
#' @param class_name A string indicating the target class (1 = factor, 2 = integer, 3 = numeric,
#' 4 = character, 5 = logical).
#' @return The converted vector.
#' @noRd
.convertClass <- function(target_var, target_class_code) {
switch(target_class_code,
"1" = as.factor(target_var),
"2" = as.integer(target_var),
"3" = as.numeric(target_var),
"4" = as.character(target_var),
"5" = as.logical(target_var)
)
}

#' Add Missing Columns with NA Values
#' @param .data A string representing the name of the data frame.
#' @param cols A character vector specifying the columns to be added if missing.
#' @return A modified data frame with missing columns added and filled with NA.
#' @importFrom dplyr mutate select
#' @importFrom tidyselect peek_vars
#' @importFrom purrr set_names
#' @export
fixColsDS <- function(.data, cols) {
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))

.data <- eval(parse(text = .data), envir = parent.frame())
missing <- setdiff(cols, colnames(.data))
out <- .data %>%
mutate(!!!set_names(rep(list(NA), length(missing)), missing)) %>%
select(sort(peek_vars()))
return(out)
}

#' Retrieve Factor Levels for Specific Columns
#' @param df.name A string representing the name of the data frame.
#' @param factor_vars A character vector specifying the factor columns.
#' @return A list of factor levels for the specified columns.
#' @importFrom tidyselect all_of
#' @importFrom purrr map imap
#' @export
getAllLevelsDS <- function(df.name, factor_vars) {
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))

df <- eval(parse(text = df.name), envir = parent.frame())
factor_vars_split <- strsplit(factor_vars, ",\\s*")[[1]]
levels <- purrr::map(df[factor_vars_split], base::levels)

disclosure_check <- imap(levels, function(lvls, var) {
.checkLevelsDisclosure(df = df, var = var, levels = lvls)
})

failed_vars <- names(disclosure_check)[unlist(disclosure_check)]

if(length(failed_vars) > 0) {
stop("Based on the value of nfilter.levels.density, these factor variables", " {", failed_vars, "} ", "have too many levels compared to the length of the variable. Please reduce the numnber of levels or change the variable type and try again")
} else {
return(levels)
}
}

#' Check variable levels against disclosure thresholds
#'
#' Internal helper function to verify whether the number of levels in a variable
#' exceeds the allowed density threshold defined by `dsBase::listDisclosureSettingsDS()`.
#'
#' @param df A data frame containing the variable.
#' @param var Character string. Name of the variable to check.
#' @param levels Character vector. Levels of the variable.
#'
#' @return Logical. `TRUE` if the check fails (i.e., disclosure threshold is violated),
#' otherwise `FALSE`.
#'
#' @keywords internal
#' @noRd
.checkLevelsDisclosure <- function(df, var, levels) {
thr <- dsBase::listDisclosureSettingsDS()
nfilter.levels.density <- as.numeric(thr$nfilter.levels.density)
n_levels <- length(levels)
length_var <- length(df[[var]])
fail <- (length_var * nfilter.levels.density) < n_levels
return(fail)
}

#' Set Factor Levels for Specific Columns in a Data Frame
#' @param df.name A string representing the name of the data frame to modify.
#' @param vars A character vector specifying the columns to be modified.
#' @param levels A named list where each element contains the levels for the corresponding factor variable.
#' @return A modified data frame with the specified columns converted to factors with the provided levels.
#' @export
fixLevelsDS <- function(df.name, vars, levels) {
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))

df.name <- eval(parse(text = df.name), envir = parent.frame())
out <- df.name %>%
mutate(across(all_of(vars), ~factor(., levels = levels[[dplyr::cur_column()]])))
}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ And the development version from
install.packages("remotes")
remotes::install_github("datashield/dsBase", "<BRANCH>")

# Install v6.3.4 with the following
remotes::install_github("datashield/dsBase", "6.3.4")
# Install v6.3.6 with the following
remotes::install_github("datashield/dsBase", "6.3.6")
```

For a full list of development branches, checkout https://github.com/datashield/dsBase/branches
Expand Down
1 change: 1 addition & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
template:
bootstrap: 5
params:
bootswatch: simplex
2 changes: 1 addition & 1 deletion azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ jobs:

sudo apt-get install -qq pkg-config -y
sudo apt-get install -qq libxml2-dev libcurl4-openssl-dev libssl-dev libgit2-dev libharfbuzz-dev libfribidi-dev libfontconfig1-dev -y
sudo apt-get install -qq libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev -y
sudo apt-get install -qq libfreetype6-dev libpng-dev libtiff5-dev libjpeg-dev libuv1-dev -y
sudo apt-get install -qq r-base -y
sudo R -e "install.packages('devtools', dependencies=TRUE)"
sudo R -e "install.packages('RANN', dependencies=TRUE)"
Expand Down
98 changes: 39 additions & 59 deletions docs/404.html

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

3 changes: 3 additions & 0 deletions docs/404.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Content not found. Please use links in the navbar.

# Page not found (404)
Loading
Loading