From d22ebb3fc5a47bb7d9874b6b824ce44e53f76d6f Mon Sep 17 00:00:00 2001 From: Tim Cadman <41470917+timcadman@users.noreply.github.com> Date: Thu, 15 Oct 2026 16:48:00 +0200 Subject: [PATCH 1/3] Remove references to defunct functions --- .Rbuildignore | 1 - DESCRIPTION | 3 +- R/colPercent.R | 22 -- R/ds.dataFrameFill.R | 180 +------------ R/ds.extractQuantiles.R | 241 ----------------- R/ds.listOpals.R | 31 +-- R/ds.listServersideFunctions.R | 80 +----- R/ds.look.R | 114 +------- R/ds.meanByClass.R | 133 +-------- R/ds.message.R | 104 +------- R/ds.recodeLevels.R | 138 +--------- R/ds.setDefaultOpals.R | 45 +--- R/ds.subset.R | 176 +----------- R/ds.subsetByClass.R | 126 +-------- R/ds.table1D.R | 180 +------------ R/ds.table2D.R | 252 +----------------- R/ds.testObjExists.R | 160 +---------- R/ds.vectorCalc.R | 96 +------ R/isAssigned.R | 24 -- R/meanByClassHelper0a.R | 46 ---- R/meanByClassHelper0b.R | 93 ------- R/meanByClassHelper1.R | 37 --- R/meanByClassHelper2.R | 93 ------- R/meanByClassHelper3.R | 75 ------ R/meanByClassHelper4.R | 38 --- R/rowPercent.R | 22 -- R/secure.global.ranking.md | 87 ------ R/subsetHelper.R | 76 ------ man/ds.dataFrameFill.Rd | 87 +----- man/ds.listOpals.Rd | 24 +- man/ds.listServersideFunctions.Rd | 60 +---- man/ds.look.Rd | 79 +----- man/ds.meanByClass.Rd | 96 +------ man/ds.message.Rd | 78 +----- man/ds.recodeLevels.Rd | 75 +----- man/ds.setDefaultOpals.Rd | 38 +-- man/ds.subset.Rd | 99 +------ man/ds.subsetByClass.Rd | 70 +---- man/ds.table1D.Rd | 80 +----- man/ds.table2D.Rd | 107 +------- man/ds.testObjExists.Rd | 64 +---- man/ds.vectorCalc.Rd | 48 +--- man/figures/lifecycle-deprecated.svg | 21 ++ .../armadillo_azure-pipeline_perf-profile.csv | 1 - ...rmadillo_github-workflows_perf-profile.csv | 1 - .../armadillo_hp-laptop-quay_perf-profile.csv | 1 - .../opal_azure-pipeline_perf-profile.csv | 1 - .../opal_github-workflows_perf-profile.csv | 1 - .../smk_expt-results/ds.ranksSecure-cont.rds | Bin 341 -> 0 bytes .../ds.ranksSecure-cont_nas.rds | Bin 341 -> 0 bytes .../ds.ranksSecure-cont_nas_neg.rds | Bin 343 -> 0 bytes .../ds.ranksSecure-cont_neg.rds | Bin 343 -> 0 bytes tests/testthat/test-arg-ds.dataFrameFill.R | 33 --- tests/testthat/test-arg-ds.look.R | 31 --- tests/testthat/test-arg-ds.meanByClass.R | 39 --- tests/testthat/test-arg-ds.message.R | 31 --- tests/testthat/test-arg-ds.recodeLevels.R | 34 --- tests/testthat/test-arg-ds.subset.R | 31 --- tests/testthat/test-arg-ds.subsetByClass.R | 32 --- tests/testthat/test-arg-ds.table1D.R | 32 --- tests/testthat/test-arg-ds.table2D.R | 31 --- tests/testthat/test-arg-ds.testObjExists.R | 33 --- tests/testthat/test-arg-ds.vectorCalc.R | 32 --- tests/testthat/test-disc-ds.meanByClass.R | 41 --- .../testthat/test-discctrl-ds.recodeLevels.R | 54 ---- tests/testthat/test-discctrl-ds.subset.R | 50 ---- .../testthat/test-discctrl-ds.subsetByClass.R | 54 ---- tests/testthat/test-perf-ds.dataFrameFill.R | 50 ---- tests/testthat/test-smk-ds.asFactor.R | 20 +- tests/testthat/test-smk-ds.asFactorSimple.R | 4 +- tests/testthat/test-smk-ds.changeRefGroup.R | 2 +- .../test-smk-ds.dataFrameFill-donothing.R | 61 ----- .../test-smk-ds.dataFrameFill-factor.R | 182 ------------- tests/testthat/test-smk-ds.dataFrameFill.R | 115 -------- .../test-smk-ds.listServersideFunctions.R | 87 ------ tests/testthat/test-smk-ds.look.R | 51 ---- tests/testthat/test-smk-ds.meanByClass.R | 123 --------- tests/testthat/test-smk-ds.message.R | 106 -------- tests/testthat/test-smk-ds.recodeLevels.R | 70 ----- tests/testthat/test-smk-ds.subset.R | 92 ------- tests/testthat/test-smk-ds.subsetByClass.R | 79 ------ tests/testthat/test-smk-ds.table1D.R | 102 ------- tests/testthat/test-smk-ds.table2D.R | 68 ----- .../test-smk-ds.testObjExists-discordant.R | 71 ----- tests/testthat/test-smk-ds.testObjExists.R | 104 -------- tests/testthat/test-smk-ds.vectorCalc.R | 70 ----- tests/testthat/test-smk_bug-ds.listOpals.R | 34 --- .../test-smk_dgr-ds.listServersideFunctions.R | 89 ------- tests/testthat/test-smk_expt-ds.ranksSecure.R | 86 ------ 89 files changed, 236 insertions(+), 5692 deletions(-) delete mode 100644 R/colPercent.R delete mode 100644 R/ds.extractQuantiles.R delete mode 100644 R/isAssigned.R delete mode 100644 R/meanByClassHelper0a.R delete mode 100644 R/meanByClassHelper0b.R delete mode 100644 R/meanByClassHelper1.R delete mode 100644 R/meanByClassHelper2.R delete mode 100644 R/meanByClassHelper3.R delete mode 100644 R/meanByClassHelper4.R delete mode 100644 R/rowPercent.R delete mode 100644 R/secure.global.ranking.md delete mode 100644 R/subsetHelper.R create mode 100644 man/figures/lifecycle-deprecated.svg delete mode 100644 tests/testthat/smk_expt-results/ds.ranksSecure-cont.rds delete mode 100644 tests/testthat/smk_expt-results/ds.ranksSecure-cont_nas.rds delete mode 100644 tests/testthat/smk_expt-results/ds.ranksSecure-cont_nas_neg.rds delete mode 100644 tests/testthat/smk_expt-results/ds.ranksSecure-cont_neg.rds delete mode 100644 tests/testthat/test-arg-ds.dataFrameFill.R delete mode 100644 tests/testthat/test-arg-ds.look.R delete mode 100644 tests/testthat/test-arg-ds.meanByClass.R delete mode 100644 tests/testthat/test-arg-ds.message.R delete mode 100644 tests/testthat/test-arg-ds.recodeLevels.R delete mode 100644 tests/testthat/test-arg-ds.subset.R delete mode 100644 tests/testthat/test-arg-ds.subsetByClass.R delete mode 100644 tests/testthat/test-arg-ds.table1D.R delete mode 100644 tests/testthat/test-arg-ds.table2D.R delete mode 100644 tests/testthat/test-arg-ds.testObjExists.R delete mode 100644 tests/testthat/test-arg-ds.vectorCalc.R delete mode 100644 tests/testthat/test-disc-ds.meanByClass.R delete mode 100644 tests/testthat/test-discctrl-ds.recodeLevels.R delete mode 100644 tests/testthat/test-discctrl-ds.subset.R delete mode 100644 tests/testthat/test-discctrl-ds.subsetByClass.R delete mode 100644 tests/testthat/test-perf-ds.dataFrameFill.R delete mode 100644 tests/testthat/test-smk-ds.dataFrameFill-donothing.R delete mode 100644 tests/testthat/test-smk-ds.dataFrameFill-factor.R delete mode 100644 tests/testthat/test-smk-ds.dataFrameFill.R delete mode 100644 tests/testthat/test-smk-ds.listServersideFunctions.R delete mode 100644 tests/testthat/test-smk-ds.look.R delete mode 100644 tests/testthat/test-smk-ds.meanByClass.R delete mode 100644 tests/testthat/test-smk-ds.message.R delete mode 100644 tests/testthat/test-smk-ds.recodeLevels.R delete mode 100644 tests/testthat/test-smk-ds.subset.R delete mode 100644 tests/testthat/test-smk-ds.subsetByClass.R delete mode 100644 tests/testthat/test-smk-ds.table1D.R delete mode 100644 tests/testthat/test-smk-ds.table2D.R delete mode 100644 tests/testthat/test-smk-ds.testObjExists-discordant.R delete mode 100644 tests/testthat/test-smk-ds.testObjExists.R delete mode 100644 tests/testthat/test-smk-ds.vectorCalc.R delete mode 100644 tests/testthat/test-smk_bug-ds.listOpals.R delete mode 100644 tests/testthat/test-smk_dgr-ds.listServersideFunctions.R delete mode 100644 tests/testthat/test-smk_expt-ds.ranksSecure.R diff --git a/.Rbuildignore b/.Rbuildignore index 39edb6391..b256292c4 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -14,7 +14,6 @@ ^docker-compose_armadillo\.yml$ ^docker-compose_opal\.yml$ ^docker-compose\.yml$ -^R/secure.global.ranking.md$ ^_pkgdown\.yml$ ^docs$ ^dsBase_7.0.0\.tar\.gz$ diff --git a/DESCRIPTION b/DESCRIPTION index 9cb98d931..7d3ff5199 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -76,7 +76,8 @@ Imports: data.table, methods, dplyr, - cli + cli, + lifecycle Suggests: lme4, httr, diff --git a/R/colPercent.R b/R/colPercent.R deleted file mode 100644 index 9aeb92c81..000000000 --- a/R/colPercent.R +++ /dev/null @@ -1,22 +0,0 @@ -#' -#' @title Produces column percentages -#' @description this is an INTERNAL function. -#' @details The function is required required by the client function \code{ds.table2D}. -#' @param dataframe a data frame -#' @keywords internal -#' @return a data frame -#' @author Gaye, A. -#' -colPercent <- function(dataframe){ - dt <- dataframe - lastcol <- dim(dataframe)[2] - lastrow <- dim(dataframe)[1] - for(i in 1:lastcol){ - totalval <- dataframe[lastrow,i] - dt[,i] <- round((dataframe[,i]/totalval)*100,2) - } - return(dt) -} - - - diff --git a/R/ds.dataFrameFill.R b/R/ds.dataFrameFill.R index 59caf5b0a..e79ca6947 100644 --- a/R/ds.dataFrameFill.R +++ b/R/ds.dataFrameFill.R @@ -1,176 +1,14 @@ -#' #' @title Creates missing values columns in the server-side -#' @description Adds extra columns with missing values in a data frame on the server-side. -#' @details This function checks if the input data frames have the same variables (i.e. the same -#' column names) in all of the used studies. When a study does not have some of the variables, the -#' function generates those variables as vectors of missing values and combines them as columns to -#' the input data frame. If any of the generated variables are of class factor, the function -#' assigns to those the corresponding levels of the factors given from the studies where such -#' factors exist. -#' -#' Server function called: \code{dataFrameFillDS} -#' @param df.name a character string representing the name of the input data frame that will be -#' filled with extra columns of missing values. -#' @param newobj a character string that provides the name for the output data frame -#' that is stored on the data servers. Default value is "dataframefill.newobj". -#' @param classConsistencyCheck logical. If TRUE, verifies that each input object has the same class across all studies. Default TRUE. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. -#' If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @return \code{ds.dataFrameFill} returns the object specified by the \code{newobj} argument which -#' is written to the server-side. +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `ds.standardiseDf()` instead. +#' @param ... Not used. #' @author Demetris Avraam for DataSHIELD Development Team #' @author Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -#' -#' @examples -#' \dontrun{ -#' -#' ## Version 6, for version 5 see the Wiki -#' # Connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') -#' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "CNSIM.CNSIM2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' -#' logindata <- builder$build() -#' -#' # Log onto the remote Armadillo/Opal training servers -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' # Create two data frames with one different column -#' -#' ds.dataFrame(x = c("D$LAB_TSC","D$LAB_TRIG","D$LAB_HDL", -#' "D$LAB_GLUC_ADJUSTED","D$PM_BMI_CONTINUOUS"), -#' newobj = "df1", -#' datasources = connections[1]) -#' -#' ds.dataFrame(x = c("D$LAB_TSC","D$LAB_TRIG","D$LAB_HDL","D$LAB_GLUC_ADJUSTED"), -#' newobj = "df1", -#' datasources = connections[2]) -#' -#' # Fill the data frame with NA columns -#' -#' ds.dataFrameFill(df.name = "df1", -#' newobj = "D.Fill", -#' datasources = connections[c(1,2)]) # Two servers are used -#' -#' -#' # Clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' } +#' @md +#' @keywords internal #' @export -#' -ds.dataFrameFill <- function(df.name=NULL, newobj=NULL, datasources=NULL, classConsistencyCheck=TRUE){ - - datasources <- .set_datasources(datasources) - - # check if user has provided the name of the data.frame to be subsetted - if(is.null(df.name)){ - stop("Please provide the name of the data.frame to be filled as a character string: eg 'xxx'", call.=FALSE) - } - - # if no value spcified for output object, then specify a default - if(is.null(newobj)){ - newobj <- "dataframefill.newobj" - } - - if(classConsistencyCheck){ - # call the internal function that checks the input object is of the same class in all studies. - typ <- checkClass(datasources, df.name) - - # if the input object is not a matrix or a dataframe stop - if(!('data.frame' %in% typ) && !('matrix' %in% typ)){ - stop("The input vector must be of type 'data.frame' or a 'matrix'!", call.=FALSE) - } - } - - column.names <- lapply(datasources, function(dts){DSI::datashield.aggregate(dts, call("colnamesDS", df.name))}) - - allNames <- unique(unlist(column.names)) - - # if the datasets share the same variables then the function stops - check.indicator <- c() - for (i in 1:length(datasources)){ - if(length(setdiff(allNames,column.names[[i]])) > 0){ - check.indicator[i] <- 1 - }else{ - check.indicator[i] <- 0} - } - - if(sum(check.indicator)==0){ - stop("The dataframes have the same variables. There are no missing variables to fill!", call.=FALSE) - } - - if(!is.null(allNames)){ - allNames.transmit <- paste(allNames,collapse=",") - }else{ - allNames.transmit <- NULL - } - - defined.list <- lapply(allNames, function(x){isDefined(datasources=datasources, obj=paste0(df.name, '$', x), error.message=FALSE)}) - defined.vect1 <- lapply(defined.list, function(x){unlist(x)}) - defined.vect2 <- lapply(defined.vect1, function(x){which(x == FALSE)}) - - # get the class of each variable in the dataframes, skipping servers where the column doesn't exist - class.list <- lapply(seq_along(allNames), function(idx){ - sapply(seq_along(datasources), function(ds_idx){ - if(ds_idx %in% defined.vect2[[idx]]){ - "NULL" - } else { - DSI::datashield.aggregate(datasources[ds_idx], call('classDS', paste0(df.name, '$', allNames[idx])))[[1]] - } - }) - }) - class.vect1 <- class.list - # the loop below is to avoid autocompletion of variable name - for (i in 1:length(allNames.transmit)){ - if(length(defined.vect2[[i]])>0){class.vect1[[i]][defined.vect2[[i]]]<-'NULL'} - } - class.vect2 <- lapply(class.vect1, function(x){x[which(x != 'NULL')[[1]]]}) - class.vect2 <- unname(unlist(class.vect2)) - - # check if any of the elements in class.vect2 are factor - # and if yes then get their levels - df.indicator <- list() - levels.vec <- list() - if(length(class.vect2)>0){ - anyFactors <- allNames[which(class.vect2 == 'factor')] - if(length(anyFactors)>0){ - for(i in 1:length(anyFactors)){ - df.indicator[[i]] <- lapply(column.names, function(x){is.element(anyFactors[i],unlist(x))}) - } - df.indicator.index <- lapply(df.indicator, function(x){which(x==TRUE)}) - for(i in 1:length(anyFactors)){ - levels.vec[[i]] <- dsBaseClient::ds.levels(x=paste0(df.name, '$', anyFactors[i]), datasources=datasources[df.indicator.index[[i]]]) - levels.vec[[i]] <- as.numeric(levels.vec[[i]][[1]][[1]]) - } - } - } - levels.vec.transmit <- unlist(lapply(levels.vec, function(x){paste(x,collapse=",")})) - - if(!is.null(class.vect2)){ - class.vect.transmit <- paste(class.vect2,collapse=",") - }else{ - class.vect.transmit <- NULL - } - - calltext <- call("dataFrameFillDS", df.name, allNames.transmit, class.vect.transmit, levels.vec.transmit) - DSI::datashield.assign(datasources, newobj, calltext) - - +ds.dataFrameFill <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.dataFrameFill()", "ds.standardiseDf()") } -# ds.dataFrameFill diff --git a/R/ds.extractQuantiles.R b/R/ds.extractQuantiles.R deleted file mode 100644 index 68900f8f3..000000000 --- a/R/ds.extractQuantiles.R +++ /dev/null @@ -1,241 +0,0 @@ -# ds.extractQuantiles -#' @title Secure ranking of a vector across all sources and use of these ranks -#' to estimate global quantiles across all studies -#' @description Takes the global ranks and quantiles held in the serverside data -#' data frame that is written by ranksSecureDS4 and named as specified by the -#' argument () and converts these values into a series of -#' quantile values that identify, for example, which value of V2BR across all of -#' the studies corresponds to the median or to the 95% quantile. There is no -#' indication in which study the V2BR corresponding to a particular quantile -#' falls and, in fact, the relevant value may fall in more than one study and -#' may appear multiple times in any one study. Finally, the output data -#' frame containing this information is written to the clientside and to the -#' serverside at each study separately. -#' @details ds.extractQuantiles is a clientside function which should usually -#' be called from within the clientside function ds.ranksSecure.If you try to -#' call ds.extractQuantiles directly(i.e. not by running ds.ranksSecure) you -#' are almost certainly going to have to set up quite a few vectors and scalars -#' that are normally set by ds.ranksSecure and this is likely to be difficult. -#' ds.extractQuantiles itself calls two serverside functions extractQuantilesDS1 -#' and extractQuantilesDS2. For more details about the cluster of functions that -#' collectively enable secure global ranking and estimation of global quantiles -#' see the associated document entitled "secure.global.ranking.docx". In -#' particular this explains how ds.extractQuantiles works. Also see the header -#' file for ds.ranksSecure. -#' @param extract.quantiles one of a restricted set of character strings. -#' The value of this argument is set in choosing the value of the argument -#' in ds.ranksSecure. In summary: to mitigate -#' disclosure risk only the following set of quantiles can be -#' generated: c(0.025,0.05,0.10,0.20,0.25,0.30,0.3333,0.40,0.50,0.60,0.6667, -#' 0.70,0.75,0.80,0.90,0.95,0.975). The allowable formats for the argument -#' are of the general form: "0.025-0.975" where the first number is the lowest -#' quantile to be estimated and the second number is the equivalent highest -#' quantile to estimate. These two quantiles are then estimated along with -#' all allowable quantiles in between. The allowable argument values are then: -#' "0.025-0.975", "0.05-0.95", "0.10-0.90", "0.20-0.80". Two alternative values -#' are "quartiles" i.e. c(0.25,0.50,0.75), and "median" i.e. c(0.50). The -#' default value is "0.05-0.95". For more details, see the associated document -#' "secure.global.ranking.docx". Also see the header file for ds.ranksSecure. -#' @param extract.summary.output.ranks.df a character string which specifies -#' the optional name for the summary data.frame written to the serverside on -#' each data source that contains 5 of the key output variables from the ranking -#' procedure pertaining to that particular data source. If no name has been -#' specified by the argument in ds.ranksSecure, the -#' default name is allocated as "summary.ranks.df".The only reason the -#' argument needs specifying in -#' ds.extractQuantiles is because, ds.extractQuantiles is the last function -#' called by ds.ranksSecure and almost the final command of ds.extractQuantiles -#' to print out the name of the data frame containing the summarised ranking -#' information generated by ds.ranksSecure and the order in which the -#' data frame is laid out. This therefore appears as the last output produced -#' when ds.ranksSecure is run, and when this happens it is clear this relates to -#' the main output of ds.ranksSecure not of ds.extractQuantiles. -#' @param extract.ranks.sort.by a character string taking two possible values. -#' These are "ID.orig" and "vals.orig". This is set via the argument -#' in ds.ranksSecure. For more details see the associated -#' document entitled "secure.global.ranking.docx". Also see the header -#' file for ds.ranksSecure. -#' @param extract.rm.residual.objects logical value. Default = TRUE: at the beginning -#' and end of each run of ds.ranksSecure delete all extraneous objects that are -#' otherwise left behind. These are not usually needed, but could be of value -#' if one were investigating a problem with the ranking. FALSE: do not delete -#' the residual objects -#' @param extract.datasources specifies the particular connection object(s) to use. -#' This is set via the argument in ds.ranksSecure. For more details -#' see the associated document entitled "secure.global.ranking.docx". Also see -#' the header file for ds.ranksSecure. -#' @return the final main output of ds.extractQuantiles is a data frame object -#' named "final.quantile.df". This contains two vectors. The first named -#' "evaluation.quantiles" lists the full set of quantiles you have requested -#' for evaluation as specified by the argument "quantiles.for.estimation" in -#' ds.ranksSecure and explained in more detail above under the information for -#' the argument "extract.quantiles" in this function. The second vector is -#' called "final.quantile.vector" which details the values of V2BR that -#' correspond to the evaluation quantiles in vector 1. The information in the -#' data frame "final.quantile.df" is generic: there is no information -#' identifying in which study each value of V2BR falls. This data frame is -#' written to the clientside (as it is non-disclosive) and is also copied to -#' the serverside in every study. This means it is easily accessible from -#' anywhere in the DataSHIELD environment. For more details -#' see the associated document entitled "secure.global.ranking.docx". -#' @author Paul Burton 11th November, 2021 - - ds.extractQuantiles <- function(extract.quantiles, - extract.summary.output.ranks.df, - extract.ranks.sort.by, - extract.rm.residual.objects, - extract.datasources=NULL){ - - # look for DS connections - if(is.null(extract.datasources)){ - datasources <- datashield.connections_find() - } - -datasources.in.current.function<-datasources - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - numstudies<-length(datasources) - - - #AFTER RUNNING ds.ranksSecure USE extractQuantilesDS1 (serverside aggregate) - #FUNCTION TO CREATE STUDY SPECIFIC BOUNDS OF NEAREST - #QUANTILES ABOVE AND BELOW EACH EVALUATION THRESHOLD AND TO WRITE - #EVALUATON QUANTILES AND STUDY-SPECIFIC BOUNDS AROUND EACH VALUE AS A - #NEW OBJECT. EVALUATION QUANTILES ARE SET ON SERVERSIDE AND CANNOT BE CHANGED - #FROM CLIENTSIDE. FULL RANGE POSSIBLE IS: - # c(0.025,0.05,0.10,0.20,0.25,0.30,0.3333,0.40,0.50, - # 0.60,0.6667,0.70,0.75,0.80,0.90,0.95,0.975) - - - calltext8 <- call("extractQuantilesDS1",extract.quantiles, - extract.summary.output.ranks.df) - closest.bounds.df<-DSI::datashield.aggregate(datasources,calltext8) - - - - - lower.bound.matrix<-matrix(NA,nrow=nrow(closest.bounds.df[[1]]),ncol=numstudies) - upper.bound.matrix<-matrix(NA,nrow=nrow(closest.bounds.df[[1]]),ncol=numstudies) - - for(ss in 1:numstudies) - { - lower.bound.matrix[,ss]<-closest.bounds.df[[ss]]$lower.bound - upper.bound.matrix[,ss]<-closest.bounds.df[[ss]]$upper.bound - } - - numvals<-length(lower.bound.matrix[,1]) - - lower.bound.vector<-rep(NA,numvals) - upper.bound.vector<-rep(NA,numvals) - - for(vv in 1:numvals){ - lower.bound.vector[vv]<-max(lower.bound.matrix[vv,]) - upper.bound.vector[vv]<-min(upper.bound.matrix[vv,]) - } - - evaluation.quantiles<-closest.bounds.df[[1]]$evaluation.quantiles - - - global.bounds.df<-data.frame(cbind(evaluation.quantiles,lower.bound.vector,upper.bound.vector)) - - colnames(global.bounds.df)[1]<-"evaluation.quantiles" - - global.bounds.df - - #CALL CLIENTSIDE FUNCTION ds.dmtC2S TO RETURN global.bounds.df TO SERVERSIDE - dsBaseClient::ds.dmtC2S(dfdata=global.bounds.df,newobj="global.bounds.df",datasources = datasources.in.current.function) - - calltext9 <- call("extractQuantilesDS2",extract.summary.output.ranks.df) - R.global.bounds<-DSI::datashield.aggregate(datasources,calltext9) - - - numvals<-length(R.global.bounds[[1]]$relevant.study.specific.input.values.lower) - - for(xx in 1:numvals){ - all.lower.values.na<-1 - all.upper.values.na<-1 - for(tt in 1:length(R.global.bounds)){ - if(!is.na(R.global.bounds[[tt]]$relevant.study.specific.input.values.lower[xx]))all.lower.values.na<-0 - if(!is.na(R.global.bounds[[tt]]$relevant.study.specific.input.values.upper[xx]))all.upper.values.na<-0 - } - if(all.lower.values.na==1||all.upper.values.na==1){ - error.message<- - paste0("FAILED: one of the extreme quantile estimates is NA probably because of a cluster of values at one end of the range of possible values. Try setting a narrower range of quantile values via the argument") - stop(error.message, call. = FALSE) - } - - } - - - final.quantile.value.vector.lower<-rep(NA,numvals) - final.quantile.value.vector.upper<-rep(NA,numvals) - - - for(vv in 1:numvals){ - for(ss in 1:numstudies){ - if(!is.na(R.global.bounds[[ss]]$relevant.study.specific.input.values.lower[vv]) ) - { - final.quantile.value.vector.lower[vv]<-R.global.bounds[[ss]]$relevant.study.specific.input.values.lower[vv] - } - - - if(!is.na(R.global.bounds[[ss]]$relevant.study.specific.input.values.upper[vv]) ) - { - final.quantile.value.vector.upper[vv]<-R.global.bounds[[ss]]$relevant.study.specific.input.values.upper[vv] - } - } - } - - final.quantile.vector<-rep(NA,numvals) - - for(ww in 1:numvals) - { - final.quantile.vector[ww]<-signif(mean(final.quantile.value.vector.lower[ww],final.quantile.value.vector.upper[ww]),6) - - } - - - final.quantile.df<-data.frame(cbind(evaluation.quantiles,final.quantile.vector)) - - final.quantile.df - - #CLEAN UP UNWANTED RESIDUAL OBJECTS FROM THE RUNNING OF ds.extractQuantiles - - if(extract.rm.residual.objects) - { - #UNLESS THE IS FALSE, - #CLEAR UP ANY UNWANTED RESIDUAL OBJECTS - - rm.names.eQ<-c("global.bounds.df") - - #make transmittable via parser - rm.names.eQ.transmit <- paste(rm.names.eQ,collapse=",") - - calltext.rm.eQ <- call("rmDS", rm.names.eQ.transmit) - - rm.output.eQ <- DSI::datashield.aggregate(datasources, calltext.rm.eQ) - - } - - #CALL CLIENTSIDE FUNCTION ds.dmtC2S TO RETURN final.quantile.df TO SERVERSIDE - dsBaseClient::ds.dmtC2S(dfdata=final.quantile.df,newobj="final.quantile.df",datasources = datasources.in.current.function) - - message("\n\n\n"," FINAL RANKING PROCEDURES COMPLETE: - PRIMARY RANKING OUTPUT IS IN DATA FRAME",extract.summary.output.ranks.df, -" - WHICH IS SORTED BY",extract.ranks.sort.by," AND HAS BEEN - WRITTEN TO THE SERVERSIDE. VALUES OF V2BR CORRESPONDING TO - KEY QUANTILES HAVE BEEN WRITTEN TO BOTH CLIENTSIDE AND - SERVERSIDE AS final.quantile.df\n\n\n\n") - - - return(final.quantile.df) -} - -########################################## -#ds.extractQuantiles - diff --git a/R/ds.listOpals.R b/R/ds.listOpals.R index 310baef56..3581a90a3 100644 --- a/R/ds.listOpals.R +++ b/R/ds.listOpals.R @@ -1,26 +1,13 @@ -#' #' @title Lists all Opal objects in the analytic environment -#' @description ds.listOpals calls the internal DataSHIELD function getOpals() which identifies -#' all Opal objects in the analytic environment. -#' @details ds.listOpals calls the internal DataSHIELD function getOpals() which identifies -#' all Opal objects in the analytic environment. If there are no Armadillo/Opal servers in the analytic -#' environment ds.listOpalsIreminds the user that they have to login to a valid set of Opal -#' login objects, if they wish to use DataSHIELD. If there is only one set of Opals, ds.listOpals -#' copies that one set and names the copy 'default.opals'. This default set will then be used by -#' default by all subsequent calls to client-side functions. If there is more than one set of Opals -#' in the analytic environment, ds.listOpals tells the user that they can either explicitly specify the -#' Opals to be used by each client-side function by providing an explicit "datasources=" argument -#' for each call, or can alternatively use the ds.setDefaultOpals function to specify a default -#' set of Opals to be used by all client-side calls unless over-ruled by the 'datasources=' argument. -#' @keywords internal -#' @return Lists all of the sets of Opals currently found in the analytic environment and advises -#' the user how best to respond depending whether there are zero, one or multiple Opals detected. +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `DSI::datashield.connections()` instead. +#' @param ... Not used. #' @author Burton, PR. 28/9/16 +#' @md +#' @keywords internal #' @export -#' - -ds.listOpals<-function(){ - .Deprecated("DSI::datashield.connections") - datashield.connections() +ds.listOpals <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.listOpals()", "DSI::datashield.connections()") } -#ds.listOpals diff --git a/R/ds.listServersideFunctions.R b/R/ds.listServersideFunctions.R index 2df6630c0..f92a3fec9 100644 --- a/R/ds.listServersideFunctions.R +++ b/R/ds.listServersideFunctions.R @@ -1,74 +1,14 @@ #' @title Lists server-side functions -#' @description Lists all current server-side functions -#' @details Uses \code{\link[DSI]{datashield.methods}} function from \code{DSI} package to list all -#' assign and aggregate functions on the available data repository servers. -#' The only choice of arguments is in \code{datasources}; i.e. which studies to interrogate. -#' Once the studies have -#' been selected \code{ds.listServersideFunctions} lists all assign functions for all -#' of these studies and then all aggregate functions for all of them. -#' -#' This function does not call any server-side function. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. -#' If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @return \code{ds.listServersideFunctions} returns to the client-side -#' a list containing all server-side functions separately for each study. -#' Firstly lists assign and then aggregate functions. -#' @examples -#' \dontrun{ -#' -#' ## Version 6, for version 5 see Wiki -#' # Connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') -#' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "CNSIM.CNSIM2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' logindata <- builder$build() -#' -#' # Log onto the remote Armadillo/Opal training servers -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' # List server-side functions -#' -#' ds.listServersideFunctions(datasources = connections) -#' -#' # Clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' } +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `DSI::datashield.methods()` instead. +#' @param ... Not used. #' @author DataSHIELD Development Team -#' @export +#' @md +#' @keywords internal #' @import DSI -ds.listServersideFunctions<-function(datasources=NULL){ - .Deprecated("DSI::datashield.methods") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - assign.funs <- DSI::datashield.methods(datasources, 'assign') - aggregate.funs <- DSI::datashield.methods(datasources, 'aggregate') - return(list(serverside.assign.functions=assign.funs, - serverside.aggregate.functions=aggregate.funs)) +#' @export +ds.listServersideFunctions <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.listServersideFunctions()", "DSI::datashield.methods()") } - -#ds.listServersideFunctions diff --git a/R/ds.look.R b/R/ds.look.R index c1d005bd0..fd13b3cbe 100644 --- a/R/ds.look.R +++ b/R/ds.look.R @@ -1,107 +1,13 @@ -#' #' @title Performs direct call to a server-side aggregate function -#' @description The function \code{ds.look} can be used to make a direct call to a server-side -#' aggregate function more simply than using the \code{datashield.aggregate} function. -#' @details The \code{ds.look} and \code{datashield.aggregate} functions are generally -#' only recommended for experienced developers. For example, the \code{toAggregate} argument has to -#' be expressed in the same form that the server-side function would usually expect from its -#' client-side pair. For example: \code{ds.look("table1DDS(female)")} works. But, if you express -#' this as \code{ds.look("table1DDS('female')")} it won't work because although when -#' you call this same function using its client-side function you write \code{ds.table1D('female')} -#' the inverted commas are stripped off during processing by the client-side function so the -#' call to the server-side does not contain inverted commas. -#' -#' Apart from during development -#' work (e.g. before a client-side function has been written) it is almost always easier -#' and less error-prone to call a server-side function using its client-side pair. -#' -#' The function is a wrapper for the DSI package function \code{datashield.aggregate}. -#' @param toAggregate a character string specifying the function call to be made. -#' For more information see \strong{Details}. -#' @param checks logical. If TRUE the optional checks are undertaken. -#' Default FALSE to save time. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} -#' objects obtained after login. If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @return the output from the specified server-side aggregate function to the client-side. -#' @author DataSHIELD Development Team -#' -#' @examples -#' \dontrun{ -#' -#' ## Version 6, for version 5 see the Wiki -#' -#' # connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') +#' @description +#' `r lifecycle::badge("deprecated")` #' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/survival/EXPAND_NO_MISSING1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "SURVIVAL.EXPAND_NO_MISSING2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' logindata <- builder$build() -#' -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' #Calculate the length of a variable using the server-side function -#' -#' ds.look(toAggregate = "lengthDS(D$age.60)", -#' checks = FALSE, -#' datasources = connections) -#' -#' #Calculate the column names of "D" object using the server-side function -#' -#' ds.look(toAggregate = "colnames(D)", -#' checks = FALSE, -#' datasources = connections) -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' } +#' This function is defunct. Its functionality has been removed. +#' @param ... Not used. +#' @author DataSHIELD Development Team +#' @md +#' @keywords internal #' @export -#' -ds.look<-function(toAggregate=NULL, checks=FALSE, datasources=NULL){ - .Deprecated() - -################################################################################################################### -#MODULE 1: IDENTIFY DEFAULT DS CONNECTIONS # - # look for DS connections # - if(is.null(datasources)){ # - datasources <- datashield.connections_find() # - } # - # - # ensure datasources is a list of DSConnection-class # - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ # - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) # - } # -################################################################################################################### - -########################################################################################### -#MODULE 3: OPTIONAL CHECKS FOR KEY DATA OBJECTS # -#IN DIFFERENT SOURCES # -if(checks==TRUE){ # - if(is.null(toAggregate)){ # - stop(" missing, please give an expression/function in inverted commas\n",# - call.=FALSE) # - } # -} # -########################################################################################### - - - # now do the business - output<-DSI::datashield.aggregate(datasources, as.symbol(toAggregate)) - return(list(output=output)) - } - -#ds.look +ds.look <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.look()", details = "Its functionality has been removed.") +} diff --git a/R/ds.meanByClass.R b/R/ds.meanByClass.R index 6940c5484..5138d8394 100644 --- a/R/ds.meanByClass.R +++ b/R/ds.meanByClass.R @@ -1,126 +1,13 @@ +#' @title Computes the mean and standard deviation across categories +#' @description +#' `r lifecycle::badge("deprecated")` #' -#' @title Computes the mean and standard deviation across categories -#' @description This function calculates the mean and the standard deviation (SD) -#' of a continuous variable for each class of up to 3 categorical variables. -#' @details The function splits the input dataset into subsets (one for each category) and calculates -#' the mean and SD of the specified numeric variables. It is important to note that the process of -#' generating the final table(s) can be time consuming particularly if the subsetting is done across -#' more than one categorical variable and the run-time lengthens if the parameter \code{type} is set to -#' \code{'split'} as a table is then produced for each study. It is therefore advisable to run the function -#' only for the studies of the user interested in but including only those studies in the -#' parameter \code{datasources}. -#' -#' Depending on the variable \code{type} can be carried out two analysis:\cr -#' (1) \code{'combine'}: a pooled table of results is generated. \cr -#' (2) \code{'split'}: a table of results is generated for each study. -#' -#' -#' @param x a character string specifying the name of the dataset or a text formula. -#' @param outvar a character vector specifying the names of the continuous variables. -#' @param covar a character vector specifying the names of up to 3 categorical variables -#' @param type a character string that represents the type of analysis to carry out. -#' \code{type} can be set as: \code{'combine'} or \code{'split'}. -#' Default \code{'combine'}. -#' For more information see \strong{Details}. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} -#' objects obtained after login. If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @return \code{ds.meanByClass} returns to the client-side a table or a list of tables that -#' hold the length of the numeric variable(s) and their mean -#' and standard deviation in each subgroup (subset). -#' @export +#' This function is defunct. Please use `ds.meanSdGp()` instead. +#' @param ... Not used. #' @author DataSHIELD Development Team -#' @seealso \code{\link{ds.subsetByClass}} to subset by the classes of factor vector(s). -#' @seealso \code{\link{ds.subset}} to subset by complete cases (i.e. removing missing values), threshold, columns and rows. -#' @examples -#' \dontrun{ -#' -#' ## Version 6, for version 5 see the Wiki -#' -#' # connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') -#' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "CNSIM.CNSIM2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' logindata <- builder$build() -#' -#' -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' #Calculate mean by class -#' -#' ds.meanByClass(x = "D", -#' outvar = c('LAB_HDL','LAB_TSC'), -#' covar = c('PM_BMI_CATEGORICAL'), -#' type = "combine", -#' datasources = connections) -#' -#' ds.meanByClass(x = "D$LAB_HDL~D$PM_BMI_CATEGORICAL", -#' type = "combine", -#' datasources = connections[1])#Only the frist server is used ("study1") -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' } -#' -ds.meanByClass <- function(x=NULL, outvar=NULL, covar=NULL, type='combine', datasources=NULL){ - .Deprecated("ds.meanSdGp") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - # check if the user specified a formula to run the process for two loose vector or if the vectors are - # in a table structure (data frame or matrix) and call the relevant function accordingly - if(is.null(x)){ - stop("Please provide the name data frame or matrix or a formula of the form 'A~B' where A is a continuous vector and B a factor vector!", call.=FALSE) - }else{ - obj <- unlist(strsplit(x, split='~')) - if(length(obj)==2){ - # check if the input variables are defined in all the studies - defined <- isDefined(datasources, obj[1]) - defined <- isDefined(datasources, obj[2]) - typ <- checkClass(datasources, obj[1]) - if(!("numeric" %in% typ) & !("integer" %in% typ)){ - stop("The first element in the formula must be of type numeric or integer!", call.=FALSE) - } - typ <- checkClass(datasources, obj[2]) - if(!("factor" %in% typ)){ - stop("The second element in the formula must be of type factor!", call.=FALSE) - } - output <- meanByClassHelper0a(obj[1], obj[2], type, datasources) - return(output) - }else{ - if(length(obj)==1){ - defined <- isDefined(datasources, x) - typ <- checkClass(datasources, x) - if(!("data.frame" %in% typ) & !("matrix" %in% typ)){stop("x must be the name of a data frame or a matrix or a formula of the form 'A~B' where A is a continuous vector and B a factor vector!", call.=FALSE)} - output <- meanByClassHelper0b(x, outvar, covar, type, datasources) - return(output) - }else{ - stop("x must be the name of a data frame or a matrix or a formula of the form 'A~B' where A is a continuous vector and B a factor vector!", call.=FALSE) - } - } - } - +#' @md +#' @keywords internal +#' @export +ds.meanByClass <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.meanByClass()", "ds.meanSdGp()") } diff --git a/R/ds.message.R b/R/ds.message.R index 361c9be63..fd1c069ec 100644 --- a/R/ds.message.R +++ b/R/ds.message.R @@ -1,99 +1,13 @@ +#' @title Returns server-side messages to the client-side +#' @description +#' `r lifecycle::badge("deprecated")` #' -#' @title Returns server-side messages to the client-side -#' @description This function allows for error messages arising from the -#' running of a server-side assign function to be returned to the client-side. -#' @details Errors arising from aggregate server-side functions can be returned -#' directly to the client-side. But this is not possible for server-side assign -#' functions because they are designed specifically to write objects to the -#' server-side and to return no meaningful information to the client-side. -#' Otherwise, users may be able to use assign functions to return disclosive -#' output to the client-side. -#' -#' Server-side functions from which error messages are to be made -#' available are designed to be able to write the designated error message to -#' the \code{$serversideMessage} object into the list that is saved on the server-side -#' as the primary output of that function. So only valid server-side functions of -#' DataSHIELD can write a \code{$studysideMessage}. The error message is a string that -#' cannot exceed a length of \code{nfilter.string} a default of 80 characters. -#' -#' Server function called: \code{messageDS} -#' @param message.obj.name is a character string specifying the name of the list that -#' contains the message. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} -#' objects obtained after login. If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @return \code{ds.message} returns a list object from each study, -#' containing the message that has been written by -#' DataSHIELD into \code{$studysideMessage}. +#' This function is defunct. Server-side errors are now returned directly and can be viewed with `DSI::datashield.errors()`. +#' @param ... Not used. #' @author DataSHIELD Development Team -#' @examples -#' \dontrun{ -#' -#' ## Version 6, for version 5 see the Wiki -#' -#' # connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') -#' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "CNSIM.CNSIM2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' logindata <- builder$build() -#' -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' #Use a ds.asCharacter assign function to create the message in the server-side -#' -#' ds.asCharacter(x.name = "D$LAB_TRIG", -#' newobj = "vector1", -#' datasources = connections) -#' -#' #Return the message to the client-side -#' -#' ds.message(message.obj.name = "vector1", -#' datasources = connections) -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' } +#' @md +#' @keywords internal #' @export -ds.message<-function(message.obj.name=NULL,datasources=NULL){ - .Deprecated() - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - # Check if user has provided the name of the studyside list object that holds the required message - # Also check that it is in character format (in inverted commas) - if(is.null(message.obj.name) | !is.character(message.obj.name)){ - stop("Please provide the name of the studyside list object that holds the message\n in character format ie: 'object.name' in inverted commas", call.=FALSE) - } - -# CALL THE MAIN SERVER SIDE FUNCTION - calltext <- call("messageDS", message.obj.name) - output.message<-DSI::datashield.aggregate(datasources, calltext) - -#RETURN COMPLETION INFORMATION TO .GlobalEnv - message("\nMESSAGES FROM STUDYSIDE SERVERS ARE:-\n") - return(Message=output.message) +ds.message <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.message()", details = "Server-side errors are now returned directly and can be viewed with `DSI::datashield.errors()`.") } -#ds.message diff --git a/R/ds.recodeLevels.R b/R/ds.recodeLevels.R index 3d85a4535..c96ca2fb8 100644 --- a/R/ds.recodeLevels.R +++ b/R/ds.recodeLevels.R @@ -1,134 +1,14 @@ +#' @title Recodes the levels of a server-side factor vector +#' @description +#' `r lifecycle::badge("deprecated")` #' -#' @title Recodes the levels of a server-side factor vector -#' @description The function replaces the levels of a factor by the specified new ones. -#' @details This function is similar to native R function \code{levels()}. -#' -#' It can for example be used to merge two classes into one, to add a level(s) to a vector -#' or to rename (i.e. re-label) the levels of a vector. -#' -#' Server function called: \code{levels()} - -#' @param x a character string specifying the name of a factor variable. -#' @param newCategories a character vector specifying the new levels. Its length must be equal or greater -#' to the current number of levels. -#' @param newobj a character string that provides the name for the output object -#' that is stored on the data servers. Default \code{recodelevels.newobj}. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} -#' objects obtained after login. If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @return \code{ds.recodeLevels} returns to the server-side a variable of type factor -#' with the replaces levels. +#' This function is defunct. Please use `ds.recodeValues()` instead. +#' @param ... Not used. #' @author DataSHIELD Development Team #' @author Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands +#' @md +#' @keywords internal #' @export -#' @examples -#' \dontrun{ -#' -#' ## Version 6, for version 5 see the Wiki -#' -#' # connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') -#' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "CNSIM.CNSIM2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' logindata <- builder$build() -#' -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' # Recode the levels of a factor variable -#' -#' ds.recodeLevels(x = "D$PM_BMI_CATEGORICAL", -#' newCategories = c("1","2","3"), -#' newobj = "BMI_CAT", -#' datasources = connections) -#' -#' # Clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' -#' } -#' -ds.recodeLevels <- function(x=NULL, newCategories=NULL, newobj=NULL, datasources=NULL){ - .Deprecated("ds.recodeValues") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - if(is.null(x)){ - message(" ALERT!") - message(" Please provide a valid numeric of character vector") - stop(" End of process!", call.=FALSE) - } - - if(is.null(newCategories)){ - message(" ALERT!") - message(" Please specify the new categories to recode to") - stop(" End of process!", call.=FALSE) - } - - # check if the input object(s) is(are) defined in all the studies - defined <- isDefined(datasources,x) - - # call the internal function that checks the input object is of the same class in all studies. - typ <- checkClass(datasources, x) - - # if input vector is not a factor stop - if(!('factor' %in% typ)){ - stop("The input vector must be a factor!", call.=FALSE) - } - - # get the current number of levels - cally <- call("levelsDS", x) - xx <- DSI::datashield.aggregate(datasources, cally) - all.study.levels <- c() - for (study.levels in xx) { - if (any(is.na(study.levels$Levels))) - stop(paste0("Failed to get levels from study: ", study.levels$ValidityMessage), call.=FALSE) - all.study.levels <- c(all.study.levels, study.levels$Levels) - } - if(length(unique(all.study.levels)) > length(newCategories)){ - stop("The number of levels you specified is smaller than the levels of the input vector!", call.=FALSE) - } - - # the input variable might be given as column table (i.e. D$x) - # or just as a vector not attached to a table (i.e. x) - # we have to make sure the function deals with each case - xnames <- extract(x) - varname <- xnames[length(xnames)] - - # if no name was provided for the new variable give it a default name - if(is.null(newobj)){ - newobj <- paste(varname, "_new", sep="") - } - - # get the names and number of the studies/datasources - stdnames <- names(datasources) - numstudies <- length(stdnames) - - # do the business - cally <- paste0("recodeLevelsDS(", x, ", vectorDS(","'",paste(newCategories,collapse="','"),"')",")") - DSI::datashield.assign(datasources, newobj, as.symbol(cally)) - - # check that the new object has been created and display a message accordingly - finalcheck <- isAssigned(datasources, newobj) +ds.recodeLevels <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.recodeLevels()", "ds.recodeValues()") } diff --git a/R/ds.setDefaultOpals.R b/R/ds.setDefaultOpals.R index dfa8912aa..9c600adaf 100644 --- a/R/ds.setDefaultOpals.R +++ b/R/ds.setDefaultOpals.R @@ -1,40 +1,13 @@ -#' #' @title Creates a default set of Opal objects called 'default.opals' -#' @description creates a default set of Opal objects called 'default.opals -#' @details By default if there is only one set of opals that is available for -#' analysis, all DataSHIELD client-side functions will -#' use that full set of Opals unless the 'datasources=' argument has been set and specifies that -#' a particular subset of those Opals should be used instead. The correct identification of the full -#' single set of opals is based on the datashield.connections_find() function which is an internal DataSHIELD -#' function that is run at the start of nearly every client side function. -#' To illustrate, if the single set of Opals is called 'study.opals' and consists of -#' six opals numbered study.opals[1] to study.opals[6] then all client-side functions will -#' use data from all six of these 'study.opals' unless, say, datasources=study.opals[c(2,5)] is -#' declared and only data from the second and fifth studies will then be used. -#' On the other hand, if there is more than one set of Opals in the analytic environment client-side functions will -#' be unable to determine which set to use. The function datashield.connections_find() has therefore been -#' written so that if one of the Opal sets is called 'default.opals' then that set - -#' i.e. 'default.opals' - will be selected by default by all DataSHIELD client-side functions. If there is more -#' than one set of Opals in the analytic environment and NONE of -#' these is called 'default.opals', the function ds.setDefaultOpals() therefore copies -#' one set of opals and to name that copy 'default.opals'. This set will then be selected -#' by default by all client-side functions, unless it is deleted and an alternative set of -#' opals is copied and named 'default.opals'. Regardless how many sets of opals exist and -#' regardless whether any of them may be called 'default.opals', the 'datasources=' argument -#' overrides the defaults and allows the user to base his/her analysis on any set of opals -#' and any subset of those opals. An earlier version of -#' 'datashield.connections_find()' asked the user to specify which Opal to choose -#' if no default could be identified, but that did not work in all versions of R -#' and so has been removed. -#' @keywords internal -#' @return Copies a specified set of Opals (on the client-side server) -#' and calls the copy 'default.opals' +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `DSI::datashield.connections_default()` instead. +#' @param ... Not used. #' @author Burton, PR. 28/9/16 +#' @md +#' @keywords internal #' @export -#' - -ds.setDefaultOpals<-function(opal.name){ - .Deprecated("DSI::datashield.connections_default") - datashield.connections_default(name = opal.name) +ds.setDefaultOpals <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.setDefaultOpals()", "DSI::datashield.connections_default()") } -#ds.setDefaultOpals diff --git a/R/ds.subset.R b/R/ds.subset.R index 03b2e7344..705e15cc5 100644 --- a/R/ds.subset.R +++ b/R/ds.subset.R @@ -1,171 +1,13 @@ -#' #' @title Generates a valid subset of a table or a vector -#' @description The function uses the R classical subsetting with squared brackets '[]' and allows also to -#' 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). -#' @details (1) If the input data is a table the user specifies the rows and/or columns to include in the subset; the columns can be -#' referred to by their names. Table subsetting can also be done using the name of a variable and a threshold (see example 3). -#' (2) If the input data is a vector and the parameters 'rows', 'logical' and 'threshold' are all provided the last two are ignored -#' (i.e. 'rows' has precedence over the other two parameters then). -#' IMPORTANT NOTE: If the requested subset is not valid (i.e. contains less than the allowed number of observations) all the values are -#' turned into missing values (NA). Hence an invalid subset is indicated by the fact that all values within it are set to NA. -#' @param subset the name of the output object, a list that holds the subset object. If set to NULL -#' the default name of this list is 'subsetObject' -#' @param x a character, the name of the dataframe or the factor vector and the range of the subset. -#' @param completeCases a character that tells if only complete cases should be included or not. -#' @param rows a vector of integers, the indices of the rows to extract. -#' @param cols a vector of integers or a vector of characters; the indices of the columns to extract or their names. -#' @param logicalOperator a boolean, the logical parameter to use if the user wishes to subset a vector using a logical -#' operator. This parameter is ignored if the input data is not a vector. -#' @param threshold a numeric, the threshold to use in conjunction with the logical parameter. This parameter is ignored -#' if the input data is not a vector. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @return no data are return to the user, the generated subset dataframe is stored on the server side. +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `ds.dataFrameSubset()` instead. +#' @param ... Not used. #' @author Gaye, A. -#' @seealso \link{ds.subsetByClass} to subset by the classes of factor vector(s). -#' @seealso \link{ds.meanByClass} to compute mean and standard deviation across categories of a factor vectors. +#' @md +#' @keywords internal #' @export -#' @examples -#' \dontrun{ -#' -#' # load the login data -#' data(logindata) -#' -#' # login and assign some variables to R -#' myvar <- list("DIS_DIAB","PM_BMI_CONTINUOUS","LAB_HDL", "GENDER") -#' conns <- datashield.login(logins=logindata,assign=TRUE,variables=myvar) -#' -#' # Example 1: generate a subset of the assigned dataframe (by default the table is named 'D') -#' # with complete cases only -#' ds.subset(x='D', subset='subD1', completeCases=TRUE) -#' # display the dimensions of the initial table ('D') and those of the subset table ('subD1') -#' ds.dim('D') -#' ds.dim('subD1') -#' -#' # Example 2: generate a subset of the assigned table (by default the table is named 'D') -#' # with only the variables -#' # DIS_DIAB' and'PM_BMI_CONTINUOUS' specified by their name. -#' ds.subset(x='D', subset='subD2', cols=c('DIS_DIAB','PM_BMI_CONTINUOUS')) -#' -#' # Example 3: generate a subset of the table D with bmi values greater than or equal to 25. -#' ds.subset(x='D', subset='subD3', logicalOperator='PM_BMI_CONTINUOUS>=', threshold=25) -#' -#' # Example 4: get the variable 'PM_BMI_CONTINUOUS' from the dataframe 'D' and generate a -#' # subset bmi -#' # vector with bmi values greater than or equal to 25 -#' ds.assign(toAssign='D$PM_BMI_CONTINUOUS', newobj='BMI') -#' ds.subset(x='BMI', subset='BMI25plus', logicalOperator='>=', threshold=25) -#' -#' # Example 5: subsetting by rows: -#' # get the logarithmic values of the variable 'lab_hdl' and generate a subset with -#' # the first 50 observations of that new vector. If the specified number of row is -#' # greater than the total -#' # number of rows in any of the studies the process will stop. -#' ds.assign(toAssign='log(D$LAB_HDL)', newobj='logHDL') -#' ds.subset(x='logHDL', subset='subLAB_HDL', rows=c(1:50)) -#' # now get a subset of the table 'D' with just the 100 first observations -#' ds.subset(x='D', subset='subD5', rows=c(1:100)) -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(conns) -#' -#' } -#' -ds.subset <- function(x=NULL, subset="subsetObject", completeCases=FALSE, rows=NULL, cols=NULL, logicalOperator=NULL, threshold=NULL, datasources=NULL){ - .Deprecated("ds.dataFrameSubset") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - if(is.null(x)){ - stop("Please provide the name of the object to subset from!", call.=FALSE) - } - - # check if the input x is defined in all the studies - defined <- isDefined(datasources, x) - - # call the internal function that checks the input object is of the same class in all studies. - typ <- checkClass(datasources, x) - - # the input object must be a dataframe or a vector - if(!('data.frame' %in% typ) & !('character' %in% typ) & !('factor' %in% typ) & !('integer' %in% typ) & !('logical' %in% typ) & !('numeric' %in% typ)){ - stop("The object to subset from must be a 'data.frame', a 'character', factor', a 'logical' or a 'numeric' vector.", call.=FALSE) - } - - # the argument 'rows' and 'cols' have precedence over 'logicalOperator' and 'threshold' - if(is.null(rows) & is.null(cols)){ - if(is.null(logicalOperator) | is.null(threshold)){ - if(!completeCases){ - stop("No subset parameters provided, the sought subset is the same as the original object!", call.=FALSE) - }else{ - cally <- call('subsetDS', x, completeCases) - DSI::datashield.assign(datasources, subset, cally) - } - }else{ - # allow this only for numeric vectors - if(("factor" %in% typ) | ("character" %in% typ)){ - stop(" Subsetting on a threshold criteria is allowed only for numeric vectors!", call.=FALSE) - } - # get the logicalOperator operator and any variable provided with it - lg <- unlist(strsplit(logicalOperator, split="")) - var2sub <- NULL - if(lg[length(lg)] == "=" & lg[(length(lg)-1)] == ">" | lg[(length(lg)-1)] == "<" | lg[(length(lg)-1)] == "=" | lg[(length(lg)-1)] == "!"){ - logicalOperator <- paste0(lg[(length(lg)-1)], lg[length(lg)]) - if(length(lg) > 2){ var2sub <- paste(lg[1:(length(lg)-2)], collapse="") } - }else{ - logicalOperator <- lg[length(lg)] - if(length(lg) > 1) { var2sub <- paste0(lg[1:(length(lg)-1)], collapse="") } - } - - # turn the logicalOperator operator into the corresponding integer that will be evaluated on the server side. - logicalOperator <- logical2int(logicalOperator) - cally <- call('subsetDS', x, completeCases, rows, cols, logicalOperator, threshold, var2sub) - DSI::datashield.assign(datasources, subset, cally) - } - }else{ - - # check if the sought subset is not larger than the vector or the table size - # if not call the server side function and carry out the subsetting - if(("factor" %in% typ) | ("numeric" %in% typ) | ("character" %in% typ)){ - # if the size of the requested subset is greater than that of original set the rows or cols to NULL - # these will then be set to the maximum size in the server side - if(!(is.null(rows))){ - ll <- DSI::datashield.aggregate(datasources, call("lengthDS", x)) - for(i in 1:length(datasources)){ - if(length(rows) > ll[[i]]){ - rows <- NULL - } - } - } - # turn the vector of row indices into a character to pass the parser - for(i in 1:length(datasources)){ - cally <- call('subsetDS', x, completeCases, rows) - DSI::datashield.assign(datasources[i], subset, cally) - } - }else{ - if(("data.frame" %in% typ) | ("matrix" %in% typ)){ - # call the internal function that ensure wrong size subset is not requested (i.e. subset size > original table) - for(i in 1:length(datasources)){ - check00 <- subsetHelper(datasources[i], x, rows, cols) - if(check00[1] == 1){ rows <- NULL } - if(check00[2] == 1){ cols <- NULL } - } - for(i in 1:length(datasources)){ - cally <- call('subsetDS', x, completeCases, rows, cols) - DSI::datashield.assign(datasources[i], subset, cally) - } - }else{ - stop("The object to subset from must be a numeric, character or factor vector or a table structure (matrix or data.frame).", call.=FALSE) - } - } - } - +ds.subset <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.subset()", "ds.dataFrameSubset()") } diff --git a/R/ds.subsetByClass.R b/R/ds.subsetByClass.R index 5470e6148..6a3fb04e9 100644 --- a/R/ds.subsetByClass.R +++ b/R/ds.subsetByClass.R @@ -1,122 +1,14 @@ -#' #' @title Generates valid subset(s) of a data frame or a factor -#' @description The function takes a categorical variable or a data frame as input and generates -#' subset(s) variables or data frames for each category. -#' @details If the input data object is a data frame it is possible to specify the variables -#' to subset on. If a subset is not 'valid' all its the values are reported as missing (i.e. NA), -#' the name of the subsets is labelled with the suffix '_INVALID'. Subsets are considered invalid if -#' the number of observations it holds are between 1 and the threshold allowed by the data owner. if -#' a subset is empty (i.e. no entries) the name of the subset is labelled with the suffix '_EMPTY'. -#' @param x a character, the name of the dataframe or the vector to generate subsets from. -#' @param variables a vector of string characters, the name(s) of the variables to subset by. -#' @param subsets the name of the output object, a list that holds the subset objects. If set to NULL -#' the default name of this list is 'subClasses'. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @return a no data are return to the user but messages are printed out. +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `ds.dataFrameSubset()` instead. +#' @param ... Not used. #' @author Gaye, A. #' @author Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -#' @seealso \link{ds.meanByClass} to compute mean and standard deviation across categories of a factor vectors. -#' @seealso \link{ds.subset} to subset by complete cases (i.e. removing missing values), threshold, columns and rows. +#' @md +#' @keywords internal #' @export -#' @examples -#' \dontrun{ -#' -#' # load the login data -#' data(logindata) -#' -#' # login and assign some variables to R -#' myvar <- list('DIS_DIAB','PM_BMI_CONTINUOUS','LAB_HDL', 'GENDER') -#' conns <- datashield.login(logins=logindata,assign=TRUE,variables=myvar) -#' -#' # Example 1: generate all possible subsets from the table assigned above (one subset table -#' # for each class in each factor) -#' ds.subsetByClass(x='D', subsets='subclasses') -#' # display the names of the subset tables that were generated in each study -#' ds.names('subclasses') -#' -#' # Example 2: subset the table initially assigned by the variable 'GENDER' -#' ds.subsetByClass(x='D', subsets='subtables', variables='GENDER') -#' # display the names of the subset tables that were generated in each study -#' ds.names('subtables') -#' -#' # Example 3: generate a new variable 'gender' and split it into two vectors: males -#' # and females -#' ds.assign(toAssign='D$GENDER', newobj='gender') -#' ds.subsetByClass(x='gender', subsets='subvectors') -#' # display the names of the subset vectors that were generated in each study -#' ds.names('subvectors') -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(conns) -#' -#' } -#' -ds.subsetByClass <- function(x=NULL, subsets="subClasses", variables=NULL, datasources=NULL){ - .Deprecated("ds.dataFrameSubset") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - if(is.null(x)){ - stop("Please provide the name of the input data frame or factor!", call.=FALSE) - } - - # check if the input x is defined in all the studies - defined <- isDefined(datasources, x) - - # call the internal function that checks the input object is of the same class in all studies. - typ <- checkClass(datasources, x) - - # the input object must be a dataframe or a factor - if(!('data.frame' %in% typ) & !('factor' %in% typ)){ - message(paste0(x, " is of type ", typ, "!")) - stop("The object to subset from must be a 'data.frame' or a 'factor'.", call.=FALSE) - } - - # number of studies and their names - numsources <- length(datasources) - stdnames <- names(datasources) - - # check that, for each study, all the columns of the input table are of 'numeric' type - if(typ == 'data.frame'){ - dtname <- x - for(i in 1:numsources){ - cols <- DSI::datashield.aggregate(datasources[i], call("colnamesDS", x)) - dims <- DSI::datashield.aggregate(datasources[i], call("dimDS", x)) - tracker <-c() - for(j in 1:dims[[1]]$dim[2]){ - cally <- call("classDS", paste0(dtname, "$", cols[[1]][j])) - res <- DSI::datashield.aggregate(datasources[i], cally) - if(res[[1]] != 'factor'){ - tracker <- append(tracker, 0) - }else{ - tracker <- append(tracker, 1) - } - } - if(sum(tracker) == 0){ - stop("No factor variable found in data frame ", dtname, " in ", stdnames[i], ".", call.=FALSE) - } - } - } - - # call the server side function that does the job - # get the indices of the columns referred to by their names in the arguments - if(is.null(variables)){ - cally <- paste0("subsetByClassDS('", x, "')") - }else{ - cally <- paste0("subsetByClassDS('", x, "', c('",paste(variables,collapse="','"),"'))") - } - DSI::datashield.assign(datasources, subsets, as.symbol(cally)) - - # check that the new object has been created and display a message accordingly - finalcheck <- isAssigned(datasources, subsets) - +ds.subsetByClass <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.subsetByClass()", "ds.dataFrameSubset()") } diff --git a/R/ds.table1D.R b/R/ds.table1D.R index 8a13afdc7..73785739e 100644 --- a/R/ds.table1D.R +++ b/R/ds.table1D.R @@ -1,175 +1,13 @@ -#' #' @title Generates 1-dimensional contingency tables -#' @description The function ds.table1D is a client-side wrapper function. -#' It calls the server-side function table1DDS to generate 1-dimensional -#' tables for all data sources. -#' @details The table returned by the server side function might be valid (non disclosive - -#' no table cell have counts between 1 and the minimal number agreed by the data owner and set in the data repository) -#' or invalid (potentially disclosive - one or more table cells have a count between 1 and the minimal number -#' agreed by the data owner). If a 1-dimensional table is invalid all the cells are set to NA except the total -#' count. This way it is possible the know the total count and combine total counts across data sources but it -#' is not possible to identify the cell(s) that had the small counts which render the table invalid. -#' @param x a character, the name of a numerical vector with discrete values - usually a factor. -#' @param type a character which represent the type of table to output: pooled table or one table for each -#' data source. If \code{type} is set to 'combine', a pooled 1-dimensional table is returned; if If \code{type} -#' is set to 'split' a 1-dimensional table is returned for each data source. -#' @param warningMessage a boolean, if set to TRUE (default) a warning is displayed if any returned table is invalid. Warning -#' messages are suppressed if this parameter is set to FALSE. However the analyst can still view 'validity' information -#' which are stored in the output object 'validity' - see the list of output objects. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @return A list object containing the following items: -#' \item{counts}{ table(s) that hold counts for each level/category. If some cells counts are invalid (see 'Details' -#' section) only the total (outer) cell counts are displayed in the returned individual study tables or in the pooled -#' table.} -#' \item{percentages}{ table(s) that hold percentages for each level/category. Here also inner cells are reported as -#' missing if one or more cells are 'invalid'.} -#' \item{validity}{ a text that informs the analyst about the validity of the output tables. If any tables are invalid the -#' studies they are originated from are also mentioned in the text message.} +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `ds.table()` instead. +#' @param ... Not used. #' @author Gaye, A.; Burton, P. -#' @seealso \link{ds.table2D} for cross-tabulating two vectors. +#' @md +#' @keywords internal #' @export -#' @examples -#' \dontrun{ -#' -#' # load the file that contains the login details -#' data(logindata) -#' -#' # login and assign all the stored variables to R -#' conns <- datashield.login(logins=logindata,assign=TRUE) -#' -#' # Example 1: generate a one dimensional table, outputting combined (pooled) contingency tables -#' output <- ds.table1D(x='D$GENDER') -#' output$counts -#' output$percentages -#' output$validity -#' -#' # Example 2: generate a one dimensional table, outputting study specific contingency tables -#' output <- ds.table1D(x='D$GENDER', type='split') -#' output$counts -#' output$percentages -#' output$validity -#' -#' # Example 3: generate a one dimensional table, outputting study specific and combined -#' # contingency tables - see what happens if the reruened table is 'invalid'. -#' output <- ds.table1D(x='D$DIS_CVA') -#' output$counts -#' output$percentages -#' output$validity -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(conns) -#' -#' } -#' -ds.table1D <- function(x=NULL, type='combine', warningMessage=TRUE, datasources=NULL){ - .Deprecated("ds.table") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - if(is.null(x)){ - stop("Please provide the name of the input vector!", call.=FALSE) - } - - # the input variable might be given as column table (i.e. D$x) - # or just as a vector not attached to a table (i.e. x) - # we have to make sure the function deals with each case - xnames <- extract(x) - varname <- xnames$elements - obj2lookfor <- xnames$holders - variable <- varname - - # check if the input object(s) is(are) defined in all the studies - if(is.na(obj2lookfor)){ - defined <- isDefined(datasources, varname) - }else{ - defined <- isDefined(datasources, obj2lookfor) - } - - # call the internal function that checks the input object is of the same class in all studies. - typ <- checkClass(datasources, x) - - # names of the studies - stdnames <- names(datasources) - - # call the server side function that produces a 1-dimensional table for each study - cally <- paste0("table1DDS(", x, ")") - output <- DSI::datashield.aggregate(datasources, as.symbol(cally)) - - # extract contingency (count) tables and validity information for each study - countTables <- vector("list", length(stdnames)) - validityInfo <- vector("list", length(stdnames)) - for(i in 1:length(stdnames)){ - countTables[[i]] <- t(output[[i]][[1]]) - colnames(countTables[[i]]) <- x - validityInfo[[i]] <- output[[i]][[2]] - } - names(countTables) <- stdnames - names(validityInfo) <- stdnames - - # first check if any study is invalid - if yes then only add up the outer columns (i.e. the total) - invalids <- which(unlist(validityInfo) == "invalid table - invalid counts present") - - # generate the pooled counts table - pooledCounts <- countTables[[1]] - pooledCounts[,1] <- 0 - for(i in 1:length(stdnames)){ - pooledCounts <- pooledCounts + countTables[[i]] - } - if(length(invalids > 0)){ - pooledCounts[1:(dim(pooledCounts)[1])-1, 1] <- NA - } - - # percentage tables (one for each study) - percentageTables <- vector("list", length(stdnames)) - for(i in 1:length(stdnames)){ - temp <- countTables[[i]] - totalIdx <- dim(countTables[[i]])[1] - temp[,1] <- round((countTables[[i]][,1]/countTables[[i]][totalIdx,1])*100,2) - percentageTables[[i]] <- temp - } - names(percentageTables) <- stdnames - - # generate the pooled counts table - if(length(invalids > 0)){ - pooledPercentages <- percentageTables[[1]] - pooledPercentages[1:(dim(pooledCounts)[1])-1, 1] <- NA - }else{ - pooledPercentages <- round((pooledCounts/pooledCounts[dim(pooledCounts)[1], 1])*100,2) - } - - # return the right output depending what the user specified: 'combine' or 'split' analysis - if(type=="combine"){ - if(length(invalids > 0)){ - if(warningMessage){ - message(paste0("WARNING: Invalid tables from '", paste(stdnames[invalids], collapse=", "), "' !\n Only total values are returned in the output table(s).")) - } - validityValue <- paste0("Invalid tables from '", paste(stdnames[invalids], collapse=", "), "'!") - }else{ - validityValue <- "All tables are valid!" - } - return(list(counts=pooledCounts, percentages=pooledPercentages, validity=validityValue)) - }else{ - if(type=="split"){ - if(length(invalids > 0)){ - if(warningMessage){ - message(paste0("WARNING: Invalid table(s) from '", paste(stdnames[invalids], collapse=", "), "' !\n Only total values are returned in the output table(s).")) - } - validityValue <- paste0("Invalid table(s) from '", paste(stdnames[invalids], collapse=", "), "'!") - }else{ - validityValue <- "All tables are valid!" - } - return(list(counts=countTables, percentages=percentageTables, validity=validityValue)) - }else{ - stop("Function argument 'type' has to be either 'combine' or 'split'") - } - } +ds.table1D <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.table1D()", "ds.table()") } diff --git a/R/ds.table2D.R b/R/ds.table2D.R index 0dee00abd..572fd571e 100644 --- a/R/ds.table2D.R +++ b/R/ds.table2D.R @@ -1,247 +1,13 @@ -#' #' @title Generates 2-dimensional contingency tables -#' @description The function ds.table2D is a client-side wrapper function. It calls the server-side function -#' 'table2DDS' that generates a 2-dimensional contingency table for each data source. -#' @details The table returned by the server side function might be valid (non disclosive - no table cell have -#' counts between 1 and the minimal number agreed by the data owner and set in the data repository as the "nfilter.tab") or -#' invalid (potentially disclosive - one or more table cells have a count between 1 and the minimal number agreed -#' by the data owner). If a 2-dimensional table is invalid all the cells are set to NA except the total counts. -#' In this way, it is possible to combine total counts across all the data sources but it is not possible to -#' identify the cell(s) that had the small counts which render the table invalid. -#' @param x a character, the name of a numerical vector with discrete values - usually a factor. -#' @param y a character, the name of a numerical vector with discrete values - usually a factor. -#' @param type a character which represent the type of table to output: pooled table or one table for each -#' data source or both. If \code{type} is set to 'combine', a pooled 2-dimensional table is returned; If \code{type} -#' is set to 'split' a 2-dimensional table is returned for each data source. If \code{type} is set to 'both' (default) -#' a pooled 2-dimensional table plus a 2-dimensional table for each data source are returned. -#' @param warningMessage a boolean, if set to TRUE (default) a warning is displayed if any returned table is invalid. Warning -#' messages are suppressed if this parameter is set to FALSE. However the analyst can still view 'validity' information -#' which are stored in the output object 'validity' - see the list of output objects. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @return A list object containing the following items: -#' \item{colPercent}{table(s) that hold column percentages for each level/category. Inner cells are reported as -#' missing if one or more cells are 'invalid'.} -#' \item{rowPercent}{table(s) that hold row percentages for each level/category. Inner cells are reported as -#' missing if one or more cells are 'invalid'.} -#' \item{chi2Test}{Chi-squared test for homogeneity.} -#' \item{counts}{table(s) that hold counts for each level/category. If some cell counts are invalid (see 'Details' -#' section) only the total (outer) cell counts are displayed in the returned individual study tables or in the pooled -#' table.} -#' \item{validity}{a text that informs the analyst about the validity of the output tables. If any tables are invalid the -#' studies they are originated from are also mentioned in the text message.} +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `ds.table()` instead. +#' @param ... Not used. #' @author Amadou Gaye, Paul Burton, Demetris Avraam, for DataSHIELD Development Team -#' @seealso \link{ds.table1D} for the tabulating one vector. +#' @md +#' @keywords internal #' @export -#' @examples -#' \dontrun{ -#' -#' # load the file that contains the login details -#' data(logindata) -#' -#' # login and assign all the variables to R -#' conns <- datashield.login(logins=logindata,assign=TRUE) -#' -#' # Example 1: generate a two dimensional table, outputting combined contingency -#' # tables - default behaviour -#' output <- ds.table2D(x='D$DIS_DIAB', y='D$GENDER') -#' # display the 5 results items, one at a time to avoid having too much information -#' # displayed at the same time -#' output$counts -#' output$rowPercent -#' output$colPercent -#' output$chi2Test -#' output$validity -#' -#' # Example 2: generate a two dimensional table, outputting study specific contingency tables -#' ds.table2D(x='D$DIS_DIAB', y='D$GENDER', type='split') -#' # display the 5 results items, one at a time to avoid having too much information displayed -#' at the same time -#' output$counts -#' output$rowPercent -#' output$colPercent -#' output$chi2Test -#' output$validity -#' -#' # Example 3: generate a two dimensional table, outputting combined contingency tables -#' # *** this example shows what happens when one or studies return an invalid table *** -#' output <- ds.table2D(x='D$DIS_CVA', y='D$GENDER', type='combine') -#' output$counts -#' output$rowPercent -#' output$colPercent -#' output$chi2Test -#' output$validity -#' -#' # Example 4: same example as above but output is given for each study, -#' # separately (i.e. type='split') -#' # *** this example shows what happens when one or studies return an invalid table *** -#' output <- ds.table2D(x='D$DIS_CVA', y='D$GENDER', type='split') -#' output$counts -#' output$rowPercent -#' output$colPercent -#' output$chi2Test -#' output$validity -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(conns) -#' -#' } -#' -ds.table2D <- function(x=NULL, y=NULL, type='both', warningMessage=TRUE, datasources=NULL){ - .Deprecated("ds.table") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - if(is.null(x)){ - stop("Please provide the name of the x vector!", call.=FALSE) - } - - if(is.null(y)){ - stop("Please provide the name of the y vector!", call.=FALSE) - } - - if(!(type=="combine" || type=="split" || type=="both")){ - stop("Function argument 'type' has to be either 'combine', 'split' or 'both'") - } - - # the input variable might be given as column table (i.e. D$x) - # or just as a vector not attached to a table (i.e. x) - # we have to make sure the function deals with each case - xnames <- extract(x) - ynames <- extract(y) - xvarname <- xnames$elements - yvarname <- ynames$elements - xobj2lookfor <- xnames$holders - yobj2lookfor <- ynames$holders - xvariable <- xvarname - yvariable <- yvarname - - # check if the input object(s) is(are) defined in all the studies - if(is.na(xobj2lookfor)){ - defined <- isDefined(datasources, xvarname) - }else{ - defined <- isDefined(datasources, xobj2lookfor) - } - if(is.na(yobj2lookfor)){ - defined <- isDefined(datasources, yvarname) - }else{ - defined <- isDefined(datasources, yobj2lookfor) - } - - # call the internal function that checks the input object is of the same class in all studies. - # typ1 <- checkClass(datasources, x) - # typ2 <- checkClass(datasources, y) - - # names of the studies - stdnames <- names(datasources) - - # call the server side function that produces a 1-dimensional table for each study - cally <- paste0("table2DDS(", x, ",", y, ")") - output <- DSI::datashield.aggregate(datasources, as.symbol(cally)) - - # extract contingency (count) tables and validity information for each study - countTables <- vector("list", length(stdnames)) - validityInfo <- vector("list", length(stdnames)) - for(i in 1:length(stdnames)){ - countTables[[i]] <- output[[i]][[1]] - validityInfo[[i]] <- output[[i]][[2]] - } - names(countTables) <- paste0(stdnames,"-",paste0(x,"(row)|",y,"(col)")) - names(validityInfo) <- stdnames - - # check if any study is invalid - if yes then only add up the outer columns (i.e. the total) - invalids <- which(unlist(validityInfo) == "invalid table - invalid counts present") - - # pooled counts table - pooledCounts <- countTables[[1]] - pooledCounts[] <- 0 - for(i in 1:length(stdnames)){ - pooledCounts <- pooledCounts + countTables[[i]] - } - - # pooled row and column percentage tables - pooledRowPercent <- rowPercent(pooledCounts) - pooledColPercent <- colPercent(pooledCounts) - - # if a table is invalid in one or more studies alter the pooled tables chi-sqaured test output accordingly - if(length(invalids > 0)){ - pooledCounts[1:(dim(pooledCounts)[1]-1), 1:(dim(pooledCounts)[2]-1)] <- NA - pooledRowPercent[1:(dim(pooledCounts)[1]-1), 1:(dim(pooledCounts)[2]-1)] <- NA - pooledColPercent[1:(dim(pooledCounts)[1]-1), 1:(dim(pooledCounts)[2]-1)] <- NA - pooledChi2test <- "Error: all entries of the table must be non-negative and finite" - }else{ - pooledContingencyTable <- pooledCounts[1:(dim(pooledCounts)[1]-1), 1:(dim(pooledCounts)[2]-1)] - pooledChi2test <- stats::chisq.test(pooledContingencyTable) - } - - # study specific row and column percentage tables (one for each study) - rowPercentTables <- vector("list", length(stdnames)) - colPercentTables <- vector("list", length(stdnames)) - for(i in 1:length(stdnames)){ - rowPercentTables[[i]] <- rowPercent(countTables[[i]]) - colPercentTables[[i]] <- colPercent(countTables[[i]]) - } - names(rowPercentTables) <- paste0(stdnames,"-",paste0(x,"(row)|",y,"(col)")) - names(colPercentTables) <- paste0(stdnames,"-",paste0(x,"(row)|",y,"(col)")) - - # chi-squared tests for each study separetely - chi2Tests <- vector("list", length(stdnames)) - for(i in 1:length(stdnames)){ - if(length(invalids) > 0 & i%in%invalids){ - chi2Tests[[i]] <- "Error: all entries of the table must be non-negative and finite" - }else{ - contingencyTable <- countTables[[i]][1:(dim(countTables[[i]])[1]-1), 1:(dim(countTables[[i]])[2]-1)] - options(warn = -1) # suppress warning temporarily to avoid 'nuisance' message, analyst will found out chi2 results anyway. - chi2Tests[[i]] <- stats::chisq.test(contingencyTable ) - options(warn = 0) # put warning back - } - } - names(chi2Tests) <- paste0(stdnames,"-",paste0(x,"(row)|",y,"(col)")) - - # return the right output depending what the user specified: 'combine' or 'split' analysis - if(type=="combine" || type=="both"){ - if(length(invalids > 0)){ - if(warningMessage){ - message(paste0("WARNING: Invalid contingency table from '", paste(stdnames[invalids], collapse=", "), "' !\n Only total values are returned in the output table(s).")) - } - validityValue <- paste0("Invalid contingency table from '", paste(stdnames[invalids], collapse=", "), "'!") - }else{ - validityValue <- "All tables are valid!" - } - # adding labels to pooled outputs before returning them - pooledCounts <- structure(list(pooledCounts), names=paste0("pooled-",x,"(row)|",y,"(col)")) - pooledRowPercent <- structure(list(pooledRowPercent), names=paste0("pooled-",x,"(row)|",y,"(col)")) - pooledColPercent <- structure(list(pooledColPercent), names=paste0("pooled-",x,"(row)|",y,"(col)")) - pooledChi2test <- structure(list(pooledChi2test), names=paste0("pooled-",x,"(row)|",y,"(col)")) - out.all.studies <- list(colPercent.all.studies=pooledColPercent, rowPercent.all.studies=pooledRowPercent, chi2Test.all.studies=pooledChi2test, counts.all.studies=pooledCounts, validity=validityValue) - output.object <- out.all.studies - } - - if(type=="split" || type=="both"){ - if(length(invalids > 0)){ - if(warningMessage){ - message(paste0("WARNING: Invalid contingency table from '", paste(stdnames[invalids], collapse=", "), "' !\n Only total values are returned in the output table(s).")) - } - validityValue <- paste0("Invalid contingency table from '", paste(stdnames[invalids], collapse=", "), "'!") - }else{ - validityValue <- "All tables are valid!" - } - out.split <- (list(colPercent=colPercentTables, rowPercent=rowPercentTables, chi2Test=chi2Tests, counts=countTables, validity=validityValue)) - output.object <- out.split - if(type=="both"){ - output.object <- list(colPercent=colPercentTables, colPercent.all.studies=pooledColPercent,rowPercent=rowPercentTables,rowPercent.all.studies=pooledRowPercent, - chi2Test=chi2Tests, chi2Test.all.studies=pooledChi2test, counts=countTables, counts.all.studies=pooledCounts, validity=validityValue) - } - } - - return(output.object) - +ds.table2D <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.table2D()", "ds.table()") } diff --git a/R/ds.testObjExists.R b/R/ds.testObjExists.R index e12799df2..70b9a9e45 100644 --- a/R/ds.testObjExists.R +++ b/R/ds.testObjExists.R @@ -1,157 +1,13 @@ -#' #' @title Checks if an R object exists on the server-side -#' @description This function checks that a specified data object exists or has been correctly created on a -#' specified set of data servers. -#' @details Close copies of the code in this function -#' are embedded into other functions that create an object and you then wish to test whether it has successfully -#' been created e.g. \code{ds.make} or \code{ds.asFactor}. -#' -#' Server function called: \code{testObjExistsDS} -#' @param test.obj.name a character string specifying the name of the object to search. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} -#' objects obtained after login. If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @return \code{ds.testObjExists} returns a list of messages specifying that the object exists -#' on the server-side. -#' If the specified object does not exist in at least one -#' of the specified data sources or it exists but is of -#' class NULL, the function returns an error message specifying that -#' the object does not exist in all data sources. -#' @examples -#' \dontrun{ -#' ## Version 6, for version 5 see the Wiki -#' -#' # connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') +#' @description +#' `r lifecycle::badge("deprecated")` #' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "CNSIM.CNSIM2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' logindata <- builder$build() -#' -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' #Check if D object exists on the server-side -#' -#' ds.testObjExists(test.obj.name = "D", -#' datasources = connections) -#' -#' # Clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' -#' } +#' This function is defunct. Server-side functions now check that their input objects exist. +#' @param ... Not used. #' @author DataSHIELD Development Team +#' @md +#' @keywords internal #' @export -ds.testObjExists <- function(test.obj.name=NULL, datasources=NULL){ - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - # if not character send error message requesting valic object name - if(!is.character(test.obj.name)){ - return.message <- "Error: please provide the name of an object on the data servers as a character string in inverted commas" - return(return.message=return.message) - } - -########################################################################################################## -#MODULE 5: CHECK KEY DATA OBJECTS EXIST IN EACH SOURCE # - # -#SET APPROPRIATE PARAMETERS FOR THIS PARTICULAR FUNCTION # -test.obj.name<-test.obj.name # - # -# CALL SEVERSIDE FUNCTION # -calltext <- call("testObjExistsDS", test.obj.name) # - # -object.info<-DSI::datashield.aggregate(datasources, calltext) # - # -# CHECK IN EACH SOURCE WHETHER OBJECT NAME EXISTS # -# AND WHETHER OBJECT PHYSICALLY EXISTS WITH A NON-NULL CLASS # -num.datasources<-length(object.info) # - # - # -obj.name.exists.in.all.sources<-TRUE # -obj.non.null.in.all.sources<-TRUE # - # -for(j in 1:num.datasources){ # - if(!object.info[[j]]$test.obj.exists){ # - obj.name.exists.in.all.sources<-FALSE # - } # - if(is.null(object.info[[j]]$test.obj.class) || ("ABSENT" %in% object.info[[j]]$test.obj.class)){ # - obj.non.null.in.all.sources<-FALSE # - } # - } # - # -if(obj.name.exists.in.all.sources && obj.non.null.in.all.sources){ # - # - return.message<- # - paste0("A valid copy of data object <", test.obj.name, "> exists in all specified data sources") # - # - return(list(return.message=return.message)) # - # - }else{ # - # - return.message.1<- # - paste0("Error: A valid data object <", test.obj.name, "> does NOT exist in ALL specified data sources")# - # - return.message.2<- # - paste0("It is either ABSENT and/or has no valid content/class, for details see return.info above") # - # - return.message<-list(return.message.1,return.message.2) # - # - return.info<-object.info # - # - return(list(return.info=return.info,return.message=return.message)) # - # - } # -#END OF MODULE 5 # -########################################################################################################## - - # check in each source whether object name exists - # and whether object physically exists with a non-null class - num.datasources <- length(object.info) - - obj.name.exists.in.all.sources <- TRUE - obj.non.null.in.all.sources <- TRUE - - for(j in 1:num.datasources){ - if(!object.info[[j]]$test.obj.exists){ - obj.name.exists.in.all.sources <- FALSE - } - if(is.null(object.info[[j]]$test.obj.class) || ("ABSENT" %in% object.info[[j]]$test.obj.class)){ - obj.non.null.in.all.sources <- FALSE - } - } - - if(obj.name.exists.in.all.sources && obj.non.null.in.all.sources){ - return.message <- paste0("Data object ", test.obj.name, " exists in all sources") - return(list(return.message=return.message)) - }else{ - return.message.1 <- paste0("Error: A valid data object ", test.obj.name, " does NOT exist in all sources") - return.message.2 <- paste0("It is either ABSENT and/or has no valid content/class,see return.info above") - return.message <- list(return.message.1,return.message.2) - return.info <- object.info - return(list(return.info=return.info,return.message=return.message)) - } - +ds.testObjExists <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.testObjExists()", details = "Server-side functions now check that their input objects exist.") } -#ds.testObjExists diff --git a/R/ds.vectorCalc.R b/R/ds.vectorCalc.R index f8918aab4..30ef13284 100644 --- a/R/ds.vectorCalc.R +++ b/R/ds.vectorCalc.R @@ -1,91 +1,13 @@ -#' #' @title Performs a mathematical operation on two or more vectors -#' @description Carries out a row-wise operation on two or more vector. The function calls no -#' server side function; it uses the R operation symbols built in DataSHIELD. -#' @details In DataSHIELD it is possible to perform an operation on vectors by just using the relevant -#' R symbols (e.g. '+' for addition, '*' for multiplication, '-' for subtraction and '/' for division). -#' This might however be inconvenient if the number of vectors to include in the operation is large. -#' This function takes the names of two or more vectors and performs the desired operation which could be -#' an addition, a multiplication, a subtraction or a division. If one or more vectors have a missing value -#' at any one entry (i.e. observation), the operation returns a missing value ('NA') for that entry; the output -#' vectors has, hence the same length as the input vectors. -#' @param x a vector of characters, the names of the vectors to include in the operation. -#' @param calc a character, a symbol that indicates the mathematical operation to carry out: -#' '+' for addition, '/' for division, *' for multiplication and '-' for subtraction. -#' @param newobj the name of the output object. By default the name is 'vectorcalc.newobj'. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @return no data are returned to user, the output vector is stored on the server side. +#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' This function is defunct. Please use `ds.make()` instead. +#' @param ... Not used. #' @author Gaye, A. +#' @md +#' @keywords internal #' @export -#' @examples -#' \dontrun{ -#' -#' # load the file that contains the login details -#' data(logindata) -#' -#' # login and assign the required variables to R -#' myvar <- list('LAB_TSC','LAB_HDL') -#' conns <- datashield.login(logins=logindata,assign=TRUE,variables=myvar) -#' -#' # performs an addtion of 'LAB_TSC' and 'LAB_HDL' -#' myvectors <- c('D$LAB_TSC', 'D$LAB_HDL') -#' ds.vectorCalc(x=myvectors, calc='+') -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(conns) -#' -#' } -#' -ds.vectorCalc <- function(x=NULL, calc=NULL, newobj=NULL, datasources=NULL){ - .Deprecated("ds.make") - - # look for DS connections - if(is.null(datasources)){ - datasources <- datashield.connections_find() - } - - # ensure datasources is a list of DSConnection-class - if(!(is.list(datasources) && all(unlist(lapply(datasources, function(d) {methods::is(d,"DSConnection")}))))){ - stop("The 'datasources' were expected to be a list of DSConnection-class objects", call.=FALSE) - } - - if(is.null(x)){ - stop("x=NULL. Please provide the names of the objects to combine!", call.=FALSE) - } - - if(length(x) < 2){ - stop("You must provide the names of at least two vectors!", call.=FALSE) - } - - # create a name by default if user did not provide a name for the new variable - if(is.null(newobj)){ - newobj <- "vectorcalc.newobj" - } - - # the input variable might be given as column table (i.e. D$object) - # or just as a vector not attached to a table (i.e. object) - # we have to make sure the function deals with each case - xnames <- extract(x) - varnames <- xnames$elements - obj2lookfor <- xnames$holders - - # check if the input object(s) is(are) defined in all the studies - for(i in 1:length(varnames)){ - if(is.na(obj2lookfor[i])){ - defined <- isDefined(datasources, varnames[i]) - }else{ - defined <- isDefined(datasources, obj2lookfor[i]) - } - } - - # call the internal function that checks the input object(s) is(are) of the same class in all studies. - for(i in 1:length(x)){ - typ <- checkClass(datasources, x[i]) - } - - # call the server side function - cally <- paste0(paste(x,collapse=calc)) - DSI::datashield.assign(datasources, newobj, as.symbol(cally)) - +ds.vectorCalc <- function(...) { + lifecycle::deprecate_stop("7.0.0", "ds.vectorCalc()", "ds.make()") } diff --git a/R/isAssigned.R b/R/isAssigned.R deleted file mode 100644 index 0460cb779..000000000 --- a/R/isAssigned.R +++ /dev/null @@ -1,24 +0,0 @@ -#' -#' @title Checks an object has been generated on the server side -#' @description This is an internal function. -#' @details After calling an assign function it is important -#' to know whether or not the action has been completed by -#' checking if the output actually exists on the server side. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @param newobj a character, the name the object to look for. -#' @keywords internal -#' @return nothing is return but the process is stopped if -#' the object was not generated in any one server. -#' -isAssigned <- function(datasources=NULL, newobj=NULL){ - cally <- call('exists', newobj) - qc <- DSI::datashield.aggregate(datasources, cally) - indx <- as.numeric(which(qc==TRUE)) - if(length(indx) > 0 & length(indx) < length(datasources)){ - stop("The output object, '", newobj, "', was generated only for ", names(datasources)[indx], "!", call.=FALSE) - } - if(length(indx) == 0){ - stop("The output object has not been generated for any of the studies!", call.=FALSE) - } -} diff --git a/R/meanByClassHelper0a.R b/R/meanByClassHelper0a.R deleted file mode 100644 index c1c51c9b6..000000000 --- a/R/meanByClassHelper0a.R +++ /dev/null @@ -1,46 +0,0 @@ -#' -#' @title Computes the mean values of a numeric vector across a factor vector -#' @description This is an internal function. -#' @details This function is called by the function 'ds.meanByClass' to produce the final tables -#' if the user specifies two loose vectors. -#' @param a a character, the name of a numeric vector. -#' @param b a character, the name of a factor vector. -#' @param type a character which represents the type of analysis to carry out. If \code{type} is set to -#' 'combine', a pooled table of results is generated. If \code{type} is set to 'split', a table of results -#' is generated for each study. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @return a table or a list of tables that hold the length of the numeric variable and its mean -#' and standard deviation in each subgroup (subset). -#' @keywords internal -#' @author Gaye, A. -#' -meanByClassHelper0a <- function(a, b, type, datasources){ - - # generate a data frame from the two vector - x <- c(a,b) - aa <- unlist(strsplit(a, split='$', fixed=TRUE)) - bb <- unlist(strsplit(b, split='$', fixed=TRUE)) - if(length(aa) > 1){ - v1 <- aa[2] - }else{ - v1 <- aa[1] - } - if(length(bb) > 1){ - v2 <- bb[2] - }else{ - v2 <- bb[1] - } - v <- c(v1, v2) - newD <- "X" - - x.names.transmit <- paste(x, collapse=",") - col.names.transmit <- paste(v, collapse=',') - cally <- call("dataFrameDS", x.names.transmit, NULL, FALSE, TRUE, col.names.transmit, TRUE, FALSE) - DSI::datashield.assign(datasources, newD, cally) - - # get the 'loose' names of the variables and call the function that generate the results - - output <- meanByClassHelper0b(newD, v1, v2, type, datasources) - return(output) -} diff --git a/R/meanByClassHelper0b.R b/R/meanByClassHelper0b.R deleted file mode 100644 index 0c37b9e43..000000000 --- a/R/meanByClassHelper0b.R +++ /dev/null @@ -1,93 +0,0 @@ -#' -#' @title Runs the computation if variables are within a table structure -#' @description This is an internal function. -#' @details This function is called by the function 'ds.meanByClass' to produce the final tables -#' if the user specify a table structure. -#' @param x a character, the name of the dataset to get the subsets from. -#' @param outvar a character vector, the names of the continuous variables -#' @param covar a character vector, the names of up to 3 categorical variables -#' @param type a character which represents the type of analysis to carry out. If \code{type} is set to -#' 'combine', a pooled table of results is generated. If \code{type} is set to 'split', a table of results -#' is generated for each study. -#' @param datasources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @return a table or a list of tables that hold the length of the numeric variable(s) and their mean -#' and standard deviation in each subgroup (subset). -#' @keywords internal -#' @author Gaye, A. -#' @author Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -#' -meanByClassHelper0b <- function(x, outvar, covar, type, datasources){ - if(is.null(outvar)){ - stop(" Please specify at least 1 continuous variables - see parameter 'outvar'!", call.=FALSE) - } - - if(is.null(covar)){ - stop(" Please specify at 1 or up to 3 categorical variables (factors) - see parameter 'covar'!", call.=FALSE) - } - - if(length(covar) > 3){ - stop("More than 3 categorical variables specified! - see parameter 'covar'.", call.=FALSE) - } - - # categories in each of the categorical variables - classes <- vector("list", length(covar)) - for(i in 1:length(covar)){ - cally <- call("levelsDS", paste0(x, '$', covar[i])) - - all.study.levels <- list() - full.levels.resp <- DSI::datashield.aggregate(datasources, cally) - for (index in 1:length(full.levels.resp)) { - if (any(is.na(full.levels.resp[[index]]$Levels))) - stop(paste0("Failed to get levels from study"), call.=FALSE) - all.study.levels[[index]] <- full.levels.resp[[index]]$Levels - } - classes[[i]] <- all.study.levels - } - - # loop through the datasources and break down the original dataset by the specified categorical variable - # the names of the subset tables are stored for mean and sd computations - message("Generating the required subset tables (this may take couple of minutes, please do not interrupt!)") - subsetnames <- vector("list", length(datasources)) - for(i in 1:length(datasources)){ - message("--", names(datasources)[i]) - datasets <- x - for(j in 1:length(covar)){ - message(" ", covar[j], "...") - newnames <- meanByClassHelper1(datasources[i], datasets, covar[j], classes[[j]][[i]]) - datasets <- newnames - } - subsetnames[[i]] <- datasets - } - names(subsetnames) <- names(datasources) - - # a study might have invalid sub-datasets which we cannot get mean and sd from, to identify those - # we loop by categories, if a study has invalid table (i.e. table with NAs only) we exclude it - # for that category when calculating the mean and sd values for that category - invalidrecorder <- vector("list", length(datasources)) - for(i in 1:length(datasources)){ - for(j in 1:length(subsetnames[[i]])){ - check1 <- which(unlist(strsplit(subsetnames[[i]][j],"_")) == "INVALID") - check2 <- which(unlist(strsplit(subsetnames[[i]][j],"_")) == "EMPTY") - if(length(check1) > 0 | length(check2 > 0)){ - invalidrecorder[[i]] <- append(invalidrecorder[[i]], 1) - }else{ - invalidrecorder[[i]] <- append(invalidrecorder[[i]], 0) - } - } - } - - # compute the length, mean and standard deviation for each 'outvar' - if(type=='combine'){ - results <- meanByClassHelper2(datasources, subsetnames, outvar, invalidrecorder) - return(results) - }else{ - if(type=='split'){ - results <- meanByClassHelper3(datasources, subsetnames, outvar, invalidrecorder) - return(results) - }else{ - stop('Function argument "type" has to be either "combine" or "split"') - } - } - -} diff --git a/R/meanByClassHelper1.R b/R/meanByClassHelper1.R deleted file mode 100644 index 4b98201e6..000000000 --- a/R/meanByClassHelper1.R +++ /dev/null @@ -1,37 +0,0 @@ -#' -#' @title Generates subset tables -#' @description This is an internal function. -#' @details This function is called by the function 'ds.meanByClass' to break down -#' the initial table by the specified categorical variables. -#' @param dtsource a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @param tables a character vector, the tables to breakdown -#' @param variable a character, the variable to subset on -#' @param categories a character vector, the classes in the variables to subset on -#' @keywords internal -#' @return a character the names of the new subset tables. -#' @author Gaye, A. -#' -meanByClassHelper1 <- function(dtsource, tables, variable, categories){ - - newtablenames <- c() - for(i in 1:length(tables)){ - dt2process <- tables[i] - # look for invalid and empty tables - check1 <- which(unlist(strsplit(dt2process,"_")) == "INVALID") - check2 <- which(unlist(strsplit(dt2process,"_")) == "EMPTY") - if(length(check1) > 0 | length(check2) > 0){ - newtablenames <- append(newtablenames, meanByClassHelper4(dtsource, 'tempholder', dt2process, variable, categories)) - }else{ - if(is.null(variable)){ - cally <- paste0("subsetByClassDS('", dt2process, "')") - }else{ - cally <- paste0("subsetByClassDS('", dt2process, "', c('",paste(variable,collapse="','"),"'))") - } - DSI::datashield.assign(dtsource, 'tempholder', as.symbol(cally)) - newtablenames <- append(newtablenames, meanByClassHelper4(dtsource, 'tempholder', dt2process)) - } - } - - return(newtablenames) -} diff --git a/R/meanByClassHelper2.R b/R/meanByClassHelper2.R deleted file mode 100644 index aa7667ba0..000000000 --- a/R/meanByClassHelper2.R +++ /dev/null @@ -1,93 +0,0 @@ -#' -#' @title Generates a table for pooled results -#' @description This is an internal function. -#' @details This function is called by the function 'ds.meanByClass' to produce the final table -#' if the user sets the parameter 'type' to combine (the default behaviour of 'ds.meanByClass'). -#' @param dtsources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @param tablenames a character vector, the name of the subset tables -#' @param variables a character vector, the names of the continuous variables to computes a mean for. -#' @param invalidrecorder a list, holds information about invalid subsets in each study. -#' @keywords internal -#' @return a matrix, a table which contains the length, mean and standard deviation of each of the -#' specified 'variables' in each subset table. -#' @author Gaye, A. -#' @author Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -#' -meanByClassHelper2 <- function(dtsources, tablenames, variables, invalidrecorder){ - numtables <- length(tablenames[[1]]) - # now get the mean and SD for the continuous variables in each of the subset tables - finaltable <- matrix(numeric(0), ncol=numtables) - finalrows <- c() - for(z in 1:length(variables)){ - # set an empty matrix to hold the results - outable <- matrix(numeric(0), nrow=2, ncol=numtables) - xrows <- c(paste0(variables[z],'(length)'), paste0(variables[z],'(mean&sd)')) - for(i in 1:numtables){ - # inform of progress - message(paste0(variables[z], " - Processing subset table ", i, " of ", numtables, "...")) - tnames <- tablenames - tablename <- paste(unlist(strsplit(tablenames[[1]][i], "_INVALID")), collapse="") - tablename <- paste(unlist(strsplit(tablename, "_EMPTY")), collapse="") - # check what datasource has invalid subset - rc <- c() - for(q in 1:length(dtsources)){ - if(invalidrecorder[[q]][i] == 1){ - rc <- append(rc, q) - } - } - if(length(rc) > 0){ - lengths <- c() - for(qq in 1:length(dtsources)){ - # check if the subset table exists (when the initial table is invalid no subsequent subset is created) - cally <- call("exists", tnames[[qq]][i]) - def <- unlist(DSI::datashield.aggregate(dtsources[qq], cally)) - if(def){ - cally <- call("dimDS", tnames[[qq]][i]) - temp <- DSI::datashield.aggregate(dtsources[qq], cally) - lengths <- append(lengths, temp[[1]]$dim[1]) - }else{ - lengths <- append(lengths, 0) - } - } - if(length(rc) == length(dtsources)){ - ll <- sum(lengths) - mm <- NA - sdv <- NA - mean.sd <- paste0(mm, '(', sdv, ')') - entries <- c(ll, mean.sd) - }else{ - ll <- sum(lengths) - dtsc <- dtsources[-rc] # ignore invalid tables when it comes to mean and sd calculation, there value is NA anyway - mm <- round(getPooledMean(dtsc, paste0(tablename,'$',variables[z])),2) - sdv <- round(getPooledVar(dtsc, paste0(tablename,'$',variables[z])),2) - if(is.na(mm)){ sdv <- NA } - mean.sd <- paste0(mm, '(', round(sqrt(sdv),2), ')') - entries <- c(ll, mean.sd) - } - }else{ - cally <- call("lengthDS", paste0(tablename,'$',variables[z])) - lengths.raw <- DSI::datashield.aggregate(dtsources, cally) - ll <- sum(sapply(lengths.raw, function(r) r$length)) - mm <- round(getPooledMean(dtsources, paste0(tablename,'$',variables[z])),2) - sdv <- round(getPooledVar(dtsources, paste0(tablename,'$',variables[z])),2) - if(is.na(mm)){ sdv <- NA} - mean.sd <- paste0(mm, '(', round(sqrt(sdv),2), ')') - entries <- c(ll, mean.sd) - } - for(j in 1:2){ - outable[j,i] <- entries[j] - } - } - finalrows <- append(finalrows, xrows) - finaltable <- rbind(finaltable, outable) - } - # specify the name of the rows and the columns - cols <- tablenames[[1]] - for(i in which(invalidrecorder[[1]] == 1)){ - cols[i] <- paste(unlist(strsplit(cols[i], "_INVALID")), collapse="") - } - colnames(finaltable) <- cols - rownames (finaltable) <- finalrows - return(finaltable) -} diff --git a/R/meanByClassHelper3.R b/R/meanByClassHelper3.R deleted file mode 100644 index 3c753776c..000000000 --- a/R/meanByClassHelper3.R +++ /dev/null @@ -1,75 +0,0 @@ -#' -#' @title Generates results tables for each study separately -#' @description This is an internal function. -#' @details This function is called by the function 'ds.meanByClass' to produce the final tables -#' if the user sets the parameter 'type' to 'split'. -#' @param dtsources a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @param tablenames a character vector, the name of the subset tables -#' @param variables a character vector, the names of the continuous variables to computes a mean for. -#' @param invalidrecorder a list, holds information about invalid subsets in each study -#' @keywords internal -#' @return a list which one results table for each study. -#' @author Gaye, A. -#' @author Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -#' -meanByClassHelper3 <- function(dtsources, tablenames, variables, invalidrecorder){ - numtables <- length(tablenames[[1]]) - stdnames <- names(dtsources) - - finalist <- vector('list', length(dtsources)) - for(s in 1:length(dtsources)){ - - # now get the mean and SD for the continuous variables in each of the subset tables - finaltable <- matrix(numeric(0), ncol=numtables) - finalrows <- c() - for(z in 1:length(variables)){ - # set an empty matrix to hold the results - outable <- matrix(numeric(0), nrow=2, ncol=numtables) - xrows <- c(paste0(variables[z],'(length)'), paste0(variables[z],'(mean&sd)')) - for(i in 1:numtables){ - # inform of progress - message(paste0(stdnames[s], ", ", variables[z], " - Processing subset table ", i, " of ", numtables, "...")) - - # check what datasource has invalid subset - rc <- c() - if(invalidrecorder[[s]][i] == 1){ rc <- append(rc, q) } - - if(length(rc) > 0){ - cally <- call("lengthDS", paste0(tablenames[[s]][i],'$',variables[z])) - ll <- DSI::datashield.aggregate(dtsources[s], cally)[[1]]$length - mm <- NA - sdv <- NA - mean.sd <- paste0(mm, '(', sdv, ')') - entries <- c(ll, mean.sd) - }else{ - cally <- call("lengthDS", paste0(tablenames[[s]][i],'$',variables[z])) - ll <- DSI::datashield.aggregate(dtsources[s], cally)[[1]]$length - mm <- round(getPooledMean(dtsources[s], paste0(tablenames[[s]][i],'$',variables[z])),2) - sdv <- round(getPooledVar(dtsources[s], paste0(tablenames[[s]][i],'$',variables[z])),2) - if(is.na(mm)){ sdv <- NA } - mean.sd <- paste0(mm, '(', round(sqrt(sdv),2), ')') - entries <- c(ll, mean.sd) - } - for(j in 1:2){ - outable[j,i] <- entries[j] - } - } - finalrows <- append(finalrows, xrows) - finaltable <- rbind(finaltable, outable) - } - - # specify the name of the rows and the columns - cols <- tablenames[[s]] - for(i in which(invalidrecorder[[s]] == 1)){ - cols[i] <- paste(unlist(strsplit(cols[i], "_INVALID")), collapse="") - } - colnames(finaltable) <- cols - rownames (finaltable) <- finalrows - - finalist[[s]] <- finaltable - - } - names(finalist) <- names(dtsources) - return(finalist) -} diff --git a/R/meanByClassHelper4.R b/R/meanByClassHelper4.R deleted file mode 100644 index 9597a7e87..000000000 --- a/R/meanByClassHelper4.R +++ /dev/null @@ -1,38 +0,0 @@ -#' -#' @title Gets the subset tables out of the list (i.e. unlist) -#' @description This is an internal function. -#' @details This function is called by the function 'ds.meanByClass' to obtain 'loose' -#' subset tables because the 'subsetByClass' function does not handle a table within a list. -#' @param dtsource a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -#' the default set of connections will be used: see \link[DSI]{datashield.connections_default}. -#' @param alist the name of the list that holds the final subset tables -#' @param initialtable a character the name of the table that the subset were generated from -#' @param variable a character, the variable to subset on -#' @param categories a character vector, the classes in the variables to subset on -#' @keywords internal -#' @return the 'loose' subset tables are stored on the server side -#' @author Gaye, A. -#' -meanByClassHelper4 <- function(dtsource, alist, initialtable, variable=NA, categories=NA){ - - check1 <- which(unlist(strsplit(initialtable,"_")) == "INVALID") - check2 <- which(unlist(strsplit(initialtable,"_")) == "EMPTY") - - newsubsets <- c() - - if(length(check1) > 0 | length(check2) > 0){ - for(m in 1:length(categories)){ - name2use <- paste0(initialtable,'.',variable, categories[m], "_INVALID") - newsubsets <- append(newsubsets, name2use) - } - }else{ - cally <- call('namesDS', alist) - subsetnames <- unique(unlist(DSI::datashield.aggregate(dtsource, cally))) - for(m in 1:length(subsetnames)){ - name2use <- paste0(unlist(strsplit(paste0(initialtable,'.',subsetnames[m]), '.level_')), collapse='') - DSI::datashield.assign(dtsource, name2use, as.symbol(paste0(alist,'$',subsetnames[m]))) - newsubsets <- append(newsubsets, name2use) - } - } - return(newsubsets) -} diff --git a/R/rowPercent.R b/R/rowPercent.R deleted file mode 100644 index fa0e798d9..000000000 --- a/R/rowPercent.R +++ /dev/null @@ -1,22 +0,0 @@ -#' -#' @title Produces row percentages -#' @description this is an INTERNAL function. -#' @details The function is required required by the client function \code{ds.table2D}. -#' @param dataframe a data frame -#' @keywords internal -#' @return a data frame -#' @author Gaye A -#' -rowPercent <- function(dataframe){ - dt <- dataframe - lastrow <- dim(dataframe)[1] - lastcol <- dim(dataframe)[2] - for(i in 1:lastrow){ - totalval <- dataframe[i, lastcol] - dt[i,] <- round((dataframe[i,]/totalval)*100,2) - } - return(dt) -} - - - diff --git a/R/secure.global.ranking.md b/R/secure.global.ranking.md deleted file mode 100644 index e53ff0f21..000000000 --- a/R/secure.global.ranking.md +++ /dev/null @@ -1,87 +0,0 @@ -Additional information detailing the cluster of functions that enable secure global ranking and estimation of key global quantiles. -=================================================================================================================================== - -This functionality is based on two pivotal clientside functions: ds.ranksSecure and ds.extractQuantiles -------------------------------------------------------------------------------------------------------- - -**ds.ranksSecure** is a clientside function which calls a series of other clientside and serverside functions to securely generate the global ranks of a numeric vector "V2BR" (vector to be ranked) in order to set up analyses on V2BR based on non-parametric methods, for some types of survival analysis and to derive key global quantiles (e.g. the median, lower (25%) and upper (75%) quartiles, and the 95% and 97.5% quantiles) across all sources simultaneously. In general, these global quantiles are different to the equivalent quantiles calculated independently in each data source separately and then summarised by their mean or median across the data sources.. - -The ranking procedure progresses in a series of steps controlled by ds.ranksSecure and each step is enacted by a series of secondary functions which are a mixture of clientside and serverside aggregate (both assign and aggregate functions). The analytic steps are as follows: - -(1) The quantileMeanDS (serverside aggregate) function is called to generate the global mean of V2BR (mean.input.var) and a deliberately non-conservative estimate of its standard deviation (max.sd.input.var) in order to intelligently prime the first stage of the encryption process (see below). - -(2) The ds.dmtC2S (clientside) function returns the estimates of the global mean and standard deviation of V2BR to the serverside at each study. - -(3) The minMaxRandDS (serverside aggregate) function uses a pseudo-random procedure based on a non-identifiable and non-repeatable seed to create a "random" maximum value in each study that is **definitely more positive** (by an indeterminate amount) than the actual maximum of V2BR in that study and an equivalent random minimum that is **definitely more negative** than the actual minimum. These are returned to the clientside from each study and an algorithm embedded in the code of ds.ranksSecure identifies the maximum (most positive) maximum **across all studies** and the corresponding minimum minimum (most negative) **across all studies**. - -(4) The ds.dmtC2S (clientside) function returns the maximum maximum and minimum minimum to -the serverside so all studies share the same values. These will not now be used unless there is an explicit decision to declare missings (NAs) as high or low via the argument NA.manage ="NA.hi" or NA.manage = "NA.low" in which case the NAs in all studies will be replaced by the shared -maximum maximum (if NA.manage = "NA.hi") or the shared minimum minimum if NA.manage = "NA.low"). In the former case all NAs will appear as the highest ranked values in every study (with the same values and ranking in all studies), in the latter case they will be the lowest ranked values in all studies (but will again be the same in all studies). Please note that the precise values of the maximum maximum or minimum minimum do not matter (hence the effect of the analysis can precisely be replicated even though it invokes a non-repeatable seed (see above). This is because the actual analysis will ultimately be based on ranks and the top and bottom rankings related to the maximum maximum and the minimum minimum will always be the same regardless of the actual quantitative values of the maximum maximum and minimum minimum - -(5) This is one of the most fundamental steps. In it, the blackBoxDS (serverside assign) function is called with a series of the key arguments specified in the original call to ds.ranksSecure (see details of parameters in the function header) or else referring to objects newly created by the serverside functions described above. These arguments include: input.var.name, max.sd.input.var, mean.input.var, shared.seedval=shared.seed.value, synth.real.ratio, and NA.manage=NA.manage). The function blackBoxDS first generates a set of randomly synthesised pseudo-data that span -the distribution of the real data, but with substantial overlap,. The number of pseudo-observations generated is determined by the synth.real.ratio argument which defaults to 2, so twice as many pseudo data are generated in each study as there originally real data. - -If the original data are not real but rounded to a given precision, blackBoxDS identifies the predominant form of rounding eg integers, tens, thousands, 0.001, 0.1 etc. Then rather than generating synthetic data at complete random (ie in double precision), blackBoxDS instead generates a vector of appropriately rounded terms: eg if the predominant rounding is tens, part of the random rounding vector may be something like …. 50,-30,0,100,40,90,-80 .... . The corresponding vector of synthetic data is then obtained by adding a random sample of the original data (in an indeterminate random order) to the random rounding data. Thus, if a sample of the original real data is ….. 10,20,‑60,0,30.23,-60,120.4 ... and the random rounding vector is as above, the relevant component of the resultant synthetic data will be … 60,-10,-60,100,70.23,30,40.4 ... . This approach ensures the nature of the rounding in the synthetic data is broadly the same as in the original data. This is important because the degree of rounding influences the number of ties expected and if (in an illustrative extreme setting) the original data were all integers while the synthetic data were double-precision, most ties (even after encryption) would be identifiable as real data. This is a crucial strategy to mitigate disclosure risk in the step when encrypted original and synthetic data are co-located on the client server (see below) - -Next, blackBoxDS uses the global estimates of mean and standard deviation (as described above) to approximately (but deliberately not precisely) centralise the real- and pseudo- data. Next, blackBoxDS sequentially applies 7 rounds of transformation to both the real and pseudo data. With data held in either double precision or any level of rounding every transformation algorithm faithfully maintains the rank order of the data. The first algorithm simply applies a probit transformation which converts the original approximately centralised real and pseudo data from values typically running from -k through 0 up to +k to proportions which are all strictly greater than 0 and less than 1. This is not strictly encryption because it is a known deterministic transformation that could easily be reversed but it sets up the data in a way that makes it easy to ensure that a range of encrypting transformations can then be applied that will definitely maintain the original rank order and cannot be replicated without knowing the order in which the transforming functions were applied and the value of the random parameters with which each transformation is associated. - -To be specific, the next 6 rounds of encryption each invoke one of three monotonic functions with a single randomly selected parameter (lambda) associated with each transformation. Each value of lambda is drawn (independently) from a pseudo-random uniform(0.0001,1) distribution. So if the current element of the variable being transformed is x[i] the transformed value is obtained as x[i+1]<- x[i]^lambda (under algorithm 1); x[i+1]<- x[i]+lambda (under algorithm 2); and x[i+1]<- x[i]*lambda (under algorithm 3). The three algorithms are each applied twice in the block of six, but their order of application is randomly selected as well as the values of lambda. The randomisation process generating the values of lambda and the order of sequential application of the three algorithms is initialised via a seed shared across the different studies so each study applies the various algorithms in the same order with the same lambda as all the other studies. - -At present this shared seed is simply determined by the argument . Even knowing that seed it would be exceedingly difficult to recover the original starting values of the input.var without having direct access to the real data on a server. This is because although the process generating the random order of the transformation procedures and the values of lambda for each transformation are the same in each study (initialised by the shared seed), the procedure leading to random generation of the pseudo-data is deliberately different in each study (the shared seed being first modified by a function that depends on the precise numeric characteristics of the variable being ranked [V2BR], before the randomisation sequence is started). This makes it more -difficult for the analyst (working on the DataSHIELD client) to distinguish between encrypted real and encrypted pseudo-observations when they are transferred to the client (see below). Furthermore, when (at the very end of the running of ds.rankSecure) the encrypted real data appear alone on the client server (also see below) the data will first have been through a procedure that converts encrypted real values to ranks and encrypted ranks and this makes reverse engineering -near impossible even knowing the shared seed. However, to increase security yet further in the immediate future we will be implementing a new function (already prototyped) that allows a number (the shared seed) to be securely shared across the studies without the client analyst being able to infer its value, even in theory. - -Before moving to the next main step in the function (where data are transferred to the client) blackBoxDS checks that the ranks in the original data, the probit transformed data and the data following each of the six rounds of random transformation are all identical. This means the ranks, -including ties in the ranks are precisely the same for all of these eight vectors, in all studies. If they -are not the same a message is returned that suggests that, amongst other information, suggests you might try a different shared random seed. This is in case some exceedingly unlikely transformation has led to, for example, an NA. To date no example has arisen where this has happened. If it repeatedly fails despite using different seeds, it suggests there is something more fundamentally wrong with the data or analysis code which should be explored and corrected. Finally, blackBoxDS writes the key components of its output to a data.frame called **"blackbox.output.df"** on the server side. This contains 8 columns in each study: column 1 = vector containing all original real values and synthesised values in the given study; column 2 = the equivalent vector containing values after all 7 seven rounds of transformation are complete; column 3 = the ranks of values in column 1 but as the data frame is sorted (ascending) by the values in column 1, it simply runs 1:Ns where Ns is the total number of real and synthetic values in the given study; column 4 = ranks of column 2 which also runs 1:Ns because of the sorting of the data frame; column 5 holds the original sequential IDs for the data vector consisting of values 1:Ns ordered in alignment with a vector containing all real values of input.var in their original order stacked over all synthetic values in their order of synthesis. The values 1:Ns in column 5 appear in a haphazard order, but by by re-sorting based on column 5 all of -the data frame values relating to the real data and synthetic data can easily be separated and extracted in their original order; column 6 is a vector of 0s and 1s denoting whether each row relates to a real value or a synthetic value; column 7 is the same as column 3 and 4 (ie 1:Ns) but it is called “ID.by.val” and can be used as the basis for re-sorting the data.frame back to value order (ascending) based on column 1 if it has been temporarily re-sorted to a different order. Please note , columns 3, 4 and 7 are technically redundant and it is possible that only column 7 will be kept in later versions of this function; column 8 is called SOURCE.ID which is a vector in which all elements take the value s in study s, where s denotes that the specified study is the sth listed study amongst the datasources used. - -(6) Next the ranksSecureDS1(serverside aggregate) function extracts columns 2 and 7 of the serverside data frame **"blackbox.output.df"** and transmits them to the clientside. These -are the 7-fold transformed ('final-encrypted') original and synthetic values from each study in ascending order and the 1:Ns IDs sitting beside them. Although they carry equivalent information pertaining to ranking as the original real/synthesised data their encryption ensures they are non-disclosive, and it is in any case impossible to separate the real and synthetic data. - -Code in ds.ranksSecure next takes the 2 column data frame consisting of the final-encrypted values and values 1:Ns from study s and adds an extra column consisting solely of the value s. These three column study-specific data frames from each study are then stacked using the rbind() function. The resultant data frame is then reordered based on the global ranks of column 1 and a fourth column is added with values 1:M where M is the sum of the number of real and synthetic values (Ns) across all studies s combined. This fourth column therefore holds the global ranks of the original values of input.var (the input variable) across all studies as well as the intervening global ranks for the synthetic data. Ranks are modified as would be expected if there are ties: eg if a short vector to be ranked was c(10,3,8,3,2) it would generate ranks c(5,2.5,4,2.5,1). - -The function ds.ranksSecure next creates a subset of the 4 column data frame for each study s. This contains values from study s only by selecting rows in which there is a values of s in column 3. - -(7) The ds.dmtC2S (clientside) function then returns each of the 4 column study-specific data frames (to be called sR4.df on the server) to the corresponding serverside for study s. It should be noted that each of these data frames is still in the original order (1:Ns) based on ascending sorting of the original input variable (real and synthetic) in study s which is also - by definition - in the order of the corresponding global ranks across ALL studies. Because the variable (numstudies) which denotes the number of studies, which was used earlier, has been lost as serverside functions are called, run, and closed the ds.dmtC2S (clientside) function is also used to retransmit the value of numstudies to the serverside. - -(8) Next the ranksSecureDS2 (serverside assign) is used to cbind the **blackbox.output.df** data frame to **sR4.df** in each study and then to select just the rows with real (rather than synthetic) data. Because of the original sort (ascending) by the value of the encrypted input.var, blackbox.output.df and sR4.df in any given study have the same number of rows in the same order. In effect, this means that ranksSecureDS2 might most simply be viewed as stamping the global ranks on to **blackbox.output.df** and restricting the resultant data frame to include only the rows corresponding to real data. This is written as the data frame **"sR5.df"** on to the serverside for each separate study, and this forms the basis of the next major component of the ranking analysis. Note that at this stage, the global ranks (based on real and synthetic data) of all the real data are in precisely the same order as their equivalent global ranks would be if they were based solely on the real data. But the numeric value of the actual ranks will in general differ in the two settings (see below). - -(9) The key component of **sR5.df** is the vector of global ranks in column 9 which is designated **sR5.df$global.rank**. The next step in analysis is based on a modified version of blackBoxDS (called blackBoxRankDS, which is also a serverside assign function). The input.var to this modified function is now declared as **sR5.df$global.rank** and blackBoxRankDS undertakes multiple rank-consistent transformations of this input variable in an equivalent way to blackBoxDS when applied to the original input.var. Following the transformation procedure the global ranks become one of the key components of a data frame designated blackbox.ranks.df that still remains in the order of the earlier processing steps (ascending on value of input.val, with any ties left in the same order as before). - -Unlike the blackBoxDS function, blackBoxRanksDS does not generate any synthetic data. This means that when the encrypted ranks are transferred to the clientside in the next step, they are not obscured by any pseudo-data. But, because these are encrypted ranks, not encrypted quantitative values, even if someone could reverse engineer the encryption all they would get are ranks rather than actual values (and in principle we already know that the ranks 1:M [incorporating possible ties] exist across all the studies and deriving the actual ranks by reverse engineering would tell a hacker nothing particularly disclosive about the original values of real data. The use of ranks rather than quantitative values would not have been possible when the original encrypted values were transmitted to the clientside (see step 6) because in order to globally rank the data it was at some stage necessary for (encrypted) quantitative values to be compared from all studies simultaneously. If only study-specific ranks had been transferred to the clientside all we would know would be that the ranks in each study ran from 1:Ns and it would be impossible to know, for example, whether the actual quantitative value corresponding to a given rank in one study was the same, higher or lower than the value corresponding to the same rank in another study. - -(10) The next step referred to under step nine is based on the ranksSecureDS3 (serverside aggregate) function. This extracts the column of encrypted global ranks from **blackbox.ranks.df** and -cbinds them to an ID vector 1:NRs (where NRs is the original number of real - not real+synthetic - observations in study s). This means that even tied ranks have unique ID values for re-sorting and checking the quality of linkage etc. The function ranksSecureDS3 also cbinds a studyid vector (all elements having the same value, s) to the encrypted global ranks vector and the ID vector. The resultant data frames from each study are copied into the clientside and then stacked across all studies using the rbind() function and the combined data frame is sorted by the encrypted -global ranks. A new global.real.rank is then allocated using the R's standard ranking function: global.real.rank <- rank(global.rank). In essence this converts the original global ranks (which were based on ranking the data including both real and synthetic data (and so ran sequentially from 1:M [with appropriate allocation for ties]) into new global ranks based only on the real data. These run from 1:MR where MR = the sum of NRs over all studies s. These two sets of ranks have precisely the same order, but the original range of real + synthetic ranks contains many values that are absent from the global.real.rank vector and so the numeric values of the two sets of ranks differ. - -(11) As before (see step 7) the ds.dmtC2S (clientside) function is now used to return the key information in the clientside data frame to the serverside. The key information includes the encrypted global ranks (the global.real.ranks vector) and the studyid vector. Only rows where studyid=s are passed to the serverside in study s. In addition, by dividing the global.real.ranks by the total number of real observations across all studies (ie MR) an extra column is created called global.real.quantile. Together these three vector form a data frame called "global.ranks.quantiles.df" which is what ds.dmtC2S actually passes to the serverside. - -(12) The global.ranks.quantiles.df data frame returned to each study is still ordered by the value of the original real input.var data (ascending) – i.e. with the same order and the same number of rows as **blackbox.ranks.df** at the end of step 10 . In the current step, the ranksSecureDS4 (serverside Assign) function cbinds the serverside data frame blackbox.ranks.df to the global.ranks.quantiles.df data frame. This combined data frame is then sorted either by the quantitative value of the original input data (ascending) – i.e. the order is left unchanged from that of **blackbox.ranks.df** - or by the order of the original sequential ID applied to the real values of input.var - ie in the same order as the original real data. Which of these two sort orders is applied is determined by the argument in ds.ranksSecure which can take the value "ID.orig" or "vals.orig". The former results in a data frame in the same order as the original input data, the latter in a data frame in which the absolute magnitude of the original input.var and corresponding ranks -increase consistently down the data frame. Regardless how it is sorted, this data frame is then written to the serverside as the data frame output.ranks.df, which can be named as desired by the character string associated with the argument . - -(13) Next, ranksSecureDS5 (serverside assign function) takes the comprehensive data frame -output.ranks.df and creates a new object summary.output.ranks.df (for which a desired name can be specified by the character string associated with the argument ). This summary data frame contains only the most essential elements of the final ranking output. To be specific, in each study s, this consists of five columns: [1] ID.seq.real.orig, contains the values of the original sequential ID for the input data in study s. This will run sequentially from 1:NRs if ranks.sort.by = "ID.orig". On the other hand, It will generally appear haphazard if ranks.sort.by = "vals.orig"; [2] input.var.real.orig, contains the values of the original (real) values -of input.var in study s. These will be in increasing order if ranks.sort.by="vals.orig" but the order will be the same as in the original input data if ranks.sort.by="ID.orig"; [3] final.ranks.global, contains the global ranks (i.e. based upon the real data values across ALL studies) that correspond to the values in input.var.real.orig and will therefore be in order of increasing value if ranks.sort.by = "vals.orig" but will typically appear haphazard if ranks.sort.by = "ID.orig"; [4] final.quantiles.global, -contains the quantile values corresponding to the final.global.ranks held in column 3. In association with column 2, these may now be used to estimate the true data values corresponding to key quantiles (across all studies) such as the median, quartiles and 5% and 95%; [5] studyid, all elements take the value s in study s. **The data frame summary.output.ranks.df** which is written to the serverside server at each study (and contains the ranking data relating only to that study) may be viewed as the primary output from the whole ranking procedure. All other outputs from the analysis (including the more comprehensive data frame output.ranks.df) are tidied up by deletion at the end of the running of the function unless ds.ranksSecure’s argument rm.residual.objects is set to FALSE. - -(14) All or selected columns from the summary.output.ranks.df data frame can now be cbinded to the original input.var variable or to the data frame from which input.var was obtained in order to add its corresponding global ranks or global quantiles. These ranks can form the basis of a wide range of non-parametric analyses - -**ds.extractQuantiles** -(15) In addition to undertaking a standard non-parametric analysis based on the ranks generated by ds.ranksSecure, what is also sometimes needed is to calculate and quote the actual values (in V2BR) for key quantiles across all studies. This is enabled by the client function ds.extractQuantiles which is called at the end of ds.ranksSecure. - -(16) Given that we have calculated the global quantile corresponding to every observation in every study, it would appear that this procedure should be straightforward. But, in practice, there is a challenge. Specifically, If we wish to calculate, for example, the global median, then based on the serverside information in a study in which the summary.output.ranks.df data frame contains a value of precisely 0.500 in the final.quantiles.global column we can infer that the true global median is the corresponding element in the input.var.real.orig column reflects. But, in a study in which the vector final.values.quantile does not contain the precise value 0.500 the global median will be indeterminant. Similarly, if the true median actually falls at a value in the middle of a large tied cluster, it is conceivable it could take the quantile value 0.49 or 0.52 in several studies and no study will contain a final.values.quantile of 0.500. So if all studies (and the client) are to have access to all the key quantile values, we need to identify these key values in a more sophisticated way. - -(17) One of the arguments for ds.secureRanks is this identifies the key quantile estimates to be estimated and returned. The broadest range is selected -by quantiles.for.estimation="0.025-0.975". This indicates estimation of the following quantiles:c(0.025,0.05,0.10,0.20,0.25,0.30,0.3333,0.40,0.50,0.60, 0.6667,0.70,0.75,0.80,0.90,0.95,0.975). The alternative allowable options for the argument all represent narrower subsets of these values (see below for information about the parameter: quantiles.for.estimation). Two serverside aggregate functions (extractQuantilesDS1 and then extractQuantilesDS2) sequentially process the information in the -summary.output.ranks.df data frame to generate the precise values of the input.var that correspond to each of the selected key quantile values, and these values are then available to the client because they are generated by an aggregate function and the final results are also written to each data server as the data frame final.quantile.df which contains two columns. The first of these is the vector evaluation.quantiles which lists all of the key quantile values targeted by the argument while the second is final.quantile.vector which contains the precise values of input.var that correspond to the key quantiles in the first column. - -The precise values in final.quantile.vector are identified in a two stage process (hence the two serverside functions). The first function (extractQuantilesDS1) identifies the lowest value of final.quantiles.global in each study that lies at or above each key target quantile value in the evaluation.quantiles vector. For convenience, these may be called: min.at.or.above.key.value_t,s for target quantile t in study s. The function extractQuantilesDS1 also identifies max.at.or.below.key.value_t,s which is the corresponding maximum value in study s at or below the target value. These vectors are sent to the client which identifies, for each target value, the minimum value of min.at.or.above.key.value_t,s across all studies and the studies in which -that value falls. Similarly, the max value of max.at.or.below.key.value_t,s across all studies is also estimated. Please note, that it is possible that in relation to any given threshold t, these values may appear once in different studies, and either or both can appear in several (or even all) studies. But that doesn’t matter. Wherever the minimum minimum or maximum maximum value for a given -threshold sits the corresponding value of input.input var is identified and recorded. Whenever one of these values occurs multiple times, we simply take the mean of the corresponding values of input.var which are, by definition, all the same and so the mean is the same as any individual value. - -This process results in a list of two input.var values that span each threshold. One is the minimum -minimum value of the values that lie at or above the threshold and the other is the maximum maximum of the values that lie below the threshold. We then take the mean of these two values and that is declared as the value of input.var that corresponds to the particular threshold of interest. If the data are such that the precise value of the threshold appears somewhere in the final.quantiles.global column of at least one study (e.g. 0.500 for the median or 0.750 for the upper quartile) the input.var values corresponding to the minimum minimum and maximum maximum values are the same and both precisely equal to the value required for that given quantile. So their mean is clearly the correct value. If the precise value for the required quantile does not appear in -the final.quantiles.global column in any study, then the required value of the input.var corresponding to the required threshold is derived as the mean of the closest two values on either side of the threshold regardless which studies they actually fall in. From a heuristic perspective this would appear to be a reasonable approach to estimating a value for a required quantile whenever it falls between two different values. - -At this point a data frame is created called **final.quantile.df** in which the first column is the vector of quantile values to be estimated as indicated by the argument and the second column is the vector of input.var values that correspond to those values based on the methods described above. This is the primary output from ds.extractQuantile and so is not deleted even if ds.ranksSecure’s argument rm.residual.objects is set to TRUE (the default). diff --git a/R/subsetHelper.R b/R/subsetHelper.R deleted file mode 100644 index 2400c0778..000000000 --- a/R/subsetHelper.R +++ /dev/null @@ -1,76 +0,0 @@ -#' -#' @title Ensures that the requested subset is not larger than the original object -#' @description Compares subset and original object sizes and eventually carries out subsetting. -#' @details This function is called by the function \code{ds.subset} to ensure that the requested subset -#' is not larger than the original object. -#' -#' This function is internal. -#' -#' Server function called: \code{dimDS} -#' @param dts a list of \code{\link[DSI]{DSConnection-class}} -#' objects obtained after login. If the \code{datasources} argument is not specified -#' the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}. -#' @param data a character string specifying the name of the data frame or -#' the factor vector and the range of the subset. -#' @param rs a vector of two integers specifying the indices of the rows de extract. -#' @param cs a vector of two integers or one or more characters. -#' @keywords internal -#' @return \code{subsetHelper} returns a message or the class of the object if the -#' object has the same class in all studies. -#' @examples -#' \dontrun{ -#' -#' ## Version 6, for version 5 see the Wiki -#' -#' # connecting to the Armadillo/Opal servers -#' -#' require('DSI') -#' require('DSMolgenisArmadillo') -#' require('DSOpal') -#' require('dsBaseClient') -#' -#' armadillo_url <- "http://192.168.56.100:8080/" -#' token <- armadillo.get_credentials(armadillo_url) -#' builder <- DSI::newDSLoginBuilder() -#' builder$append(server = "study1", -#' url = armadillo_url, -#' token = token@access_token, -#' table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") -#' builder$append(server = "study2", -#' url = "https://192.168.56.100:8443/", -#' user = "administrator", password = "datashield_test&", -#' table = "CNSIM.CNSIM2", driver = "OpalDriver", -#' options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") -#' logindata <- builder$build() -#' -#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") -#' -#' subsetHelper(dts = connections, -#' data = "D", -#' rs = 1:10, -#' cs = c("D$LAB_TSC","D$LAB_TRIG")) -#' -#' # clear the Datashield R sessions and logout -#' datashield.logout(connections) -#' } -#' -subsetHelper <- function(dts, data, rs=NULL, cs=NULL){ - - # if the size of the requested subset is greater than that of original inform the user and stop the process - dims <- DSI::datashield.aggregate(dts, call("dimDS", data)) - fail <- c(0,0) - - if(!(is.null(rs))){ - if(length(rs) > dims[[1]]$dim[1] ){ - fail[1] <- 1 - } - } - - if(!(is.null(cs))){ - if(length(cs) > dims[[1]]$dim[2]){ - fail[2] <- 1 - } - } - return(fail) - -} diff --git a/man/ds.dataFrameFill.Rd b/man/ds.dataFrameFill.Rd index 02adb7851..cb8fbd789 100644 --- a/man/ds.dataFrameFill.Rd +++ b/man/ds.dataFrameFill.Rd @@ -4,96 +4,19 @@ \alias{ds.dataFrameFill} \title{Creates missing values columns in the server-side} \usage{ -ds.dataFrameFill( - df.name = NULL, - newobj = NULL, - datasources = NULL, - classConsistencyCheck = TRUE -) +ds.dataFrameFill(...) } \arguments{ -\item{df.name}{a character string representing the name of the input data frame that will be -filled with extra columns of missing values.} - -\item{newobj}{a character string that provides the name for the output data frame -that is stored on the data servers. Default value is "dataframefill.newobj".} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. -If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} - -\item{classConsistencyCheck}{logical. If TRUE, verifies that each input object has the same class across all studies. Default TRUE.} -} -\value{ -\code{ds.dataFrameFill} returns the object specified by the \code{newobj} argument which -is written to the server-side. +\item{...}{Not used.} } \description{ -Adds extra columns with missing values in a data frame on the server-side. -} -\details{ -This function checks if the input data frames have the same variables (i.e. the same -column names) in all of the used studies. When a study does not have some of the variables, the -function generates those variables as vectors of missing values and combines them as columns to -the input data frame. If any of the generated variables are of class factor, the function -assigns to those the corresponding levels of the factors given from the studies where such -factors exist. - -Server function called: \code{dataFrameFillDS} -} -\examples{ -\dontrun{ - - ## Version 6, for version 5 see the Wiki - # Connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "CNSIM.CNSIM2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - - logindata <- builder$build() - - # Log onto the remote Armadillo/Opal training servers - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - # Create two data frames with one different column - - ds.dataFrame(x = c("D$LAB_TSC","D$LAB_TRIG","D$LAB_HDL", - "D$LAB_GLUC_ADJUSTED","D$PM_BMI_CONTINUOUS"), - newobj = "df1", - datasources = connections[1]) - - ds.dataFrame(x = c("D$LAB_TSC","D$LAB_TRIG","D$LAB_HDL","D$LAB_GLUC_ADJUSTED"), - newobj = "df1", - datasources = connections[2]) - - # Fill the data frame with NA columns - - ds.dataFrameFill(df.name = "df1", - newobj = "D.Fill", - datasources = connections[c(1,2)]) # Two servers are used - - - # Clear the Datashield R sessions and logout - datashield.logout(connections) -} +This function is defunct. Please use \code{ds.standardiseDf()} instead. } \author{ Demetris Avraam for DataSHIELD Development Team Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands } +\keyword{internal} diff --git a/man/ds.listOpals.Rd b/man/ds.listOpals.Rd index c06b47ca9..f95de9a75 100644 --- a/man/ds.listOpals.Rd +++ b/man/ds.listOpals.Rd @@ -4,27 +4,15 @@ \alias{ds.listOpals} \title{Lists all Opal objects in the analytic environment} \usage{ -ds.listOpals() +ds.listOpals(...) } -\value{ -Lists all of the sets of Opals currently found in the analytic environment and advises -the user how best to respond depending whether there are zero, one or multiple Opals detected. +\arguments{ +\item{...}{Not used.} } \description{ -ds.listOpals calls the internal DataSHIELD function getOpals() which identifies -all Opal objects in the analytic environment. -} -\details{ -ds.listOpals calls the internal DataSHIELD function getOpals() which identifies -all Opal objects in the analytic environment. If there are no Armadillo/Opal servers in the analytic -environment ds.listOpalsIreminds the user that they have to login to a valid set of Opal -login objects, if they wish to use DataSHIELD. If there is only one set of Opals, ds.listOpals -copies that one set and names the copy 'default.opals'. This default set will then be used by -default by all subsequent calls to client-side functions. If there is more than one set of Opals -in the analytic environment, ds.listOpals tells the user that they can either explicitly specify the -Opals to be used by each client-side function by providing an explicit "datasources=" argument -for each call, or can alternatively use the ds.setDefaultOpals function to specify a default -set of Opals to be used by all client-side calls unless over-ruled by the 'datasources=' argument. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + +This function is defunct. Please use \code{DSI::datashield.connections()} instead. } \author{ Burton, PR. 28/9/16 diff --git a/man/ds.listServersideFunctions.Rd b/man/ds.listServersideFunctions.Rd index 3706a4fb3..75107fe8a 100644 --- a/man/ds.listServersideFunctions.Rd +++ b/man/ds.listServersideFunctions.Rd @@ -4,67 +4,17 @@ \alias{ds.listServersideFunctions} \title{Lists server-side functions} \usage{ -ds.listServersideFunctions(datasources = NULL) +ds.listServersideFunctions(...) } \arguments{ -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. -If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} -} -\value{ -\code{ds.listServersideFunctions} returns to the client-side -a list containing all server-side functions separately for each study. -Firstly lists assign and then aggregate functions. +\item{...}{Not used.} } \description{ -Lists all current server-side functions -} -\details{ -Uses \code{\link[DSI]{datashield.methods}} function from \code{DSI} package to list all -assign and aggregate functions on the available data repository servers. -The only choice of arguments is in \code{datasources}; i.e. which studies to interrogate. -Once the studies have -been selected \code{ds.listServersideFunctions} lists all assign functions for all -of these studies and then all aggregate functions for all of them. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -This function does not call any server-side function. -} -\examples{ -\dontrun{ - - ## Version 6, for version 5 see Wiki - # Connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') - - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "CNSIM.CNSIM2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - logindata <- builder$build() - - # Log onto the remote Armadillo/Opal training servers - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - # List server-side functions - - ds.listServersideFunctions(datasources = connections) - - # Clear the Datashield R sessions and logout - datashield.logout(connections) -} +This function is defunct. Please use \code{DSI::datashield.methods()} instead. } \author{ DataSHIELD Development Team } +\keyword{internal} diff --git a/man/ds.look.Rd b/man/ds.look.Rd index bacde6f39..7b434b153 100644 --- a/man/ds.look.Rd +++ b/man/ds.look.Rd @@ -4,86 +4,17 @@ \alias{ds.look} \title{Performs direct call to a server-side aggregate function} \usage{ -ds.look(toAggregate = NULL, checks = FALSE, datasources = NULL) +ds.look(...) } \arguments{ -\item{toAggregate}{a character string specifying the function call to be made. -For more information see \strong{Details}.} - -\item{checks}{logical. If TRUE the optional checks are undertaken. -Default FALSE to save time.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} -objects obtained after login. If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} -} -\value{ -the output from the specified server-side aggregate function to the client-side. +\item{...}{Not used.} } \description{ -The function \code{ds.look} can be used to make a direct call to a server-side -aggregate function more simply than using the \code{datashield.aggregate} function. -} -\details{ -The \code{ds.look} and \code{datashield.aggregate} functions are generally -only recommended for experienced developers. For example, the \code{toAggregate} argument has to -be expressed in the same form that the server-side function would usually expect from its -client-side pair. For example: \code{ds.look("table1DDS(female)")} works. But, if you express -this as \code{ds.look("table1DDS('female')")} it won't work because although when -you call this same function using its client-side function you write \code{ds.table1D('female')} -the inverted commas are stripped off during processing by the client-side function so the -call to the server-side does not contain inverted commas. - -Apart from during development -work (e.g. before a client-side function has been written) it is almost always easier -and less error-prone to call a server-side function using its client-side pair. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -The function is a wrapper for the DSI package function \code{datashield.aggregate}. -} -\examples{ -\dontrun{ - - ## Version 6, for version 5 see the Wiki - - # connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') - - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/survival/EXPAND_NO_MISSING1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "SURVIVAL.EXPAND_NO_MISSING2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - logindata <- builder$build() - - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - #Calculate the length of a variable using the server-side function - - ds.look(toAggregate = "lengthDS(D$age.60)", - checks = FALSE, - datasources = connections) - - #Calculate the column names of "D" object using the server-side function - - ds.look(toAggregate = "colnames(D)", - checks = FALSE, - datasources = connections) - - # clear the Datashield R sessions and logout - datashield.logout(connections) -} +This function is defunct. Its functionality has been removed. } \author{ DataSHIELD Development Team } +\keyword{internal} diff --git a/man/ds.meanByClass.Rd b/man/ds.meanByClass.Rd index 592de07ce..a54c0b6e3 100644 --- a/man/ds.meanByClass.Rd +++ b/man/ds.meanByClass.Rd @@ -4,103 +4,17 @@ \alias{ds.meanByClass} \title{Computes the mean and standard deviation across categories} \usage{ -ds.meanByClass( - x = NULL, - outvar = NULL, - covar = NULL, - type = "combine", - datasources = NULL -) +ds.meanByClass(...) } \arguments{ -\item{x}{a character string specifying the name of the dataset or a text formula.} - -\item{outvar}{a character vector specifying the names of the continuous variables.} - -\item{covar}{a character vector specifying the names of up to 3 categorical variables} - -\item{type}{a character string that represents the type of analysis to carry out. -\code{type} can be set as: \code{'combine'} or \code{'split'}. -Default \code{'combine'}. -For more information see \strong{Details}.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} -objects obtained after login. If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} -} -\value{ -\code{ds.meanByClass} returns to the client-side a table or a list of tables that -hold the length of the numeric variable(s) and their mean -and standard deviation in each subgroup (subset). +\item{...}{Not used.} } \description{ -This function calculates the mean and the standard deviation (SD) - of a continuous variable for each class of up to 3 categorical variables. -} -\details{ -The function splits the input dataset into subsets (one for each category) and calculates -the mean and SD of the specified numeric variables. It is important to note that the process of -generating the final table(s) can be time consuming particularly if the subsetting is done across -more than one categorical variable and the run-time lengthens if the parameter \code{type} is set to -\code{'split'} as a table is then produced for each study. It is therefore advisable to run the function -only for the studies of the user interested in but including only those studies in the -parameter \code{datasources}. - - Depending on the variable \code{type} can be carried out two analysis:\cr - (1) \code{'combine'}: a pooled table of results is generated. \cr - (2) \code{'split'}: a table of results is generated for each study. -} -\examples{ -\dontrun{ - - ## Version 6, for version 5 see the Wiki - - # connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') - - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "CNSIM.CNSIM2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - logindata <- builder$build() - - - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - #Calculate mean by class - - ds.meanByClass(x = "D", - outvar = c('LAB_HDL','LAB_TSC'), - covar = c('PM_BMI_CATEGORICAL'), - type = "combine", - datasources = connections) - - ds.meanByClass(x = "D$LAB_HDL~D$PM_BMI_CATEGORICAL", - type = "combine", - datasources = connections[1])#Only the frist server is used ("study1") - - # clear the Datashield R sessions and logout - datashield.logout(connections) -} - -} -\seealso{ -\code{\link{ds.subsetByClass}} to subset by the classes of factor vector(s). +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -\code{\link{ds.subset}} to subset by complete cases (i.e. removing missing values), threshold, columns and rows. +This function is defunct. Please use \code{ds.meanSdGp()} instead. } \author{ DataSHIELD Development Team } +\keyword{internal} diff --git a/man/ds.message.Rd b/man/ds.message.Rd index 9a99f1daa..9f971dfd9 100644 --- a/man/ds.message.Rd +++ b/man/ds.message.Rd @@ -4,85 +4,17 @@ \alias{ds.message} \title{Returns server-side messages to the client-side} \usage{ -ds.message(message.obj.name = NULL, datasources = NULL) +ds.message(...) } \arguments{ -\item{message.obj.name}{is a character string specifying the name of the list that -contains the message.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} -objects obtained after login. If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} -} -\value{ -\code{ds.message} returns a list object from each study, -containing the message that has been written by -DataSHIELD into \code{$studysideMessage}. +\item{...}{Not used.} } \description{ -This function allows for error messages arising from the -running of a server-side assign function to be returned to the client-side. -} -\details{ -Errors arising from aggregate server-side functions can be returned -directly to the client-side. But this is not possible for server-side assign -functions because they are designed specifically to write objects to the -server-side and to return no meaningful information to the client-side. -Otherwise, users may be able to use assign functions to return disclosive -output to the client-side. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -Server-side functions from which error messages are to be made -available are designed to be able to write the designated error message to -the \code{$serversideMessage} object into the list that is saved on the server-side -as the primary output of that function. So only valid server-side functions of -DataSHIELD can write a \code{$studysideMessage}. The error message is a string that -cannot exceed a length of \code{nfilter.string} a default of 80 characters. - -Server function called: \code{messageDS} -} -\examples{ -\dontrun{ - - ## Version 6, for version 5 see the Wiki - - # connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') - - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "CNSIM.CNSIM2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - logindata <- builder$build() - - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - #Use a ds.asCharacter assign function to create the message in the server-side - - ds.asCharacter(x.name = "D$LAB_TRIG", - newobj = "vector1", - datasources = connections) - - #Return the message to the client-side - - ds.message(message.obj.name = "vector1", - datasources = connections) - - # clear the Datashield R sessions and logout - datashield.logout(connections) -} +This function is defunct. Server-side errors are now returned directly and can be viewed with \code{DSI::datashield.errors()}. } \author{ DataSHIELD Development Team } +\keyword{internal} diff --git a/man/ds.recodeLevels.Rd b/man/ds.recodeLevels.Rd index 0faa5407d..7b1be9ae2 100644 --- a/man/ds.recodeLevels.Rd +++ b/man/ds.recodeLevels.Rd @@ -4,84 +4,19 @@ \alias{ds.recodeLevels} \title{Recodes the levels of a server-side factor vector} \usage{ -ds.recodeLevels( - x = NULL, - newCategories = NULL, - newobj = NULL, - datasources = NULL -) +ds.recodeLevels(...) } \arguments{ -\item{x}{a character string specifying the name of a factor variable.} - -\item{newCategories}{a character vector specifying the new levels. Its length must be equal or greater -to the current number of levels.} - -\item{newobj}{a character string that provides the name for the output object -that is stored on the data servers. Default \code{recodelevels.newobj}.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} -objects obtained after login. If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} -} -\value{ -\code{ds.recodeLevels} returns to the server-side a variable of type factor -with the replaces levels. +\item{...}{Not used.} } \description{ -The function replaces the levels of a factor by the specified new ones. -} -\details{ -This function is similar to native R function \code{levels()}. - -It can for example be used to merge two classes into one, to add a level(s) to a vector -or to rename (i.e. re-label) the levels of a vector. - -Server function called: \code{levels()} -} -\examples{ -\dontrun{ - - ## Version 6, for version 5 see the Wiki - - # connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') - - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "CNSIM.CNSIM2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - logindata <- builder$build() - - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - # Recode the levels of a factor variable - - ds.recodeLevels(x = "D$PM_BMI_CATEGORICAL", - newCategories = c("1","2","3"), - newobj = "BMI_CAT", - datasources = connections) - - # Clear the Datashield R sessions and logout - datashield.logout(connections) - -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +This function is defunct. Please use \code{ds.recodeValues()} instead. } \author{ DataSHIELD Development Team Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands } +\keyword{internal} diff --git a/man/ds.setDefaultOpals.Rd b/man/ds.setDefaultOpals.Rd index f6cc967b9..d6167a1a9 100644 --- a/man/ds.setDefaultOpals.Rd +++ b/man/ds.setDefaultOpals.Rd @@ -4,41 +4,15 @@ \alias{ds.setDefaultOpals} \title{Creates a default set of Opal objects called 'default.opals'} \usage{ -ds.setDefaultOpals(opal.name) +ds.setDefaultOpals(...) } -\value{ -Copies a specified set of Opals (on the client-side server) -and calls the copy 'default.opals' +\arguments{ +\item{...}{Not used.} } \description{ -creates a default set of Opal objects called 'default.opals -} -\details{ -By default if there is only one set of opals that is available for -analysis, all DataSHIELD client-side functions will -use that full set of Opals unless the 'datasources=' argument has been set and specifies that -a particular subset of those Opals should be used instead. The correct identification of the full -single set of opals is based on the datashield.connections_find() function which is an internal DataSHIELD -function that is run at the start of nearly every client side function. -To illustrate, if the single set of Opals is called 'study.opals' and consists of -six opals numbered study.opals[1] to study.opals[6] then all client-side functions will -use data from all six of these 'study.opals' unless, say, datasources=study.opals[c(2,5)] is -declared and only data from the second and fifth studies will then be used. -On the other hand, if there is more than one set of Opals in the analytic environment client-side functions will -be unable to determine which set to use. The function datashield.connections_find() has therefore been -written so that if one of the Opal sets is called 'default.opals' then that set - -i.e. 'default.opals' - will be selected by default by all DataSHIELD client-side functions. If there is more -than one set of Opals in the analytic environment and NONE of -these is called 'default.opals', the function ds.setDefaultOpals() therefore copies -one set of opals and to name that copy 'default.opals'. This set will then be selected -by default by all client-side functions, unless it is deleted and an alternative set of -opals is copied and named 'default.opals'. Regardless how many sets of opals exist and -regardless whether any of them may be called 'default.opals', the 'datasources=' argument -overrides the defaults and allows the user to base his/her analysis on any set of opals -and any subset of those opals. An earlier version of -'datashield.connections_find()' asked the user to specify which Opal to choose -if no default could be identified, but that did not work in all versions of R -and so has been removed. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} + +This function is defunct. Please use \code{DSI::datashield.connections_default()} instead. } \author{ Burton, PR. 28/9/16 diff --git a/man/ds.subset.Rd b/man/ds.subset.Rd index 2b2d91b99..1556e1997 100644 --- a/man/ds.subset.Rd +++ b/man/ds.subset.Rd @@ -4,106 +4,17 @@ \alias{ds.subset} \title{Generates a valid subset of a table or a vector} \usage{ -ds.subset( - x = NULL, - subset = "subsetObject", - completeCases = FALSE, - rows = NULL, - cols = NULL, - logicalOperator = NULL, - threshold = NULL, - datasources = NULL -) +ds.subset(...) } \arguments{ -\item{x}{a character, the name of the dataframe or the factor vector and the range of the subset.} - -\item{subset}{the name of the output object, a list that holds the subset object. If set to NULL -the default name of this list is 'subsetObject'} - -\item{completeCases}{a character that tells if only complete cases should be included or not.} - -\item{rows}{a vector of integers, the indices of the rows to extract.} - -\item{cols}{a vector of integers or a vector of characters; the indices of the columns to extract or their names.} - -\item{logicalOperator}{a boolean, the logical parameter to use if the user wishes to subset a vector using a logical -operator. This parameter is ignored if the input data is not a vector.} - -\item{threshold}{a numeric, the threshold to use in conjunction with the logical parameter. This parameter is ignored -if the input data is not a vector.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} -} -\value{ -no data are return to the user, the generated subset dataframe is stored on the server side. +\item{...}{Not used.} } \description{ -The function uses the R classical subsetting with squared brackets '[]' and allows also to -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). -} -\details{ -(1) If the input data is a table the user specifies the rows and/or columns to include in the subset; the columns can be -referred to by their names. Table subsetting can also be done using the name of a variable and a threshold (see example 3). -(2) If the input data is a vector and the parameters 'rows', 'logical' and 'threshold' are all provided the last two are ignored -(i.e. 'rows' has precedence over the other two parameters then). -IMPORTANT NOTE: If the requested subset is not valid (i.e. contains less than the allowed number of observations) all the values are -turned into missing values (NA). Hence an invalid subset is indicated by the fact that all values within it are set to NA. -} -\examples{ -\dontrun{ - - # load the login data - data(logindata) - - # login and assign some variables to R - myvar <- list("DIS_DIAB","PM_BMI_CONTINUOUS","LAB_HDL", "GENDER") - conns <- datashield.login(logins=logindata,assign=TRUE,variables=myvar) - - # Example 1: generate a subset of the assigned dataframe (by default the table is named 'D') - # with complete cases only - ds.subset(x='D', subset='subD1', completeCases=TRUE) - # display the dimensions of the initial table ('D') and those of the subset table ('subD1') - ds.dim('D') - ds.dim('subD1') - - # Example 2: generate a subset of the assigned table (by default the table is named 'D') - # with only the variables - # DIS_DIAB' and'PM_BMI_CONTINUOUS' specified by their name. - ds.subset(x='D', subset='subD2', cols=c('DIS_DIAB','PM_BMI_CONTINUOUS')) - - # Example 3: generate a subset of the table D with bmi values greater than or equal to 25. - ds.subset(x='D', subset='subD3', logicalOperator='PM_BMI_CONTINUOUS>=', threshold=25) - - # Example 4: get the variable 'PM_BMI_CONTINUOUS' from the dataframe 'D' and generate a - # subset bmi - # vector with bmi values greater than or equal to 25 - ds.assign(toAssign='D$PM_BMI_CONTINUOUS', newobj='BMI') - ds.subset(x='BMI', subset='BMI25plus', logicalOperator='>=', threshold=25) - - # Example 5: subsetting by rows: - # get the logarithmic values of the variable 'lab_hdl' and generate a subset with - # the first 50 observations of that new vector. If the specified number of row is - # greater than the total - # number of rows in any of the studies the process will stop. - ds.assign(toAssign='log(D$LAB_HDL)', newobj='logHDL') - ds.subset(x='logHDL', subset='subLAB_HDL', rows=c(1:50)) - # now get a subset of the table 'D' with just the 100 first observations - ds.subset(x='D', subset='subD5', rows=c(1:100)) - - # clear the Datashield R sessions and logout - datashield.logout(conns) - -} - -} -\seealso{ -\link{ds.subsetByClass} to subset by the classes of factor vector(s). +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -\link{ds.meanByClass} to compute mean and standard deviation across categories of a factor vectors. +This function is defunct. Please use \code{ds.dataFrameSubset()} instead. } \author{ Gaye, A. } +\keyword{internal} diff --git a/man/ds.subsetByClass.Rd b/man/ds.subsetByClass.Rd index cd25fe69e..e91b0f359 100644 --- a/man/ds.subsetByClass.Rd +++ b/man/ds.subsetByClass.Rd @@ -4,79 +4,19 @@ \alias{ds.subsetByClass} \title{Generates valid subset(s) of a data frame or a factor} \usage{ -ds.subsetByClass( - x = NULL, - subsets = "subClasses", - variables = NULL, - datasources = NULL -) +ds.subsetByClass(...) } \arguments{ -\item{x}{a character, the name of the dataframe or the vector to generate subsets from.} - -\item{subsets}{the name of the output object, a list that holds the subset objects. If set to NULL -the default name of this list is 'subClasses'.} - -\item{variables}{a vector of string characters, the name(s) of the variables to subset by.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} -} -\value{ -a no data are return to the user but messages are printed out. +\item{...}{Not used.} } \description{ -The function takes a categorical variable or a data frame as input and generates -subset(s) variables or data frames for each category. -} -\details{ -If the input data object is a data frame it is possible to specify the variables -to subset on. If a subset is not 'valid' all its the values are reported as missing (i.e. NA), -the name of the subsets is labelled with the suffix '_INVALID'. Subsets are considered invalid if -the number of observations it holds are between 1 and the threshold allowed by the data owner. if -a subset is empty (i.e. no entries) the name of the subset is labelled with the suffix '_EMPTY'. -} -\examples{ -\dontrun{ - - # load the login data - data(logindata) - - # login and assign some variables to R - myvar <- list('DIS_DIAB','PM_BMI_CONTINUOUS','LAB_HDL', 'GENDER') - conns <- datashield.login(logins=logindata,assign=TRUE,variables=myvar) - - # Example 1: generate all possible subsets from the table assigned above (one subset table - # for each class in each factor) - ds.subsetByClass(x='D', subsets='subclasses') - # display the names of the subset tables that were generated in each study - ds.names('subclasses') - - # Example 2: subset the table initially assigned by the variable 'GENDER' - ds.subsetByClass(x='D', subsets='subtables', variables='GENDER') - # display the names of the subset tables that were generated in each study - ds.names('subtables') - - # Example 3: generate a new variable 'gender' and split it into two vectors: males - # and females - ds.assign(toAssign='D$GENDER', newobj='gender') - ds.subsetByClass(x='gender', subsets='subvectors') - # display the names of the subset vectors that were generated in each study - ds.names('subvectors') - - # clear the Datashield R sessions and logout - datashield.logout(conns) - -} - -} -\seealso{ -\link{ds.meanByClass} to compute mean and standard deviation across categories of a factor vectors. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} -\link{ds.subset} to subset by complete cases (i.e. removing missing values), threshold, columns and rows. +This function is defunct. Please use \code{ds.dataFrameSubset()} instead. } \author{ Gaye, A. Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands } +\keyword{internal} diff --git a/man/ds.table1D.Rd b/man/ds.table1D.Rd index b79ee21ee..714b2be5e 100644 --- a/man/ds.table1D.Rd +++ b/man/ds.table1D.Rd @@ -4,87 +4,17 @@ \alias{ds.table1D} \title{Generates 1-dimensional contingency tables} \usage{ -ds.table1D( - x = NULL, - type = "combine", - warningMessage = TRUE, - datasources = NULL -) +ds.table1D(...) } \arguments{ -\item{x}{a character, the name of a numerical vector with discrete values - usually a factor.} - -\item{type}{a character which represent the type of table to output: pooled table or one table for each -data source. If \code{type} is set to 'combine', a pooled 1-dimensional table is returned; if If \code{type} -is set to 'split' a 1-dimensional table is returned for each data source.} - -\item{warningMessage}{a boolean, if set to TRUE (default) a warning is displayed if any returned table is invalid. Warning -messages are suppressed if this parameter is set to FALSE. However the analyst can still view 'validity' information -which are stored in the output object 'validity' - see the list of output objects.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} -} -\value{ -A list object containing the following items: -\item{counts}{ table(s) that hold counts for each level/category. If some cells counts are invalid (see 'Details' -section) only the total (outer) cell counts are displayed in the returned individual study tables or in the pooled -table.} -\item{percentages}{ table(s) that hold percentages for each level/category. Here also inner cells are reported as -missing if one or more cells are 'invalid'.} -\item{validity}{ a text that informs the analyst about the validity of the output tables. If any tables are invalid the -studies they are originated from are also mentioned in the text message.} +\item{...}{Not used.} } \description{ -The function ds.table1D is a client-side wrapper function. -It calls the server-side function table1DDS to generate 1-dimensional -tables for all data sources. -} -\details{ -The table returned by the server side function might be valid (non disclosive - -no table cell have counts between 1 and the minimal number agreed by the data owner and set in the data repository) -or invalid (potentially disclosive - one or more table cells have a count between 1 and the minimal number -agreed by the data owner). If a 1-dimensional table is invalid all the cells are set to NA except the total -count. This way it is possible the know the total count and combine total counts across data sources but it -is not possible to identify the cell(s) that had the small counts which render the table invalid. -} -\examples{ -\dontrun{ - - # load the file that contains the login details - data(logindata) - - # login and assign all the stored variables to R - conns <- datashield.login(logins=logindata,assign=TRUE) +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - # Example 1: generate a one dimensional table, outputting combined (pooled) contingency tables - output <- ds.table1D(x='D$GENDER') - output$counts - output$percentages - output$validity - - # Example 2: generate a one dimensional table, outputting study specific contingency tables - output <- ds.table1D(x='D$GENDER', type='split') - output$counts - output$percentages - output$validity - - # Example 3: generate a one dimensional table, outputting study specific and combined - # contingency tables - see what happens if the reruened table is 'invalid'. - output <- ds.table1D(x='D$DIS_CVA') - output$counts - output$percentages - output$validity - - # clear the Datashield R sessions and logout - datashield.logout(conns) - -} - -} -\seealso{ -\link{ds.table2D} for cross-tabulating two vectors. +This function is defunct. Please use \code{ds.table()} instead. } \author{ Gaye, A.; Burton, P. } +\keyword{internal} diff --git a/man/ds.table2D.Rd b/man/ds.table2D.Rd index 3d0e2a2c2..0d462b635 100644 --- a/man/ds.table2D.Rd +++ b/man/ds.table2D.Rd @@ -4,114 +4,17 @@ \alias{ds.table2D} \title{Generates 2-dimensional contingency tables} \usage{ -ds.table2D( - x = NULL, - y = NULL, - type = "both", - warningMessage = TRUE, - datasources = NULL -) +ds.table2D(...) } \arguments{ -\item{x}{a character, the name of a numerical vector with discrete values - usually a factor.} - -\item{y}{a character, the name of a numerical vector with discrete values - usually a factor.} - -\item{type}{a character which represent the type of table to output: pooled table or one table for each -data source or both. If \code{type} is set to 'combine', a pooled 2-dimensional table is returned; If \code{type} -is set to 'split' a 2-dimensional table is returned for each data source. If \code{type} is set to 'both' (default) -a pooled 2-dimensional table plus a 2-dimensional table for each data source are returned.} - -\item{warningMessage}{a boolean, if set to TRUE (default) a warning is displayed if any returned table is invalid. Warning -messages are suppressed if this parameter is set to FALSE. However the analyst can still view 'validity' information -which are stored in the output object 'validity' - see the list of output objects.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} -} -\value{ -A list object containing the following items: -\item{colPercent}{table(s) that hold column percentages for each level/category. Inner cells are reported as -missing if one or more cells are 'invalid'.} -\item{rowPercent}{table(s) that hold row percentages for each level/category. Inner cells are reported as -missing if one or more cells are 'invalid'.} -\item{chi2Test}{Chi-squared test for homogeneity.} -\item{counts}{table(s) that hold counts for each level/category. If some cell counts are invalid (see 'Details' -section) only the total (outer) cell counts are displayed in the returned individual study tables or in the pooled -table.} -\item{validity}{a text that informs the analyst about the validity of the output tables. If any tables are invalid the -studies they are originated from are also mentioned in the text message.} +\item{...}{Not used.} } \description{ -The function ds.table2D is a client-side wrapper function. It calls the server-side function -'table2DDS' that generates a 2-dimensional contingency table for each data source. -} -\details{ -The table returned by the server side function might be valid (non disclosive - no table cell have -counts between 1 and the minimal number agreed by the data owner and set in the data repository as the "nfilter.tab") or -invalid (potentially disclosive - one or more table cells have a count between 1 and the minimal number agreed -by the data owner). If a 2-dimensional table is invalid all the cells are set to NA except the total counts. -In this way, it is possible to combine total counts across all the data sources but it is not possible to -identify the cell(s) that had the small counts which render the table invalid. -} -\examples{ -\dontrun{ - - # load the file that contains the login details - data(logindata) - - # login and assign all the variables to R - conns <- datashield.login(logins=logindata,assign=TRUE) +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - # Example 1: generate a two dimensional table, outputting combined contingency - # tables - default behaviour - output <- ds.table2D(x='D$DIS_DIAB', y='D$GENDER') - # display the 5 results items, one at a time to avoid having too much information - # displayed at the same time - output$counts - output$rowPercent - output$colPercent - output$chi2Test - output$validity - - # Example 2: generate a two dimensional table, outputting study specific contingency tables - ds.table2D(x='D$DIS_DIAB', y='D$GENDER', type='split') - # display the 5 results items, one at a time to avoid having too much information displayed - at the same time - output$counts - output$rowPercent - output$colPercent - output$chi2Test - output$validity - - # Example 3: generate a two dimensional table, outputting combined contingency tables - # *** this example shows what happens when one or studies return an invalid table *** - output <- ds.table2D(x='D$DIS_CVA', y='D$GENDER', type='combine') - output$counts - output$rowPercent - output$colPercent - output$chi2Test - output$validity - - # Example 4: same example as above but output is given for each study, - # separately (i.e. type='split') - # *** this example shows what happens when one or studies return an invalid table *** - output <- ds.table2D(x='D$DIS_CVA', y='D$GENDER', type='split') - output$counts - output$rowPercent - output$colPercent - output$chi2Test - output$validity - - # clear the Datashield R sessions and logout - datashield.logout(conns) - -} - -} -\seealso{ -\link{ds.table1D} for the tabulating one vector. +This function is defunct. Please use \code{ds.table()} instead. } \author{ Amadou Gaye, Paul Burton, Demetris Avraam, for DataSHIELD Development Team } +\keyword{internal} diff --git a/man/ds.testObjExists.Rd b/man/ds.testObjExists.Rd index 47e9406d0..46aef2600 100644 --- a/man/ds.testObjExists.Rd +++ b/man/ds.testObjExists.Rd @@ -4,71 +4,17 @@ \alias{ds.testObjExists} \title{Checks if an R object exists on the server-side} \usage{ -ds.testObjExists(test.obj.name = NULL, datasources = NULL) +ds.testObjExists(...) } \arguments{ -\item{test.obj.name}{a character string specifying the name of the object to search.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} -objects obtained after login. If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} -} -\value{ -\code{ds.testObjExists} returns a list of messages specifying that the object exists -on the server-side. -If the specified object does not exist in at least one -of the specified data sources or it exists but is of -class NULL, the function returns an error message specifying that -the object does not exist in all data sources. +\item{...}{Not used.} } \description{ -This function checks that a specified data object exists or has been correctly created on a -specified set of data servers. -} -\details{ -Close copies of the code in this function -are embedded into other functions that create an object and you then wish to test whether it has successfully -been created e.g. \code{ds.make} or \code{ds.asFactor}. - -Server function called: \code{testObjExistsDS} -} -\examples{ -\dontrun{ - ## Version 6, for version 5 see the Wiki - - # connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "CNSIM.CNSIM2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - logindata <- builder$build() - - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - #Check if D object exists on the server-side - - ds.testObjExists(test.obj.name = "D", - datasources = connections) - - # Clear the Datashield R sessions and logout - datashield.logout(connections) - -} +This function is defunct. Server-side functions now check that their input objects exist. } \author{ DataSHIELD Development Team } +\keyword{internal} diff --git a/man/ds.vectorCalc.Rd b/man/ds.vectorCalc.Rd index 87d7a5dd7..132da0939 100644 --- a/man/ds.vectorCalc.Rd +++ b/man/ds.vectorCalc.Rd @@ -4,55 +4,17 @@ \alias{ds.vectorCalc} \title{Performs a mathematical operation on two or more vectors} \usage{ -ds.vectorCalc(x = NULL, calc = NULL, newobj = NULL, datasources = NULL) +ds.vectorCalc(...) } \arguments{ -\item{x}{a vector of characters, the names of the vectors to include in the operation.} - -\item{calc}{a character, a symbol that indicates the mathematical operation to carry out: -'+' for addition, '/' for division, *' for multiplication and '-' for subtraction.} - -\item{newobj}{the name of the output object. By default the name is 'vectorcalc.newobj'.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} -} -\value{ -no data are returned to user, the output vector is stored on the server side. +\item{...}{Not used.} } \description{ -Carries out a row-wise operation on two or more vector. The function calls no -server side function; it uses the R operation symbols built in DataSHIELD. -} -\details{ -In DataSHIELD it is possible to perform an operation on vectors by just using the relevant -R symbols (e.g. '+' for addition, '*' for multiplication, '-' for subtraction and '/' for division). -This might however be inconvenient if the number of vectors to include in the operation is large. -This function takes the names of two or more vectors and performs the desired operation which could be -an addition, a multiplication, a subtraction or a division. If one or more vectors have a missing value -at any one entry (i.e. observation), the operation returns a missing value ('NA') for that entry; the output -vectors has, hence the same length as the input vectors. -} -\examples{ -\dontrun{ - - # load the file that contains the login details - data(logindata) - - # login and assign the required variables to R - myvar <- list('LAB_TSC','LAB_HDL') - conns <- datashield.login(logins=logindata,assign=TRUE,variables=myvar) - - # performs an addtion of 'LAB_TSC' and 'LAB_HDL' - myvectors <- c('D$LAB_TSC', 'D$LAB_HDL') - ds.vectorCalc(x=myvectors, calc='+') - - # clear the Datashield R sessions and logout - datashield.logout(conns) - -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} +This function is defunct. Please use \code{ds.make()} instead. } \author{ Gaye, A. } +\keyword{internal} diff --git a/man/figures/lifecycle-deprecated.svg b/man/figures/lifecycle-deprecated.svg new file mode 100644 index 000000000..b61c57c3f --- /dev/null +++ b/man/figures/lifecycle-deprecated.svg @@ -0,0 +1,21 @@ + + lifecycle: deprecated + + + + + + + + + + + + + + + lifecycle + + deprecated + + diff --git a/tests/testthat/perf_files/armadillo_azure-pipeline_perf-profile.csv b/tests/testthat/perf_files/armadillo_azure-pipeline_perf-profile.csv index 84d295b95..5faafdf4c 100644 --- a/tests/testthat/perf_files/armadillo_azure-pipeline_perf-profile.csv +++ b/tests/testthat/perf_files/armadillo_azure-pipeline_perf-profile.csv @@ -27,7 +27,6 @@ "ds.corTest::perf::combine:0","22.45","0.5","2" "ds.cov::perf::combine:0","7.010","0.5","2" "ds.dataFrame::perf::0","5.943","0.5","2" -"ds.dataFrameFill::perf::0","2.749","0.5","2" "ds.dataFrameSort::perf::0","14.38","0.5","2" "ds.dataFrameSubset::perf::0","1.103","0.5","2" "ds.densityGrid::perf::0","4.653","0.5","2" diff --git a/tests/testthat/perf_files/armadillo_github-workflows_perf-profile.csv b/tests/testthat/perf_files/armadillo_github-workflows_perf-profile.csv index e9eb1fa69..c7291e5e8 100644 --- a/tests/testthat/perf_files/armadillo_github-workflows_perf-profile.csv +++ b/tests/testthat/perf_files/armadillo_github-workflows_perf-profile.csv @@ -27,7 +27,6 @@ "ds.corTest::perf::combine:0","22.45","0.333","3" "ds.cov::perf::combine:0","7.010","0.333","3" "ds.dataFrame::perf::0","4.043","0.333","3" -"ds.dataFrameFill::perf::0","3.549","0.333","3" "ds.dataFrameSort::perf::0","24.38","0.333","3" "ds.dataFrameSubset::perf::0","2.450","0.333","3" "ds.densityGrid::perf::0","4.653","0.333","3" diff --git a/tests/testthat/perf_files/armadillo_hp-laptop-quay_perf-profile.csv b/tests/testthat/perf_files/armadillo_hp-laptop-quay_perf-profile.csv index f40fabd92..afe7ec10e 100644 --- a/tests/testthat/perf_files/armadillo_hp-laptop-quay_perf-profile.csv +++ b/tests/testthat/perf_files/armadillo_hp-laptop-quay_perf-profile.csv @@ -21,7 +21,6 @@ "ds.corTest::perf::combine:0","7.006","0.5","2" "ds.cov::perf::combine:0","3.723","0.5","2" "ds.dataFrame::perf::0","1.955","0.5","2" -"ds.dataFrameFill::perf::0","0.9282","0.5","2" "ds.dataFrameSort::perf::0","4.599","0.5","2" "ds.dataFrameSubset::perf::0","0.5505","0.5","2" "ds.dim::perf::0","25.31","0.5","2" diff --git a/tests/testthat/perf_files/opal_azure-pipeline_perf-profile.csv b/tests/testthat/perf_files/opal_azure-pipeline_perf-profile.csv index db1258d63..8eb7296eb 100644 --- a/tests/testthat/perf_files/opal_azure-pipeline_perf-profile.csv +++ b/tests/testthat/perf_files/opal_azure-pipeline_perf-profile.csv @@ -25,7 +25,6 @@ "ds.corTest::perf::combine:0","8.246","0.5","2" "ds.cov::perf::combine:0","4.792","0.5","2" "ds.dataFrame::perf::0","2.488","0.5","2" -"ds.dataFrameFill::perf::0","1.098","0.5","2" "ds.dataFrameSort::perf::0","8.263","0.5","2" "ds.dataFrameSubset::perf::0","0.822","0.5","2" "ds.densityGrid::perf::0","2.365","0.5","2" diff --git a/tests/testthat/perf_files/opal_github-workflows_perf-profile.csv b/tests/testthat/perf_files/opal_github-workflows_perf-profile.csv index 693040be8..8bdeed454 100644 --- a/tests/testthat/perf_files/opal_github-workflows_perf-profile.csv +++ b/tests/testthat/perf_files/opal_github-workflows_perf-profile.csv @@ -27,7 +27,6 @@ "ds.corTest::perf::combine:0","14.95","0.333","3" "ds.cov::perf::combine:0","13.18","0.333","3" "ds.dataFrame::perf::0","2.488","0.333","3" -"ds.dataFrameFill::perf::0","1.556","0.333","3" "ds.dataFrameSort::perf::0","13.83","0.333","3" "ds.dataFrameSubset::perf::0","1.559","0.333","3" "ds.densityGrid::perf::0","5.385","0.333","3" diff --git a/tests/testthat/smk_expt-results/ds.ranksSecure-cont.rds b/tests/testthat/smk_expt-results/ds.ranksSecure-cont.rds deleted file mode 100644 index fe6633ef0ad8aa1dd887e4102574f041545456e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341 zcmV-b0jmBViwFP!000001B>8dU|?WkU}0opU}6R`nT5f81_nML=C@xt69i`2?}XAP zq4Wg?FtERD3gc{j)SMuzvxSe+gCp<_rj& zwSNbZhuQBSFl+w4vJ+bzgp{vy*%mBu5I%LFStxIYgGkjw_jMxG4x*xsY$|v49Yo8| z-4turb`Uf7KDPY*JO^>-sUQgli5QKqhx%h2BxN`0@`bTDNVdxD2z=e@ASJ!@aq#!^ z4pMjZrRMJ|caZsUG n(u#lNVF(jXq diff --git a/tests/testthat/smk_expt-results/ds.ranksSecure-cont_nas.rds b/tests/testthat/smk_expt-results/ds.ranksSecure-cont_nas.rds deleted file mode 100644 index fe6633ef0ad8aa1dd887e4102574f041545456e6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 341 zcmV-b0jmBViwFP!000001B>8dU|?WkU}0opU}6R`nT5f81_nML=C@xt69i`2?}XAP zq4Wg?FtERD3gc{j)SMuzvxSe+gCp<_rj& zwSNbZhuQBSFl+w4vJ+bzgp{vy*%mBu5I%LFStxIYgGkjw_jMxG4x*xsY$|v49Yo8| z-4turb`Uf7KDPY*JO^>-sUQgli5QKqhx%h2BxN`0@`bTDNVdxD2z=e@ASJ!@aq#!^ z4pMjZrRMJ|caZsUG n(u#lNVF(jXq diff --git a/tests/testthat/smk_expt-results/ds.ranksSecure-cont_nas_neg.rds b/tests/testthat/smk_expt-results/ds.ranksSecure-cont_nas_neg.rds deleted file mode 100644 index 4a22af0a97b1f15a62e296d149e6ac562fc517ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 343 zcmV-d0jT~TiwFP!000001B>8dU|?WkU}0opU}6R`nT5f81_nML=C@xt69i`2?}XAP zq4Wg?FtERD3gc{j)SMuzvxSe+gCp<_rj& zwSNbZhuOdX-VgIFi;U;k@7cdGI^1rx{fp#}jtbES>^~T)y{x$M&;Il4R=FL4Z|uK` zR6TTGCu09A$@kL7m46%<;!N#p-cEF2j?wsfs6WPmweII_r3+6T*f#0%g|SFFa5S>1 z+|`$M;F{j+f8RRAL4eD)VDWV>2cc-7sstwn1{P2lFfy<(Z~|%8yu{qpVjx2R5?EkC zk<_xpoYKUS%=|pP!qUXNlFS^S8i<@|T4r8i4qRBTEH$|#zX;vb8dU|?WkU}0opU}6R`nT5f81_nML=C@xt69i`2?}XAP zq4Wg?FtERD3gc{j)SMuzvxSe+gCp<_rj& zwSNbZhuOdX-VgIFi;U;k@7cdGI^1rx{fp#}jtbES>^~T)y{x$M&;Il4R=FL4Z|uK` zR6TTGCu09A$@kL7m46%<;!N#p-cEF2j?wsfs6WPmweII_r3+6T*f#0%g|SFFa5S>1 z+|`$M;F{j+f8RRAL4eD)VDWV>2cc-7sstwn1{P2lFfy<(Z~|%8yu{qpVjx2R5?EkC zk<_xpoYKUS%=|pP!qUXNlFS^S8i<@|T4r8i4qRBTEH$|#zX;vb. -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC")) - -# -# Tests -# - -# context("ds.dataFrameFill::arg::test errors") -test_that("dataFrameFill_erros", { - expect_error(ds.dataFrameFill(), "Please provide the name of the data.frame to be filled as a character string: eg 'xxx'", fixed=TRUE) - expect_error(ds.dataFrameFill("NonDF"), "DataSHIELD errors") - expect_error(ds.dataFrameFill("D$LAB_TSC"), "The input vector must be of type 'data.frame' or a 'matrix'!", fixed=TRUE) -}) - -# -# Done -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.look.R b/tests/testthat/test-arg-ds.look.R deleted file mode 100644 index 705660be7..000000000 --- a/tests/testthat/test-arg-ds.look.R +++ /dev/null @@ -1,31 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC")) - -# -# Tests -# - -# context("ds.look::arg::test errors") -test_that("look_erros", { - expect_error(expect_warning(ds.look(checks=TRUE), "'ds.look' is deprecated.", fixed = TRUE), " missing, please give an expression/function in inverted commas\n", fixed=TRUE) -}) - -# -# Done -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.meanByClass.R b/tests/testthat/test-arg-ds.meanByClass.R deleted file mode 100644 index c4de0a22b..000000000 --- a/tests/testthat/test-arg-ds.meanByClass.R +++ /dev/null @@ -1,39 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC","LAB_HDL","GENDER","DIS_DIAB","PM_BMI_CATEGORICAL")) - -# -# Tests -# - -# context("ds.meanByClass::arg::test errors") -test_that("meanByClass_erros", { - ds.asCharacter(x='D$GENDER', newobj="not_a_numeric") - ds.asCharacter(x='D$GENDER', newobj="not_a_factor") - ds.assign("D$GENDER", "sex") - ds.assign("D$LAB_HDL", "ldl") - - expect_error(expect_warning(ds.meanByClass(), "'ds.meanByClass' is deprecated.", fixed = TRUE), "Please provide the name data frame or matrix or a formula of the form 'A~B' where A is a continuous vector and B a factor vector!", fixed=TRUE) - expect_error(expect_warning(ds.meanByClass(x='not_a_numeric~sex'), "'ds.meanByClass' is deprecated.", fixed = TRUE), "The first element in the formula must be of type numeric or integer!", fixed=TRUE) - expect_error(expect_warning(ds.meanByClass(x='ldl~not_a_factor'), "'ds.meanByClass' is deprecated.", fixed = TRUE), "The second element in the formula must be of type factor!", fixed=TRUE) - expect_error(expect_warning(ds.meanByClass(x='ldl~sex~not_a_factor'), "'ds.meanByClass' is deprecated.", fixed = TRUE), "x must be the name of a data frame or a matrix or a formula of the form 'A~B' where A is a continuous vector and B a factor vector!", fixed=TRUE) -}) - -# -# Tear down -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.message.R b/tests/testthat/test-arg-ds.message.R deleted file mode 100644 index ea55ca136..000000000 --- a/tests/testthat/test-arg-ds.message.R +++ /dev/null @@ -1,31 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC")) - -# -# Tests -# - -# context("ds.message::arg") -test_that("request message for NULL", { - expect_error(expect_warning(ds.message(NULL), "'ds.message' is deprecated.", fixed = TRUE), "Please provide the name of the studyside list object that holds the message\n in character format ie: 'object.name' in inverted commas", fixed=TRUE) -}) - -# -# Done -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.recodeLevels.R b/tests/testthat/test-arg-ds.recodeLevels.R deleted file mode 100644 index 88b4b36e5..000000000 --- a/tests/testthat/test-arg-ds.recodeLevels.R +++ /dev/null @@ -1,34 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("PM_BMI_CATEGORICAL", "LAB_TSC")) - -# -# Tests -# - -# context("ds.recodeLevels::arg::test errors") -test_that("recodeLevels_erros", { - expect_error(expect_warning(ds.recodeLevels(), "'ds.recodeLevels' is deprecated.", fixed = TRUE), " End of process!", fixed=TRUE) - expect_error(expect_warning(ds.recodeLevels(x='D$PM_BMI_CATEGORICAL'), "'ds.recodeLevels' is deprecated.", fixed = TRUE), " End of process!", fixed=TRUE) - expect_error(expect_warning(ds.recodeLevels(x='D$LAB_TSC', newCategories=c('normal', 'overweight')), "'ds.recodeLevels' is deprecated.", fixed = TRUE), "The input vector must be a factor!", fixed=TRUE) - expect_error(expect_warning(ds.recodeLevels(x='D$PM_BMI_CATEGORICAL', newCategories=c('normal', 'overweight')), "'ds.recodeLevels' is deprecated.", fixed = TRUE), "The number of levels you specified is smaller than the levels of the input vector!", fixed=TRUE) -}) - -# -# Tear down -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.subset.R b/tests/testthat/test-arg-ds.subset.R deleted file mode 100644 index 65a96c814..000000000 --- a/tests/testthat/test-arg-ds.subset.R +++ /dev/null @@ -1,31 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("DIS_DIAB","PM_BMI_CONTINUOUS","LAB_HDL", "GENDER")) - -# -# Tests -# - -# context("ds.subset::arg::test errors") -test_that("subset_erros", { - expect_error(expect_warning(ds.subset(), "'ds.subset' is deprecated.", fixed = TRUE), "Please provide the name of the object to subset from!", fixed=TRUE) -}) - -# -# Tear down -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.subsetByClass.R b/tests/testthat/test-arg-ds.subsetByClass.R deleted file mode 100644 index 9645b195e..000000000 --- a/tests/testthat/test-arg-ds.subsetByClass.R +++ /dev/null @@ -1,32 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC")) - -# -# Tests -# - -# context("ds.subsetByClass::arg::test errors") -test_that("subsetByClass_erros", { - expect_error(expect_warning(ds.subsetByClass(), "'ds.subsetByClass' is deprecated.", fixed = TRUE), "Please provide the name of the input data frame or factor!", fixed=TRUE) - expect_error(expect_warning(ds.subsetByClass(x='D$LAB_TSC'), "'ds.subsetByClass' is deprecated.", fixed = TRUE), "The object to subset from must be a 'data.frame' or a 'factor'.", fixed=TRUE) -}) - -# -# Tear down -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.table1D.R b/tests/testthat/test-arg-ds.table1D.R deleted file mode 100644 index 56c17dd4e..000000000 --- a/tests/testthat/test-arg-ds.table1D.R +++ /dev/null @@ -1,32 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("DIS_CVA","GENDER")) - -# -# Tests -# - -# context("ds.table1D::arg::test errors") -test_that("table1D_erros", { - expect_error(expect_warning(ds.table1D(), "'ds.table1D' is deprecated.", fixed = TRUE), "Please provide the name of the input vector!", fixed=TRUE) - expect_error(expect_warning(ds.table1D(x='D$GENDER', type="datashield"), "'ds.table1D' is deprecated.", fixed = TRUE), "Function argument 'type' has to be either 'combine' or 'split'", fixed=TRUE) -}) - -# -# Tear down -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.table2D.R b/tests/testthat/test-arg-ds.table2D.R deleted file mode 100644 index e7b0623ee..000000000 --- a/tests/testthat/test-arg-ds.table2D.R +++ /dev/null @@ -1,31 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC")) - -# -# Tests -# - -# context("ds.table2D::arg::test errors") -test_that("table2D_erros", { - expect_error(expect_warning(ds.table2D(), "'ds.table2D' is deprecated.", fixed = TRUE), "Please provide the name of the x vector!", fixed=TRUE) -}) - -# -# Done -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.testObjExists.R b/tests/testthat/test-arg-ds.testObjExists.R deleted file mode 100644 index bf01cc77a..000000000 --- a/tests/testthat/test-arg-ds.testObjExists.R +++ /dev/null @@ -1,33 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC")) - -# -# Tests -# - -# context("ds.testObjExists::arg::test errors") -test_that("testObjExists_erros", { - res <- ds.testObjExists() - - expect_equal(res, "Error: please provide the name of an object on the data servers as a character string in inverted commas") -}) - -# -# Done -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-arg-ds.vectorCalc.R b/tests/testthat/test-arg-ds.vectorCalc.R deleted file mode 100644 index 4c331b869..000000000 --- a/tests/testthat/test-arg-ds.vectorCalc.R +++ /dev/null @@ -1,32 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.survival(list("survtime")) - -# -# Tests -# - -# context("ds.vectorCalc::arg::test errors") - -test_that("ds.vectorCalc erros", { - expect_error(expect_warning(ds.vectorCalc(), "'ds.vectorCalc' is deprecated.\nUse 'ds.make' instead.", fixed = TRUE), "x=NULL. Please provide the names of the objects to combine!", fixed=TRUE) -}) - -# -# Done -# - -disconnect.studies.dataset.survival() diff --git a/tests/testthat/test-disc-ds.meanByClass.R b/tests/testthat/test-disc-ds.meanByClass.R deleted file mode 100644 index b1e7cedb6..000000000 --- a/tests/testthat/test-disc-ds.meanByClass.R +++ /dev/null @@ -1,41 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.meanByClass::disc::setup") - -connect.studies.dataset.cnsim(list("LAB_TSC","LAB_HDL","GENDER","DIS_DIAB","PM_BMI_CATEGORICAL")) - -# -# Tests -# - -# context("ds.meanByClass::disc::test errors") -test_that("meanByClass_erros", { -# expect_error(ds.meanByClass(x='D', outvar='LAB_HDL', covar='GENDER', type='split'), 'Failed to get levels from study: FAILED: Result less than nfilter.subset', fixed=TRUE) -}) - -# -# Tear down -# - -# context("ds.meanByClass::disc::teardown") - -disconnect.studies.dataset.cnsim() - -# -# Done -# - -# context("ds.meanByClass::disc::done") diff --git a/tests/testthat/test-discctrl-ds.recodeLevels.R b/tests/testthat/test-discctrl-ds.recodeLevels.R deleted file mode 100644 index 39551aa15..000000000 --- a/tests/testthat/test-discctrl-ds.recodeLevels.R +++ /dev/null @@ -1,54 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.recodeLevels::discctrl::setup") - -connect.studies.dataset.cnsim(list("PM_BMI_CATEGORICAL")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# -# context("ds.recodeLevels::discctrl") -test_that("simple recodeLevels", { - expect_error(expect_warning(ds.recodeLevels(x='D$PM_BMI_CATEGORICAL', newCategories=c('normal', 'overweight', 'obesity'), newobj='bmi_new'), "", fixed = TRUE), "There are some DataSHIELD errors, list them with datashield.errors()", fixed = TRUE) - - res_errors <- DSI::datashield.errors() - - expect_length(res_errors, 3) - expect_length(res_errors$sim1, 1) - expect_equal(res_errors$sim1, "Command 'levelsDS(D$PM_BMI_CATEGORICAL)' failed on 'sim1': Error while evaluating 'dsBase::levelsDS(D$PM_BMI_CATEGORICAL)' -> Error in checkPermissivePrivacyControlLevel() : \n BLOCKED: The server is running in 'non-permissive' mode which has caused this method to be blocked\n", fixed = TRUE) - expect_length(res_errors$sim2, 1) - expect_equal(res_errors$sim2, "Command 'levelsDS(D$PM_BMI_CATEGORICAL)' failed on 'sim2': Error while evaluating 'dsBase::levelsDS(D$PM_BMI_CATEGORICAL)' -> Error in checkPermissivePrivacyControlLevel() : \n BLOCKED: The server is running in 'non-permissive' mode which has caused this method to be blocked\n", fixed = TRUE) - expect_length(res_errors$sim3, 1) - expect_equal(res_errors$sim3, "Command 'levelsDS(D$PM_BMI_CATEGORICAL)' failed on 'sim3': Error while evaluating 'dsBase::levelsDS(D$PM_BMI_CATEGORICAL)' -> Error in checkPermissivePrivacyControlLevel() : \n BLOCKED: The server is running in 'non-permissive' mode which has caused this method to be blocked\n", fixed = TRUE) -}) - -# -# Done -# - -# context("ds.recodeLevels::discctrl::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.recodeLevels::discctrl::done") diff --git a/tests/testthat/test-discctrl-ds.subset.R b/tests/testthat/test-discctrl-ds.subset.R deleted file mode 100644 index 6da2146d5..000000000 --- a/tests/testthat/test-discctrl-ds.subset.R +++ /dev/null @@ -1,50 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.subset::discctrl::setup") - -connect.studies.dataset.cnsim(list("DIS_DIAB","PM_BMI_CONTINUOUS","LAB_HDL", "GENDER")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# -# context("ds.subset::discctrl") -test_that("simple subset", { - expect_error(expect_warning(ds.subset(datasources=ds.test_env$connections, subset='subD', x='D', rows=c(1:50), cols=c(1,2)), "", fixed = TRUE), "There are some DataSHIELD errors, list them with datashield.errors()", fixed = TRUE) - - res_errors <- DSI::datashield.errors() - - expect_length(res_errors, 1) - expect_length(res_errors$sim1, 1) - expect_equal(res_errors$sim1, "Command 'subsetDS(\"D\", FALSE, 1:50, c(1, 2))' failed on 'sim1': Error while evaluating 'is.null(base::assign('subD', value={dsBase::subsetDS(\"D\", FALSE, 1:50, dsBase::vectorDS(1, 2))}))' -> Error in checkPermissivePrivacyControlLevel() : \n BLOCKED: The server is running in 'non-permissive' mode which has caused this method to be blocked\n", fixed = TRUE) -}) - -# -# Done -# - -# context("ds.subset::discctrl::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.subset::discctrl::done") diff --git a/tests/testthat/test-discctrl-ds.subsetByClass.R b/tests/testthat/test-discctrl-ds.subsetByClass.R deleted file mode 100644 index a767cd546..000000000 --- a/tests/testthat/test-discctrl-ds.subsetByClass.R +++ /dev/null @@ -1,54 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.subsetByClass::discctrl::setup") - -connect.studies.dataset.cnsim(list("LAB_TSC", "GENDER")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# -# context("ds.subsetByClass::discctrl") -test_that("simple subsetByClass", { - expect_error(expect_warning(ds.subsetByClass(x='D', subsets='subclasses1'), "", fixed = TRUE), "There are some DataSHIELD errors, list them with datashield.errors()", fixed = TRUE) - - res_errors <- DSI::datashield.errors() - - expect_length(res_errors, 3) - expect_length(res_errors$sim1, 1) - expect_equal(res_errors$sim1, "Command 'subsetByClassDS('D')' failed on 'sim1': Error while evaluating 'is.null(base::assign('subclasses1', value={dsBase::subsetByClassDS('D')}))' -> Error in checkPermissivePrivacyControlLevel() : \n BLOCKED: The server is running in 'non-permissive' mode which has caused this method to be blocked\n", fixed = TRUE) - expect_length(res_errors$sim2, 1) - expect_equal(res_errors$sim2, "Command 'subsetByClassDS('D')' failed on 'sim2': Error while evaluating 'is.null(base::assign('subclasses1', value={dsBase::subsetByClassDS('D')}))' -> Error in checkPermissivePrivacyControlLevel() : \n BLOCKED: The server is running in 'non-permissive' mode which has caused this method to be blocked\n", fixed = TRUE) - expect_length(res_errors$sim3, 1) - expect_equal(res_errors$sim3, "Command 'subsetByClassDS('D')' failed on 'sim3': Error while evaluating 'is.null(base::assign('subclasses1', value={dsBase::subsetByClassDS('D')}))' -> Error in checkPermissivePrivacyControlLevel() : \n BLOCKED: The server is running in 'non-permissive' mode which has caused this method to be blocked\n", fixed = TRUE) -}) - -# -# Done -# - -# context("ds.subsetByClass::discctrl::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.subsetByClass::discctrl::done") diff --git a/tests/testthat/test-perf-ds.dataFrameFill.R b/tests/testthat/test-perf-ds.dataFrameFill.R deleted file mode 100644 index f8ca43397..000000000 --- a/tests/testthat/test-perf-ds.dataFrameFill.R +++ /dev/null @@ -1,50 +0,0 @@ - -# -# Set up -# - -# context("ds.dataFrameFill::perf::setup") -connect.discordant.dataset.simple(list("A", "B", "C")) - -# -# Tests -# - -# context("ds.dataFrameFill::perf::0") -test_that("performance", { - .durationSec <- 30 # seconds - .count <- 0 - .start.time <- Sys.time() - .current.time <- .start.time - - while (difftime(.current.time, .start.time, units = "secs")[[1]] < .durationSec) { - ds.dataFrameFill("D", newobj="fill.newobj") - - .count <- .count + 1 - .current.time <- Sys.time() - } - - .current.rate <- .count / (difftime(.current.time, .start.time, units = "secs")[[1]]) - .reference.rate <- perf.reference.rate("ds.dataFrameFill::perf::0") - if (any(length(.reference.rate) == 0) || any(is.null(.reference.rate))) { - print(paste("ds.dataFrameFill::perf::0 ", .current.rate, 0.5, 2.0)) - perf.reference.save("ds.dataFrameFill::perf::0", .current.rate, 0.5, 2.0) - } else { - print(paste("ds.dataFrameFill::perf::0 ", format(.current.rate, digits = 8), ", ", format(100.0 * .current.rate / .reference.rate, digits = 4), "%", sep = '')) - } - - .reference.rate <- perf.reference.rate("ds.dataFrameFill::perf::0") - .reference.tolerance.lower <- perf.reference.tolerance.lower("ds.dataFrameFill::perf::0") - .reference.tolerance.upper <- perf.reference.tolerance.upper("ds.dataFrameFill::perf::0") - - expect_gt(.current.rate, .reference.rate * .reference.tolerance.lower, label = "Observed rate", expected.label = "lower threshold on rate") - expect_lt(.current.rate, .reference.rate * .reference.tolerance.upper, label = "Observed rate", expected.label = "upper threshold on rate") -}) - -# -# Done -# - -# context("ds.dataFrameFill::perf::shutdown") -disconnect.discordant.dataset.simple() -# context("ds.dataFrameFill::perf::done") diff --git a/tests/testthat/test-smk-ds.asFactor.R b/tests/testthat/test-smk-ds.asFactor.R index c87d06a75..e1fac4b7f 100644 --- a/tests/testthat/test-smk-ds.asFactor.R +++ b/tests/testthat/test-smk-ds.asFactor.R @@ -32,60 +32,60 @@ test_that("with no force.factor.levels", { ds.asFactor("TID", "TID.f1") res1 <- ds.class("TID.f1") - res2 <- expect_warning(ds.table1D("TID.f1"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) + res2 <- ds.table("TID.f1") expect_equal("factor", res1$`survival1`) expect_equal("factor", res1$`survival2`) expect_equal("factor", res1$`survival3`) - expect_equal("All tables are valid!", res2$validity) + expect_equal("Data in all studies were valid", res2$validity.message) }) test_that("with forced.factor.levels of 1:6", { ds.asFactor("TID", "TID.f2", forced.factor.levels=1:6) res1 <- ds.class("TID.f2") - res2 <- expect_warning(ds.table1D("TID.f2"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) + res2 <- ds.table("TID.f2") expect_equal("factor", res1$`survival1`) expect_equal("factor", res1$`survival2`) expect_equal("factor", res1$`survival3`) - expect_equal("All tables are valid!", res2$validity) + expect_equal("Data in all studies were valid", res2$validity.message) }) test_that("with force.factor.levels of 0:10", { ds.asFactor("TID", "TID.f3", forced.factor.levels=0:10) res1 <- ds.class("TID.f3") - res2 <- expect_warning(ds.table1D("TID.f3"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) + res2 <- ds.table("TID.f3") expect_equal("factor", res1$`survival1`) expect_equal("factor", res1$`survival2`) expect_equal("factor", res1$`survival3`) - expect_equal("All tables are valid!", res2$validity) + expect_equal("Data in all studies were valid", res2$validity.message) }) test_that("with force.factor.levels of 2:3", { ds.asFactor("TID", "TID.f4", forced.factor.levels=2:3) res1 <- ds.class("TID.f4") - res2 <- expect_warning(ds.table1D("TID.f4"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) + res2 <- ds.table("TID.f4") expect_equal("factor", res1$`survival1`) expect_equal("factor", res1$`survival2`) expect_equal("factor", res1$`survival3`) - expect_equal("All tables are valid!", res2$validity) + expect_equal("Data in all studies were valid", res2$validity.message) }) test_that("with force.factor.levels of c(1,2,3,4,'a','h',5)", { ds.asFactor("TID", "TID.f5", forced.factor.levels=c(1,2,3,4,'a','h',5)) res1 <- ds.class("TID.f5") - res2 <- expect_warning(ds.table1D("TID.f5"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) + res2 <- ds.table("TID.f5") expect_equal("factor", res1$`survival1`) expect_equal("factor", res1$`survival2`) expect_equal("factor", res1$`survival3`) - expect_equal("All tables are valid!", res2$validity) + expect_equal("Data in all studies were valid", res2$validity.message) }) # context("ds.asFactor::smk::fixed.dummy.vars") diff --git a/tests/testthat/test-smk-ds.asFactorSimple.R b/tests/testthat/test-smk-ds.asFactorSimple.R index 029b3465e..fb1870822 100644 --- a/tests/testthat/test-smk-ds.asFactorSimple.R +++ b/tests/testthat/test-smk-ds.asFactorSimple.R @@ -32,12 +32,12 @@ test_that("with no force.factor.levels", { ds.asFactorSimple("TID", "TID.f1") res1 <- ds.class("TID.f1") - res2 <- expect_warning(ds.table1D("TID.f1"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) + res2 <- ds.table("TID.f1") expect_equal("factor", res1$`survival1`) expect_equal("factor", res1$`survival2`) expect_equal("factor", res1$`survival3`) - expect_equal("All tables are valid!", res2$validity) + expect_equal("Data in all studies were valid", res2$validity.message) }) # diff --git a/tests/testthat/test-smk-ds.changeRefGroup.R b/tests/testthat/test-smk-ds.changeRefGroup.R index 5c0964dfd..d072622f5 100644 --- a/tests/testthat/test-smk-ds.changeRefGroup.R +++ b/tests/testthat/test-smk-ds.changeRefGroup.R @@ -28,7 +28,7 @@ test_that("setup", { # context("ds.changeRefGroup::smk") test_that("simple changeRefGroup", { newNames <- c('normal', 'overweight', 'obesity') - expect_warning(ds.recodeLevels(x='D$PM_BMI_CATEGORICAL', newCategories=newNames, newobj='bmi_new'), "'ds.recodeLevels' is deprecated.\nUse 'ds.recodeValues' instead.", fixed = TRUE) + ds.recodeValues(var.name='D$PM_BMI_CATEGORICAL', values2replace.vector=c(1, 2, 3), new.values.vector=newNames, newobj='bmi_new') res <- ds.changeRefGroup(x='bmi_new', ref='obesity', newobj='bmi_ob') diff --git a/tests/testthat/test-smk-ds.dataFrameFill-donothing.R b/tests/testthat/test-smk-ds.dataFrameFill-donothing.R deleted file mode 100644 index f7fa24e55..000000000 --- a/tests/testthat/test-smk-ds.dataFrameFill-donothing.R +++ /dev/null @@ -1,61 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.dataFrameFill::smk::donothing setup") - -connect.studies.dataset.cnsim(list("LAB_TSC", "LAB_TRIG", "LAB_HDL")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.dataFrameFill::smk::donothing dataframes") -test_that("dataFrameFill_donothing", { - colnamesD <- ds.colnames('D') - - expect_length(colnamesD, 3) - expect_length(colnamesD$sim1, 3) - expect_equal(colnamesD$sim1[1], "LAB_TSC") - expect_equal(colnamesD$sim1[2], "LAB_TRIG") - expect_equal(colnamesD$sim1[3], "LAB_HDL") - expect_length(colnamesD$sim2, 3) - expect_equal(colnamesD$sim2[1], "LAB_TSC") - expect_equal(colnamesD$sim2[2], "LAB_TRIG") - expect_equal(colnamesD$sim2[3], "LAB_HDL") - expect_length(colnamesD$sim3, 3) - expect_equal(colnamesD$sim3[1], "LAB_TSC") - expect_equal(colnamesD$sim3[2], "LAB_TRIG") - expect_equal(colnamesD$sim3[3], "LAB_HDL") - - expect_error(ds.dataFrameFill(df.name="D", newobj="filled_df"), "The dataframes have the same variables. There are no missing variables to fill!") -}) - -# -# Done -# - -# context("ds.dataFrameFill::smk::donothing shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.dataFrameFill::smk::donothing done") diff --git a/tests/testthat/test-smk-ds.dataFrameFill-factor.R b/tests/testthat/test-smk-ds.dataFrameFill-factor.R deleted file mode 100644 index f23842c8d..000000000 --- a/tests/testthat/test-smk-ds.dataFrameFill-factor.R +++ /dev/null @@ -1,182 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.dataFrameFill::smk::factor setup") - -connect.studies.dataset.cnsim(list('LAB_TSC', 'DIS_CVA', 'LAB_HDL', 'DIS_DIAB')) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.dataFrameFill::smk::factor setup dataframes") -test_that("setup", { - ds_expect_variables(c("D")) - - vectors1 <- c('D$LAB_TSC', 'D$DIS_CVA', 'D$LAB_HDL') - ds.dataFrame(x=vectors1, newobj = "DD", datasources=ds.test_env$connections[1]) - - vectors2 <- c('D$LAB_TSC', 'D$DIS_CVA', 'D$DIS_DIAB') - ds.dataFrame(x=vectors2, newobj = "DD", datasources=ds.test_env$connections[2]) - - vectors3 <- c('D$LAB_TSC', 'D$LAB_HDL', 'D$DIS_DIAB') - ds.dataFrame(x=vectors3, newobj = "DD", datasources=ds.test_env$connections[3]) - - colnamesDD <- ds.colnames('DD') - - expect_length(colnamesDD, 3) - expect_length(colnamesDD$sim1, 3) - expect_equal(colnamesDD$sim1[1], "LAB_TSC") - expect_equal(colnamesDD$sim1[2], "DIS_CVA") - expect_equal(colnamesDD$sim1[3], "LAB_HDL") - expect_length(colnamesDD$sim2, 3) - expect_equal(colnamesDD$sim2[1], "LAB_TSC") - expect_equal(colnamesDD$sim2[2], "DIS_CVA") - expect_equal(colnamesDD$sim2[3], "DIS_DIAB") - expect_length(colnamesDD$sim3, 3) - expect_equal(colnamesDD$sim3[1], "LAB_TSC") - expect_equal(colnamesDD$sim3[2], "LAB_HDL") - expect_equal(colnamesDD$sim3[3], "DIS_DIAB") - - classesDD <- ds.class('DD') - - expect_length(classesDD, 3) - expect_length(classesDD$sim1, 1) - expect_equal(classesDD$sim1, "data.frame") - expect_length(classesDD$sim2, 1) - expect_equal(classesDD$sim2, "data.frame") - expect_length(classesDD$sim3, 1) - expect_equal(classesDD$sim3, "data.frame") -}) - - -# context("ds.dataFrameFill::smk::factor extend unfilled dataframes") -test_that("dataFrameFill_exists", { - res <- ds.dataFrameFill(df.name="DD", newobj="filled_df") - - - colnamesFilled <- ds.colnames('filled_df') - - expect_length(colnamesFilled, 3) - expect_length(colnamesFilled$sim1, 4) - expect_equal(colnamesFilled$sim1[1], "LAB_TSC") - expect_equal(colnamesFilled$sim1[2], "DIS_CVA") - expect_equal(colnamesFilled$sim1[3], "LAB_HDL") - expect_equal(colnamesFilled$sim1[4], "DIS_DIAB") - expect_length(colnamesFilled$sim2, 4) - expect_equal(colnamesFilled$sim2[1], "LAB_TSC") - expect_equal(colnamesFilled$sim2[2], "DIS_CVA") - expect_equal(colnamesFilled$sim2[3], "DIS_DIAB") - expect_equal(colnamesFilled$sim2[4], "LAB_HDL") - expect_length(colnamesFilled$sim3, 4) - expect_equal(colnamesFilled$sim3[1], "LAB_TSC") - expect_equal(colnamesFilled$sim3[2], "LAB_HDL") - expect_equal(colnamesFilled$sim3[3], "DIS_DIAB") - expect_equal(colnamesFilled$sim3[4], "DIS_CVA") - - classFilled <- ds.class('filled_df') - - expect_length(classFilled, 3) - expect_length(classFilled$sim1, 1) - expect_equal(classFilled$sim1, "data.frame") - expect_length(classFilled$sim2, 1) - expect_equal(classFilled$sim2, "data.frame") - expect_length(classFilled$sim3, 1) - expect_equal(classFilled$sim3, "data.frame") - - lab_tsc_classFilled <- ds.class('filled_df$LAB_TSC') - - expect_length(lab_tsc_classFilled, 3) - expect_length(lab_tsc_classFilled$sim1, 1) - expect_equal(lab_tsc_classFilled$sim1, "numeric") - expect_length(lab_tsc_classFilled$sim2, 1) - expect_equal(lab_tsc_classFilled$sim2, "numeric") - expect_length(lab_tsc_classFilled$sim3, 1) - expect_equal(lab_tsc_classFilled$sim3, "numeric") - - dis_cva_classFilled <- ds.class('filled_df$DIS_CVA') - - expect_length(dis_cva_classFilled, 3) - expect_length(dis_cva_classFilled$sim1, 1) - expect_equal(dis_cva_classFilled$sim1, "factor") - expect_length(dis_cva_classFilled$sim2, 1) - expect_equal(dis_cva_classFilled$sim2, "factor") - expect_length(dis_cva_classFilled$sim3, 1) - expect_equal(dis_cva_classFilled$sim3, "factor") - - dis_cva_levelsFilled <- ds.levels('filled_df$DIS_CVA') - - expect_length(dis_cva_levelsFilled, 3) - expect_length(dis_cva_levelsFilled$sim1, 1) - expect_length(dis_cva_levelsFilled$sim1$Levels, 2) - expect_true(all(dis_cva_levelsFilled$sim1$Levels %in% c("0", "1"))) - expect_length(dis_cva_levelsFilled$sim2, 1) - expect_length(dis_cva_levelsFilled$sim2$Levels, 2) - expect_true(all(dis_cva_levelsFilled$sim2$Levels %in% c("0", "1"))) - expect_length(dis_cva_levelsFilled$sim3, 1) - expect_length(dis_cva_levelsFilled$sim3$Levels, 2) - expect_true(all(dis_cva_levelsFilled$sim3$Levels %in% c("0", "1"))) - - lab_hdl_classFilled <- ds.class('filled_df$LAB_HDL') - - expect_length(lab_hdl_classFilled, 3) - expect_length(lab_hdl_classFilled$sim1, 1) - expect_equal(lab_hdl_classFilled$sim1, "numeric") - expect_length(lab_hdl_classFilled$sim2, 1) - expect_equal(lab_hdl_classFilled$sim2, "numeric") - expect_length(lab_hdl_classFilled$sim3, 1) - expect_equal(lab_hdl_classFilled$sim3, "numeric") - - dis_diab_classFilled <- ds.class('filled_df$DIS_DIAB') - - expect_length(dis_diab_classFilled, 3) - expect_length(dis_diab_classFilled$sim1, 1) - expect_equal(dis_diab_classFilled$sim1, "factor") - expect_length(dis_diab_classFilled$sim2, 1) - expect_equal(dis_diab_classFilled$sim2, "factor") - expect_length(dis_diab_classFilled$sim3, 1) - expect_equal(dis_diab_classFilled$sim3, "factor") - - dis_diab_levelsFilled <- ds.levels('filled_df$DIS_DIAB') - - expect_length(dis_diab_levelsFilled, 3) - expect_length(dis_diab_levelsFilled$sim1, 1) - expect_length(dis_diab_levelsFilled$sim1$Levels, 2) - expect_true(all(dis_diab_levelsFilled$sim1$Levels %in% c("0", "1"))) - expect_length(dis_diab_levelsFilled$sim2, 1) - expect_length(dis_diab_levelsFilled$sim2$Levels, 2) - expect_true(all(dis_diab_levelsFilled$sim2$Levels %in% c("0", "1"))) - expect_length(dis_diab_levelsFilled$sim3, 1) - expect_length(dis_diab_levelsFilled$sim3$Levels, 2) - expect_true(all(dis_diab_levelsFilled$sim3$Levels %in% c("0", "1"))) -}) - -# -# Done -# - -# context("ds.dataFrameFill::smk::factor shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "DD", "filled_df")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.dataFrameFill::smk::factor done") diff --git a/tests/testthat/test-smk-ds.dataFrameFill.R b/tests/testthat/test-smk-ds.dataFrameFill.R deleted file mode 100644 index c05064fac..000000000 --- a/tests/testthat/test-smk-ds.dataFrameFill.R +++ /dev/null @@ -1,115 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.dataFrameFill::smk::setup") - -connect.discordant.dataset.simple(list("A", "B", "C")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.dataFrameFill::smk::extend unfilled dataframes") -test_that("dataFrameFill_exists", { - colnamesD <- ds.colnames('D') - - expect_length(colnamesD, 3) - expect_length(colnamesD$discordant1, 2) - expect_equal(colnamesD$discordant1[1], "A") - expect_equal(colnamesD$discordant1[2], "B") - expect_length(colnamesD$discordant2, 2) - expect_equal(colnamesD$discordant2[1], "A") - expect_equal(colnamesD$discordant2[2], "C") - expect_length(colnamesD$discordant3, 2) - expect_equal(colnamesD$discordant3[1], "B") - expect_equal(colnamesD$discordant3[2], "C") - - res <- ds.dataFrameFill(df.name="D", newobj="filled_df") - - - colnamesFilled <- ds.colnames('filled_df') - - expect_length(colnamesFilled, 3) - expect_length(colnamesFilled$discordant1, 3) - expect_equal(colnamesFilled$discordant1[1], "A") - expect_equal(colnamesFilled$discordant1[2], "B") - expect_equal(colnamesFilled$discordant1[3], "C") - expect_length(colnamesFilled$discordant2, 3) - expect_equal(colnamesFilled$discordant2[1], "A") - expect_equal(colnamesFilled$discordant2[2], "C") - expect_equal(colnamesFilled$discordant2[3], "B") - expect_length(colnamesFilled$discordant3, 3) - expect_equal(colnamesFilled$discordant3[1], "B") - expect_equal(colnamesFilled$discordant3[2], "C") - expect_equal(colnamesFilled$discordant3[3], "A") - - classFilled <- ds.class('filled_df') - - expect_length(classFilled, 3) - expect_length(classFilled$discordant1, 1) - expect_equal(classFilled$discordant1, "data.frame") - expect_length(classFilled$discordant2, 1) - expect_equal(classFilled$discordant2, "data.frame") - expect_length(classFilled$discordant3, 1) - expect_equal(classFilled$discordant3, "data.frame") - - classFilled <- ds.class('filled_df$A') - - expect_length(classFilled, 3) - expect_length(classFilled$discordant1, 1) - expect_equal(classFilled$discordant1, "integer") - expect_length(classFilled$discordant2, 1) - expect_equal(classFilled$discordant2, "integer") - expect_length(classFilled$discordant3, 1) - expect_equal(classFilled$discordant3, "integer") - - classFilled <- ds.class('filled_df$B') - - expect_length(classFilled, 3) - expect_length(classFilled$discordant1, 1) - expect_equal(classFilled$discordant1, "integer") - expect_length(classFilled$discordant2, 1) - expect_equal(classFilled$discordant2, "integer") - expect_length(classFilled$discordant3, 1) - expect_equal(classFilled$discordant3, "integer") - - classFilled <- ds.class('filled_df$C') - - expect_length(classFilled, 3) - expect_length(classFilled$discordant1, 1) - expect_equal(classFilled$discordant1, "integer") - expect_length(classFilled$discordant2, 1) - expect_equal(classFilled$discordant2, "integer") - expect_length(classFilled$discordant3, 1) - expect_equal(classFilled$discordant3, "integer") -}) - -# -# Done -# - -# context("ds.dataFrameFill::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "filled_df")) -}) - -disconnect.discordant.dataset.simple() - -# context("ds.dataFrameFill::smk::done") diff --git a/tests/testthat/test-smk-ds.listServersideFunctions.R b/tests/testthat/test-smk-ds.listServersideFunctions.R deleted file mode 100644 index 9d48474cb..000000000 --- a/tests/testthat/test-smk-ds.listServersideFunctions.R +++ /dev/null @@ -1,87 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC", "LAB_HDL")) - -# -# Tests -# - -# context("ds.listServersideFunctions::smk::check results") -test_that("check results", { - assign.functions <- factor(c( - "BooleDS", "abs", "absDS", "acos", "as.character", "as.null", "as.numeric", "asCharacterDS", "asDataMatrixDS", - "asFactorDS2", "asFactorSimpleDS", "asIntegerDS", "asListDS", "asLogicalDS", "asMatrixDS", - "asNumericDS", "asin", "atan", "attach", "blackBoxRanksDS", "blackBoxRanksDS", "boxPlotGG_data_TreatmentDS", "boxPlotGG_data_Treatment_numericDS", "cDS", - "cbindDS", "changeRefGroupDS", "completeCasesDS", "complete.cases", "dataFrameDS", "dataFrameFillDS", "dataFrameSortDS", - "dataFrameSubsetDS2", "dataFrameDS", "dmtC2SDS", "expDS", "glmPredictDS.as", "glmSLMADS.assign", "glmSummaryDS.as", "glmerSLMADS.assign", - "lexisDS2", "lexisDS3", "list", "listDS", "logDS", "lsplineDS", - "matrixDS", "matrixDetDS2", "matrixDiagDS", "matrixDimnamesDS", "matrixInvertDS", - "matrixMultDS", "matrixTransposeDS", "mergeDS", "nsDS", "qlsplineDS", "rBinomDS", "rNormDS", "rPoisDS", - "rUnifDS", "ranksSecureDS2", "ranksSecureDS4", "ranksSecureDS5", "rbindDS", "reShapeDS", "recodeLevelsDS", "recodeValuesDS", "repDS", - "replaceNaDS", "rowColCalcDS", "seqDS", "sin", "subsetByClassDS", "subsetDS", "sum", "sampleDS", - "tableDS.assign", "tan", "tapplyDS.assign", "unlist", "unListDS", "vectorDS" - )) - aggregate.functions <- factor(c( - "NROW", "asFactorDS1", "aucDS", - "checkNegValueDS", "classDS", "colnamesDS", "corDS", "corTestDS", - "covDS", "dataFrameSubsetDS1", - "densityGridDS", "dimDS", "gamlssDS", - "exists", "glmDS1", "glmDS1", "glmDS2", - "glmDS2", "glmerSLMADS2", "glmPredictDS.ag", "glmSLMADS1", "glmSLMADS2", "glmSummaryDS.ag", - "heatmapPlotDS", "histogramDS1", "histogramDS2", "is.character", "is.factor", "is.list", "is.null", "is.numeric", - "isNaDS", "isValidDS", "kurtosisDS1", "kurtosisDS2", "lengthDS", - "levelsDS", "lexisDS1", "listDisclosureSettingsDS", "lmerSLMADS2", "lsDS", - "matrixDetDS1", "meanDS", "meanSdGpDS", "messageDS", "miceDS", - "namesDS", "numNaDS", "quantileMeanDS", "rangeDS", - "ranksSecureDS1", "ranksSecureDS3", - "rmDS", "skewnessDS1", "skewnessDS2", "scatterPlotDS", - "scoreVectDS", "setSeedDS", "t.test", - "table1DDS", "table2DDS", "tableDS", "tableDS2", "tapplyDS", - "testObjExistsDS", "varDS" - )) - - expect_warning(res <- ds.listServersideFunctions(), "'ds.listServersideFunctions' is deprecated.", fixed=TRUE) - - expect_length(res, 2) - expect_length(res$serverside.assign.functions, 7) - expect_length(res$serverside.aggregate.functions, 7) - - sim1.assign.res <- subset(res$serverside.assign.functions, server == 'sim1', c('name')) - sim1.aggregate.res <- subset(res$serverside.aggregate.functions, server == 'sim1', c('name')) - sim2.assign.res <- subset(res$serverside.assign.functions, server == 'sim2', c('name')) - sim2.aggregate.res <- subset(res$serverside.aggregate.functions, server == 'sim2', c('name')) - sim3.assign.res <- subset(res$serverside.assign.functions, server == 'sim3', c('name')) - sim3.aggregate.res <- subset(res$serverside.aggregate.functions, server == 'sim3', c('name')) - - for (func.name in assign.functions) - expect_true(func.name %in% sim1.assign.res$name, info = func.name) - for (func.name in aggregate.functions) - expect_true(func.name %in% sim1.aggregate.res$name, info = func.name) - for (func.name in assign.functions) - expect_true(func.name %in% sim2.assign.res$name, info = func.name) - for (func.name in aggregate.functions) - expect_true(func.name %in% sim2.aggregate.res$name, info = func.name) - for (func.name in assign.functions) - expect_true(func.name %in% sim3.assign.res$name, info = func.name) - for (func.name in aggregate.functions) - expect_true(func.name %in% sim3.aggregate.res$name, info = func.name) -}) - -# -# Done -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-smk-ds.look.R b/tests/testthat/test-smk-ds.look.R deleted file mode 100644 index 636154458..000000000 --- a/tests/testthat/test-smk-ds.look.R +++ /dev/null @@ -1,51 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.look::smk::setup") - -connect.studies.dataset.cnsim(list("LAB_TSC", "LAB_TRIG", "LAB_HDL")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.look::smk") -test_that("simple look", { - res <- ds.look("lengthDS('D$LAB_TSC')") - - expect_length(res, 1) - expect_length(res$output, 3) - expect_equal(res$output$sim1$length, 2163) - expect_equal(res$output$sim2$length, 3088) - expect_equal(res$output$sim3$length, 4128) -}) - -# -# Done -# - -# context("ds.look::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.look::smk::done") diff --git a/tests/testthat/test-smk-ds.meanByClass.R b/tests/testthat/test-smk-ds.meanByClass.R deleted file mode 100644 index e830843d9..000000000 --- a/tests/testthat/test-smk-ds.meanByClass.R +++ /dev/null @@ -1,123 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.meanByClass::smk::setup") - -connect.studies.dataset.cnsim(list("LAB_TSC","LAB_HDL","PM_BMI_CATEGORICAL")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.meanByClass::smk::LAB_TSC across PM_BMI_CATEGORICAL categories where both vectors are 'loose'") -ds.assign("D$LAB_TSC", "ldl") -ds.assign("D$PM_BMI_CATEGORICAL", "pm_bmi") -test_that("LAB_TSC_across_", { - res <- ds.meanByClass(x='ldl~pm_bmi') - - expect_length(res, 6) - expect_equal(res[[1]], '2753') - expect_equal(res[[2]], '5.85(1.03)') - expect_equal(res[[3]], '3545') - expect_equal(res[[4]], '5.82(1.05)') - expect_equal(res[[5]], '2629') - expect_equal(res[[6]], '5.89(1.15)') -}) - -# context("ds.meanByClass::smk::calculate the mean proportion for LAB_HDL across PM_BMI_CATEGORICAL categories") -res <- ds.meanByClass(x='D', outvar='LAB_HDL', covar='PM_BMI_CATEGORICAL') -test_that("LAB_HDL_across_PM_BMI_CATEGORICAL", { - - expect_length(res, 6) - expect_equal(res[[1]], '2753') - expect_equal(res[[2]], '1.64(0.41)') - expect_equal(res[[3]], '3545') - expect_equal(res[[4]], '1.57(0.41)') - expect_equal(res[[5]], '2629') - expect_equal(res[[6]], '1.5(0.44)') -}) - - -# context("ds.meanByClass::smk::calculate the mean proportion for LAB_HDL & LAB_TSC across bmi categories") -res <- ds.meanByClass(x='D', outvar=c('LAB_HDL','LAB_TSC'), covar=c('PM_BMI_CATEGORICAL')) -test_that("LAB_HDL-LAB_TSC_across_PM_BMI_CATEGORICAL", { - - expect_length(res, 12) - expect_equal(res[[1]], '2753') - expect_equal(res[[2]], '1.64(0.41)') - expect_equal(res[[3]], '2753') - expect_equal(res[[4]], '5.85(1.03)') - expect_equal(res[[5]], '3545') - expect_equal(res[[6]], '1.57(0.41)') - expect_equal(res[[7]], '3545') - expect_equal(res[[8]], '5.82(1.05)') - expect_equal(res[[9]], '2629') - expect_equal(res[[10]], '1.5(0.44)') - expect_equal(res[[11]], '2629') - expect_equal(res[[12]], '5.89(1.15)') -}) - - -# context("ds.meanByClass::smk::calculate the mean proportion for LAB_HDL across gender bmi and diabetes status categories") -# res <- ds.meanByClass(datasources=ds.test_env$connection.opal, x='D', outvar=c('LAB_HDL','LAB_TSC'), covar=c('GENDER','PM_BMI_CATEGORICAL','DIS_DIAB')) - - -# context("ds.meanByClass::smk::calculate the mean proportion for LAB_HDL across PM_BMI_CATEGORICAL categories, split") -res <- ds.meanByClass(x='D', outvar='LAB_HDL', covar='PM_BMI_CATEGORICAL', type='split') -test_that("LAB_HDL_across_PM_BMI_CATEGORICAL", { - - expect_length(res, 3) - expect_length(res$sim1, 6) - expect_equal(res$sim1[[1]], '641') - expect_equal(res$sim1[[2]], '1.64(0.4)') - expect_equal(res$sim1[[3]], '816') - expect_equal(res$sim1[[4]], '1.57(0.4)') - expect_equal(res$sim1[[5]], '609') - expect_equal(res$sim1[[6]], '1.51(0.42)') - expect_length(res$sim2, 6) - expect_equal(res$sim2[[1]], '899') - expect_equal(res$sim2[[2]], '1.62(0.4)') - expect_equal(res$sim2[[3]], '1173') - expect_equal(res$sim2[[4]], '1.56(0.41)') - expect_equal(res$sim2[[5]], '866') - expect_equal(res$sim2[[6]], '1.49(0.45)') - expect_length(res$sim3, 6) - expect_equal(res$sim3[[1]], '1213') - expect_equal(res$sim3[[2]], '1.65(0.41)') - expect_equal(res$sim3[[3]], '1556') - expect_equal(res$sim3[[4]], '1.57(0.41)') - expect_equal(res$sim3[[5]], '1154') - expect_equal(res$sim3[[6]], '1.51(0.44)') -}) - - -# -# Tear down -# - -# context("ds.meanByClass::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "D.PM_BMI_CATEGORICAL1", "D.PM_BMI_CATEGORICAL2", "D.PM_BMI_CATEGORICAL3", - "ldl", "pm_bmi", "tempholder", "X", "X.pm_bmi1", "X.pm_bmi2", "X.pm_bmi3")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.meanByClass::smk::done") diff --git a/tests/testthat/test-smk-ds.message.R b/tests/testthat/test-smk-ds.message.R deleted file mode 100644 index bc3572633..000000000 --- a/tests/testthat/test-smk-ds.message.R +++ /dev/null @@ -1,106 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.message::smk::setup") - -connect.studies.dataset.cnsim(list("LAB_TSC")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - - -# -# Tests -# - -# context("ds.message::smk") -test_that("not exists - request message", { - message.res <- ds.message('Test') - - expect_length(message.res, 3) - expect_equal(message.res$sim1, "Error: the object does not exist in this datasource", fixed=TRUE) - expect_equal(message.res$sim2, "Error: the object does not exist in this datasource", fixed=TRUE) - expect_equal(message.res$sim3, "Error: the object does not exist in this datasource", fixed=TRUE) -}) - -test_that("exists - request message", { - ds.list("D$LAB_TSC", "Test") - - message.res <- ds.message('Test') - - expect_length(message.res, 3) - expect_equal(message.res$sim1, "ALL OK: there are no studysideMessage(s) on this datasource", fixed=TRUE) - expect_equal(message.res$sim2, "ALL OK: there are no studysideMessage(s) on this datasource", fixed=TRUE) - expect_equal(message.res$sim3, "ALL OK: there are no studysideMessage(s) on this datasource", fixed=TRUE) -}) - -test_that("partial - request message - conn 1", { - ds.rm("TestP") - - ds.list("D$LAB_TSC", newobj="TestP", datasources=ds.test_env$connections[1]) - - message.res <- ds.message('TestP') - - expect_length(message.res, 3) - expect_equal(message.res$sim1, "ALL OK: there are no studysideMessage(s) on this datasource", fixed=TRUE) - expect_equal(message.res$sim2, "Error: the object does not exist in this datasource", fixed=TRUE) - expect_equal(message.res$sim3, "Error: the object does not exist in this datasource", fixed=TRUE) - - ds.rm("TestP") -}) - -test_that("partial - request message - conn 2", { - ds.rm("TestP") - - ds.list("D$LAB_TSC", newobj="TestP", datasources=ds.test_env$connections[2]) - - message.res <- ds.message('TestP') - - expect_length(message.res, 3) - expect_equal(message.res$sim1, "Error: the object does not exist in this datasource", fixed=TRUE) - expect_equal(message.res$sim2, "ALL OK: there are no studysideMessage(s) on this datasource", fixed=TRUE) - expect_equal(message.res$sim3, "Error: the object does not exist in this datasource", fixed=TRUE) - - ds.rm("TestP") -}) - -test_that("partial - request message - conn 3", { - ds.rm("TestP") - - ds.list("D$LAB_TSC", newobj="TestP", datasources=ds.test_env$connections[3]) - - message.res <- ds.message('TestP') - - expect_length(message.res, 3) - expect_equal(message.res$sim1, "Error: the object does not exist in this datasource", fixed=TRUE) - expect_equal(message.res$sim2, "Error: the object does not exist in this datasource", fixed=TRUE) - expect_equal(message.res$sim3, "ALL OK: there are no studysideMessage(s) on this datasource", fixed=TRUE) - - ds.rm("TestP") -}) - -# -# Done -# -# context("ds.message::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "Test")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.message::smk::done") diff --git a/tests/testthat/test-smk-ds.recodeLevels.R b/tests/testthat/test-smk-ds.recodeLevels.R deleted file mode 100644 index 3b813074f..000000000 --- a/tests/testthat/test-smk-ds.recodeLevels.R +++ /dev/null @@ -1,70 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.recodeLevels::smk::setup") - -connect.studies.dataset.cnsim(list("PM_BMI_CATEGORICAL")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.recodeLevels::smk") -test_that("new levels", { - expect_warning(ds.recodeLevels(x='D$PM_BMI_CATEGORICAL', newCategories=c('normal', 'overweight', 'obesity'), newobj='bmi_new'), "'ds.recodeLevels' is deprecated.\nUse 'ds.recodeValues' instead.", fixed = TRUE) - levels <- ds.levels(x='bmi_new') - - expected <- c("normal", "overweight", "obesity") - expect_length(levels, 3) - expect_length(levels$sim1$Levels, 3) - expect_equal(levels$sim1$Levels, expected) - expect_length(levels$sim2$Levels, 3) - expect_equal(levels$sim2$Levels, expected) - expect_length(levels$sim3$Levels, 3) - expect_equal(levels$sim3$Levels, expected) -}) - -# context("ds.recodeLevels::smk::no connections or newobj") -test_that("new levels auto", { - expect_warning(ds.recodeLevels(x='D$PM_BMI_CATEGORICAL', newCategories=c('normal', 'overweight', 'obesity')), "'ds.recodeLevels' is deprecated.\nUse 'ds.recodeValues' instead.", fixed = TRUE) - levels <- ds.levels(x='PM_BMI_CATEGORICAL_new') - - expected <- c("normal", "overweight", "obesity") - expect_length(levels, 3) - expect_length(levels$sim1$Levels, 3) - expect_equal(levels$sim1$Levels, expected) - expect_length(levels$sim2$Levels, 3) - expect_equal(levels$sim2$Levels, expected) - expect_length(levels$sim3$Levels, 3) - expect_equal(levels$sim3$Levels, expected) -}) - -# -# Tear down -# - -# context("ds.recodeLevels::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "bmi_new", "PM_BMI_CATEGORICAL_new")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.recodeLevels::smk::done") diff --git a/tests/testthat/test-smk-ds.subset.R b/tests/testthat/test-smk-ds.subset.R deleted file mode 100644 index 88fecdd2d..000000000 --- a/tests/testthat/test-smk-ds.subset.R +++ /dev/null @@ -1,92 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.subset::smk::setup") - -connect.studies.dataset.cnsim(list("DIS_DIAB","PM_BMI_CONTINUOUS","LAB_HDL", "GENDER")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.subset::smk::generate a subset of the assigned table (by default the table is named 'D') with the first 50 observations and the two first columns") -ds.subset(datasources=ds.test_env$connections, subset='subD', x='D', rows=c(1:50), cols=c(1,2)) -res <- ds.exists('subD') -test_that("subD_exists", { - expect_length(res, 3) - expect_true(res$sim1) - expect_true(res$sim2) - expect_true(res$sim3) -}) - -# context("ds.subset::smk::generate a subset of the assigned table (by default the table is named 'D') with the first 50 observations and the two first columns referred to by their names") -ds.subset(subset='subD2', x='D', rows=c(1:50), cols = c('DIS_DIAB','PM_BMI_CONTINUOUS')) -res <- ds.exists('subD2') -test_that("subD2_exists", { - expect_length(res, 3) - expect_true(res$sim1) - expect_true(res$sim2) - expect_true(res$sim3) -}) - -# context("ds.subset::smk::generate a subset of the table D with bmi values greater than or equal to 25.") -ds.subset(datasources=ds.test_env$connections, subset='subD3', x='D', logical='PM_BMI_CONTINUOUS>=', threshold=25) -res <- ds.exists('subD3') -test_that("subD3_exists", { - expect_length(res, 3) - expect_true(res$sim1) - expect_true(res$sim2) - expect_true(res$sim3) -}) - -# context("ds.subset::smk::get the logarithmic values of the variable 'lab_hdl' and generate a subset with the first 50 observations of that new vector.") -# ds.assign(toAssign='log(D$LAB_HDL)', newobj='logHDL') -# ds.subset(datasources=ds.test_env$connections, subset="subLAB_HDL", x="logHDL", rows=c(1:50)) -# res <- ds.exists('subLAB_HDL') -# test_that("subLAB_HDL_exists", { -# expect_length(res, 3) -# expect_true(res$sim1) -# expect_true(res$sim2) -# expect_true(res$sim3) -# }) - -# context("ds.subset::smk::get the variable 'PM_BMI_CONTINUOUS' from the dataframe 'D' and generate a subset bmi vector with bmi values greater than or equal to 25") -# ds.assign(toAssign='D$PM_BMI_CONTINUOUS', newobj='BMI') -# ds.subset(datasources=ds.test_env$connections, subset='subBMI', x='BMI', logical='>=', threshold=25) -# res <- ds.exists('subBMI') -# test_that("subBMI_exists", { -# expect_length(res, 3) -# expect_true(res$sim1) -# expect_true(res$sim2) -# expect_true(res$sim3) -# }) - -# -# Tear down -# - -# context("ds.subset::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "subD", "subD2", "subD3")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.subset::smk::done") diff --git a/tests/testthat/test-smk-ds.subsetByClass.R b/tests/testthat/test-smk-ds.subsetByClass.R deleted file mode 100644 index 71420fcbe..000000000 --- a/tests/testthat/test-smk-ds.subsetByClass.R +++ /dev/null @@ -1,79 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.subsetByClass::smk::setup") - -connect.studies.dataset.cnsim(list("LAB_TSC", "GENDER")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.subsetByClass::smk") -test_that("gender implicit", { - res <- ds.subsetByClass(x='D', subsets='subclasses1') - - expect_true(is.null(res)) - - check <- ds.names('subclasses1') - - expect_length(check, 3) - expect_length(check$sim1, 2) - expect_equal(check$sim1[1], 'GENDER.level_0') - expect_equal(check$sim1[2], 'GENDER.level_1') - expect_length(check$sim2, 2) - expect_equal(check$sim2[1], 'GENDER.level_0') - expect_equal(check$sim2[2], 'GENDER.level_1') - expect_length(check$sim3, 2) - expect_equal(check$sim3[1], 'GENDER.level_0') - expect_equal(check$sim3[2], 'GENDER.level_1') -}) - -test_that("gender explicit", { - res <- ds.subsetByClass(x='D', subsets='subclasses2', variables='GENDER') - - expect_true(is.null(res)) - - check <- ds.names('subclasses2') - - expect_length(check, 3) - expect_length(check$sim1, 2) - expect_equal(check$sim1[1], 'GENDER.level_0') - expect_equal(check$sim1[2], 'GENDER.level_1') - expect_length(check$sim2, 2) - expect_equal(check$sim2[1], 'GENDER.level_0') - expect_equal(check$sim2[2], 'GENDER.level_1') - expect_length(check$sim3, 2) - expect_equal(check$sim3[1], 'GENDER.level_0') - expect_equal(check$sim3[2], 'GENDER.level_1') -}) - -# -# Tear down -# - -# context("ds.subsetByClass::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "subclasses1", "subclasses2")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.subsetByClass::smk::done") diff --git a/tests/testthat/test-smk-ds.table1D.R b/tests/testthat/test-smk-ds.table1D.R deleted file mode 100644 index a875f5929..000000000 --- a/tests/testthat/test-smk-ds.table1D.R +++ /dev/null @@ -1,102 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.table1D::smk::setup") - -connect.studies.dataset.cnsim(list("DIS_CVA","GENDER")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.table1D::smk::generate a one dimensional table, outputting combined contingency tables") -test_that("GENDER_normal", { - res <- expect_warning(ds.table1D(x='D$GENDER'), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) - - expect_equal(res$validity, "All tables are valid!") - expect_equal(res$counts[2], 4611) - expect_equal(res$counts[3], 9379) -}) - -# context("ds.table1D::smk::generate a one dimensional table, outputting combined contingency tables fail") -test_that("DIS_CVA_invalid", { - res <- expect_warning(ds.table1D(x='D$DIS_CVA'), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) - - expect_length(res, 3) - expect_equal(class(res), "list") - expect_length(res$counts, 3) - expect_length(res$percentages, 3) - expect_length(res$validity, 1) - expect_equal(res$validity, "All tables are valid!") -}) - -# context("ds.table1D::smk::generate a one dimensional table, outputting combined contingency tables fail split") -test_that("DIS_CVA_invalid_split", { - res <- expect_warning(ds.table1D(x='D$DIS_CVA', type="split"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) - - expect_length(res, 3) - expect_equal(class(res), "list") - expect_length(res$counts, 3) - expect_length(res$percentages, 3) - expect_length(res$validity, 1) - expect_equal(res$validity, "All tables are valid!") -}) - -# context("ds.table1D::smk::generate a one dimensional table, outputting study specific contingency tables") -test_that("GENDER_split", { - res <- expect_warning(ds.table1D(x='D$GENDER', type="split"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) - - expect_equal(res$validity, "All tables are valid!") - expect_equal(res$counts$sim1[1], 1092) - expect_equal(res$counts$sim2[2], 1503) - expect_equal(res$counts$sim3[1], 2091) -}) - -# context("ds.table1D::smk::generate a one dimensional table, outputting study specific contingency tables for study 1 and 2") -test_that("GENDER_split_12", { - res <- expect_warning(ds.table1D(datasources=ds.test_env$connections[1:2], x='D$GENDER', type="split"), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) - - expect_equal(res$validity, "All tables are valid!") - expect_equal(res$counts$sim1[1], 1092) - expect_equal(res$counts$sim2[2], 1503) - expect_equal(res$counts$sim3[1], NULL) -}) - -# context("ds.table1D::smk::generate a one dimensional table, outputting study specific and combined contingency tables") -test_that("GENDER_normal_2", { - res <- expect_warning(ds.table1D(datasources=ds.test_env$connections, x='D$GENDER'), "'ds.table1D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) - - expect_equal(res$validity, "All tables are valid!") - expect_equal(res$counts[2], 4611) - expect_equal(res$counts[3], 9379) -}) - -# -# Tear down -# - -# context("ds.table1D::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.table1D::smk::done") diff --git a/tests/testthat/test-smk-ds.table2D.R b/tests/testthat/test-smk-ds.table2D.R deleted file mode 100644 index 596ae5080..000000000 --- a/tests/testthat/test-smk-ds.table2D.R +++ /dev/null @@ -1,68 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.table2D::smk::setup") - -connect.studies.dataset.cnsim(list("DIS_DIAB", "GENDER")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.table2D::smk") -test_that("simple table2D", { - table2D.res <- expect_warning(ds.table2D(x='D$DIS_DIAB', y='D$GENDER'), "'ds.table2D' is deprecated.\nUse 'ds.table' instead.", fixed = TRUE) - - expect_length(table2D.res, 9) - expect_length(table2D.res$colPercent, 3) - expect_length(table2D.res$colPercent$`sim1-D`, 3) - expect_length(table2D.res$colPercent$`sim2-D`, 3) - expect_length(table2D.res$colPercent$`sim3-D`, 3) - expect_length(table2D.res$colPercent.all.studies, 1) - expect_length(table2D.res$rowPercent, 3) - expect_length(table2D.res$rowPercent$`sim1-D`, 3) - expect_length(table2D.res$rowPercent$`sim2-D`, 3) - expect_length(table2D.res$rowPercent$`sim3-D`, 3) - expect_length(table2D.res$rowPercent.all.studies, 1) - expect_length(table2D.res$chi2Test, 3) - expect_length(table2D.res$chi2Test$`sim1-D`, 9) - expect_length(table2D.res$chi2Test$`sim2-D`, 9) - expect_length(table2D.res$chi2Test$`sim3-D`, 9) - expect_length(table2D.res$chi2Test.all.studies, 1) - expect_length(table2D.res$counts, 3) - expect_length(table2D.res$counts$`sim1-D`, 3) - expect_length(table2D.res$counts$`sim2-D`, 3) - expect_length(table2D.res$counts$`sim3-D`, 3) - expect_length(table2D.res$counts.all.studies, 1) - expect_equal(table2D.res$validity, "All tables are valid!", fixed=TRUE) -}) - -# -# Done -# - -# context("ds.table2D::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.table2D::smk::done") diff --git a/tests/testthat/test-smk-ds.testObjExists-discordant.R b/tests/testthat/test-smk-ds.testObjExists-discordant.R deleted file mode 100644 index 5163217fd..000000000 --- a/tests/testthat/test-smk-ds.testObjExists-discordant.R +++ /dev/null @@ -1,71 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.testObjExists::smk::setup") - -connect.discordant.dataset.simple(list("A", "B", "C")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.testObjExists::smk::discordant") -test_that("simple testObjExists, discordant", { - res <- ds.testObjExists('D') - - expect_length(res, 1) - expect_equal(res$return.message, "A valid copy of data object exists in all specified data sources") -}) - -test_that("data.frame testObjExists, discordant", { - res <- ds.testObjExists("D$A") - - expect_length(res, 2) - expect_length(res$return.info, 3) - expect_length(res$return.info$discordant1, 2) - expect_false(res$return.info$discordant1$test.obj.exists) - expect_true(is.null(res$return.info$discordant1$test.obj.class)) - expect_length(res$return.info$discordant2, 2) - expect_false(res$return.info$discordant2$test.obj.exists) - expect_true(is.null(res$return.info$discordant2$test.obj.class)) - expect_length(res$return.info$discordant3, 2) - expect_false(res$return.info$discordant3$test.obj.exists) - expect_true(is.null(res$return.info$discordant3$test.obj.class)) - expect_length(res$return.info, 3) - expect_length(res$return.info, 3) - expect_length(res$return.message, 2) - expect_length(res$return.message[[1]], 1) - expect_equal(res$return.message[[1]], "Error: A valid data object does NOT exist in ALL specified data sources") - expect_length(res$return.message[[2]], 1) - expect_equal(res$return.message[[2]], "It is either ABSENT and/or has no valid content/class, for details see return.info above") -}) - -# -# Done -# - -# context("ds.testObjExists::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.discordant.dataset.simple() - -# context("ds.testObjExists::smk::done") diff --git a/tests/testthat/test-smk-ds.testObjExists.R b/tests/testthat/test-smk-ds.testObjExists.R deleted file mode 100644 index 857fe823c..000000000 --- a/tests/testthat/test-smk-ds.testObjExists.R +++ /dev/null @@ -1,104 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.testObjExists::smk::setup") - -connect.studies.dataset.cnsim(list("LAB_TSC", "LAB_HDL")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.testObjExists::smk") -test_that("simple testObjExists", { - res <- ds.testObjExists('D') - - expect_length(res, 1) - expect_equal(res$return.message, "A valid copy of data object exists in all specified data sources") -}) - -test_that("data.frame testObjExists", { - myvectors <- c('D$LAB_TSC', 'D$LAB_HDL') - ds.dataFrame(x=myvectors) - - res <- ds.testObjExists("dataframe.newobj") - - expect_length(res, 1) - expect_equal(res$return.message, "A valid copy of data object exists in all specified data sources") -}) - -test_that("data.frame testObjExists", { - res <- ds.testObjExists("D$TEST") - - expect_length(res, 2) - expect_length(res$return.info, 3) - expect_length(res$return.info$sim1, 2) - expect_false(res$return.info$sim1$test.obj.exists) - expect_true(is.null(res$return.info$sim1$test.obj.class)) - expect_length(res$return.info$sim2, 2) - expect_false(res$return.info$sim2$test.obj.exists) - expect_true(is.null(res$return.info$sim2$test.obj.class)) - expect_length(res$return.info$sim3, 2) - expect_false(res$return.info$sim3$test.obj.exists) - expect_true(is.null(res$return.info$sim3$test.obj.class)) - expect_length(res$return.info, 3) - expect_length(res$return.info, 3) - expect_length(res$return.message, 2) - expect_length(res$return.message[[1]], 1) - expect_equal(res$return.message[[1]], "Error: A valid data object does NOT exist in ALL specified data sources") - expect_length(res$return.message[[2]], 1) - expect_equal(res$return.message[[2]], "It is either ABSENT and/or has no valid content/class, for details see return.info above") -}) - -test_that("data.frame testObjExists", { - res <- ds.testObjExists("TEST") - - expect_length(res, 2) - expect_length(res$return.info, 3) - expect_length(res$return.info$sim1, 2) - expect_false(res$return.info$sim1$test.obj.exists) - expect_true(is.null(res$return.info$sim1$test.obj.class)) - expect_length(res$return.info$sim2, 2) - expect_false(res$return.info$sim2$test.obj.exists) - expect_true(is.null(res$return.info$sim2$test.obj.class)) - expect_length(res$return.info$sim3, 2) - expect_false(res$return.info$sim3$test.obj.exists) - expect_true(is.null(res$return.info$sim3$test.obj.class)) - expect_length(res$return.info, 3) - expect_length(res$return.info, 3) - expect_length(res$return.message, 2) - expect_length(res$return.message[[1]], 1) - expect_equal(res$return.message[[1]], "Error: A valid data object does NOT exist in ALL specified data sources") - expect_length(res$return.message[[2]], 1) - expect_equal(res$return.message[[2]], "It is either ABSENT and/or has no valid content/class, for details see return.info above") -}) - -# -# Done -# - -# context("ds.testObjExists::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "dataframe.newobj")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.testObjExists::smk::done") diff --git a/tests/testthat/test-smk-ds.vectorCalc.R b/tests/testthat/test-smk-ds.vectorCalc.R deleted file mode 100644 index 3c03191fe..000000000 --- a/tests/testthat/test-smk-ds.vectorCalc.R +++ /dev/null @@ -1,70 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.vectorCalc::smk::setup") - -connect.studies.dataset.cnsim(list('LAB_TSC', 'LAB_HDL')) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.vectorCalc::smk") -test_that("simple test", { - vectors <- c('D$LAB_TSC', 'D$LAB_HDL') - res <- expect_warning(ds.vectorCalc(x=vectors, calc='+'), "'ds.vectorCalc' is deprecated.\nUse 'ds.make' instead.", fixed = TRUE) - - expect_length(res, 0) - - res_class <- ds.class("vectorcalc.newobj") - - expect_length(res_class, 3) - expect_length(res_class$sim1, 1) - expect_equal(res_class$sim1[1], "numeric") - expect_length(res_class$sim2, 1) - expect_equal(res_class$sim2[1], "numeric") - expect_length(res_class$sim3, 1) - expect_equal(res_class$sim3[1], "numeric") - - res_length <- ds.length("vectorcalc.newobj") - - expect_length(res_length, 4) - expect_length(res_length$`length of vectorcalc.newobj in sim1`, 1) - expect_equal(res_length$`length of vectorcalc.newobj in sim1`, 2163) - expect_length(res_length$`length of vectorcalc.newobj in sim2`, 1) - expect_equal(res_length$`length of vectorcalc.newobj in sim2`, 3088) - expect_length(res_length$`length of vectorcalc.newobj in sim3`, 1) - expect_equal(res_length$`length of vectorcalc.newobj in sim3`, 4128) - expect_length(res_length$`total length of vectorcalc.newobj in all studies combined`, 1) - expect_equal(res_length$`total length of vectorcalc.newobj in all studies combined`, 9379) -}) - -# -# Done -# - -# context("ds.vectorCalc::smk::shutdown") - -test_that("shutdown", { - ds_expect_variables(c("D", "vectorcalc.newobj")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.vectorCalc::smk::done") diff --git a/tests/testthat/test-smk_bug-ds.listOpals.R b/tests/testthat/test-smk_bug-ds.listOpals.R deleted file mode 100644 index 72b28ccdb..000000000 --- a/tests/testthat/test-smk_bug-ds.listOpals.R +++ /dev/null @@ -1,34 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2014 OBiBa, -# 2018-2022 University of Newcastle upon Tyne. All rights reserved. -# 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -connect.studies.dataset.cnsim(list("LAB_TSC", "LAB_HDL")) - -# -# Tests -# - -# context("ds.listOpals::smk::check results") -test_that("check results", { - message <- "\n* This function lists all Opal objects in the R analysis environment\n\n\n* There is only one set of opals available,\n that is: 'ds.test_env$connections'\n\n\n\n* This set of Opals has been copied to create 'default.opals',\n which all DataSHIELD functions will now use by default.\n If you want to change the default Opal object,\n please run the function ds.setDefaultOpals() again. \n\n\n\n" - - expect_message(res <- ds.listOpals(), message, fixed=TRUE) -}) - -# -# Done -# - -disconnect.studies.dataset.cnsim() diff --git a/tests/testthat/test-smk_dgr-ds.listServersideFunctions.R b/tests/testthat/test-smk_dgr-ds.listServersideFunctions.R deleted file mode 100644 index 9ed962278..000000000 --- a/tests/testthat/test-smk_dgr-ds.listServersideFunctions.R +++ /dev/null @@ -1,89 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.listServersideFunctions::smk_dgr::setup") - -require(dsDangerClient) - -connect.studies.dataset.cnsim(list("LAB_TSC", "LAB_HDL")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.listServersideFunctions::smk_dgr::check results") -test_that("check results", { - assign.functions <- factor(c( - )) - aggregate.functions <- factor(c( - "DANGERc2sMATDFDS", - "DANGERlistcodeDS", - "DANGERdfEXTRACTDS", - "DANGERpassPARSERDS", - "DANGERprintDS", - "DANGERplotDS", - "DANGERsearchDS", - "DANGERseedEXTRACTDS", - "DANGERvarsEXTRACTDS" - )) - - expect_warning(res <- ds.listServersideFunctions(), "'ds.listServersideFunctions' is deprecated.", fixed=TRUE) - - expect_length(res, 2) - expect_length(res$serverside.assign.functions, 7) - expect_length(res$serverside.aggregate.functions, 7) - - sim1.assign.res <- subset(res$serverside.assign.functions, server == 'sim1', c('name')) - sim1.aggregate.res <- subset(res$serverside.aggregate.functions, server == 'sim1', c('name')) - sim2.assign.res <- subset(res$serverside.assign.functions, server == 'sim2', c('name')) - sim2.aggregate.res <- subset(res$serverside.aggregate.functions, server == 'sim2', c('name')) - sim3.assign.res <- subset(res$serverside.assign.functions, server == 'sim3', c('name')) - sim3.aggregate.res <- subset(res$serverside.aggregate.functions, server == 'sim3', c('name')) - - for (func.name in assign.functions) - expect_true(func.name %in% sim1.assign.res$name, info = func.name) - for (func.name in aggregate.functions) - expect_true(func.name %in% sim1.aggregate.res$name, info = func.name) - for (func.name in assign.functions) - expect_true(func.name %in% sim2.assign.res$name, info = func.name) - for (func.name in aggregate.functions) - expect_true(func.name %in% sim2.aggregate.res$name, info = func.name) - for (func.name in assign.functions) - expect_true(func.name %in% sim3.assign.res$name, info = func.name) - for (func.name in aggregate.functions) - expect_true(func.name %in% sim3.aggregate.res$name, info = func.name) -}) - -# -# Done -# - -# context("ds.listServersideFunctions::smk_dgr::shtudown") - -test_that("shutdown", { - ds_expect_variables(c("D")) -}) - -disconnect.studies.dataset.cnsim() - -# -# Done -# - -# context("ds.listServersideFunctions::smk_dgr::done") diff --git a/tests/testthat/test-smk_expt-ds.ranksSecure.R b/tests/testthat/test-smk_expt-ds.ranksSecure.R deleted file mode 100644 index 4da33430b..000000000 --- a/tests/testthat/test-smk_expt-ds.ranksSecure.R +++ /dev/null @@ -1,86 +0,0 @@ -#------------------------------------------------------------------------------- -# Copyright (c) 2019-2022 University of Newcastle upon Tyne. All rights reserved. -# Copyright (c) 2022-2025 Arjuna Technologies, Newcastle upon Tyne. All rights reserved. -# -# This program and the accompanying materials -# are made available under the terms of the GNU Public License v3.0. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . -#------------------------------------------------------------------------------- - -# -# Set up -# - -# context("ds.ranksSecure::smk_expt::setup") - -connect.studies.dataset.cnsim(list("LAB_TRIG", "LAB_TSC")) - -test_that("setup", { - ds_expect_variables(c("D")) -}) - -# -# Tests -# - -# context("ds.ranksSecure::smk_expt::continous, without NAs, all positive") -test_that("continous, without NAs, all positive", { -# res.cc <- ds.completeCases("D$LAB_TSC", newobj="CC_LAB_TSC") -# expect_equal(res.cc$validity.check, " appears valid in all sources") -# -# res.num.na <- ds.numNA("CC_LAB_TSC") -# expect_length(res.num.na, 3) -# expect_equal(res.num.na$sim1, 0) -# expect_equal(res.num.na$sim2, 0) -# expect_equal(res.num.na$sim3, 0) -# -# res <- ds.ranksSecure("CC_LAB_TSC") -# -# expect_equal_to_reference(res, 'smk_expt-results/ds.ranksSecure-cont.rds') -}) - -# context("ds.ranksSecure::smk_expt::continous, without NAs, with negative") -test_that("continous, without NAs, with negative", { -# res.cc <- ds.completeCases("D$LAB_TRIG", newobj="CC_LAB_TRIG") -# expect_equal(res.cc$validity.check, " appears valid in all sources") -# -# res.num.na <- ds.numNA("CC_LAB_TRIG") -# expect_length(res.num.na, 3) -# expect_equal(res.num.na$sim1, 0) -# expect_equal(res.num.na$sim2, 0) -# expect_equal(res.num.na$sim3, 0) -# -# res <- ds.ranksSecure("CC_LAB_TRIG") -# -# expect_equal_to_reference(res, 'smk_expt-results/ds.ranksSecure-cont_neg.rds') -}) - -# context("ds.ranksSecure::smk_expt::continous, with NAs, all positive") -test_that("continous, with NAs, all positive", { -# res <- ds.ranksSecure("D$LAB_TSC") -# -# expect_equal_to_reference(res, 'smk_expt-results/ds.ranksSecure-cont_nas.rds') -}) - -# context("ds.ranksSecure::smk_expt::continous, with NAs, with negative") -test_that("continous, with NAs, with negative", { -# res <- ds.ranksSecure("D$LAB_TRIG") -# -# expect_equal_to_reference(res, 'smk_expt-results/ds.ranksSecure-cont_nas_neg.rds') -}) - -# -# Done -# - -# context("ds.ranksSecure::smk_expt::shutdown") - -test_that("setup", { -# ds_expect_variables(c("D", "CC_LAB_TSC", "CC_LAB_TRIG", "final.quantile.df", "summary.ranks.df", "testvar.ranks")) -}) - -disconnect.studies.dataset.cnsim() - -# context("ds.ranksSecure::smk_expt::done") From da9ac19d63fdf712fc7530a28c478dac2bab7450 Mon Sep 17 00:00:00 2001 From: Tim Cadman <41470917+timcadman@users.noreply.github.com> Date: Thu, 15 Oct 2026 16:49:28 +0200 Subject: [PATCH 2/3] Remove unused internal helpers --- man/colPercent.Rd | 24 --------- man/ds.extractQuantiles.Rd | 107 ------------------------------------- man/isAssigned.Rd | 27 ---------- man/meanByClassHelper0a.Rd | 35 ------------ man/meanByClassHelper0b.Rd | 39 -------------- man/meanByClassHelper1.Rd | 32 ----------- man/meanByClassHelper2.Rd | 35 ------------ man/meanByClassHelper3.Rd | 34 ------------ man/meanByClassHelper4.Rd | 40 -------------- man/rowPercent.Rd | 24 --------- man/subsetHelper.Rd | 74 ------------------------- 11 files changed, 471 deletions(-) delete mode 100644 man/colPercent.Rd delete mode 100644 man/ds.extractQuantiles.Rd delete mode 100644 man/isAssigned.Rd delete mode 100644 man/meanByClassHelper0a.Rd delete mode 100644 man/meanByClassHelper0b.Rd delete mode 100644 man/meanByClassHelper1.Rd delete mode 100644 man/meanByClassHelper2.Rd delete mode 100644 man/meanByClassHelper3.Rd delete mode 100644 man/meanByClassHelper4.Rd delete mode 100644 man/rowPercent.Rd delete mode 100644 man/subsetHelper.Rd diff --git a/man/colPercent.Rd b/man/colPercent.Rd deleted file mode 100644 index bccd9431d..000000000 --- a/man/colPercent.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/colPercent.R -\name{colPercent} -\alias{colPercent} -\title{Produces column percentages} -\usage{ -colPercent(dataframe) -} -\arguments{ -\item{dataframe}{a data frame} -} -\value{ -a data frame -} -\description{ -this is an INTERNAL function. -} -\details{ -The function is required required by the client function \code{ds.table2D}. -} -\author{ -Gaye, A. -} -\keyword{internal} diff --git a/man/ds.extractQuantiles.Rd b/man/ds.extractQuantiles.Rd deleted file mode 100644 index 26308f61c..000000000 --- a/man/ds.extractQuantiles.Rd +++ /dev/null @@ -1,107 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/ds.extractQuantiles.R -\name{ds.extractQuantiles} -\alias{ds.extractQuantiles} -\title{Secure ranking of a vector across all sources and use of these ranks -to estimate global quantiles across all studies} -\usage{ -ds.extractQuantiles( - extract.quantiles, - extract.summary.output.ranks.df, - extract.ranks.sort.by, - extract.rm.residual.objects, - extract.datasources = NULL -) -} -\arguments{ -\item{extract.quantiles}{one of a restricted set of character strings. -The value of this argument is set in choosing the value of the argument - in ds.ranksSecure. In summary: to mitigate -disclosure risk only the following set of quantiles can be -generated: c(0.025,0.05,0.10,0.20,0.25,0.30,0.3333,0.40,0.50,0.60,0.6667, -0.70,0.75,0.80,0.90,0.95,0.975). The allowable formats for the argument -are of the general form: "0.025-0.975" where the first number is the lowest -quantile to be estimated and the second number is the equivalent highest -quantile to estimate. These two quantiles are then estimated along with -all allowable quantiles in between. The allowable argument values are then: -"0.025-0.975", "0.05-0.95", "0.10-0.90", "0.20-0.80". Two alternative values -are "quartiles" i.e. c(0.25,0.50,0.75), and "median" i.e. c(0.50). The -default value is "0.05-0.95". For more details, see the associated document -"secure.global.ranking.docx". Also see the header file for ds.ranksSecure.} - -\item{extract.summary.output.ranks.df}{a character string which specifies -the optional name for the summary data.frame written to the serverside on -each data source that contains 5 of the key output variables from the ranking -procedure pertaining to that particular data source. If no name has been -specified by the argument in ds.ranksSecure, the -default name is allocated as "summary.ranks.df".The only reason the - argument needs specifying in -ds.extractQuantiles is because, ds.extractQuantiles is the last function -called by ds.ranksSecure and almost the final command of ds.extractQuantiles -to print out the name of the data frame containing the summarised ranking -information generated by ds.ranksSecure and the order in which the -data frame is laid out. This therefore appears as the last output produced -when ds.ranksSecure is run, and when this happens it is clear this relates to -the main output of ds.ranksSecure not of ds.extractQuantiles.} - -\item{extract.ranks.sort.by}{a character string taking two possible values. -These are "ID.orig" and "vals.orig". This is set via the argument - in ds.ranksSecure. For more details see the associated -document entitled "secure.global.ranking.docx". Also see the header -file for ds.ranksSecure.} - -\item{extract.rm.residual.objects}{logical value. Default = TRUE: at the beginning -and end of each run of ds.ranksSecure delete all extraneous objects that are -otherwise left behind. These are not usually needed, but could be of value -if one were investigating a problem with the ranking. FALSE: do not delete -the residual objects} - -\item{extract.datasources}{specifies the particular connection object(s) to use. -This is set via the argument in ds.ranksSecure. For more details -see the associated document entitled "secure.global.ranking.docx". Also see -the header file for ds.ranksSecure.} -} -\value{ -the final main output of ds.extractQuantiles is a data frame object -named "final.quantile.df". This contains two vectors. The first named -"evaluation.quantiles" lists the full set of quantiles you have requested -for evaluation as specified by the argument "quantiles.for.estimation" in -ds.ranksSecure and explained in more detail above under the information for -the argument "extract.quantiles" in this function. The second vector is -called "final.quantile.vector" which details the values of V2BR that -correspond to the evaluation quantiles in vector 1. The information in the -data frame "final.quantile.df" is generic: there is no information -identifying in which study each value of V2BR falls. This data frame is -written to the clientside (as it is non-disclosive) and is also copied to -the serverside in every study. This means it is easily accessible from -anywhere in the DataSHIELD environment. For more details -see the associated document entitled "secure.global.ranking.docx". -} -\description{ -Takes the global ranks and quantiles held in the serverside data -data frame that is written by ranksSecureDS4 and named as specified by the -argument () and converts these values into a series of -quantile values that identify, for example, which value of V2BR across all of -the studies corresponds to the median or to the 95% quantile. There is no -indication in which study the V2BR corresponding to a particular quantile -falls and, in fact, the relevant value may fall in more than one study and -may appear multiple times in any one study. Finally, the output data -frame containing this information is written to the clientside and to the -serverside at each study separately. -} -\details{ -ds.extractQuantiles is a clientside function which should usually -be called from within the clientside function ds.ranksSecure.If you try to -call ds.extractQuantiles directly(i.e. not by running ds.ranksSecure) you -are almost certainly going to have to set up quite a few vectors and scalars -that are normally set by ds.ranksSecure and this is likely to be difficult. -ds.extractQuantiles itself calls two serverside functions extractQuantilesDS1 -and extractQuantilesDS2. For more details about the cluster of functions that -collectively enable secure global ranking and estimation of global quantiles -see the associated document entitled "secure.global.ranking.docx". In -particular this explains how ds.extractQuantiles works. Also see the header -file for ds.ranksSecure. -} -\author{ -Paul Burton 11th November, 2021 -} diff --git a/man/isAssigned.Rd b/man/isAssigned.Rd deleted file mode 100644 index d46bed497..000000000 --- a/man/isAssigned.Rd +++ /dev/null @@ -1,27 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/isAssigned.R -\name{isAssigned} -\alias{isAssigned} -\title{Checks an object has been generated on the server side} -\usage{ -isAssigned(datasources = NULL, newobj = NULL) -} -\arguments{ -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} - -\item{newobj}{a character, the name the object to look for.} -} -\value{ -nothing is return but the process is stopped if -the object was not generated in any one server. -} -\description{ -This is an internal function. -} -\details{ -After calling an assign function it is important -to know whether or not the action has been completed by -checking if the output actually exists on the server side. -} -\keyword{internal} diff --git a/man/meanByClassHelper0a.Rd b/man/meanByClassHelper0a.Rd deleted file mode 100644 index ec7fed67e..000000000 --- a/man/meanByClassHelper0a.Rd +++ /dev/null @@ -1,35 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/meanByClassHelper0a.R -\name{meanByClassHelper0a} -\alias{meanByClassHelper0a} -\title{Computes the mean values of a numeric vector across a factor vector} -\usage{ -meanByClassHelper0a(a, b, type, datasources) -} -\arguments{ -\item{a}{a character, the name of a numeric vector.} - -\item{b}{a character, the name of a factor vector.} - -\item{type}{a character which represents the type of analysis to carry out. If \code{type} is set to -'combine', a pooled table of results is generated. If \code{type} is set to 'split', a table of results -is generated for each study.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} -} -\value{ -a table or a list of tables that hold the length of the numeric variable and its mean -and standard deviation in each subgroup (subset). -} -\description{ -This is an internal function. -} -\details{ -This function is called by the function 'ds.meanByClass' to produce the final tables -if the user specifies two loose vectors. -} -\author{ -Gaye, A. -} -\keyword{internal} diff --git a/man/meanByClassHelper0b.Rd b/man/meanByClassHelper0b.Rd deleted file mode 100644 index b465e40a3..000000000 --- a/man/meanByClassHelper0b.Rd +++ /dev/null @@ -1,39 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/meanByClassHelper0b.R -\name{meanByClassHelper0b} -\alias{meanByClassHelper0b} -\title{Runs the computation if variables are within a table structure} -\usage{ -meanByClassHelper0b(x, outvar, covar, type, datasources) -} -\arguments{ -\item{x}{a character, the name of the dataset to get the subsets from.} - -\item{outvar}{a character vector, the names of the continuous variables} - -\item{covar}{a character vector, the names of up to 3 categorical variables} - -\item{type}{a character which represents the type of analysis to carry out. If \code{type} is set to -'combine', a pooled table of results is generated. If \code{type} is set to 'split', a table of results -is generated for each study.} - -\item{datasources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} -} -\value{ -a table or a list of tables that hold the length of the numeric variable(s) and their mean -and standard deviation in each subgroup (subset). -} -\description{ -This is an internal function. -} -\details{ -This function is called by the function 'ds.meanByClass' to produce the final tables -if the user specify a table structure. -} -\author{ -Gaye, A. - -Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -} -\keyword{internal} diff --git a/man/meanByClassHelper1.Rd b/man/meanByClassHelper1.Rd deleted file mode 100644 index 648eb577c..000000000 --- a/man/meanByClassHelper1.Rd +++ /dev/null @@ -1,32 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/meanByClassHelper1.R -\name{meanByClassHelper1} -\alias{meanByClassHelper1} -\title{Generates subset tables} -\usage{ -meanByClassHelper1(dtsource, tables, variable, categories) -} -\arguments{ -\item{dtsource}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} - -\item{tables}{a character vector, the tables to breakdown} - -\item{variable}{a character, the variable to subset on} - -\item{categories}{a character vector, the classes in the variables to subset on} -} -\value{ -a character the names of the new subset tables. -} -\description{ -This is an internal function. -} -\details{ -This function is called by the function 'ds.meanByClass' to break down -the initial table by the specified categorical variables. -} -\author{ -Gaye, A. -} -\keyword{internal} diff --git a/man/meanByClassHelper2.Rd b/man/meanByClassHelper2.Rd deleted file mode 100644 index 3c513277d..000000000 --- a/man/meanByClassHelper2.Rd +++ /dev/null @@ -1,35 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/meanByClassHelper2.R -\name{meanByClassHelper2} -\alias{meanByClassHelper2} -\title{Generates a table for pooled results} -\usage{ -meanByClassHelper2(dtsources, tablenames, variables, invalidrecorder) -} -\arguments{ -\item{dtsources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} - -\item{tablenames}{a character vector, the name of the subset tables} - -\item{variables}{a character vector, the names of the continuous variables to computes a mean for.} - -\item{invalidrecorder}{a list, holds information about invalid subsets in each study.} -} -\value{ -a matrix, a table which contains the length, mean and standard deviation of each of the -specified 'variables' in each subset table. -} -\description{ -This is an internal function. -} -\details{ -This function is called by the function 'ds.meanByClass' to produce the final table -if the user sets the parameter 'type' to combine (the default behaviour of 'ds.meanByClass'). -} -\author{ -Gaye, A. - -Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -} -\keyword{internal} diff --git a/man/meanByClassHelper3.Rd b/man/meanByClassHelper3.Rd deleted file mode 100644 index 0c6b753e8..000000000 --- a/man/meanByClassHelper3.Rd +++ /dev/null @@ -1,34 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/meanByClassHelper3.R -\name{meanByClassHelper3} -\alias{meanByClassHelper3} -\title{Generates results tables for each study separately} -\usage{ -meanByClassHelper3(dtsources, tablenames, variables, invalidrecorder) -} -\arguments{ -\item{dtsources}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} - -\item{tablenames}{a character vector, the name of the subset tables} - -\item{variables}{a character vector, the names of the continuous variables to computes a mean for.} - -\item{invalidrecorder}{a list, holds information about invalid subsets in each study} -} -\value{ -a list which one results table for each study. -} -\description{ -This is an internal function. -} -\details{ -This function is called by the function 'ds.meanByClass' to produce the final tables -if the user sets the parameter 'type' to 'split'. -} -\author{ -Gaye, A. - -Tim Cadman, Genomics Coordination Centre, UMCG, Netherlands -} -\keyword{internal} diff --git a/man/meanByClassHelper4.Rd b/man/meanByClassHelper4.Rd deleted file mode 100644 index cbf0b67c1..000000000 --- a/man/meanByClassHelper4.Rd +++ /dev/null @@ -1,40 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/meanByClassHelper4.R -\name{meanByClassHelper4} -\alias{meanByClassHelper4} -\title{Gets the subset tables out of the list (i.e. unlist)} -\usage{ -meanByClassHelper4( - dtsource, - alist, - initialtable, - variable = NA, - categories = NA -) -} -\arguments{ -\item{dtsource}{a list of \code{\link[DSI]{DSConnection-class}} objects obtained after login. If the -the default set of connections will be used: see \link[DSI]{datashield.connections_default}.} - -\item{alist}{the name of the list that holds the final subset tables} - -\item{initialtable}{a character the name of the table that the subset were generated from} - -\item{variable}{a character, the variable to subset on} - -\item{categories}{a character vector, the classes in the variables to subset on} -} -\value{ -the 'loose' subset tables are stored on the server side -} -\description{ -This is an internal function. -} -\details{ -This function is called by the function 'ds.meanByClass' to obtain 'loose' -subset tables because the 'subsetByClass' function does not handle a table within a list. -} -\author{ -Gaye, A. -} -\keyword{internal} diff --git a/man/rowPercent.Rd b/man/rowPercent.Rd deleted file mode 100644 index 17e01c0c8..000000000 --- a/man/rowPercent.Rd +++ /dev/null @@ -1,24 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/rowPercent.R -\name{rowPercent} -\alias{rowPercent} -\title{Produces row percentages} -\usage{ -rowPercent(dataframe) -} -\arguments{ -\item{dataframe}{a data frame} -} -\value{ -a data frame -} -\description{ -this is an INTERNAL function. -} -\details{ -The function is required required by the client function \code{ds.table2D}. -} -\author{ -Gaye A -} -\keyword{internal} diff --git a/man/subsetHelper.Rd b/man/subsetHelper.Rd deleted file mode 100644 index fb6c9a999..000000000 --- a/man/subsetHelper.Rd +++ /dev/null @@ -1,74 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/subsetHelper.R -\name{subsetHelper} -\alias{subsetHelper} -\title{Ensures that the requested subset is not larger than the original object} -\usage{ -subsetHelper(dts, data, rs = NULL, cs = NULL) -} -\arguments{ -\item{dts}{a list of \code{\link[DSI]{DSConnection-class}} -objects obtained after login. If the \code{datasources} argument is not specified -the default set of connections will be used: see \code{\link[DSI]{datashield.connections_default}}.} - -\item{data}{a character string specifying the name of the data frame or -the factor vector and the range of the subset.} - -\item{rs}{a vector of two integers specifying the indices of the rows de extract.} - -\item{cs}{a vector of two integers or one or more characters.} -} -\value{ -\code{subsetHelper} returns a message or the class of the object if the -object has the same class in all studies. -} -\description{ -Compares subset and original object sizes and eventually carries out subsetting. -} -\details{ -This function is called by the function \code{ds.subset} to ensure that the requested subset -is not larger than the original object. - -This function is internal. - -Server function called: \code{dimDS} -} -\examples{ -\dontrun{ - - ## Version 6, for version 5 see the Wiki - - # connecting to the Armadillo/Opal servers - - require('DSI') - require('DSMolgenisArmadillo') - require('DSOpal') - require('dsBaseClient') - - armadillo_url <- "http://192.168.56.100:8080/" - token <- armadillo.get_credentials(armadillo_url) - builder <- DSI::newDSLoginBuilder() - builder$append(server = "study1", - url = armadillo_url, - token = token@access_token, - table = "datashield/cnsim/CNSIM1", driver = "ArmadilloDriver") - builder$append(server = "study2", - url = "https://192.168.56.100:8443/", - user = "administrator", password = "datashield_test&", - table = "CNSIM.CNSIM2", driver = "OpalDriver", - options = "list(ssl_verifyhost=0, ssl_verifypeer=0)") - logindata <- builder$build() - - connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") - - subsetHelper(dts = connections, - data = "D", - rs = 1:10, - cs = c("D$LAB_TSC","D$LAB_TRIG")) - - # clear the Datashield R sessions and logout - datashield.logout(connections) -} - -} -\keyword{internal} From 517b4b1987e52787a4a5a3a369d234538f925eac Mon Sep 17 00:00:00 2001 From: Tim Cadman <41470917+timcadman@users.noreply.github.com> Date: Thu, 15 Oct 2026 17:09:48 +0200 Subject: [PATCH 3/3] remove now unused package and duplicate cli import --- DESCRIPTION | 2 -- 1 file changed, 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 7d3ff5199..b9f3b680e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -74,9 +74,7 @@ Imports: ggplot2, gridExtra, data.table, - methods, dplyr, - cli, lifecycle Suggests: lme4,