OBJECTIVE: Compute aggregate percentiles for one variable by one grouping variable. ALGORITHM: Same as SPSS FREQUENCIES AUTHOR: Tom Dierickx (tom@data-for-all.com) MODIFIED: February 5, 2003. Notes: 1) If you want them across the entire dataset, simply do a COMPUTE dumvar = 1. and save your sav file before you run this and use dumvar as your "grouping" variable. 2) If you want percentiles by multiple grouping variables, you could concatenate them together into a single grouping variable first (again., saving your sav file before you run this); that is, for this example you could find aggregate percentiles by accel, year, and origin combinations: STRING cubeID (A9). COMPUTE cubeID = CONCAT(STRING(accel,F4.0),"-",STRING(year,F2.0),"-",STRING(origin,F1.0)). ***************************************************************************. *** JUST ALTER THESE VALUES AS NEEDED AND GO ******************************. ***************************************************************************. DEFINE @Path() "C:\\Program Files\\SPSS\\" !ENDDEFINE. DEFINE @SavFile() "Cars.sav" !ENDDEFINE. DEFINE @VarX() mpg !ENDDEFINE. DEFINE @VarXQ() "mpg" !ENDDEFINE. DEFINE @GrpBy() cylinder !ENDDEFINE. ***************************************************************************. *** STEP 1: IMPORT SAV FILE OF INTEREST AND SORT CASES ***. GET FILE= @Path + @SavFile. SORT CASES @GrpBy(A) @VarX(A). *** STEP 2: SAVE OUT DATA INTO A TEMPORARY FILE ****. *** KEEP ONLY GROUPING ID AND NON-MISSING VALUES ***. SELECT IF NOT(SYSMIS(@VarX)) AND NOT(MISSING(@VarX)). SAVE OUTFILE = "C:\\Temp\\" + @VarXQ + ".sav" /rename= (@GrpBy @VarX = grp_id value) /keep= grp_id value. GET FILE = "C:\\Temp\\" + @VarXQ + ".sav". *** STEP 3: NUMBER RECORDS WITHIN EACH GROUPING ***. IF ( ($CASENUM=1) OR (SYSMIS(LAG(grp_id)) AND NOT(SYSMIS(grp_id))) OR (grp_id <> LAG(grp_id)) ) recno=1. IF (MISSING(recno)) recno=LAG(recno) + 1. EXECUTE. *** STEP 4: SAVE OUT ORDERED DATA ***. SAVE OUTFILE= "C:\\Temp\\" + @VarXQ + ".sav". GET FILE= "C:\\Temp\\" + @VarXQ + ".sav". *** STEP 5: FIND COUNTS FOR EACH GROUPING ***. AGGREGATE /OUTFILE= * /BREAK= grp_id /N= N. *** STEP 6: ATTACH COUNTS TO ORDERED DATA ***. MATCH FILES /FILE= "C:\\Temp\\" + @VarXQ + ".sav" /TABLE= * /BY= grp_id. EXECUTE. *** STEP 7: COMPUTE PERCENTILES USING "p(n+1) AND INTERPOLATE" METHOD *****. *** SEE http://www.itl.nist.gov/div898/handbook/prc/section2/prc252.htm ***. DO REPEAT p= .10 .25 .50 .75 .90 /OBS= i_10 i_25 i_50 i_75 i_90 /k= k_10 k_25 k_50 k_75 k_90 /r= r_10 r_25 r_50 r_75 r_90 /ptile= p_10 p_25 p_50 p_75 p_90. COMPUTE OBS = p*(N+1). COMPUTE k = TRUNC(OBS). COMPUTE r = OBS - k. DO IF ((OBS <= 1) AND (recno = 1)). COMPUTE ptile = value. ELSE IF ((OBS >= N) AND (recno = N)). COMPUTE ptile = value. ELSE IF (lag(recno) = k). COMPUTE ptile = (1-r)*lag(value) + r*(value). END IF. END REPEAT . EXECUTE. *** STEP 7: "SQUEEZE DATA", RETAINING ONLY SUMMARIZED CALCULATIONS ***. AGGREGATE /OUTFILE= * /BREAK= grp_id /n = N /mean = MEAN(value) /min = MIN(value) /p_10 = MAX(p_10) /p_25 = MAX(p_25) /p_50 = MAX(p_50) /p_75 = MAX(p_75) /p_90 = MAX(p_90) /max = MAX(value). *** STEP 9: APPLY SOME GENERIC LABELS ***. VARIABLE LABELS n "Count: " + @varXQ. VARIABLE LABELS mean "Mean: " + @varXQ. VARIABLE LABELS min "Minimum: " + @varXQ. VARIABLE LABELS p_10 "10th percentile: " + @varXQ. VARIABLE LABELS p_25 "25th percentile: " + @varXQ. VARIABLE LABELS p_50 "Median: " + @varXQ. VARIABLE LABELS p_75 "75th percentile: " + @varXQ. VARIABLE LABELS p_90 "90th percentile: " + @varXQ. VARIABLE LABELS max "Maximum: " + @varXQ. *** STEP 10: WE'RE DONE! *** SAVE OUTFILE= "C:\\Temp\\" + @VarXQ + ".sav".