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
Тема: Re: Я в ступоре
Дата: 02.10.1997
Автор: David Mark Marso <marso@spss.com>

Martin Lee пишет:

Я пытаюсь написать процедуру, которая бы проходила по числовым переменным, именованным в стиле a1000, a1001, a1002 и т.д., брала бы 5 последовательно расположенных переменных, запускала бы синтаксис, который бы считал значения (count) и с некоторым условием (do if) создавал бы новую переменную, затем делал бы то же самое, пропустив следующие 2 переменные, и так далее, 32 раза. Я использую версию 7.5.

Я пытаюсь использовать для этого макрос, но у меня нет книжки "SPSS Macros для чайников", поэтому вот всё, что я смог:

*Введём пример данных для того, чтобы продемонстрировать работу. - А.Б.
*--------------------------.
INPUT PROGRAM.
VECTOR a (1288F2.0).
LOOP #i=1 to 10.
- LOOP #j=1 to 225.
-   COMPUTE a(1063+#j)=TRUNC(UNIFORM(100)).
- END LOOP.
- END CASE.
END LOOP.
END FILE.
END INPUT PROGRAM.
EXECUTE.
*Удаление лишних переменных потребует некоторого времени.
DELETE VARIABLES a1 to a1063.
*--------------------------Далее следует текст письма -А.Б.

                
> *Макрос для подсчёта dmft в DMDS в базах p15 и p18.
> 1 DEFINE dmftmac  (c1start = !TOKENS(1)
> 2  /c1end = !TOKENS(1)).
> 3 !DO !idx = c1start !TO c1end !BY 7.
> 4  !LET !a = !CONCAT(a,!idx).
> 5  !LET !b = !CONCAT(a,!idx + 4).
> 6  count #(!idx)= !a to !b (1 thru 5).
>    do if (#(!idx) gt 0).
>    compute t(!idx)=1.
>    else.
>    if (#(!idx) eq 0)t(!idx)=0.
>    end if.
>  !DOEND.
> !ENDDEFINE.
>
> dmftmac 1064 1281 .
> exec.

К сожалению, программе не нравится сложение в строке номер 5 (это я добавил номера) и она говорит, что сложение не выполнено. Очень жаль, поскольку это то немногое, что я смог придумать в моём случае.

Есть ли решение? Буду действительно очень признателен.

Martin Lee
Стоматолог в общественной клинике
Healthlink South
Christchurch, New Zealand
leem1@hsl.co.nz


* Тут не нужен макрос *
* Вот непротестированная, но методологически верная программка, использующая старый добрый синтаксис. (исправления внесены А.Б.).

Vector vars=a1064 to a1288.
Vector t(32).

loop #i=1 to 224 by 7.
do repeat new=XX1 XX2 XX3 XX4 XX5 / J=0 to 4.
compute new=vars(#i + J).
end repeat.

count #temp=XX1 to XX5 (1 thru 5).
*Дробных индексов здесь не возникает, так как шаг цикла равен 7. - А.Б.
compute t((#i-1)/7+1)= #temp > 0.
end loop.

На своём опыте вы убедились, что МАКРОСЫ не очень-то хорошо понимают в арифметике.
Фактически, макрос - просто обработчик строк. Если бы он ходил в школу, он провалил бы математику ;-). 
Если вам нужно сделать что-то вроде этого и вы настаиваете на решение через макросы, можете изучить макрос для вычисления канонических корреляций, который поставляется с модулем Advanced statistics.
Он симулирует умножение (m*n), беря строку длиной n и размножает эту строку m раз.
Затем, проверяя длину полученной строки mn, вы получаете результат умножения n*m, как будто макрос выполнил математическое действие (или что-то вроде этого).

Кстати.  Когда я работал в службе технической поддержки, я бы специалистом по МАКРОСАМ.  Самый первый раз я сильно загрузился тогда, когда мне попался человек, пытающийся провести в макросе математические действия. Этот вопрос заблокировал всю мою деятельность до тех пор, пока до меня не дошло, что макрос ничего не знает про математические действия! ;-)  Ну, поскольку у вас есть SPSS 7.5, вам проще задействовать скрипт для подобных вещей.

Рекомендую изучить объект SPSSInfo и его свойства (в частности, VariableAt).

*Вот скопированный пример из файла помощи*.

Dim objSpssInfo as ISpssInfo
Dim strVarName as String, strLabel as String
Set objSpssInfo = objSpssApp.SpssInfo
' Получить имена переменных и метку для переменной с именем GENDER:

Dim Count as Integer, I as Integer
Count = objSpssInfo.NumVariables
For I = 0 To Count - 1
strVarName = objSpssInfo.VariableAt(I)
        If strVarName = "gender" Then
        strLabel = objSpssInfo.VariableLabelAt(I)
        Exit For
        End If
Next