* Вопрос. * Я знаю, как построить гистограммы для каждого из двух вузов с количеством студентов по оси Y и долларами по оси X (единица анализа - студент, а переменная интереса - доллар). * Мне нужно иметь процент студентов по оси Y вместо абсолютных частот. Я могу сделать это в другой программе, но, думаю, и в SPSS есть такая возможность. * Ответ. * Следующий (очень полезный) макрос поможет нам и в этом случае. * Автор: rlevesque@videotron.ca. * Идея приведённого синтаксиса в том, что вместо гистограммы строится столбцовая диаграмма (Bar Chart) со сконструированными определённым образом категориями. Таким образом, результирующий график напоминает гистограмму с процентами по оси Y - А.Б.. * NB! В "современных" версиях SPSS (например, 13 версия), проблема, указанная в вопросе, может быть решена с помощью интерактивных графиков (см. пример синтаксиса в конце файла). Если стоит отдельная задача создать интервалы для числовой переменной (что и делает макрос в этом файле), это удобно делать с помощью новой опции Visual Bander - А.Б. *///////////////////////////////////////////////////////. DEFINE !label (vname=!TOKENS(1) /vcoded=!TOKENS(1) /begr=!TOKENS(1) /endr=!TOKENS(1) /nbbins=!TOKENS(1)) * Загражаем данные, после чего запускаем этот макрос. * vname = имя переменной, которую перекодируем. * vcoded = имя переменной, которая будет содержать результат перекодировки. * begr = начало первого интервала. * endr = конец первого интервала (4 означает 4.99999...). * nbbins = количество столбцов на гистограмме. * nbbins, begr и endr должны быть целыми значениями. * Автор: 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). * создаём файл синтаксиса для перекодировки значений. 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. * пишем синтаксис для определения меток значений. 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. *\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\. * Сгенерируем данные для демонстрации работы решения. INPUT PROGRAM. SET SEED=9876531. LOOP school=1 TO 2. LEAVE school. LOOP id=1 TO school*50. COMPUTE dollars=7000+UNIFORM( 10000). * следующая строка создаёт "пробел" (пустой столбец) в данных для демонстрации возможной проблемы и возможного решения. IF RANGE(dollars,11999,13001) dollars=dollars-1000. END CASE. END LOOP. END LOOP. END FILE. END INPUT PROGRAM. * осуществляем перекодировку значений и помечаем новые коды. !label vname=dollars vcoded=dollar2 begr=7000 endr=7999 nbbins=11. SORT CASES BY school . SPLIT FILE LAYERED BY school . * Метод 1. GRAPH /TITLE='Метод 1, пустые столбцы не печатаются' /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. * Заполняем "пропуски" таким образом, чтобы столбцы выводились на график даже если они пустые. 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='Метод 2, пустые столбцы печатаются' /BAR(SIMPLE)=VALUE( pc ) BY dollar2 . * В версии 13 SPSS такая задача может быть решена непосредственно без помощи макросов через меню интерактивных графиков: IGRAPH /VIEWNAME='Histogram' /X1 = VAR(dollars) TYPE = SCALE /Y = $pct /COORDINATE = VERTICAL /PANEL VAR(school) /X1LENGTH=3.0 /YLENGTH=3.0 /X2LENGTH=3.0 /CATORDER VAR(school) (ASCENDING VALUES OMITEMPTY) /Histogram SHAPE = HISTOGRAM CURVE = OFF X1INTERVAL AUTO X1START = 0.