diff --git a/.Rbuildignore b/.Rbuildignore new file mode 100644 index 0000000..85d152d --- /dev/null +++ b/.Rbuildignore @@ -0,0 +1,6 @@ +^.*\.Rproj$ +^\.Rproj\.user$ +^\.git$ +^\.gitignore$ +^README\.md$ +^\.github$ \ No newline at end of file diff --git a/DESCRIPTION b/DESCRIPTION new file mode 100644 index 0000000..1eb8bc7 --- /dev/null +++ b/DESCRIPTION @@ -0,0 +1,16 @@ +Package: dsCodaClient +Title: DataSHIELD client-side functions for compositional data analysis +Description: DataSHIELD client functions for compositional data analysis using the compositions package. +Version: 0.1.0 +Author: Xavier Escriba Montagut and Stuart Wheater +Maintainer: Xavier Escriba Montagut and Stuart Wheater +License: GPL-3 +Depends: + R (>= 3.5.0), + DSI (>= 1.1.0) +Suggests: + knitr, + testthat +RoxygenNote: 7.3.2 +Encoding: UTF-8 +VignetteBuilder: knitr diff --git a/NAMESPACE b/NAMESPACE new file mode 100644 index 0000000..ee02a4f --- /dev/null +++ b/NAMESPACE @@ -0,0 +1,4 @@ +# Generated by roxygen2: do not edit by hand + +export(ds.acomp) +export(ds.lrEM) diff --git a/R/ds.acomp.R b/R/ds.acomp.R new file mode 100644 index 0000000..ef72cec --- /dev/null +++ b/R/ds.acomp.R @@ -0,0 +1,117 @@ +#' @title Creates a server-side Aitchison composition object for compositional data analysis +#' @description Creates a server-side Aitchison composition object using the compositions::acomp() function +#' @details This function creates a server-side Aitchison composition object that can be used +#' for compositional data analysis. It wraps the compositions::acomp() function for use in DataSHIELD. +#' +#' Server function called: \code{acompDS}. +#' +#' @param X character string specifying the name of the server-side dataset or vector +#' containing the compositional data. +#' @param parts vector containing the indices or names of the columns to be used. +#' If NULL (default), all columns will be used. +#' @param total numeric value specifying the total amount to be used, typically 1 or 100. +#' Default is 1. +#' @param warn.na logical value indicating whether the user should be warned in case of +#' NA, NaN or 0 coding different types of missing values. Default is FALSE. +#' @param detectionlimit a number, vector or matrix of positive numbers giving the +#' detection limit of all values, all columns or each value, respectively. Default is NULL. +#' @param BDL the code for 'Below Detection Limit' in X. Default is NULL. +#' @param MAR the code for 'Missing At Random' in X. Default is NULL. +#' @param MNAR the code for 'Missing Not At Random' in X. Default is NULL. +#' @param SZ the code for 'Structural Zero' in X. Default is NULL. +#' @param objectname character string specifying the name of the new server-side object +#' which will store the Aitchison composition object. +#' @param datasources a list of \code{\link{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{datashield.connections_default}}. +#' @return \code{ds.acomp} returns a server-side Aitchison composition object for use in +#' compositional data analysis. +#' @author DataSHIELD Development Team +#' @examples +#' \dontrun{ +#' +#' # connecting to the DataSHIELD servers +#' +#' require('DSI') +#' require('DSOpal') +#' require('dsBaseClient') +#' require('dsCodaClient') +#' +#' builder <- DSI::newDSLoginBuilder() +#' builder$append(server = "study1", +#' url = "http://192.168.56.100:8080/", +#' user = "administrator", password = "datashield_test&", +#' table = "COMPOSITIONAL.DATA1", driver = "OpalDriver") +#' builder$append(server = "study2", +#' url = "http://192.168.56.100:8080/", +#' user = "administrator", password = "datashield_test&", +#' table = "COMPOSITIONAL.DATA2", driver = "OpalDriver") +#' logindata <- builder$build() +#' +#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") +#' +#' # Create a server-side Aitchison composition object +#' # Using all columns of the dataset +#' dsCodaClient::ds.acomp(X = 'D', +#' objectname = 'comp_object', +#' datasources = connections) +#' +#' # Using specific columns +#' dsCodaClient::ds.acomp(X = 'D', +#' parts = c(1, 2, 3), +#' total = 100, +#' objectname = 'comp_object_subset', +#' datasources = connections) +#' +#' # Using column names +#' dsCodaClient::ds.acomp(X = 'D', +#' parts = c('component1', 'component2', 'component3'), +#' objectname = 'comp_object_named', +#' datasources = connections) +#' +#' # clear the DataSHIELD R sessions and logout +#' datashield.logout(connections) +#' } +#' +#' @export +ds.acomp <- function( + X = NULL, + parts = NULL, + total = 1, + warn.na = FALSE, + detectionlimit = NULL, + BDL = NULL, + MAR = NULL, + MNAR = NULL, + SZ = NULL, + objectname = NULL, + datasources = NULL +) { + + # look for DS connections + # if one not provided then get current + if (is.null(datasources)) { + datasources <- DSI::datashield.connections_find() + } + + # verify that 'X' was set + if (is.null(X)) { + stop("Please provide a valid compositional dataset parameter (X)", call. = FALSE) + } + + # handle objectname - use default if not provided + if (is.null(objectname)) { + objectname <- "acomp_object" + warning("No objectname provided, using default: 'acomp_object'", call. = FALSE) + } + + # call the server side function + calltext <- call("acompDS", X, parts, total, warn.na, detectionlimit, BDL, MAR, MNAR, SZ) + + # call assign function to create the object on the server + output <- DSI::datashield.assign(conns = datasources, value = calltext, symbol = objectname) + + # return the output + return(output) + +} \ No newline at end of file diff --git a/R/ds.lrEM.R b/R/ds.lrEM.R new file mode 100644 index 0000000..04647e6 --- /dev/null +++ b/R/ds.lrEM.R @@ -0,0 +1,147 @@ +#' @title Creates a server-side log-ratio EM algorithm object for compositional data imputation +#' @description Creates a server-side object using the zCompositions::lrEM() function +#' @details This function creates a server-side log-ratio EM algorithm object that can be used +#' for imputing left-censored data (e.g. values below detection limit, rounded zeros) in +#' compositional data sets. It wraps the zCompositions::lrEM() function for use in DataSHIELD. +#' +#' Server function called: \code{lrEMDS}. +#' +#' @param X character string specifying the name of the server-side dataset or matrix +#' containing the compositional data. +#' @param label unique label (numeric or character) used to denote unobserved values in X. +#' Default is NULL. +#' @param dl numeric vector or matrix of detection limits/thresholds. These must be given on +#' the same scale as X. Default is NULL. +#' @param rob logical value. FALSE provides maximum-likelihood estimates of model parameters, +#' TRUE provides robust parameter estimates. Default is FALSE. +#' @param ini.cov initial estimation of either the log-ratio covariance matrix (ML estimation) +#' or unobserved data (robust estimation). It can be based on either complete observations +#' ("complete.obs") or multiplicative simple replacement ("multRepl"). Default is "complete.obs". +#' @param frac if ini.cov="multRepl", fraction parameter for initial multiplicative simple +#' replacement of left-censored data expressed in proportions. Default is 0.65. +#' @param tolerance convergence criterion for the EM algorithm. Default is 0.0001. +#' @param max.iter maximum number of iterations for the EM algorithm. Default is 50. +#' @param rlm.maxit if rob=TRUE, maximum number of iterations for the embedded robust +#' regression estimation. Default is 150. +#' @param imp.missing if TRUE then unobserved data identified by label are treated as +#' missing data. Default is FALSE. +#' @param suppress.print suppress printed feedback. Default is FALSE. +#' @param closure closure value used to add a residual part if needed when ini.cov="multRepl" +#' is used. Default is NULL. +#' @param z.warning threshold for the proportion of modified zeros per part above which +#' a warning is issued. Default is 0.8. +#' @param z.delete logical value indicating whether rows containing only zeros should be +#' deleted prior to imputation. Default is TRUE. +#' @param objectname character string specifying the name of the new server-side object +#' which will store the log-ratio EM imputation result. +#' @param datasources a list of \code{\link{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{datashield.connections_default}}. +#' @return \code{ds.lrEM} returns a server-side object containing the imputed compositional +#' data set for use in compositional data analysis. +#' @author DataSHIELD Development Team +#' @examples +#' \dontrun{ +#' +#' # connecting to the DataSHIELD servers +#' +#' require('DSI') +#' require('DSOpal') +#' require('dsBaseClient') +#' require('dsCodaClient') +#' +#' builder <- DSI::newDSLoginBuilder() +#' builder$append(server = "study1", +#' url = "http://192.168.56.100:8080/", +#' user = "administrator", password = "datashield_test&", +#' table = "COMPOSITIONAL.DATA1", driver = "OpalDriver") +#' builder$append(server = "study2", +#' url = "http://192.168.56.100:8080/", +#' user = "administrator", password = "datashield_test&", +#' table = "COMPOSITIONAL.DATA2", driver = "OpalDriver") +#' logindata <- builder$build() +#' +#' connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") +#' +#' # Create a server-side log-ratio EM imputation +#' # Using default parameters +#' dsCodaClient::ds.lrEM(X = 'D', +#' label = 0, +#' objectname = 'imputed_data', +#' datasources = connections) +#' +#' # Using specific detection limits +#' dsCodaClient::ds.lrEM(X = 'D', +#' label = 0, +#' dl = c(0.1, 0.1, 0.1), +#' rob = FALSE, +#' tolerance = 0.001, +#' objectname = 'imputed_data_custom', +#' datasources = connections) +#' +#' # Using robust estimation +#' dsCodaClient::ds.lrEM(X = 'D', +#' label = 0, +#' dl = c(0.1, 0.1, 0.1), +#' rob = TRUE, +#' ini.cov = "multRepl", +#' frac = 0.5, +#' objectname = 'robust_imputed_data', +#' datasources = connections) +#' +#' # clear the DataSHIELD R sessions and logout +#' datashield.logout(connections) +#' } +#' +#' @export +ds.lrEM <- function( + X = NULL, + label = NULL, + dl = NULL, + rob = FALSE, + ini.cov = c("complete.obs", "multRepl"), + frac = 0.65, + tolerance = 0.0001, + max.iter = 50, + rlm.maxit = 150, + imp.missing = FALSE, + suppress.print = FALSE, + closure = NULL, + z.warning = 0.8, + z.delete = TRUE, + objectname = NULL, + datasources = NULL +) { + + # look for DS connections + # if one not provided then get current + if (is.null(datasources)) { + datasources <- DSI::datashield.connections_find() + } + + # verify that 'X' was set + if (is.null(X)) { + stop("Please provide a valid compositional dataset parameter (X)", call. = FALSE) + } + + # handle objectname - use default if not provided + if (is.null(objectname)) { + objectname <- "lrEM_object" + warning("No objectname provided, using default: 'lrEM_object'", call. = FALSE) + } + + # match ini.cov argument + ini.cov <- match.arg(ini.cov) + + # call the server side function + calltext <- call("lrEMDS", X, label, dl, rob, ini.cov, frac, tolerance, + max.iter, rlm.maxit, imp.missing, suppress.print, closure, + z.warning, z.delete) + + # call assign function to create the object on the server + output <- DSI::datashield.assign(conns = datasources, value = calltext, symbol = objectname) + + # return the output + return(output) + +} \ No newline at end of file diff --git a/man/ds.acomp.Rd b/man/ds.acomp.Rd new file mode 100644 index 0000000..a4f37e0 --- /dev/null +++ b/man/ds.acomp.Rd @@ -0,0 +1,114 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ds.acomp.R +\name{ds.acomp} +\alias{ds.acomp} +\title{Creates a server-side Aitchison composition object for compositional data analysis} +\usage{ +ds.acomp( + X = NULL, + parts = NULL, + total = 1, + warn.na = FALSE, + detectionlimit = NULL, + BDL = NULL, + MAR = NULL, + MNAR = NULL, + SZ = NULL, + objectname = NULL, + datasources = NULL +) +} +\arguments{ +\item{X}{character string specifying the name of the server-side dataset or vector +containing the compositional data.} + +\item{parts}{vector containing the indices or names of the columns to be used. +If NULL (default), all columns will be used.} + +\item{total}{numeric value specifying the total amount to be used, typically 1 or 100. +Default is 1.} + +\item{warn.na}{logical value indicating whether the user should be warned in case of +NA, NaN or 0 coding different types of missing values. Default is FALSE.} + +\item{detectionlimit}{a number, vector or matrix of positive numbers giving the +detection limit of all values, all columns or each value, respectively. Default is NULL.} + +\item{BDL}{the code for 'Below Detection Limit' in X. Default is NULL.} + +\item{MAR}{the code for 'Missing At Random' in X. Default is NULL.} + +\item{MNAR}{the code for 'Missing Not At Random' in X. Default is NULL.} + +\item{SZ}{the code for 'Structural Zero' in X. Default is NULL.} + +\item{objectname}{character string specifying the name of the new server-side object +which will store the Aitchison composition object.} + +\item{datasources}{a list of \code{\link{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{datashield.connections_default}}.} +} +\value{ +\code{ds.acomp} returns a server-side Aitchison composition object for use in +compositional data analysis. +} +\description{ +Creates a server-side Aitchison composition object using the compositions::acomp() function +} +\details{ +This function creates a server-side Aitchison composition object that can be used +for compositional data analysis. It wraps the compositions::acomp() function for use in DataSHIELD. + +Server function called: \code{acompDS}. +} +\examples{ +\dontrun{ + + # connecting to the DataSHIELD servers + + require('DSI') + require('DSOpal') + require('dsBaseClient') + require('dsCodaClient') + + builder <- DSI::newDSLoginBuilder() + builder$append(server = "study1", + url = "http://192.168.56.100:8080/", + user = "administrator", password = "datashield_test&", + table = "COMPOSITIONAL.DATA1", driver = "OpalDriver") + builder$append(server = "study2", + url = "http://192.168.56.100:8080/", + user = "administrator", password = "datashield_test&", + table = "COMPOSITIONAL.DATA2", driver = "OpalDriver") + logindata <- builder$build() + + connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") + + # Create a server-side Aitchison composition object + # Using all columns of the dataset + dsCodaClient::ds.acomp(X = 'D', + objectname = 'comp_object', + datasources = connections) + + # Using specific columns + dsCodaClient::ds.acomp(X = 'D', + parts = c(1, 2, 3), + total = 100, + objectname = 'comp_object_subset', + datasources = connections) + + # Using column names + dsCodaClient::ds.acomp(X = 'D', + parts = c('component1', 'component2', 'component3'), + objectname = 'comp_object_named', + datasources = connections) + + # clear the DataSHIELD R sessions and logout + datashield.logout(connections) +} + +} +\author{ +DataSHIELD Development Team +} diff --git a/man/ds.lrEM.Rd b/man/ds.lrEM.Rd new file mode 100644 index 0000000..dce6830 --- /dev/null +++ b/man/ds.lrEM.Rd @@ -0,0 +1,144 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ds.lrEM.R +\name{ds.lrEM} +\alias{ds.lrEM} +\title{Creates a server-side log-ratio EM algorithm object for compositional data imputation} +\usage{ +ds.lrEM( + X = NULL, + label = NULL, + dl = NULL, + rob = FALSE, + ini.cov = c("complete.obs", "multRepl"), + frac = 0.65, + tolerance = 1e-04, + max.iter = 50, + rlm.maxit = 150, + imp.missing = FALSE, + suppress.print = FALSE, + closure = NULL, + z.warning = 0.8, + z.delete = TRUE, + objectname = NULL, + datasources = NULL +) +} +\arguments{ +\item{X}{character string specifying the name of the server-side dataset or matrix +containing the compositional data.} + +\item{label}{unique label (numeric or character) used to denote unobserved values in X. +Default is NULL.} + +\item{dl}{numeric vector or matrix of detection limits/thresholds. These must be given on +the same scale as X. Default is NULL.} + +\item{rob}{logical value. FALSE provides maximum-likelihood estimates of model parameters, +TRUE provides robust parameter estimates. Default is FALSE.} + +\item{ini.cov}{initial estimation of either the log-ratio covariance matrix (ML estimation) +or unobserved data (robust estimation). It can be based on either complete observations +("complete.obs") or multiplicative simple replacement ("multRepl"). Default is "complete.obs".} + +\item{frac}{if ini.cov="multRepl", fraction parameter for initial multiplicative simple +replacement of left-censored data expressed in proportions. Default is 0.65.} + +\item{tolerance}{convergence criterion for the EM algorithm. Default is 0.0001.} + +\item{max.iter}{maximum number of iterations for the EM algorithm. Default is 50.} + +\item{rlm.maxit}{if rob=TRUE, maximum number of iterations for the embedded robust +regression estimation. Default is 150.} + +\item{imp.missing}{if TRUE then unobserved data identified by label are treated as +missing data. Default is FALSE.} + +\item{suppress.print}{suppress printed feedback. Default is FALSE.} + +\item{closure}{closure value used to add a residual part if needed when ini.cov="multRepl" +is used. Default is NULL.} + +\item{z.warning}{threshold for the proportion of modified zeros per part above which +a warning is issued. Default is 0.8.} + +\item{z.delete}{logical value indicating whether rows containing only zeros should be +deleted prior to imputation. Default is TRUE.} + +\item{objectname}{character string specifying the name of the new server-side object +which will store the log-ratio EM imputation result.} + +\item{datasources}{a list of \code{\link{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{datashield.connections_default}}.} +} +\value{ +\code{ds.lrEM} returns a server-side object containing the imputed compositional +data set for use in compositional data analysis. +} +\description{ +Creates a server-side object using the zCompositions::lrEM() function +} +\details{ +This function creates a server-side log-ratio EM algorithm object that can be used +for imputing left-censored data (e.g. values below detection limit, rounded zeros) in +compositional data sets. It wraps the zCompositions::lrEM() function for use in DataSHIELD. + +Server function called: \code{lrEMDS}. +} +\examples{ +\dontrun{ + + # connecting to the DataSHIELD servers + + require('DSI') + require('DSOpal') + require('dsBaseClient') + require('dsCodaClient') + + builder <- DSI::newDSLoginBuilder() + builder$append(server = "study1", + url = "http://192.168.56.100:8080/", + user = "administrator", password = "datashield_test&", + table = "COMPOSITIONAL.DATA1", driver = "OpalDriver") + builder$append(server = "study2", + url = "http://192.168.56.100:8080/", + user = "administrator", password = "datashield_test&", + table = "COMPOSITIONAL.DATA2", driver = "OpalDriver") + logindata <- builder$build() + + connections <- DSI::datashield.login(logins = logindata, assign = TRUE, symbol = "D") + + # Create a server-side log-ratio EM imputation + # Using default parameters + dsCodaClient::ds.lrEM(X = 'D', + label = 0, + objectname = 'imputed_data', + datasources = connections) + + # Using specific detection limits + dsCodaClient::ds.lrEM(X = 'D', + label = 0, + dl = c(0.1, 0.1, 0.1), + rob = FALSE, + tolerance = 0.001, + objectname = 'imputed_data_custom', + datasources = connections) + + # Using robust estimation + dsCodaClient::ds.lrEM(X = 'D', + label = 0, + dl = c(0.1, 0.1, 0.1), + rob = TRUE, + ini.cov = "multRepl", + frac = 0.5, + objectname = 'robust_imputed_data', + datasources = connections) + + # clear the DataSHIELD R sessions and logout + datashield.logout(connections) +} + +} +\author{ +DataSHIELD Development Team +}