Использование векторной (индексной) адресации переменных:
команда VECTOR
В прошлом выпуске рассылки нам встретилась команда VECTOR, которую
мы использовали для того, чтобы упростить работу с 12 переменными, последовательно
располагающимися в файле данных. Разберём сегодня более подробно приёмы и особенности
работы с этой командой.
Вектором в командном языке SPSS является последовательность переменных,
ассоциированная с именем вектора (например, vecvar), на которые можно ссылаться
с помощью индекса (например, vecvar(1), vecvar(2) и т.д.). Такой способ ссылок
на переменные удобен, когда нужно произвести ряд однотипных преобразований с
большим числом переменных, либо осуществить специфические условные вычисления.
И тот, и другой способ мы позже рассмотрим в примерах синтаксиса.
Вызов команды VECTOR возможен в двух основных вариантах: определение
и одновременная ссылка на новые векторные переменные, а также ссылка на уже
существующие переменные.
Первый вариант
VECTOR myvec (3, F4.0).
Команда создаёт 3 переменных c именами myvec1, myvec2, myvec3
числового формата с 4 знаками без отображения знака после запятой. При этом
одновременно в памяти создаётся вектор myvec, первая компонента которого (myvec(1))
ассоциирована с переменной myvec1, вторая - c myvec2, третья - с myvec3.
Как это часто случается в SPSS, в написании синтаксиса существует
некоторая "гибкость". Так, следующие варианты написания команды VECTOR
дали бы аналогичные результаты:
VECTOR myvec (3F4.0).
VECTOR myvec (F4.0, 3).
При необходимости можно определять одновременно несколько векторных
переменных одной и той же размерности. Например:
VECTOR myvec newvec (3F4.0).
Команда создаст 6 переменных (myvec1-myvec3 и newvec1-newvec3)
и 2 соответствующих вектора.
Второй вариант
Если вы желаете определить вектор на основе уже существующих переменных
(допустим, в вашем файле данных имеются переменные aaa1, aaa2, aaa3 и вы хотите
адресовать их в цикле LOOP как vecvar(1), vecvar(2), vecvar(3)), следует вызвать
команду VECTOR в ином виде:
VECTOR vecvar=aaa1 TO aaa3.
Обратите внимание, что в подобном вызове всегда должно присутствовать
ключевое слово TO.
Если требуется за раз определить несколько векторов, их имена
разделяются "слэшем":
VECTOR vecvar=aaa1 TO aaa3 / newvec=bbb1 TO bbb2.
С помощью второго варианта определения векторов можно осуществлять
индексную адресацию для переменных, которые хоть и не имеют в конце своего имени
номеров, но расположены последовательно в файле данных. Например, если переменных
a, b, x, c расположены в файле друг за другом, команда
VECTOR myvec = a TO c.
определит вектор с четырьмя компонентами, причем ссылка myvec(3),
например, будет указывать на переменную x.
К сожалению, концевая нумерация переменных при работе с векторами
даёт преимущество лишь в наглядности отображения данных. Так, если переменные-компоненты
одного вектора будут "раскиданы" по файлу данных, например, bbb1,
a, bbb2, c, bbb3, то команда
VECTOR myvec = bbb1 TO bbb3.
определит 5-компонентный вектор (bbb1, a, bbb2, c, bbb3) вместо
желаемого (bbb1, bbb2, bbb3).
Определение "временных" (scratch) векторных
переменных
Порой нет нужды создавать векторные переменные в явном виде. Иногда
можно использовать scratch-вектора, которые содержатся лишь в памяти ЭВМ и не
записываются в файл данных. Такие переменные задаются в командном языке SPSS
с префиксом "#". Например:
VECTOR #myvec (10).
Создаст в памяти 10 временных переменных с именами #myvec1 - #myvec10.
В редакторе данных изменения заметны не будут.
Вычисления с временными переменными не отличаются от вычислений
с обычными переменными. Например, небольшой синтаксис
VECTOR #myvec(10).
COMPUTE #myvec(1) = $casenum.
COMPUTE #myvec(2) = #myvec(1)*10.
COMPUTE result = #myvec(2).
EXE.
запишет в "реальную" переменную result результат вычислений,
произведённых с помощью временных векторных переменных. А именно - result будет
содержать "табулированный" (умноженный на 10) порядковый номер наблюдения.
Здесь, кстати, используется специальная системная переменная $casenum с префиксом
"$", которая означает текущий номер наблюдения в файле данных.
"Время жизни" векторов
Существенным моментом, который нужно учитывать при работе с векторами,
является тот, что раз определённый вектор понимается системой SPSS как таковой
до момента первого "прохождения данных" (выполнения построчных вычислений,
вызываемых командой EXECUTE или иной процедурой, выполняющей отложенные вычисления).
Подчеркнём, что после вычислений с вектором, определённым на основе существующих
переменных, сами переменные никуда не исчезнут, однако система перестанет "понимать"
векторную запись в отношении этих переменных. Поясним это на примере. Определим
вектор myvec на основе существующих переменных aaa1-aaa3. И произведём вычисления.
VECTOR myvec=aaa1 TO aaa3.
LOOP #i=1 TO 3.
COMPUTE myvec(#i)=#i.
END LOOP.
EXECUTE.
LOOP #i=1 TO 3.
COMPUTE myvec(#i)=myvec(#i)-#i.
END LOOP.
EXECUTE.
При выполнении второго цикла LOOP SPSS сообщит об ошибке, т.к.
после серии вычислений, вызванных первой командой EXECUTE, вектор myvec более
не существует (переменные aaa1-aaa3, однако же, никуда не пропали!). Вариант
решения этой проблемы - либо заново определить вектор, либо убрать первую команду
EXECUTE. Результаты будут аналогичны.
К векторам, определённым на основе "временных" переменных,
относятся те же правила. Однако здесь вместе с уничтожением самой структуры
вектора после вычислений пропадают и временные переменные-компоненты, которые
в него входили.
Индекс из данных
Традиционно векторные переменные используются внутри циклов, поскольку
именно они позволяют осуществлять пробегание индекса по всем компонентам вектора.
Особым вариантом использования векторов является выбор индекса
из существующих значений других переменных. В этом случае происходит что-то
вроде условного вычисления.
Рассмотрим пример.
DATA LIST FREE /x.
BEGIN DATA
1 2 3 4
END DATA.
VECTOR diag(4).
COMPUTE diag(x)=x.
EXE.
Данный синтаксис определяет 4 наблюдения переменной x, а затем
выстраивает их по "главной диагонали" в 4 переменные diag1-diag4.
Далее рассмотрим примеры использования векторных переменных в
файлах синтаксиса на сайте www.spsstools.ru.
Здесь два вектора time и gluc определяются на основе существующих
переменных и затем используются в циклах для расчета "дельта" при
интегрировании. Например, "time(#k) - time(#k -1)", где #k - временная
индексная переменная в цикле LOOP.
Этот синтаксис разбирался в предыдущем выпуске рассылки. С помощью
команд
VECTOR var(12).
COMPUTE var((varn-1)*3+ctr)=rk.
мы "раскидываем" по 12 переменным сгенерированные ранее
значения из столбца rk таким образом, чтобы заполнить последовательно каждую
из 4 триад переменных. Обратите внимание, что индекс для адресации вектора берётся
в данном случае из данных.
Оригинальный пример использования векторов содержится и в данном
синтаксисе. Мы определяем 4-компонентный вектор cell и заполняем его значения
единицами таким образом, что первая компонента содержит единицу для тех наблюдений,
где переменные x и y равны 0, вторая компонента - единицу для наблюдений, где
x равно 0, а y - единице и т.д.