-
Notifications
You must be signed in to change notification settings - Fork 29
Expand file tree
/
Copy pathBooleDS.R
More file actions
156 lines (125 loc) · 5.62 KB
/
BooleDS.R
File metadata and controls
156 lines (125 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#'
#' @title BooleDS
#' @description Converts the individual elements of a vector or other object into
#' Boolean indicators.
#' @details The function converts the input vector into Boolean indicators.
#' @param V1.name A character string specifying the name of the vector to which the
#' Boolean operator is to be applied
#' @param V2.name A character string specifying the name of the vector or scalar to
#' which <V1> is to be compared.
#' @param Boolean.operator.n An integer value (1 to 6) providing a numeric coding for
#' the character string
#' specifying one of six possible Boolean operators: '==', '!=', '>', '>=','<', '<='
#' that could legally be passed
#' from client to server via DataSHIELD parser
#' @param numeric.output a TRUE/FALSE indicator defaulting to TRUE determining whether
#' the final output variable
#' should be of class numeric (1/0) or class logical (TRUE/FALSE).
#' @param na.assign.text A character string taking values 'NA', '1' or '0'. If 'NA'
#' then any NA values in the
#' input vector remain as NAs in the output vector. If '1' or '0' NA values in the
#' input vector are all converted to 1 or 0 respectively.
#'
#' @author DataSHIELD Development Team
#'
#' @return the levels of the input variable.
#' @export
#'
BooleDS <- function(V1.name=NULL, V2.name=NULL, Boolean.operator.n=NULL, na.assign.text, numeric.output=TRUE){
# Check Permissive Privacy Control Level.
dsBase::checkPermissivePrivacyControlLevel(c('permissive', 'banana', 'carrot'))
#########################################################################
# DataSHIELD MODULE: CAPTURE THE nfilter SETTINGS #
thr <- dsBase::listDisclosureSettingsDS() #
#nfilter.tab<-as.numeric(thr$nfilter.tab) #
#nfilter.glm<-as.numeric(thr$nfilter.glm) #
#nfilter.subset<-as.numeric(thr$nfilter.subset) #
#nfilter.string<-as.numeric(thr$nfilter.string) #
#nfilter.stringShort<-as.numeric(thr$nfilter.stringShort) #
#nfilter.kNN<-as.numeric(thr$nfilter.kNN) #
#datashield.privacyLevel<-as.numeric(thr$datashield.privacyLevel) #
#########################################################################
#V1: numeric, factor or logical vector or scalar in .GlobalEnv
#V2: numeric, factor or logical vector or scalar in .GlobalEnv or client specified scalar with which to compare V1
#EVAL V1 and V2
##########CHECK NOT LONG SPECIFIED VECTOR##############
V1<-eval(parse(text=V1.name), envir = parent.frame())
V2<-eval(parse(text=V2.name), envir = parent.frame())
if(is.character(V1)){
studysideMessage<-"FAILED: V_i is character, please convert to numeric, factor or logical before running Boole"
stop(studysideMessage, call. = FALSE)
}
if(is.character(V2)){
studysideMessage<-"FAILED: V_ii is character, please convert to numeric, factor or logical before running Boole"
stop(studysideMessage, call. = FALSE)
}
V1.length<-length(V1)
V2.length<-length(V2)
if(!((V1.length == V2.length) | (V2.length==1))){
studysideMessage<-"FAILED: V_ii must either be of length one or of length equal to V_i"
stop(studysideMessage, call. = FALSE)
}
if(!is.numeric(Boolean.operator.n) | Boolean.operator.n==0){
studysideMessage<-"FAILED: Boolean.operator specified incorrectly. Must be: '==', '!=', '<', '<=', '>' or '>='"
stop(studysideMessage, call. = FALSE)
}
Boolean.operator<-" "
if(Boolean.operator.n==1) Boolean.operator<-"=="
if(Boolean.operator.n==2) Boolean.operator<-"!="
if(Boolean.operator.n==3) Boolean.operator<-"<"
if(Boolean.operator.n==4) Boolean.operator<-"<="
if(Boolean.operator.n==5) Boolean.operator<-">"
if(Boolean.operator.n==6) Boolean.operator<-">="
#APPLY BOOLEAN OPERATOR SPECIFIED
Boolean.indicator<-integer(length=V1.length)
#EVALUATE DIFFERENTLY IF V2 IS SAME LENGTH AS V1 OR OF LENGTH 1
if(V2.length==V1.length){
for(j in 1:V1.length){
command.text<-paste0(V1.name,"[",j,"] ",Boolean.operator," ",V2.name,"[",j,"]")
Boolean.indicator[j]<-eval(parse(text=command.text), envir = parent.frame())*1
}
}
if(V2.length==1){
for(j in 1:V1.length){
command.text<-paste0(V1.name,"[",j,"] ",Boolean.operator," ",V2.name)
Boolean.indicator[j]<-eval(parse(text=command.text), envir = parent.frame())*1
}
}
#BY DEFAULT NAs REMAIN AS NAs BUT IF YOU WANT TO YOU CAN FORCE THEM TO 1 OR 0 USING <na.assign.text> ARGUMENT
if(na.assign.text=="1"){
Boolean.indicator[is.na(Boolean.indicator)==1]<-1
}
if(na.assign.text=="0"){
Boolean.indicator[is.na(Boolean.indicator)==1]<-0
}
outobj.b<-as.logical(Boolean.indicator)
outobj<-Boolean.indicator
#COMMENT OUT THIS CODE BLOCK BECAUSE TESTS OF MINIMUM CELL SIZE SHOULD ALL BE
#ENACTED IN AGGREGATE FUNCTIONS. NO VECTOR IS DISCLOSIVE UNTIL IT RETURNS
#SOMETHING TO THE CLIENTSIDE. I AM LEAVING THIS COMMENTED BUT UNDELETED
#IN CASE WE LATER DECIDE TO CHANGE THIS STRATEGY
#CHECK OUTPUT VECTOR VALIDITY
# outobj.invalid<-0
#
# unique.values.outobj<-unique(outobj)
# unique.values.noNA.outobj<-unique.values.outobj[complete.cases(unique.values.outobj)]
#
# #Boolean and can therefore only be binary so check this:
# if(length(unique.values.noNA.outobj)>2) outobj.invalid<-1
#
# tabvar<-table(outobj,useNA="no")[table(outobj,useNA="no")>=1]
# min.category<-min(tabvar)
# if(min.category<nfilter.tab)outobj.invalid<-1
#
#TERMINATE CALCULATION IF outobj.invalid==1
#if(outobj.invalid==1){
# studysideMessage<-"FAILED: outobj has at least one category below table filter limit"
# stop(studysideMessage, call. = FALSE)
#}
if(numeric.output==TRUE){
Boole.obj<-outobj
}else{Boole.obj<-outobj.b}
return(Boole.obj)
}
#ASSIGN FUNCTION
# BooleDS