source: main/adopters/nm/trunk/src/main/backend_qModules/3.0/_EPHT/mortmc/NM_RateAA100K_GE35.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.1 KB
Line 
1#NM_RateAA100K_GE35.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 agegrp18 (agepop elsewhere)
6#  groups are always included/represented  (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 agegrp18 %cross1%
26                ?cross2? %cross2%
27                ;
28                output out=tmp sum=count;
29        proc sort data=tmp; by agegrp18 %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                        agegrp18 = 1 to 18 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
81                   agegrp18;
82                run;
83        proc print data=new_frame noobs; title2 'new_frame, sorted with nodupkey'; run;
84        proc sort data=tmp; by %cross1% %cross2% agegrp18; run;
85        data newtmp;
86                merge new_frame tmp;  *must list frame dataset first, then tmp;
87                by %cross1% %cross2% agegrp18;
88                drop _TYPE_ _FREQ_ ;
89        run;
90
91        proc print data=newtmp noobs;
92                title2 '2. NEWTMP, after frame merged with tmp';
93                run;
94        data tmp;
95                set newtmp;
96        run;
97
98 ************************* 3. POP *******************************;
99 * Sum the pop counts by age group, cross1 and cross2.           ;
100 * Read proc summary output, recode the agepop total records,    ;
101 * cross1 and cross2 totals to -1.                               ;
102 ****************************************************************;
103        data poptmp; format agegrp18 %popcross1% %popcross2% 8.; set poptmp; run; 
104        proc summary data=poptmp;
105                var popcount;
106                class agegrp18  %popcross1% %popcross2%;
107                output out=pop sum=popcount;
108        run;
109        data pop;
110                set pop;
111                drop _TYPE_ _FREQ_;
112                proc print data=pop noobs; 
113                   title2 '3. POP - denominator dataset';
114        run;
115 
116 *********************** 4. NUMBERS *****************************;
117 * Join tmp, pop.                                                ;
118 * -1 values are left of out NUMBERS because stdpop doesn't have ;
119 * any -1 values.                                                ;
120 ****************************************************************;
121        proc sql;
122                create table numbers as
123                select tmp.*, pop.*
124                from tmp left join pop
125                on tmp.agegrp18=pop.agegrp18
126                ?popcross1? and tmp.%cross1%=pop.%popcross1% 
127                ?popcross2? and tmp.%cross2%=pop.%popcross2%
128                ;
129        quit;
130        data numbers;
131                set numbers;
132                if agegrp18^=.; *get rid of total rows to stop doubling from pop proc summary;
133                if %cross1%=. then %cross1%=-1;
134                ?cross2? if %cross2%=. then %cross2%=-1;
135        proc print data=numbers noobs;
136                title2 '4. NUMBERS';
137                title3 ' ';
138        run;
139
140 ************************ 5. STDWGT *****************************;
141 * Select the appropriate records from the stdwgts  datafile.    ;
142 * All weights are for U.S. 2000 standard population (per NCHS   ;
143 * Statnote20). 'stdvar' values are as follows:                  ;
144 *      agepop - the standard 11 age group weights                 ;
145 *      agepopGE35 - agepop wgts for age>=35                       ;
146 *      AADist10 - Statnote20 dist #10, for BRFSS                  ;
147 *      AADist10GE40 - AADist10 for ages >=40                      ;
148 *      AADist10GE50 - AADist10 for ages >=50                      ;
149 *      AgeGrp18 - 5-year age groups, for cancer data              ;
150 *      AgeGrp18LT50 - AgeGrp18 for age <50                        ;
151 *      AgeGrp18GE50 - AgeGrp18 for age >=50                       ;
152 *      AgeGrp18LT15 - AgeGrp18 for age <15                        ;
153 *      AgeGrp18LT20 - AgeGrp18 for age <20                        ;
154 ****************************************************************;
155        data stdwgt;
156                informat stdwgt 7.6;
157                set pop.stdwgts;
158                *pop libname is set in .cfg file with the saspop statement;
159                if (stdvar='AgeGrp18GE25'); *stdvar name is case-sensitive;
160                keep agegrp18 stdwgt;
161        run;
162        proc print data=stdwgt noobs; 
163                title2 '5. STDWGT- std. pop. weights for direct age-adjustment';
164        run;
165 ******************** 6. NUMBERS2 *******************************;
166 * Adds the standard population weights to the numerator and     ;
167 * denominator table. This is done as a separate sql, left join  ;
168 * to preserve all the -1 values.                                ;
169 ****************************************************************;
170        proc sql;
171                create table numbers2 as
172                select numbers.*, stdwgt.stdwgt
173                from numbers left join stdwgt
174                on numbers.agegrp18=stdwgt.agegrp18
175                ;
176        quit;
177        proc print data=numbers2 noobs;
178                title2 '6. NUMBERS2- Standard POP wgts merged onto dataset';
179        run;
180
181 *********************** 7. AGESPECIFIC *************************;
182 * Calculate age-specific rates & cross-products                 ;
183 ****************************************************************;
184        data agespecific;
185                set numbers2;
186                r=(count/popcount);             *age-specific proportion;
187                ratewgt=r*stdwgt;               *weighted age-specific proportion;
188                * Montana method... rate_var=count*(stdwgt/popcount)**2;  * New formula from doh.wa.gov;
189                rate_var=(stdwgt**2)*((r*(1-r))/popcount);
190
191        proc print data=agespecific noobs; 
192                title2 '7. AGESPECIFIC - combines numer and denom data, includes R (age-specific proportion),';
193                title3 'RATEWGT (weighted age-specific rate), and RATE_VAR (rate variance) vars';
194        run;
195   
196 ************************ 8. AARATE ******************************;
197 * Sum the age-specific rates into aa rates, and merge wgtmax.    ;   
198 *****************************************************************;
199        proc summary data=agespecific nway;
200                var ratewgt rate_var count popcount;
201                class %cross1% %cross2%;
202                output out=aarate sum(ratewgt rate_var count popcount)=aarate aarate_var count popcount;
203        run;
204        data aarate;
205                set aarate;
206                drop _TYPE_ _FREQ_ ;
207                run;
208                proc sort data=aarate; by %cross1% %cross2%; run;
209        proc print data=aarate noobs;
210                title2 '8. AARATE - summed across weighted agepop cross-products to get AA rate and';
211                title3 'rate variance within each cross-by var';
212      run;
213
214 ******************* 9. TMP *************************************;
215 * Almost final IBIS output dataset.                             ;
216 * Make sure no summary rows are included. All -1 totals will be ;
217 * coded back to '.' after this step.                            ;
218 ****************************************************************;
219        data tmp;
220                set aarate;
221                if %cross1%=-1 then %cross1%=.;         *Recode the statewide totals.;
222                ?cross2? if %cross2%=-1 then %cross2%=.;
223               
224                if (count>0) then do;
225                                rateper=(aarate*100000);
226                                rate_se=sqrt(aarate_var);
227                                stderr=(rate_se*100000);
228                        end;
229                if (count<=0) then do;
230                                count=0;
231
232                                rateper=0;
233                                stderr=sqrt((3/popcount)*(1-(3/popcount))/popcount)*100000;
234                        end;
235                t1=(rateper-(1.96*stderr));
236                if (t1<0) then t1=0;
237                LL=put(t1, 8.2);
238                UL=put((rateper+(1.96*stderr)), 8.2);
239                LL=compress(LL);
240                UL=compress(UL);
241                n=count;
242
243 *********************** 10. Red Flag ****************************;
244 * redflag is the statistical stability indicator based on the    ;
245 * relative standard error (RSE, or coefficient of variation).    ;
246 * Redflag values created here are converted to images or special ;
247 * characters in IBIS-View application XSLTfiles, for instance:   ;
248 * (xslt\html\query\module\result\ResultPage.xslt, ...Values.xslt ;
249 *****************************************************************;
250                if count>0 then do;
251                        rse=(stderr/rateper);
252                        redflag=put('-', $14.);
253                        if rse>.3 then redflag=put('Unstable', $14.);
254                        if rse>.5 then redflag=put('Very Unstable', $14.);
255                        if stderr=. then redflag=put('Unstable', $14.);
256                end;
257                if count<=0 then redflag=put('Unstable', $14.);  *no variance, n=0, rse=div by zero;
258        run;
259
260 ************* 11. New Mexico Small Numbers Rule *******************;
261 * Suppress cells if the numerator in (1 2 3) AND the denominator   ;
262 * is less than 20. For Counts, must run the crude rate code to     ;
263 * capture the denominator, but only output the N. ZW's program     ;
264 * uses ".A" to identify cells for suppression. I have co-opted     ;
265 * his method so I can use the NM logic for cell suppression instead;
266 * of the standard IBIS logic. And I need to use ZW's program       ;
267 * because it will suppress the table marginals that can be used to ;
268 * calculate the suppressed cells. If this code is used, the .def   ;
269 * file should have the "NM_" prefix. Needs suppressed_variabes     ;
270 * code at the end of this file to work.                            ;
271 *******************************************************************;
272        data tmp;
273                set tmp;
274                if ((0<n<4) and (popcount<5000)) then do;
275                        n = .A;
276                        rateper = .A;
277                        LL = put('**', 8.0);
278                        UL = put('**', 8.0);
279                end;
280        proc print data=tmp noobs;  title2 '11. TMP - final dataset to pass to IBIS View app';
281        run;
282
283--------BoNdArY--------
284f out_variable
285# definition for output file
286f xml_out_map_file XMLRate100KNDLCLUCL.map
287--------BoNdArY--------
288f out_detail lbl_not_used__see_xml_out_map_file
289 rateper 15.1
290 n 15.0
291 popcount 15.0
292 LL 15.3
293 UL 15.3
294 redflag 15.0
295--------BoNdArY--------
296 ***************** 12. suppressed variables *************************;
297 * ZW's CGI program must be told how many variables it will need to  ;
298 * suppress and which ones they are. NOTE: If the SAS code, above, is;
299 * commented out, these lines can be left in the .def file without   ;
300 * causing any problems. They will only be used if the SAS code,     ;
301 * above is active, OR if the small_num and small_pop parameters     ;
302 * are active in the .CFG file, and with non-zero values.            ;
303 ********************************************************************;
304--------BoNdArY--------
3051 suppressed_variables 2
306 n
307 rateper
308--------BoNdArY--------
Note: See TracBrowser for help on using the repository browser.