Skip to content

Commit 89837f0

Browse files
committed
improve code and increase test coverage
1 parent 5224c75 commit 89837f0

12 files changed

Lines changed: 189 additions & 171 deletions

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Imports:
2121
childsds,
2222
purrr,
2323
tibble,
24+
tidyselect,
2425
tidyverse
2526
Suggests:
2627
testthat

NAMESPACE

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ export(BooleDS)
44
export(absDS)
55
export(asCharacterDS)
66
export(asDataFrameDS)
7-
export(asDataMatrixDS)
87
export(asFactorDS1)
98
export(asFactorDS2)
109
export(asFactorSimpleDS)

R/BooleDS.R

Lines changed: 75 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@
1616
#' the final output variable
1717
#' should be of class numeric (1/0) or class logical (TRUE/FALSE).
1818
#' @param na.assign.text A character string taking values 'NA', '1' or '0'. If 'NA'
19-
#' then any NA values in the
20-
#' input vector remain as NAs in the output vector. If '1' or '0' NA values in the
21-
#' input vector are
22-
#' all converted to 1 or 0 respectively.#' @return the levels of the input variable.
19+
#' then any NA values in the input vector remain as NAs in the output vector. If '1'
20+
#' or '0' NA values in the input vector are all converted to 1 or 0 respectively.
21+
#' @return the levels of the input variable.
2322
#' @author DataSHIELD Development Team
2423
#' @export
2524
#'
@@ -28,127 +27,77 @@ BooleDS <- function(V1.name=NULL, V2.name=NULL, Boolean.operator.n=NULL, na.assi
2827
# Check Permissive Privacy Control Level.
2928
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana'))
3029

31-
#########################################################################
32-
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS #
33-
thr <- dsBase::listDisclosureSettingsDS() #
34-
#nfilter.tab<-as.numeric(thr$nfilter.tab) #
35-
#nfilter.glm<-as.numeric(thr$nfilter.glm) #
36-
#nfilter.subset<-as.numeric(thr$nfilter.subset) #
37-
#nfilter.string<-as.numeric(thr$nfilter.string) #
38-
#nfilter.stringShort<-as.numeric(thr$nfilter.stringShort) #
39-
#nfilter.kNN<-as.numeric(thr$nfilter.kNN) #
40-
#datashield.privacyLevel<-as.numeric(thr$datashield.privacyLevel) #
41-
#########################################################################
42-
43-
44-
#V1: numeric, factor or logical vector or scalar in .GlobalEnv
45-
#V2: numeric, factor or logical vector or scalar in .GlobalEnv or client specified scalar with which to compare V1
46-
47-
#EVAL V1 and V2
48-
49-
##########CHECK NOT LONG SPECIFIED VECTOR##############
50-
51-
V1<-eval(parse(text=V1.name), envir = parent.frame())
52-
V2<-eval(parse(text=V2.name), envir = parent.frame())
53-
54-
55-
if(is.character(V1)){
56-
studysideMessage<-"FAILED: V_i is character, please convert to numeric, factor or logical before running Boole"
57-
stop(studysideMessage, call. = FALSE)
58-
}
59-
60-
if(is.character(V2)){
61-
studysideMessage<-"FAILED: V_ii is character, please convert to numeric, factor or logical before running Boole"
62-
stop(studysideMessage, call. = FALSE)
63-
}
64-
65-
V1.length<-length(V1)
66-
V2.length<-length(V2)
67-
68-
if(!((V1.length == V2.length) | (V2.length==1))){
69-
studysideMessage<-"FAILED: V_ii must either be of length one or of length equal to V_i"
70-
stop(studysideMessage, call. = FALSE)
71-
}
72-
73-
if(!is.numeric(Boolean.operator.n) | Boolean.operator.n==0){
74-
studysideMessage<-"FAILED: Boolean.operator specified incorrectly. Must be: '==', '!=', '<', '<=', '>' or '>='"
75-
stop(studysideMessage, call. = FALSE)
76-
}
77-
78-
Boolean.operator<-" "
79-
if(Boolean.operator.n==1) Boolean.operator<-"=="
80-
if(Boolean.operator.n==2) Boolean.operator<-"!="
81-
if(Boolean.operator.n==3) Boolean.operator<-"<"
82-
if(Boolean.operator.n==4) Boolean.operator<-"<="
83-
if(Boolean.operator.n==5) Boolean.operator<-">"
84-
if(Boolean.operator.n==6) Boolean.operator<-">="
85-
86-
87-
#APPLY BOOLEAN OPERATOR SPECIFIED
88-
89-
Boolean.indicator<-integer(length=V1.length)
90-
91-
#EVALUATE DIFFERENTLY IF V2 IS SAME LENGTH AS V1 OR OF LENGTH 1
92-
if(V2.length==V1.length){
93-
for(j in 1:V1.length){
94-
command.text<-paste0(V1.name,"[",j,"] ",Boolean.operator," ",V2.name,"[",j,"]")
95-
Boolean.indicator[j]<-eval(parse(text=command.text), envir = parent.frame())*1
96-
}
97-
}
98-
99-
if(V2.length==1){
100-
for(j in 1:V1.length){
101-
command.text<-paste0(V1.name,"[",j,"] ",Boolean.operator," ",V2.name)
102-
Boolean.indicator[j]<-eval(parse(text=command.text), envir = parent.frame())*1
103-
}
104-
}
105-
106-
107-
#BY DEFAULT NAs REMAIN AS NAs BUT IF YOU WANT TO YOU CAN FORCE THEM TO 1 OR 0 USING <na.assign.text> ARGUMENT
108-
109-
if(na.assign.text=="1"){
110-
Boolean.indicator[is.na(Boolean.indicator)==1]<-1
111-
}
112-
113-
if(na.assign.text=="0"){
114-
Boolean.indicator[is.na(Boolean.indicator)==1]<-0
115-
}
116-
117-
118-
outobj.b<-as.logical(Boolean.indicator)
119-
outobj<-Boolean.indicator
120-
121-
122-
123-
#COMMENT OUT THIS CODE BLOCK BECAUSE TESTS OF MINIMUM CELL SIZE SHOULD ALL BE
124-
#ENACTED IN AGGREGATE FUNCTIONS. NO VECTOR IS DISCLOSIVE UNTIL IT RETURNS
125-
#SOMETHING TO THE CLIENTSIDE. I AM LEAVING THIS COMMENTED BUT UNDELETED
126-
#IN CASE WE LATER DECIDE TO CHANGE THIS STRATEGY
127-
#CHECK OUTPUT VECTOR VALIDITY
128-
# outobj.invalid<-0
129-
#
130-
# unique.values.outobj<-unique(outobj)
131-
# unique.values.noNA.outobj<-unique.values.outobj[complete.cases(unique.values.outobj)]
132-
#
133-
# #Boolean and can therefore only be binary so check this:
134-
# if(length(unique.values.noNA.outobj)>2) outobj.invalid<-1
135-
#
136-
# tabvar<-table(outobj,useNA="no")[table(outobj,useNA="no")>=1]
137-
# min.category<-min(tabvar)
138-
# if(min.category<nfilter.tab)outobj.invalid<-1
139-
#
140-
#TERMINATE CALCULATION IF outobj.invalid==1
141-
#if(outobj.invalid==1){
142-
# studysideMessage<-"FAILED: outobj has at least one category below table filter limit"
143-
# stop(studysideMessage, call. = FALSE)
144-
#}
145-
146-
147-
148-
if(numeric.output==TRUE){
149-
Boole.obj<-outobj
150-
}else{Boole.obj<-outobj.b}
151-
return(Boole.obj)
30+
V1 <- eval(parse(text=V1.name), envir = parent.frame())
31+
V2 <- eval(parse(text=V2.name), envir = parent.frame())
32+
33+
if(is.character(V1)){
34+
studysideMessage <- "FAILED: V1 is character, please convert to numeric, factor or logical before running Boole"
35+
stop(studysideMessage, call. = FALSE)
36+
}
37+
38+
if(is.character(V2)){
39+
studysideMessage <- "FAILED: V2 is character, please convert to numeric, factor or logical before running Boole"
40+
stop(studysideMessage, call. = FALSE)
41+
}
42+
43+
V1.length <- length(V1)
44+
V2.length <- length(V2)
45+
46+
if(!((V1.length == V2.length) | (V2.length==1))){
47+
studysideMessage <- "FAILED: V2 must either be of length one or of length equal to V1"
48+
stop(studysideMessage, call. = FALSE)
49+
}
50+
51+
if(!(Boolean.operator.n %in% c(1,2,3,4,5,6))){
52+
studysideMessage <- "FAILED: Boolean.operator specified incorrectly. Must be: '==', '!=', '<', '<=', '>' or '>='"
53+
stop(studysideMessage, call. = FALSE)
54+
}
55+
56+
Boolean.operator <- " "
57+
if(Boolean.operator.n==1) Boolean.operator <- "=="
58+
if(Boolean.operator.n==2) Boolean.operator <- "!="
59+
if(Boolean.operator.n==3) Boolean.operator <- "<"
60+
if(Boolean.operator.n==4) Boolean.operator <- "<="
61+
if(Boolean.operator.n==5) Boolean.operator <- ">"
62+
if(Boolean.operator.n==6) Boolean.operator <- ">="
63+
64+
# APPLY BOOLEAN OPERATOR SPECIFIED
65+
Boolean.indicator <- integer(length=V1.length)
66+
67+
# EVALUATE DIFFERENTLY IF V2 IS SAME LENGTH AS V1 OR OF LENGTH 1
68+
if(V2.length==V1.length){
69+
for(j in 1:V1.length){
70+
command.text <- paste0(V1.name,"[",j,"] ",Boolean.operator," ",V2.name,"[",j,"]")
71+
Boolean.indicator[j]<-eval(parse(text=command.text), envir = parent.frame())*1
72+
}
73+
}
74+
75+
if(V2.length==1){
76+
for(j in 1:V1.length){
77+
command.text<-paste0(V1.name,"[",j,"] ",Boolean.operator," ",V2.name)
78+
Boolean.indicator[j]<-eval(parse(text=command.text), envir = parent.frame())*1
79+
}
80+
}
81+
82+
# BY DEFAULT NAs REMAIN AS NAs BUT IF YOU WANT TO YOU CAN FORCE THEM TO 1 OR 0 USING <na.assign.text> ARGUMENT
83+
if(na.assign.text=="1"){
84+
Boolean.indicator[is.na(Boolean.indicator)==1]<-1
85+
}
86+
87+
if(na.assign.text=="0"){
88+
Boolean.indicator[is.na(Boolean.indicator)==1]<-0
89+
}
90+
91+
outobj.b <- as.logical(Boolean.indicator)
92+
outobj <- Boolean.indicator
93+
94+
if(numeric.output==TRUE){
95+
Boole.obj <- outobj
96+
}else{
97+
Boole.obj <- outobj.b
98+
}
99+
100+
return(Boole.obj)
152101
}
153-
#ASSIGN FUNCTION
102+
# ASSIGN FUNCTION
154103
# BooleDS

R/asCharacterDS.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#' @author Amadou Gaye, Paul Burton, Demetris Avraam for DataSHIELD Development Team
1313
#' @export
1414
#'
15-
asCharacterDS <- function (x.name){
15+
asCharacterDS <- function(x.name){
1616

1717
x <- eval(parse(text=x.name), envir = parent.frame())
1818

R/asFactorDS2.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
#' a factor type that presented as a vector or as a matrix with dummy variables.
55
#' @details The functions converts the input variable into a factor which is presented as a vector
66
#' if the \code{fixed.dummy.vars} is set to FALSE or as a matrix with dummy variables if the
7-
#' \code{fixed.dummy.vars} is set to TRUE (see the help file of ds.asFactor.b for more details).
7+
#' \code{fixed.dummy.vars} is set to TRUE (see the help file of ds.asFactor for more details).
88
#' @param input.var.name the name of the variable that is to be converted to a factor.
99
#' @param all.unique.levels.transmit the levels that the variable will be transmitted to.
1010
#' @param fixed.dummy.vars a boolean that determines whether the new object will be represented as
1111
#' a vector or as a matrix of dummy variables indicating the factor level of each data point.
12-
#' If this argyment is set to FALSE (default) then the input variable is converted to a factor and
12+
#' If this argument is set to FALSE (default) then the input variable is converted to a factor and
1313
#' assigned as a vector. If is set to TRUE then the input variable is converted to a factor but
1414
#' assigned as a matrix of dummy variables.
1515
#' @param baseline.level a number indicating the baseline level to be used in the creation of the

man/BooleDS.Rd

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/asDataFrameDS.Rd

Lines changed: 12 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/asDataMatrixDS.Rd

Lines changed: 0 additions & 34 deletions
This file was deleted.

man/asFactorDS2.Rd

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/disclosure/set_disclosure_settings.R

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,27 @@ set.standard.disclosure.settings <- function() {
2424
options(default.nfilter.levels.density = "0.33")
2525
options(default.nfilter.levels.max = "40")
2626
}
27+
28+
set.specific.disclosure.settings <- function(datashield.privacyControlLevel='permissive',
29+
nfilter.tab='3',
30+
nfilter.subset='3',
31+
nfilter.glm='0.33',
32+
nfilter.string='80',
33+
nfilter.stringShort='20',
34+
nfilter.kNN='3',
35+
nfilter.levels.density='0.33',
36+
nfilter.levels.max='40',
37+
nfilter.noise='0.25',
38+
nfilter.privacy.old='5') {
39+
options(datashield.privacyLevel = nfilter.privacy.old)
40+
options(default.datashield.privacyControlLevel = datashield.privacyControlLevel)
41+
options(default.nfilter.glm = nfilter.glm)
42+
options(default.nfilter.kNN = nfilter.kNN)
43+
options(default.nfilter.string = nfilter.string)
44+
options(default.nfilter.subset = nfilter.subset)
45+
options(default.nfilter.stringShort = nfilter.stringShort)
46+
options(default.nfilter.tab = nfilter.tab)
47+
options(default.nfilter.noise = nfilter.noise)
48+
options(default.nfilter.levels.density = nfilter.levels.density)
49+
options(default.nfilter.levels.max = nfilter.levels.max)
50+
}

0 commit comments

Comments
 (0)