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
* (Вопрос) Найти все сочетания по n объектов из m объектов.

* (Ответ) Автор: rlevesque@videotron.ca, 11.09.2001;
	См. веб-сайт, посвящённый SPSS: http://www.spsstoolsnet.

* Замечание: это сложный синтаксис, который, впрочем, прост в использовании. Смотри пример в конце.
*	Макрос (combine) создаёт файл синтаксиса, который затем пишет сочетания в текстовый файл. Затем текстовый файл читается в редактор данных и используется для построения всех сочетаний.


SET MPRINT=no.

*/////////////////////////////.
DEFINE !combine (n=!TOKENS(1) 
	/items=!CMDEND).

/* Найти все сочетания по n объектов из m объектов*/
/* 11 сентября 2001, rlevesque@videotron.ca */

* Считаем число переданных переменных.
!LET !nb=!NULL
!DO !cnt !IN (!items)
!LET !nb=!CONCAT(!nb,!BLANK(1))
!DOEND
!LET !m=!LENGTH(!nb)



NEW FILE.
INPUT PROGRAM.
LOOP i=1 TO !n.
END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
LIST.

!LET !list=!NULL
!DO !cnt=1 !TO !n
	!LET !list=!CONCAT(!list," ","j",!cnt)
!DOEND

COMPUTE n=!n.

* Получим имена переменных для цикла  LOOP в команде WRITE ниже *.
STRING cntname cntbeg(A8).

COMPUTE cntname=CONCAT('j',LTRIM(STRING(i,F8.0))).

* Получим первый параметр цикла LOOP в команде WRITE ниже *.
DO IF i=1.
COMPUTE cntbeg="1".
ELSE.
COMPUTE cntbeg=CONCAT('j',LTRIM(STRING(i-1,F8.0))," + 1").
END IF.

* Получим второй параметр цикла LOOP в команде WRITE ниже *.
COMPUTE k=!m - !n + i.
FORMATS i k n(F8.0).

STRING quote(A1) strlist(A255).
COMPUTE quote='"'.
COMPUTE strlist=!QUOTE(!list).

* Создадим файл синтаксиса, который затем запишет сочетания в текстовый файл list.txt*.
WRITE OUTFILE "c:\\temp\\macro.sps" 
	/"LOOP "cntname"="cntbeg" TO "k".".
DO IF i=!n.
+	WRITE OUTFILE "c:\\temp\\macro.sps" 
	/"WRITE OUTFILE "quote"c:\\temp\\list.txt"quote "/" strlist "." .
+	LOOP cnt=1 TO !n.
+		WRITE OUTFILE "c:\\temp\\macro.sps" /"END LOOP.".
+	END LOOP.
+	WRITE OUTFILE "c:\\temp\\macro.sps" /"EXECUTE.". 
END IF.
EXECUTE.
INCLUDE FILE="c:\\temp\\macro.sps".

/* Загружаем текстовый файл в редактор данных - получаем файл .sav */.
DATA LIST FILE='c:\\temp\\list.txt' LIST /!list.
SAVE OUTFILE='c:\\temp\\list1.sav'.

/* Убираем дубликаты  */.
SORT CASES BY ALL.
MATCH FILES FILE=* /BY=ALL /FIRST=first.
SELECT IF first.
SAVE OUTFILE='c:\\temp\\all combinations.sav'.

/* Извлекаем название последнего из переданных объектов */
!DO !var !IN (!items)
!LET !lastone=!var
!DOEND

VECTOR vnames(!m A8).
!LET !cnt=!BLANK(1)

/* Создаём переменные, содержащие названия переданных объектов */
!DO !var !IN (!items)
COMPUTE vnames(!LEN(!cnt))=!QUOTE(!var).
!LET !cnt=!CONCAT(!cnt,!BLANK(1))
!DOEND

/* Создаём строковую переменную, содержащую сочетания */.
STRING items(A255).
VECTOR j=j1 TO !CONCAT('j',!n) /ind=vnames1 TO  !CONCAT('vnames',!m).
COMPUTE nvar=NVALID(j1 TO !CONCAT('j',!n)).
LOOP cnt=1 TO nvar.
+	COMPUTE items=CONCAT(RTRIM(items)," ",vnames(j(cnt))).
END LOOP.

* Запишем файл синтаксиса, который будет вызывать макрос для каждого сочетания объектов.
WRITE OUTFILE='c:\\temp\\mymacro.sps' /'!kendal 'items'.'.
EXECUTE.

!ENDDEFINE.
*////////////////////////////.


*////////////////////////////.
DEFINE !kendal (!POS=!CMDEND)
NPAR TESTS
  /KENDALL = !1
  /MISSING LISTWISE.
!ENDDEFINE.
*////////////////////////////.


*************************.
* Пример использования.
*************************.

SET MPRINT=yes.
* Создадим файл синтаксиса, который будет рассчитывать корреляции Кендала для каждой пары из следующих переменных.
!combine n=2 items=educ jobcat jobtime prevexp minority.

GET FILE='c:\\program files\\spss\\employee data.sav'.
*** Следующая команда выполнит нужные действия ***.
INCLUDE FILE='c:\\temp\\mymacro.sps'.

****** Конец синтаксиса ******.

*********************.
* Комментарии по поводу примера выше.
*********************.

Всё, что нужно сделать - заменить в строке
!combine n=2 items=educ jobcat jobtime prevexp minority.
список переменных на нужные вам переменные, а затем заменить строку 

GET FILE='c:\\program files\\spss\\employee data.sav'.
на ту, которая загрузит ваш файл данных.

Остальное будет сделано автоматически. Если у вас есть 50 переменных, которые нужно скомбинировать, ввести их в строку вызова макроса не очень сложно. Если же есть сотни последовательно поименованных переменных, можете использовать синтаксис "Задать список переменных указанием первой и последней переменной.SPS " , расположенный в разделе "Макросы: избранное" моего сайта. С этим макросом вам нужно будет задать лишь имя первой и последней переменной в списке.