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
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 .