Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Статистика в SPSS: за пределами кнопочного интерфейса. Выпуск 43


В рассылке используются материалы веб-сайта www.spsstools.ru

3.11.2006

Содержание выпуска

Дополнение к 41-му выпуску от 22.10.2006

Новое на сайте www.spsstools.ru

 

Здравствуйте, уважаемые подписчики!

С наступающим/наступившим вас праздником! Сегодня вашему вниманию предлагается праздничное дополнение к 41-му выпуску рассылки, посвящённое временным переменным.

 

Дополнение к 41-му выпуску от 22.10.2006

В 41-м выпуске рассылки мы коснулись некоторых вопросов работы с временными (scratch) переменными. Мы отметили, что они являются эффективным вспомогательным средством разработки программ на синтаксисе SPSS, поскольку не записываются в файл данных и исчезают после завершения преобразований проходом по данным. По этой причине, например, часто временные переменные используются в качестве индексов в циклах. Для этой цели можно использовать и постоянные переменные, но в последнем случае после преобразований в файле данных у вас появится лишний(е) столбец(цы), содержащий(е) последнее(ие) значение(я) индексной(ых) переменной(ых) для каждого наблюдения. Простейший пример:

 

COMPUTE a=1.

LOOP i=1 to 10.
- COMPUTE a=a*i.

END LOOP.

 

запишет для каждого наблюдения в переменную a значение 10! (10-факториал), равное 3628800. Но, вместе с этим, ненужная, вообще говоря, переменная i будет содержать для каждого наблюдения число 11, т.е. последнее значение индекса, вышедшее за верхнюю границу (для данного значения цикл уже не выполнялся).

Использование временного аналога переменной i (например, #i) приведёт к тем же результатам, но без появления лишней переменной в файле (будете пробовать - не забудьте удалить старые переменные i и a из файла):

 

COMPUTE a=1.

LOOP #i=1 to 10.
- COMPUTE a=a*#i.

END LOOP.

 

Если говорить об индексных переменных в цикле LOOP, то на этом различия между временными и постоянными переменными обычно заканчиваются. Временные переменные не подвергаются реинициализации при переходе к следующему наблюдению, но это никак не влияет на работу LOOP, поскольку этот цикл всегда выполняется лишь в рамках одного и того же наблюдения. Из этого правила, однако же, есть исключение, на которое мне недавно любезно указали в форуме SPSSX-L (см. исходное сообщение здесь; Автор сообщения: Richard Ristow).

В том случае, если цикл LOOP помещается внутри процедуры чтения данных (INPUT PROGRAM), конец очередного наблюдения (инструкция END CASE) может находиться внутри цикла LOOP. В некоторых случаях это приведёт к разным результатам, в зависимости от того, используем ли мы постоянные, или временные переменные в качестве индекса. Сравните два варианта:

 

первый...

INPUT PROGRAM.

LOOP i=1 to 10.

- LOOP j=1 to 20.
- COMPUTE a=i*j.
- END CASE.

- END LOOP.

END LOOP.

END FILE.

END INPUT PROGRAM.

EXECUTE.

 

...и второй...

INPUT PROGRAM.

LOOP #i=1 to 10.

- LOOP #j=1 to 20.
- COMPUTE a=#i*#j.
- END CASE.

- END LOOP.

END LOOP.

END FILE.

END INPUT PROGRAM.

EXECUTE.

 

Первый вариант, как будто, не даёт тех результатов, которые мы от него ожидали. Это связано с тем, что внутри второго (вложенного) цикла LOOP стоит инструкция перехода к следующему наблюдению, в результате чего происходит реинициализация всех переменных. Переменной j, как индексу второго цикла, присваивается очередное значение, но переменная i, поскольку возвращения в первый цикл не происходит, инициализируется в системное пропущенное значение (SYSMIS), что и объясняет получаемый результат. Сбоя в исполнении внешнего цикла всё же не происходит, так как, вероятно, за "видимой" переменной "i" скрывается её второе "я" в форме системной переменной - счётчика цикла (подробнее об этом можно почитать в одном из сообщений (и связанных с ним сообщениях) того же форума SPSSX-L).

Второй пример сработал отлично, поскольку индексные переменные в данном случае реинициализации не подвергаются и сохраняют свои значения до следующего обновления.

К слову, первый вариант программы (с постоянными переменными) можно легко исправить, добавив инструкцию LEAVE, подавляющую реинициализацию отдельных переменных:

 

INPUT PROGRAM.

LOOP i=1 to 10.

- LEAVE i.

- LOOP j=1 to 20.
- COMPUTE a=i*j.
- END CASE.

- END LOOP.

END LOOP.

END FILE.

END INPUT PROGRAM.

EXECUTE.

 

Всего доброго!

Ведущий рассылки,

Балабанов Антон


Новое на сайте www.spsstools.ru

Переведены и добавлены примеры синтаксиса (страница http://www.spsstools.ru/SampleSyntax.htm#ReadWriteOrCreateData)

Пример работы DATA LIST.SPS

Пример работы INPUT PROGRAM.SPS

Прочесть данные с разным числом записей на одно наблюдение.SPS

Прочесть файл ASCII (значения каждой переменной собраны в 5 строк шириной в 10 колонок).SPS

Прочесть файл ASCII с использованием FILE TYPE.SPS

Прочесть файл ASCII с использованием INPUT PROGRAM.SPS

Прочесть файл ASCII с косой чертой в качестве разделителя.SPS

 

© См. www.spsstools.ru, 2005-2006


В избранное