source: main/adopters/md/trunk/src/main/backend_qModules/brfss23/SurveyCrudeRate.sas @ 21330

Last change on this file since 21330 was 21330, checked in by Paul Leo, 2 months ago

Maryland BRFSS V1 Splits - changed the .def files for V1 splits to newly named weight variables.
Will need to do the same for V2 and V3 splits.
Minor cleanup of SurveyCrudeRate?.sas

File size: 11.0 KB
Line 
1*******************************************************************************************************;
2* Program filename: SurveyCrudeRate.sas                                                                 ;
3*                                                                                                      ;
4* This file is "included" in each BRFSS indicator .def file for crude rates. The macro variables       ;
5* (varname, weight) are also set in the .def file. The %spvar2% variable is referenced in the .def     ;
6* file. The value for %spvar2% is set in the IBIS Module.xml file. It is also a filter-exclude         ;
7* variable, which allows keeps the whole survey dataset in the analytic file, and allows the user to   ;
8* select whether to calculate the at-risk percentage (%VarLevel=1) or the not-at-risk percentage       ;
9* (%VarLevel=2).                                                                                       ;
10*                                                                                                      ;
11* Missing values have been set to '.' for all indicator and dimension variables.                       ;
12*                                                                                                      ;
13* Notes for ibisq survey program.                                                                      ;
14*                                                                                                      ;
15* surveyvar1 allow the variance estimate to be calculated with the entire dataset, regardless of other ;
16* dataset filters. This is appropriate according to Michael Friedrichs in Utah.                        ;
17*                                                                                                      ;
18* ageadjfilter has something to do with maintaining the entire population dataset in the results for   ;
19* the state overall.                                                                                   ;
20*******************************************************************************************************;
21
22OPTIONS MPRINT MLOGIC SYMBOLGEN SPOOL SOURCE2;
23options sumsize=138m nocenter pagesize=4000 linesize=MAX;
24
25/* CODE FOR ADJUSTING FOR MULTIPLE YEARS.
26    CURRENTLY NOT USING SINCE ONLY DOING ONE YEAR
27        COULD LEAVE THIS IN, BUT PREFER NOT TO
28
29   proc freq data=tmp noprint;
30     tables year / out=wgt;
31     run;
32     proc print data=wgt noobs; title1 '-------------'; title2 'wgt: first output frequency table'; run;
33   
34   data wgt;
35     set wgt;
36     keep year wpercent;
37     wpercent=percent/100;
38     run;
39     proc print data=wgt noobs; title1 '-------------'; title2 'wgt: final year percentages'; run;
40     
41   proc sort data=tmp; by year; run;
42   data tmp;
43     merge wgt tmp;
44     by year;
45     _LLCPWT=_LLCPWT*wpercent;
46     run;
47    *proc print data=tmp (obs=10); title2 'tmp: for submission to proc surveymeans'; run;
48
49*/
50
51
52title2 'PROC SURVEYMEANS OUTPUT';
53
54******************************************************************************;
55*%macro crudrt(varname,weight,FocusLevel);
56******************************;
57%macro crudrt(varname,weight);
58
59?cross1? proc surveymeans data=tmp nomcar nobs sum mean stderr CLM CV;
60?cross1?  var &varname. ;
61?cross1?   class &varname. ;
62?cross1?   strata _STSTR;
63?cross1?   domain
64?cross1? %cross1%
65?cross1? %surveyvar1%
66?cross1? ;
67?cross1?   ods output statistics=stats
68?cross1?        summary=sum
69?cross1?        domain=domain ;
70?cross1?   weight &weight. ;
71?cross1?   proc print data=stats; title1 ' '; title2 'stats';
72?cross1?   proc print data=domain; title2 'domain';
73?cross1? run;
74
75?cross1? ?cross2? proc surveymeans data=tmp nomcar nobs sum mean stderr CLM CV;
76?cross1? ?cross2?   var &varname. ;
77?cross1? ?cross2?   class &varname. ;
78?cross1? ?cross2?   strata _STSTR;
79?cross1? ?cross2?  domain
80?cross1? ?cross2? %cross1%*%cross2%
81?cross1? ?cross2? %surveyvar1%
82?cross1? ?cross2? ;
83?cross1? ?cross2?   ods output statistics=stats
84?cross1? ?cross2?       summary=sum
85?cross1? ?cross2?       domain=domain ;
86?cross1? ?cross2?   weight &weight. ;
87?cross1? ?cross2?   proc print data=stats; title1 ' '; title2 'stats';
88?cross1? ?cross2?   proc print data=domain; title2 'domain';
89?cross1? ?cross2? run;
90
91*****************************************************************;
92********* tmp1: Grab stats for dimension totals *****************;
93*****************************************************************;
94data tmp1;
95  set stats;
96  wgtN=ROUND(sum,1);
97  &varname.=input(VarLevel, 8.);
98  %cross1% = -1;
99  ?cross2? %cross2% = -1;
100  *drop VarLevel VarName VarLabel wgtN StdDev;
101  proc print;
102        title1 '===================================================================';
103        title2 'tot: Grab percentage for MD overall';
104run;
105
106******************************************************************;
107********* tmp2: Grab %, SE, codes for indicator variable *********;
108******************************************************************;
109data tmp2;
110  set domain;
111    wgtN=ROUND(sum,1);
112  &varname.=input(VarLevel, 8.);
113  *drop LowerCLMean UpperCLMean VarLevel DomainLabel VarLabel VarName wgtN StdDev;
114  %if '%cross1%' != 'year' %then %do;
115        if year_sflag<=0 then delete;
116  %end;
117  proc print; title2 'tmp2: stats for indicator variable';
118run;
119
120**********************************************************;
121********** tmp3: Grab sample size (denominator) **********;
122****** N Number of respondents in sample *****************;
123*****  Denom denominator in each cross by group **********;
124**********************************************************;
125proc summary data=tmp2;
126  var N;
127  class %cross1%
128  ?cross2? %cross2%
129  &varname.
130  ;
131  output out=sampleD sum(N)=Denom;
132  proc sort data=SampleD; by %cross1%
133  ?cross2? %cross2%
134  ;
135  proc print; title2 'SampleD - (Unweighted number of folks who answered either y or n) Number of Records for cell suppression';
136  run;
137data tmp3;
138  set SampleD;
139  if &varname. =.;
140  *Denom=N;
141  drop  _TYPE_ _FREQ_ N ;
142  if %cross1% = . then %cross1% = -1;
143  ?cross2? if %cross2% = . then %cross2% = -1;
144  proc print; title2 'tmp3, Sample Size (denominator)';
145run;
146/*   MD will not use Asymmetric Confidence Intervals
147        If they want to in future, need to align the tmp datasets
148*****************************************************************;
149********** tmp4: Calculate asymmetric confidence ints ***********;
150*****************************************************************;
151data tmp2;
152        set tmp2;
153run;
154data tmp4;
155  set tmp2 tmp1;
156  f=log(mean)-log(1-mean); 
157  s=stderr/(mean*(1-mean));
158  Lf=f-1.96*s; 
159  Uf=f+1.96*s; 
160  percent=mean*100;
161  lower=(exp(Lf)/(1+exp(Lf)))*100;   
162  upper=(exp(Uf)/(1+exp(Uf)))*100;
163  drop f s Lf Uf VarName;
164  proc sort data=tmp4; by %cross1%
165        ?cross2? %cross2%
166        ;
167  proc print; title2 'tmp4: Calculate asymmetric CIs';
168run;
169*/
170data tmp4;
171        set tmp2 tmp1; /* totals onto the domain (cross1 and cross2 */
172        percent=mean*100;
173        lower=LowerCLMean*100;
174        upper=UpperCLMean*100;
175         proc sort data=tmp4; by %cross1%
176        ?cross2? %cross2%
177        ;
178        proc print; title2 'tmp4:merged tmp2 (from proc summary) and tmp1 (stats), and set percent=mean';
179run;
180******************************************************************;
181********* tmp5: Add Denom field to every record ******************;
182********* this is only for cell suppression           ************;
183******************************************************************;
184
185data tmp5; *Add Denom field to each record;
186  merge tmp3 tmp4 ;
187  by %cross1%
188  ?cross2? %cross2%
189  ;
190  proc print; title2 'tmp5: Add denom field to every record';
191run;
192
193*****************************************************************;
194****** tmp5 and tmp6: Add wgtdenom field to every record ********;
195**********wgtdenom is the weighted denominator
196*********Used by MD and HI, they want pop num, not Denom*******;
197***********  **************************;
198*****************************************************************;
199proc summary data=tmp5;
200  var wgtN;
201  class %cross1%
202  ?cross2? %cross2%
203  &varname.
204  ;
205  output out=wgtNdat sum(wgtN)=wgtdenom;
206  proc sort data=wgtNdat; by %cross1%
207  ?cross2? %cross2%
208  ;
209  proc print; title2 'wgtNdat - estimated population category in that category or response';
210  run;
211  data wgtdenomdat;
212  set wgtNdat;
213  if &varname. =.;
214  if %cross1% = . then delete;
215        ?cross2? if %cross2% = . then delete;
216  proc print; title2 'wgtdenomdat: Total rows of weighted N - estimated number in that category or response';
217        run;
218       
219  proc sort data=tmp5;
220        by %cross1%
221        ?cross2? %cross2%
222        ;
223        run;
224  proc sort data=wgtdenomdat;
225        by %cross1%
226        ?cross2? %cross2%
227        ;
228        run;
229
230data tmp6; *Add wgtdenom field to each record;
231  merge wgtdenomdat tmp5;
232  by %cross1%
233  ?cross2? %cross2%
234  ;
235  drop _TYPE_ _FREQ_ ;
236  proc print; title2 'tmp6: Add weighted sample (wgtdenom) field to every record';
237run;
238
239************************************************************;
240********** tmp6: Add RSE, redflag to dataset, clean up *****;
241************************************************************;
242* redflag is the statistical stability indicator, based on  ;
243* the relative standard error (RSE, or coefficient of       ;
244* variation.                                                ;
245************************************************************;
246
247data tmp7;
248  set tmp6;
249/* USING CV instead
250  if 0<mean<.50 then RSE=(StdErr/mean);
251  if .50<=mean<1 then RSE=(StdErr/(1-mean));
252 */
253  redflag=put('Stable', $14.);
254  if CV>.3 then redflag=put('Unstable', $14.);
255  if Denom in (0 1) then redflag=put('No Variance', $14.);
256
257
258
259  if (%cross1%=-1) then %cross1%=.;
260  ?cross2? if (%cross2%=-1) then %cross2%=.;
261  popnum=wgtdenom;
262  *drop RSE Mean StdErr Denom;
263
264  proc sort data=tmp7; by %cross1%
265  ?cross2? %cross2%
266  &varname.
267  ;
268  run;
269
270proc print data=tmp7; title2 'tmp7: Add redflag to dataset, clean up';
271run;
272
273************************************************************;
274*********** tmp: Convert values for cell suppression *******;
275************************************************************;
276data tmp;
277  set tmp7;
278  **** spvar2 ************************************************************;
279  * spvar2 is the indicator DIMENSION/VALUE passed in by the URL.         ;
280  * I have included "." in the if statement because ZWs total row cell    ;
281  * suppression algorithm was getting confused about where the total rows ;
282  * were and suppressing too many rows. ibisph-view will ignore all but   ;
283  * the grand total row. But the others need to stay in.                  ;
284  ************************************************************************;
285  if &varname in (%spvar2% .);
286  if (0<Denom<30)  OR  (CV >.3) then do;        /* MD cell supression Rule  Denom (number of folks who answered either y or n)*/
287        wgtN  = .A;
288        percent = .A;
289        lower = .A;
290        upper = .A;
291        popnum = .A;
292        redflag=put('Not Reportable', $14.);
293  end;
294  proc print data=tmp; title2 'final tmp: Convert values for cell suppression';
295run;
296
297%mend;
298
Note: See TracBrowser for help on using the repository browser.