* (Вопрос) Нужно найти все сочетания 1, 2, ..., n объектов из m объектов. * (Ответ) Автор: rlevesque@videotron.ca, 30.08.2001; Сайт, посвящённый SPSS: http://www.spsstools.net. * Заметка: Это достаточно сложный синтаксис, который, впрочем, очень прост в использовании. Макрос n раз создаёт новый файл синтаксиса, который записывает сочетания в текстовый файл. Затем этот файл читается в редактор данных SPSS и используется для создания полного списка сочетаний. * См. пример использования в конце. SET MPRINT=no. */////////////////////////////. DEFINE !combine (n=!TOKENS(1) /items=!CMDEND). /* Ищем все сочетания 1,2, ... n объектов из m объектов*/ /* 30 августа 2001 года, rlevesque@videotron.ca */ * Считаем количество переданных переменных. !LET !nb=!NULL !DO !cnt !IN (!items) !LET !nb=!CONCAT(!nb,!BLANK(1)) !DOEND !LET !m=!LENGTH(!nb) !DO !thisn=1 !TO !n NEW FILE. INPUT PROGRAM. LOOP i=1 TO !thisn. END CASE. END LOOP. END FILE. END INPUT PROGRAM. LIST. !LET !list=!NULL !DO !cnt=1 !TO !thisn !LET !list=!CONCAT(!list," ","j",!cnt) !DOEND COMPUTE n=!thisn. * Получим имена переменных для цикла 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 - !thisn + 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=!thisn. + WRITE OUTFILE "c:\\temp\\macro.sps" /"WRITE OUTFILE "quote"c:\\temp\\list.txt"quote "/" strlist "." . + LOOP cnt=1 TO !thisn. + 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". /* Конвертируем данные из файла list.txt в соответствующий .sav файл */. DATA LIST FILE='c:\\temp\\list.txt' LIST /!list. SAVE OUTFILE=!QUOTE(!CONCAT('c:\\temp\\list',!thisn,'.sav')). !DOEND /* Собираем все .sav-файлы в один */. GET FILE='c:\\temp\\list1.sav'. !DO !nb=2 !TO !n. ADD FILES FILE=* /FILE=!QUOTE(!CONCAT('c:\\temp\\list',!nb,'.sav.')). !DOEND /* Убираем дубликаты */. 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. EXECUTE. !ENDDEFINE. *////////////////////////////. *************************. * Примеры использования. *************************. SET MPRINT=yes. !combine n=5 items=educ jobcat jobtime prevexp minority. * Example 2. !combine n=3 items=a b c d e f g.