SET MPRINT=ON.
* Сгенерируем данные для примера.
NEW file.
input program.
set seed=987654321.
loop casenum=1 to 100.
compute draw=uniform(100).
compute class1=rnd(uniform(1)).
end case.
end loop.
end file.
end input program.
execute.
* Допустим, нам нужно найти границы децилей (делящих ряд значений переменной на 10 равных частей) по переменной
* draw на основе наблюдений, для которых class1=0. А затем - определить, в какой из 10 интервалов попадают значения
* draw для всех наблюдений (в т.ч. и для тех, для которых class1=1).
* Автор: Raynald Levesque.
*Важно заблаговременно создать вспомогательную переменную в главном файле данных.
COMPUTE dummy=1.
SAVE OUTFILE='c:\\temp\\temp.sav'.
SELECT IF class1=0.
SORT CASES BY draw.
* Нумеруем наблюдения и считаем их количество.
COMPUTE nb=$casenum.
RANK draw /n INTO n.
* В следующей строке замените число 10 на нужно число интервалов (если нужны не децили, а другие интервалы).
COMPUTE #delta=n/(10-.0001).
* Следующие 2 команды вычисляют границы децилей.
COMPUTE flag=TRUNC(nb/#delta).
AGGREGATE
/OUTFILE=*
/BREAK=flag
/cut_off = FIRST(draw).
* Приготовим граничные значения децилей для слияния с основным файлом.
FLIP
VARIABLES=cut_off.
COMPUTE dummy=1.
SAVE OUTFILE='c:\\temp\\cutoff points.sav'.
* Сольём файл граничных значений с главным файлом.
GET FILE='c:\\temp\\temp.sav'.
MATCH FILES /FILE=*
/TABLE='c:\\temp\\cutoff points.sav'
/BY dummy.
DEFINE !rank_it (vname=!TOKENS(1)
/nb_bins=!TOKENS(1))
VECTOR cutoff=var001 TO !CONCAT('var',!nb_bins).
COMPUTE rank1=1.
LOOP #cnt=2 TO !nb_bins.
COMPUTE rank1=rank1 + (!vname>cutoff(#cnt)).
END LOOP.
EXECUTE.
!ENDDEFINE.
* Примеч.: при вызове макроса аргумент nb_bins должен быть трёхсимвольным, например, не 5, а 005, не 15, а 015 и т.д.
!rank_it vname=draw nb_bins=010 .