Когда следует использовать EXECUTE
?
Понимание этого вопроса и ответа может сэкономить для вас много времени. Эти сообщения были помещены в SPSSX-L 2 апреля 1999 года (David Matheson, техническая поддержка SPSS)
Вопрос
Я выполняю различные преобразования данных в SPSS. Очень был удивлён, узнав, что получение корректных результатов может требовать помещения командыEXECUTE
между командами преобразований данных. Вот один из моих синтаксисов:1 2 3 4 5 | DATA LIST FILE '/tmp/ret.dat' FIXED /da 1-15 w 19-20 . COMPUTE RETURN = da-LAG(da). COMPUTE sv =(w<=1 or w>=5). SELECT IF (sv=0). LIST. |
Результаты для переменной RETURN в некоторых случаях были некорректны. Корректные результаты были получены, когда между строками 2 (Compute RETURN…
) и 4 (SELECT IF…
) была помещена команда EXECUTE
. Есть какие-то общие правила, устанавливающие регламент использования команды EXECUTE
?
Ответ
Правильным в данном примере было бы поместитьEXECUTE
перед SELECT IF
. (В данном конкретном случае помещение EXECUTE
между двумя командами COMPUTE
тоже бы сработало) Иначе, когда вы считаете RETURN как DA - LAG(DA)
для конкретного наблюдения, наблюдение, вначале предшествовавшее текущему наблюдению, может быть уже исключено из файла и LAG(DA)
может ссылаться на значение DA не из нужного вам наблюдения.Для дальнейшей иллюстрации использования команды EXECUTE
между командами трансформации, рассмотрим 3 последовательных наблюдения с ID 1, 2 и 3. Предположим, мы хотим сохранить, или убрать наблюдение с ID = 2 в зависимости от результата его сравнения с наблюдением 1. Аналогично нам нужно будет сравнить наблюдение 3 с наблюдением 2 и сохранить или выбросить 3 в результате. Предположим, что наблюдение 2 было выкинуто по результатам сравнения, но наблюдение 3 прошло бы тест в сравнении с наблюдением 2 таким образом, что 3 следовало бы в результате сохранить. Без команды EXECUTE
(или другой команды, инициирующей «проход» по всем данным) перед SELECT IF
, наблюдение 2 будет оценено и выкинуто перед тем, как будет оценено наблюдение 3. В результате наблюдение 3 будет сравниваться с «предыдущим» наблюдением, которым в данном случае будет наблюдение 1 и будет сохранено или выкинуто уже в результате неверного сравнения. Помещение EXECUTE
перед SELECT IF
гарантирует наличие всех наблюдений для функции LAG
. Но, разумеется, мы можем себе представить и такую процедуру сравнения, при которой последующее наблюдение сравнивается с последним из предыдущих наблюдений, успешно прошедших такое же сравнение. В таком случае мы должны будем убрать EXECUTE
, чтобы достичь нужного результата.
Аналогичная ситуация возникает когда наблюдения отбираются по порядковому номеру в файле данных. Допустим, нам нужно отобрать каждое пятое наблюдение, и мы используем следующий синтаксис:
1 2 3 4 | compute seq = $casenum. select if (mod(seq,5) = 0). frequencies x. * функция mod возвращает остаток от деления первого числа на второе. |
У вас не будет ни одного наблюдения для построения частотной таблицы. Первому наблюдению будет присвоено значение 1 в переменной seq, поскольку значение системной переменной $casenum для него будет равно 1. (mod(seq,5)=0)
вернёт «False» и наблюдение будет удалено. Второе наблюдение теперь стало первым и будет удалено тем же манером (теперь для него $casenum = 1, seq = 1). То же самое случится и с тем наблюдением, которое изначально было пятым, десятым и т.д. А вот следующий синтаксис будет работать:
1 2 3 4 | compute seq = $casenum. execute. select if (mod(seq,5) = 0). frequencies x. |
Добавление EXECUTE
перед SELECT
обеспечивает корректность вычисления seq перед тем, как наблюдения начнут удаляться.
Если имеется серия команд преобразований (COMPUTE, IF
, и т.д.), за которыми следует команда MISSING VALUES
(задание кодов пропущенных значений), затрагивающая те же переменные, что и команды преобразования, может потребоваться использование команды EXECUTE
перед MISSING VALUES
. Ведь MISSING VALUES
изменяет словарь данных немедленно, до прохода по данным, то есть до того, как преобразования будут иметь место. Например, рассмотрим:
1 2 | IF (x = 0) y = z*2. MISSING VALUES x (0). |
Наблюдения, где x=0
будут рассматриваться как пропущенные и переменная y не будет изменена. Помещение EXECUTE
перед MISSING VALUES
принудит SPSS выполнить вычисления до того, как 0 для переменной x получит статус пропущенного значения.
Команда EXECUTE
часто необходима, если вы используете команду WRITE
для записи данных в ASCII-файл, или если используете команду XSAVE
вместо SAVE
, для сохранения данных в .sav-файл. Команды WRITE
и XSAVE
имеют тот же статус, что и COMPUTE
(при их интерпретации процессор SPSS помещает их в список отложенных вычислений). Если ваша программа оканчивается командами WRITE
или XSAVE
без процедур, вызывающих проход по данным, файл, в который вы хотите записать, окажется пустым. Если же WRITE
или XSAVE
являются частью циклов LOOP
или DO IF
, команду EXECUTE
использовать не надо (и нельзя).
Также, если за командами WRITE
или XSAVE
будет следовать статистическая процедура, данные будут записаны в новый файл.
Наконец, если вы задали серию вычислительно нагруженных преобразований и получаете сообщения о нехватке памяти когда SPSS пытается их отработать, вы можете поместить несколько команд EXECUTE
вразбивку по коду, чтобы принудить SPSS пройти по данным и освободить память для следующей группы преобразований.Не помещайте EXECUTE
внутрь структур трансформации данных, таких, как LOOP...END LOOP
, DO IF...END IF
, или DO REPEAT...END REPEAT
. Также не помещайте EXECUTE
между командами, которые создают временные (scratch) переменные и теми командами, которые их потом используют. Если за набором крупных преобразований у вас стоит вычислительно тяжелая команда, как, например, CLUSTER
или MANOVA
, вы можете поместить EXECUTE
перед статистической процедурой. Хотя процедура и сама провела бы все преобразования, помещение EXECUTE
перед ней позволит немного разгрузить память перед ее выполнением.
Это лишь примеры случаев, когда команду EXECUTE
следует поместить между или после команд преобразований. Помещение EXECUTE
после каждой команды COMPUTE
почти всегда будет вычислительно неэффективным (в лучшем случае), или приведет к неработоспособности (в худшем), как, например, если поместить EXECUTE
внутрь конструкций LOOP
или DO IF
.
...