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
* QUESTION.
*I know how to produce two histograms that have number of 
students on the y axis and dollars on the x axis (unit of analysis is student and variable
 of interest is dollars) for each of the two schools in my study.

*What I want is to have *percentage* of students rather than number of students 
on the y axis. I can do this in other software but I'm confident that it can be done in 
SPSS and I just haven't figured out how to do it.


*ANSWER.
* The following (very useful) macro is used in the solution.
* rlevesque@videotron.ca.

*///////////////////////////////////////////////////////.
DEFINE !label (vname=!TOKENS(1)
                /vcoded=!TOKENS(1)
                /begr=!TOKENS(1)
                /endr=!TOKENS(1)
                /nbbins=!TOKENS(1))
* Notes.
* Load data file then call this macro.
* vname 	=name of variable to be recoded.
* vcoded        	=name of variable which is to contain recoded value.
* begr 		=BEGinning of first Range.
* endr  		=ENDing of first Range (4 means 4.99999...).
* nbbins        	=NumBer of BINS.
* nbbins, begr and endr must be integers.
* Raynald Levesque rlevesque@videotron.ca

SAVE OUTFILE='C:\\temp\\data temp zz1z.sav'.
NEW file.
INPUT PROGRAM.
LOOP id=1 TO !nbbins.
+COMPUTE #delta=1+ !endr - !begr.
+DO IF id=1.
++COMPUTE begv=!begr.
++COMPUTE endv=begv + #delta.
++ELSE.
++COMPUTE begv=LAG(begv)+#delta.
++COMPUTE endv=LAG(endv) + #delta.
+END IF.
+END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.

STRING vname(A8).
COMPUTE vname=!QUOTE(!EVAL(!vname)).
COMPUTE dummy=0.
MATCH FILES FILE=* /BY dummy /LAST=last.
STRING vcoded(A8).
COMPUTE vcoded=!QUOTE(!EVAL(!vcoded)).
FORMATS id begv endv (F8.0).

* write syntax to recode the values.
DO IF $CASENUM=1.
WRITE OUTFILE="c:\\temp\\recode values1.sps"/"RECODE " vname " (" begv " THRU" endv " = " id " )".
ELSE.
WRITE OUTFILE="c:\\temp\\recode values1.sps"/" (" begv " THRU " endv " = " id" )".
END IF.
DO IF last.
WRITE OUTFILE="c:\\temp\\recode values1.sps"/" INTO " vcoded  ". ".
END IF.

* write syntax to define the value labels.
COMPUTE endv=RND(endv).
STRING q1(A1) /label1(A14).
COMPUTE q1="'".
COMPUTE label1=CONCAT(LTRIM(STRING(begv,F8.0))," -",LTRIM(STRING(endv,F8.0))).
WRITE OUTFILE="c:\\temp\\recode values2.sps"
        /"ADD VALUE LABELS " vcoded  id " " q1 label1 q1 ".".
EXECUTE.

GET FILE='C:\\temp\\data temp zz1z.sav'.
INCLUDE "c:\\temp\\recode values1.sps".
INCLUDE "c:\\temp\\recode values2.sps".
SET TNUMBERS=LABELS /TVARS=LABELS.
VARIABLE LABEL !vcoded !QUOTE(!vname).
EXECUTE.

!ENDDEFINE.
*\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\.


* Ceate dummy data to illustrate the solution.
INPUT PROGRAM.
SET SEED=9876531.
LOOP school=1 TO 2.
LEAVE school.
LOOP id=1 TO school*50.
COMPUTE dollars=7000+UNIFORM( 10000).
* next line creates a gap in the data, to show problem and solution.
IF RANGE(dollars,11999,13001) dollars=dollars-1000.
END CASE.
END LOOP.
END LOOP.
END FILE.
END INPUT PROGRAM.

* recode and label the values.
!label vname=dollars vcoded=dollar2 begr=7000 endr=7999 nbbins=11.

SORT CASES BY school .
SPLIT FILE LAYERED BY school .

* Method 1.
GRAPH
  /TITLE='Method 1, empty bars are not printed'
  /BAR(SIMPLE)=PCT BY dollar2
  /MISSING=REPORT.

* Method 2.

SPLIT FILE OFF.
AGGREGATE
  /OUTFILE='c:\\temp\\temp01.sav'
  /BREAK=school
  /totcases = N(id).

AGGREGATE
  /OUTFILE=*
  /BREAK=school dollar2
  /nbcases = N(id).

MATCH FILES /FILE=*
 /TABLE='C:\\Temp\\temp01.sav'
 /BY school.

* Fill the gaps so that all columns are printed (even if there are zero cases in that range).
DO IF $casenum=1.
+ LOOP sch=1 TO 2.
+ LOOP varx=1 TO 11.
+ XSAVE OUTFILE='c:\\temp\\temp02.sav' /KEEP=varx sch.
+ END LOOP.
+ END LOOP.
END IF.
EXECUTE.
SORT CASES BY school dollar2.
MATCH FILES FILE=* /DROP=varx sch.
MATCH FILES FILE=* /FILE='c:\\temp\\temp02.sav' 
 /RENAME= (varx=dollar2) (sch=school) /BY school dollar2.
EXECUTE.

DO IF MISSING(nbcases).
COMPUTE totcases=1.
COMPUTE nbcases=1E-30.
END IF.
COMPUTE pc=nbcases/totcases.

SORT CASES BY school .
SPLIT FILE LAYERED BY school .
FORMATS pc(PCT8.1).
GRAPH
  /TITLE='Method 2, empty bars are printed'
  /BAR(SIMPLE)=VALUE ( pc ) BY dollar2 .