source: main/adopters/nm/trunk/src/main/backend_qModules/3.0/_EPHT/mortmc/NM_RateAA10K.def @ 21905

Last change on this file since 21905 was 21905, checked in by LoisHaggard_NM, 2 years ago

NMBIS Backend QModules - all updates

File size: 12.0 KB
Line 
1#NM_RateAA10K.def
2#Calculates directly age-adjusted rates per 10,000 for
3#  records that have been filtered by IBIS-Q (data=tmp)
4#Uses the IBIS-Q data_frame for cross1 and cross2
5#Uses an "agepop_frame" so all agepop groups are always included/represented
6#  (weights will sum to 1.0)
7#NM_ in filename = applies cell suppression rule
8#Outputs redflag var based on RSE
9#
10f type special 
11#########################################
12--------BoNdArY--------
131 script
14OPTIONS MPRINT MLOGIC SYMBOLGEN NONUMBER NODATE linesize=175 PAGESIZE=4000;
15OPTION SPOOL;
16
17 ************************** 1. TMP ******************************;
18 * The dataset 'tmp' is the numerator dataset that has been read ;
19 * in already by ibis-q. Any filters have already been applied.  ;
20 * The proc summary counts deaths by agepop, cross1, and cross2. ;
21 * The variable "x" must be in the dataset, it is set equal to 1.;
22 ****************************************************************;
23        proc summary data=tmp;
24                var x;
25                class agepop %cross1%
26                ?cross2? %cross2%
27                ;
28                output out=tmp sum=count;
29        proc sort data=tmp; by agepop %cross1%
30                ?cross2? %cross2%
31                ; run;
32        proc print data=tmp noobs;
33                title1 '---------------------------------';
34                title2 '1. TMP - numerator dataset';
35                run;
36
37 ********************** 2. %data_frame% *************************;
38 * %data_frame% is a dataset created by IBIS-Q. It consists of   ;
39 * %cross1% and %cross2% (if the user specified %cross2%) and a  ;
40 * variable named "count" that has been set to "0". The results  ;
41 * of the proc summary must be merged with the %data_frame%      ;
42 * dataset.                                                      ;
43 ****************************************************************;
44        data agepop_frame;
45                retain count 0;
46                do
47                        agepop= 1 to 11 by 1 ;
48                        output;
49                end;
50        run;
51        *************************************************************************************;
52        * If user selects specific dimension values, e.g., years, the total dimension value  ;
53        * will not be included in the data frame. This creates a dimension value for the     ;
54        * total row. But if user does not select specific values (e.g., selects a year,      ;
55        * then crosses by sex), there will be a total row for the cross1 and cross2 values.  ;
56        * So in a later step, the new_frame dataset is sorted with a "nodupkey" option to    ;
57        * remove the additional dimension total values.                                      ;
58        *************************************************************************************;
59        data crosstotalframe;
60                retain count 0;
61                do
62                        %cross1%=.;
63                        ?cross2? %cross2%=.;
64                        output;
65                end;
66        run;
67        data df_%cross1%%cross2%;
68                set df_%cross1%%cross2% crosstotalframe;
69        run;
70        proc print data=df_%cross1%%cross2% noobs; title2 'cross1cross2 frame with total row'; run;
71        proc print data=agepop_frame noobs; title2 'agepop frame'; run;
72        proc sql;
73                create table new_frame as
74                select df_%cross1%%cross2%.*, agepop_frame.*
75                from df_%cross1%%cross2%, agepop_frame ;
76        quit;
77        proc sort data=new_frame nodupkey;
78                by %cross1%
79                   ?cross2? %cross2%
80                   agepop;
81                run;
82        proc print data=new_frame noobs; title2 'new_frame, sorted with nodupkey'; run;
83        proc sort data=tmp; by %cross1% %cross2% agepop; run;
84        data newtmp;
85                merge new_frame tmp;  *must list frame dataset first, then tmp;
86                by %cross1% %cross2% agepop;
87                drop _TYPE_ _FREQ_ ;
88        run;
89
90        proc print data=newtmp noobs;
91                title2 '2. NEWTMP, after frame merged with tmp';
92                run;
93        data tmp;
94                set newtmp;
95        run;
96
97 ************************* 3. POP *******************************;
98 * Sum the pop counts by age group, cross1 and cross2.           ;
99 * Read proc summary output, recode the agepop total records,    ;
100 * cross1 and cross2 totals to -1.                               ;
101 ****************************************************************;
102        data poptmp; format agepop %popcross1% %popcross2% 8.; set poptmp; run; 
103        proc summary data=poptmp;
104                var popcount;
105                class agepop  %popcross1% %popcross2%;
106                output out=pop sum=popcount;
107        run;
108        data pop;
109                set pop;
110                drop _TYPE_ _FREQ_;
111                proc print data=pop noobs; 
112                   title2 '3. POP - denominator dataset';
113        run;
114 
115 *********************** 4. NUMBERS *****************************;
116 * Join tmp, pop.                                                ;
117 * -1 values are left of out NUMBERS because stdpop doesn't have ;
118 * any -1 values.                                                ;
119 ****************************************************************;
120        proc sql;
121                create table numbers as
122                select tmp.*, pop.*
123                from tmp left join pop
124                on tmp.agepop=pop.agepop
125                ?popcross1? and tmp.%cross1%=pop.%popcross1% 
126                ?popcross2? and tmp.%cross2%=pop.%popcross2%
127                ;
128        quit;
129        data numbers;
130                set numbers;
131                if agepop^=.; *get rid of total rows to stop doubling from pop proc summary;
132                if %cross1%=. then %cross1%=-1;
133                ?cross2? if %cross2%=. then %cross2%=-1;
134        proc print data=numbers noobs;
135                title2 '4. NUMBERS';
136                title3 ' ';
137        run;
138
139 ************************ 5. STDWGT *****************************;
140 * Select the appropriate records from the stdwgts  datafile.    ;
141 * All weights are for U.S. 2000 standard population (per NCHS   ;
142 * Statnote20). 'stdvar' values are as follows:                  ;
143 *      agepop - the standard 11 age group weights                 ;
144 *      agepopGE35 - agepop wgts for age>=35                       ;
145 *      AADist10 - Statnote20 dist #10, for BRFSS                  ;
146 *      AADist10GE40 - AADist10 for ages >=40                      ;
147 *      AADist10GE50 - AADist10 for ages >=50                      ;
148 *      AgeGrp18 - 5-year age groups, for cancer data              ;
149 *      AgeGrp18LT50 - AgeGrp18 for age <50                        ;
150 *      AgeGrp18GE50 - AgeGrp18 for age >=50                       ;
151 *      AgeGrp18LT15 - AgeGrp18 for age <15                        ;
152 *      AgeGrp18LT20 - AgeGrp18 for age <20                        ;
153 ****************************************************************;
154        data stdwgt;
155                informat stdwgt 7.6;
156                set pop.stdwgts;
157                *pop libname is set in .cfg file with the saspop statement;
158                if (stdvar='agepop'); *stdvar name is case-sensitive;
159                keep agepop stdwgt;
160        run;
161        proc print data=stdwgt noobs; 
162                title2 '5. STDWGT- std. pop. weights for direct age-adjustment';
163        run;
164 ******************** 6. NUMBERS2 *******************************;
165 * Adds the standard population weights to the numerator and     ;
166 * denominator table. This is done as a separate sql, left join  ;
167 * to preserve all the -1 values.                                ;
168 ****************************************************************;
169        proc sql;
170                create table numbers2 as
171                select numbers.*, stdwgt.stdwgt
172                from numbers left join stdwgt
173                on numbers.agepop=stdwgt.agepop
174                ;
175        quit;
176        proc print data=numbers2 noobs;
177                title2 '6. NUMBERS2- Standard POP wgts merged onto dataset';
178        run;
179
180 *********************** 7. AGESPECIFIC *************************;
181 * Calculate age-specific rates & cross-products                 ;
182 ****************************************************************;
183        data agespecific;
184                set numbers2;
185                r=(count/popcount);             *age-specific proportion;
186                ratewgt=r*stdwgt;               *weighted age-specific proportion;
187                * Montana method... rate_var=count*(stdwgt/popcount)**2;  * New formula from doh.wa.gov;
188                rate_var=(stdwgt**2)*((r*(1-r))/popcount);
189
190        proc print data=agespecific noobs; 
191                title2 '7. AGESPECIFIC - combines numer and denom data, includes R (age-specific proportion),';
192                title3 'RATEWGT (weighted age-specific rate), and RATE_VAR (rate variance) vars';
193        run;
194   
195 ************************ 8. AARATE ******************************;
196 * Sum the age-specific rates into aa rates, and merge wgtmax.    ;   
197 *****************************************************************;
198        proc summary data=agespecific nway;
199                var ratewgt rate_var count popcount;
200                class %cross1% %cross2%;
201                output out=aarate sum(ratewgt rate_var count popcount)=aarate aarate_var count popcount;
202        run;
203        data aarate;
204                set aarate;
205                drop _TYPE_ _FREQ_ ;
206                run;
207                proc sort data=aarate; by %cross1% %cross2%; run;
208        proc print data=aarate noobs;
209                title2 '8. AARATE - summed across weighted agepop cross-products to get AA rate and';
210                title3 'rate variance within each cross-by var';
211      run;
212
213 ******************* 9. TMP *************************************;
214 * Almost final IBIS output dataset.                             ;
215 * Make sure no summary rows are included. All -1 totals will be ;
216 * coded back to '.' after this step.                            ;
217 ****************************************************************;
218        data tmp;
219                set aarate;
220                if %cross1%=-1 then %cross1%=.;         *Recode the statewide totals.;
221                ?cross2? if %cross2%=-1 then %cross2%=.;
222               
223                if (count>0) then do;
224                                rateper=(aarate*10000);
225                                rate_se=sqrt(aarate_var);
226                                stderr=(rate_se*10000);
227                        end;
228                if (count<=0) then do;
229                                count=0;
230
231                                rateper=0;
232                                stderr=sqrt((3/popcount)*(1-(3/popcount))/popcount)*10000;
233                        end;
234                t1=(rateper-(1.96*stderr));
235                if (t1<0) then t1=0;
236                LL=put(t1, 8.2);
237                UL=put((rateper+(1.96*stderr)), 8.2);
238                LL=compress(LL);
239                UL=compress(UL);
240                n=count;
241
242 *********************** 10. Red Flag ****************************;
243 * redflag is the statistical stability indicator based on the    ;
244 * relative standard error (RSE, or coefficient of variation).    ;
245 * Redflag values created here are converted to images or special ;
246 * characters in IBIS-View application XSLTfiles, for instance:   ;
247 * (xslt\html\query\module\result\ResultPage.xslt, ...Values.xslt ;
248 *****************************************************************;
249                if count>0 then do;
250                        rse=(stderr/rateper);
251                        redflag=put('-', $14.);
252                        if rse>.3 then redflag=put('Unstable', $14.);
253                        if rse>.5 then redflag=put('Very Unstable', $14.);
254                        if stderr=. then redflag=put('Unstable', $14.);
255                end;
256                if count<=0 then redflag=put('Unstable', $14.);  *no variance, n=0, rse=div by zero;
257        run;
258
259 ************* 11. New Mexico Small Numbers Rule *******************;
260 * Suppress cells if the numerator in (1 2 3) AND the denominator   ;
261 * is less than 20. For Counts, must run the crude rate code to     ;
262 * capture the denominator, but only output the N. ZW's program     ;
263 * uses ".A" to identify cells for suppression. I have co-opted     ;
264 * his method so I can use the NM logic for cell suppression instead;
265 * of the standard IBIS logic. And I need to use ZW's program       ;
266 * because it will suppress the table marginals that can be used to ;
267 * calculate the suppressed cells. If this code is used, the .def   ;
268 * file should have the "NM_" prefix. Needs suppressed_variabes     ;
269 * code at the end of this file to work.                            ;
270 *******************************************************************;
271        data tmp;
272                set tmp;
273                if ((0<n<4) and (popcount<5000)) then do;
274                        n = .A;
275                        rateper = .A;
276                        LL = put('**', 8.0);
277                        UL = put('**', 8.0);
278                end;
279        proc print data=tmp noobs;  title2 '11. TMP - final dataset to pass to IBIS View app';
280        run;
281
282--------BoNdArY--------
283f out_variable
284# definition for output file
285f xml_out_map_file XMLRate10KNDLCLUCL.map
286--------BoNdArY--------
287f out_detail lbl_not_used__see_xml_out_map_file
288 rateper 15.1
289 n 15.0
290 popcount 15.0
291 LL 15.3
292 UL 15.3
293 redflag 15.0
294--------BoNdArY--------
295 ***************** 12. suppressed variables *************************;
296 * ZW's CGI program must be told how many variables it will need to  ;
297 * suppress and which ones they are. NOTE: If the SAS code, above, is;
298 * commented out, these lines can be left in the .def file without   ;
299 * causing any problems. They will only be used if the SAS code,     ;
300 * above is active, OR if the small_num and small_pop parameters     ;
301 * are active in the .CFG file, and with non-zero values.            ;
302 ********************************************************************;
303--------BoNdArY--------
3041 suppressed_variables 2
305 n
306 rateper
307--------BoNdArY--------
Note: See TracBrowser for help on using the repository browser.