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

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


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

03.10.2006

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

ШИРОКИЙ - УЗКИЙ - ШИРОКИЙ, или один пример преобразования данных

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

 

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

Прежде, чем перейти к обсуждению темы выпуска, задам вам сразу небольшой вопрос не по теме. Сайт www.spsstools.ru пользуется бесплатным сервисом поиска от компании Atomz. Поиск корректно работает с русским языком на переведённых html-страницах, но не справляется с кириллицей в текстовых ASCII-файлах (в которых, собственно, и находится основная часть коллекции синтаксиса и скриптов). Возможно, кто-то из вас замечал это досадное обстоятельство. Я, конечно, поищу решение в специализированных источниках, но вдруг кто-то из 300 подписчиков даст дельный совет: каким ещё бесплатным сервисом можно воспользоваться, или как грамотно настроить существующий?

А теперь - к делу.

ШИРОКИЙ - УЗКИЙ - ШИРОКИЙ, или один пример преобразования данных

Разберём одну, не слишком часто возникающую, но типовую задачку преобразования данных, с которой мы можем столкнуться, например, при работе с лонгитюдными данными. Допустим, у нас есть информация о состоянии одних и тех же объектов в разные моменты (или интервалы) времени. Скажем, среднесписочное число работников разных предприятий за 1999, 2000 и 2001 годы. Либо доходы респондентов за последний месяц, собранные в ходе трёх волн исследования: в 1999, 2000 и 2001 году. Или что-нибудь в этом роде.

Традиционным способом организации таких сведений в матрице данных является сохранение всех данных об одном и том же объекте наблюдения (предприятии, респонденте) в одной строке, содержащей, кроме прочего, идентификатор данного объекта. Часто подобная организация данных получается после слияния записей из разных файлов (имеющих единую структуру, но содержащих данные на разные моменты времени) по ключу - уникальному идентификатору объекта. Назовём такой формат представления лонгитюдных данных "широким". Приведём пример "широкой" записи данных для 7 объектов на три момента времени. Отметим, что для объектов с номерами 1 и 5 данные на второй момент времени неизвестны. Итак, переменные var_99 - var_01 содержат значения одинаковых показателей в разное время.

DATA LIST LIST /id var_99 var_00 var_01.

BEGIN DATA
1 34 .   35
2 34 33 34
3 34 44 32
4 34 54 33
5 33 .   12
6 78 48 29
7 38 37 34

END DATA.

В ряде случаев (например, если требуется осуществить для этих данных подгонку многоуровневой регрессионной модели с помощью процедуры SPSS MIXED, равно как и в менее или более экзотических ситуациях) может потребоваться "растянуть" эти данные. "Растянуть" - значит сопоставить каждому объекту в каждый момент времени отдельное наблюдение (строку в файле данных). Поскольку переменные var_99 - var_01 содержат одни и те же показатели, но в разные моменты времени, нам более не потребуются все три переменные, а нужна будет лишь одна переменная var с дополнительной идентификационной переменной, которая будет говорить нам, к какому времени относится то или иное наблюдение. Такой формат мы назовём "узким". В результате преобразования данных примера в редакторе должно появиться примерно следующее:

id time var

1 1 34

1 2 .

1 3 35

2 1 34

2 2 33

2 3 34 и т.д.

Переменная time в данном случае и есть тот дополнительный идентификатор, характеризующий момент времени, к которому относится значение переменной var.

Когда подобная задача возникла в первый раз, мне показалось очень элегантным и очевидным решение с помощью команды WRITE. WRITE может записать данные из одной строки файла данных в несколько строк внешнего файла, если запросить это повторением списка переменных после знака "/". В примере ниже мы записываем данные в файл data.txt, по три строки на каждый объект, поскольку имеются данные о трёх моментах времени. Строки в подкомандах WRITE (/1, /2, /3) мы нумеруем для собственного удобства. Эти номера в файл не записываются. Между переменными id и соответствующей моменту времени переменной var мы помещаем строку вида ' i ', где i - номер момента времени. Пробелы до и после индекса мы вставляем для разделения колонок переменных. Ведь переменной id по умолчанию при записи в файл отводится 8 колонок (формат F8.2). Поскольку выравнивание идёт по правому краю, значение индекса i без пробела "прилипнет" к десятичным знакам переменной id. "Отлепить" индекс времени от id можно будет только при чтении этого файла в фиксированном формате (FIXED). Мы же стремимся ограничиться везде форматом колонок (LIST).

Команда WRITE не вызывает прохода по данным, поэтому непосредственно после выполнения нижеприведённого кода файл data.txt будет открыт и очищен, но ещё не заполнен данными. Знакомая ситуация. Нужно ли принудительно запустить проход по данным командой EXECUTE? В этом случае - да. Ведь следующей инструкцией DATA LIST мы попытаемся прочесть данные из файла в новом формате. Но эта команда заново инициализирует файл данных, что делает выполнение отложенных вычислений невозможным (команде WRITE записывать в файл будет уже нечего). Таким образом, если поставить EXECUTE только после DATA LIST, в редактор данных будет загружен пустой файл data.txt. В DATA LIST мы указываем новый набор переменных, учитывающий порядок, в котором мы записывали данные командой WRITE. После чтения данных в качестве дополнительной опции мы можем уничтожить наблюдения с пропусками по переменной var, вызвав соответствующую инструкцию SELECT IF (тильда ("~") означает отрицание, функция MISSing принимает значение истина, если её аргумент (переменная) имеет пропущенное значение (системное, либо определённое пользователем)). После этого мы помещаем второй EXECUTE чтобы увидеть результаты преобразований. Данные представлены теперь в "узком" формате.

WRITE OUTFILE='c:\temp\data.txt'
/1 id ' 1 ' var_99
/2 id ' 2 ' var_00
/3 id ' 3 ' var_01.

EXECUTE.

DATA LIST FILE='c:\temp\data.txt' LIST /id time var.

SELECT IF ~MISSING(var).

EXECUTE.

Можно ли решить обратную задачу, т.е. перейти к "широкому" формату? Рассмотрим следующий вариант, комбинирующий векторную адресацию и команду агрегирования.

Создадим вектор из трёх вспомогательных переменных (по количеству моментов времени). Запишем в них значения из переменной var, используя в качестве индекса значения time. Т.е. в переменную vars1 всегда будем записывать значение, соответствующее 1-му моменту времени, в переменную vars2 - второму и т.д. В результате колонки со вспомогательными переменными будут заполнены по диагоналям: каждое наблюдение будет давать значение одной из трёх векторных переменных. Теперь остаётся только "сплюснуть" файл данных, "обобщив" его по переменной id, т.е. вновь создав единственную строчку для отдельного объекта наблюдения. Функция FIRST вернёт нам первое непропущенное значение переменных vars1, vars2 и vars3 в каждой группе наблюдений с одним и тем же id. Нетрудно убедиться, что для каждого id есть лишь одно непропущенное наблюдение по каждой из этих переменных, так что первое наблюдение является и последним. В результате мы получим исходный файл данных. Для первого и пятого объектов значение переменной var_00 по-прежнему будет пустым.

VECTOR vars(3F8.2).

COMPUTE vars(time)=var.

AGGREGATE OUTFILE=*
/BREAK=id
/var_99 var_00 var_01=FIRST(vars1 vars2 vars3).

Рассмотренные варианты преобразования кажутся простыми, наглядными. Они ещё раз демонстрируют, как полезно владеть синтаксисом таких гибких и мощных команд, как WRITE, DATA LIST, AGGREGATE... К недостаткам этих вариантов, пожалуй, можно отнести то, что "пропускание" данных через текстовый файл не сохраняет "словарь" базы данных, т.е метки переменных и значений, а также определённые пользователем пропущенные значения и т.д. Точнее, при переходе от "широкого" к "узкому" формату теряются вообще все описания, а при переходе от "узкого" к "широкому" сохраняет свои описания (если такие были заданы) только переменная id.

Однако же, типичность этих и других схожих операций преобразования, о которой мы говорили в самом начале, привела разработчиков SPSS к созданию более удобных команд преобразований, а именно: VARSTOCASES и CASESTOVARS. Названия их говорят сами за себя. Вновь создайте командой DATA LIST исходный файл данных и выполните нижеследующий синтаксис. Команды не требуют дополнительных EXECUTE; выполняются немедленно. При этом делают всё возможное, чтобы сохранить словарь исходного файла. Так, при вызове VARSTOCASES создаваемая переменная var получает все описания первой переменной из группы, т.е. var_99, id сохраняет свои описания. Обратная команда, CASESTOVARS, также сохраняет описания для id и приписывает свойства var создаваемым переменным var.1 - var.3.

В последних версиях пакета команды VARSTOCASES и CASESTOVARS имеют графическую оболочку, доступную через меню Data - Restructure.

VARSTOCASES
/MAKE var FROM var_99 var_00 var_01
/INDEX = time(3)
/KEEP = id
/NULL = drop.

 

CASESTOVARS
/ID = id
/INDEX = time
/GROUPBY = VARIABLE.

К слову, именно такой вариант преобразования (Data - Restructure) рекомендуется в брошюре "Linear Mixed-Effects Modeling in SPSS: An Introduction to the MIXED Procedure" (SPSS Inc, 2005): http://www.spss.com/registration/index.cfm?WP_ID=127. Нет регистрации для загрузки файла? Внимательно прочтите совет по адресу http://www.spsstools.ru/FAQ.htm#FindHelp.

Мы рассмотрели два альтернативных варианта преобразования файла данных из "широкого" формата к "узкому" и наоборот.

 

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

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

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


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

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

Осуществить 2 независимых выборки с отбором по условию.sps

Осуществить 2 случайных выборки индивидов одного и того же пола, возраста, образования.sps (по сути, аналог предыдущего примера)

Осуществить n независимых случайных выборок объёма m из одного и того же файла.SPS

Случайно отобрать x% наблюдений из каждой страты.SPS

Случайно отобрать n наблюдений из каждой страты.SPS

Вывести случайные номера по 10 штук в строке.SPS

 

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


В избранное