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
* Автоматизированное преобразование данных из "высокой" таблицы в "широкую".

* ВОПРОС: имеется набор данных, похожий по структуре на тот, что представлен в команде DATA LIST
  ниже. Необходимо сделать так, чтобы в данных приходилось одно наблюдение на одно уникальное значение var1.
* Поскольку максимальное число уникальных категорий для переменной var1 всякий раз будет разным, 
* хотелось бы иметь синтаксис, самостоятельно адаптирующийся к этой особенности.

* ОТВЕТ: размещён в новостной группе 23.06.2001, автор: rlevesque@videotron.ca.

DATA LIST LIST /var1(A1) var2(F8.0).
BEGIN DATA
A    1
A    7
A    32
A    5
B    9
C    34
C    9
D    3
D    7
D    0
D    1
END DATA.
LIST.
AUTORECODE VARIABLES=var1 /INTO var1num.
SAVE OUTFILE='c:\\temp\\mydata.sav'.

** Надо будет определить макрос, содержащий число необходимых колонок **.
SET MPRINT=no.

AGGREGATE
  /OUTFILE=*
  /BREAK=var1num
  /n = N(var1num).

COMPUTE nobreak=1.
AGGREGATE
  /OUTFILE=*
  /BREAK=nobreak
  /n = MAX(n).

* Определяем этот макрос.
DO IF $CASENUM=1.
WRITE OUTFILE='c:\\temp\\define n.sps' /'DEFINE !n()'n'!ENDDEFINE.'.
END IF.
EXECUTE.
INCLUDE FILE='c:\\temp\\define n.sps'.

** Теперь определим макрос, который выполнит само преобразование **.

*/////////////////////////.
DEFINE !doit(!POS=!TOKENS(1))

COMPUTE casen=$CASENUM.
RANK
  VARIABLES=casen  (A) BY !1  /RANK /PRINT=NO.
VECTOR vec(!n F8.0).
COMPUTE vec(rcasen)=var2.
AGGREGATE
  /OUTFILE=*
  /BREAK=var1
  /vec1 TO !CONCAT(vec,!n) = MAX(vec1 TO !CONCAT(vec,!n)).
!ENDDEFINE.
*/////////////////////////.

GET FILE='c:\\temp\\mydata.sav'.

* Осуществим преобразование.
SET MPRINT=yes.
!doit var1num.