Рассылка закрыта
Вы можете найти рассылки сходной тематики в Каталоге рассылок.
Статистика в SPSS: за пределами кнопочного интерфейса. Выпуск 22
В рассылке используются материалы веб-сайта
www.spsstools.ru
Содержание выпускаНовое на сайте www.spsstools.ru Здравствуйте, уважаемые подписчики! Макросы. Начальные сведенияДумаю, многие из вас знают о возможности оформлять синтаксис SPSS в так называемые макропроцедуры, или макросы. Макросы действительно подобны процедурам или функциям в языках структурного программирования. Они сочетают в себе заданную последовательность инструкций, к которым можно обращаться одной командой из любой части программы. Причём при обращении можно передавать аргументы, что делает макросы не просто инструментом структурирования программы, а мощным средством реализации алгоритмов. В полезности макросов при программировании в SPSS убеждать кого-либо излишне. Достаточно обратить внимание читателя на то, что львиная доля примеров синтаксиса в "Коллекции Raynald'а" составлена с использованием макропроцедур. До сих пор я избегал в рассылке использования макросов, но не потому, что считаю их чересчур сложными, а потому, что овладение макросами - принципиально важный шаг в программировании в SPSS, требующий какого-то минимума вводных комментариев. Сегодня - именно такой, вводный выпуск рассылки. Как пишет Рейналь Левек в своей книге SPSS Programming and Data Management, макросы обычно появляются в программе, если вам требуется, например: - выполнить один и тот же анализ (последовательность действий) на многих переменных или нескольких файлах данных; - выполнить разные виды анализа в зависимости от некоторых параметров (например, одни процедуры для годового и другие процедуры для квартальных отчётов); - выполнить повторяющийся набор действий (например, сгенерировать 1000 случайных выборок из файла данных, получив и сохранив для каждой из них свою статистику). Когда мы будем разбирать примеры синтаксиса с использованием макросов, вы увидите, что под эту широкую классификацию попадает множество специальных задач, которые с макросами решаются быстрее и проще, чем без них. В равной степени начинающим и опытным пользователям я бы рекомендовал ознакомиться с уже переведёнными разделами сайта www.spsstools.ru по макросам. Макроязык - достаточно объёмный технический вопрос и получить целостное представление о нём из одного выпуска рассылки невозможно. Поэтому... На странице Мастер-класс по макросам вы найдёте важнейшие сведения о макросах (назначение, общие правила написания, примеры). Непременно обратите внимание на раздел Макрос ? синтаксический анализатор, обработчик строк. Многие особенности и кажущиеся "глюки" в поведении макросов станут понятны и прозрачны. На странице Отладка макросов, как следует из её названия, собраны несколько ценных советов по выяснению причин "неправильной" работы макрокода. На странице Макросы собраны примеры макросов, которые, в основном, ценны изяществом написания самих макросов. Не столь важно, какие именно практические задачи решают эти примеры. Вы можете использовать идеи и готовые конструкции отсюда для написания собственных макросов независимо от их назначения. Множество макросов "в деле" можно увидеть непосредственно на странице примеров синтаксиса: Синтаксис. Читающим по-английски я могу рекомендовать уже упоминавшуюся выше книгу Raynald Levesque SPSS Programming and Data Management, а в качестве постоянного справочного материала - официальный справочник по синтаксису SPSS. Описание макрокоманд даётся в разделе DEFINE - !ENDDEFINE. Указав на дополнительные источники информации, я сфокусируюсь в этом выпуске на простых примерах определения и вызова макросов, а также на способах передачи аргументов. Думаю, что со следующего выпуска это позволит нам начать разбор примеров макросов, содержащихся в "Коллекции".
Простейший пример. Пустой макрос. Он ничего не делает. Мы просто знакомимся с принципом его определения. Макрос задаётся внутри команд DEFINE - !ENDDEFINE. С точки зрения синтаксиса, это обычная команда, которая может быть написана и в одну строку. После инструкции DEFINE мы указываем имя макроса, к которому нам потом удобно будет обращаться. В данном случае имя начинается с восклицательного знака. Восклицательный знак - характерный символ при написании макрокоманд, но в имени макроса он вовсе необязателен. Определим вслед за макросом !mac1 макрос mac1, это будет отдельный макрос. Пустые скобки после имени символизируют отсутствие каких-либо аргументов. Когда SPSS получает инструкцию DEFINE с именем определяемого макроса, все последующие инструкции вплоть до команды !ENDDEFINE он интерпретирует как тело макроса. При вызове этого макроса в дальнейшем все инструкции из тела макроса будут исполнены. Будучи раз определённым, макрос помещается в оперативной памяти до окончания сеанса работы с SPSS. Это значит, что обратиться к нему вы сможете и после того, как откроете другой файл данных, из другого файла синтаксиса и проч. Повторное определение макроса с тем же именем, которое уже имеется в памяти, вызывает переопределение макроса. Пользователь информируется об этом в окне результатов. Выполните дважды команды определения обоих макросов. Вы увидите, как SPSS сообщает о переопределении. DEFINE !mac1() !ENDDEFINE.
DEFINE mac1() !ENDDEFINE. Определение макроса !mac1 можно записать и так: DEFINE !mac1() !ENDDEFINE. Наконец, вызвать макрос на исполнение можно простым упоминанием его имени в коде за пределами определения макроса: !mac1.
Макрос-константа. Если мы поместим внутрь макроса "что-то", это "что-то" будет подставляться каждый раз в то место кода, в котором встретится имя макроса. Отсюда - некоторые возможности автоматизации своей работы. Следующий макрос "запоминает" путь к рабочей директории. В дальнейшем это избавляет нас от написания пути целиком: DEFINE !dp() 'c:\temp\' !ENDDEFINE.
GET FILE = 'Employee data.sav'. /* Я полагаю, по умолчанию у вас настроен путь к директории SPSS */. SAVE OUTFILE = !dp+'mydata.sav'. Чтобы убедиться в том, что SPSS при исполнении последней строки действительно выполнил желаемую команду "SAVE OUTFILE = 'c:\temp\mydata.sav'.", вставим перед вызовом макроса инструкцию "SET MPRINT=yes." Теперь макрос, перед тем как исполниться, будет "разворачиваться" (expand) у нас на глазах: отличный способ поиска ошибок в программировании. SET MPRINT=yes. SAVE OUTFILE = !dp+'mydata.sav'. Отключить опцию MPRINT можно обратной командой: SET MPRINT=no. Разумеется, все эти трюки с MPRINT имеют смысл лишь в том случае, если у вас включена опция отображения в окне результатов командного синтаксиса, а если вы программируете в SPSS, это должно быть сделано (через меню, или командой "SET Printback=On."). На место 'c:\temp' вы можете подставить какое-либо число, строку, имя переменной и использовать это в коде по своему усмотрению.
Макрос-набор команд. Туда, куда можно подставить "любую строку", можно подставить и исполняемый код: DEFINE !mac2() GET FILE = 'Employee data.sav'. DESCRIPTIVES VARIABLES=salbegin salary. !ENDDEFINE. Никакой статистики пока не появляется. Мы лишь определили макрос. А теперь исполним его: !mac2. А как насчёт того, чтобы в определении одного макроса использовать уже ранее определённые макросы? И это можно: DEFINE !mac2() GET FILE = !dp+'mydata.sav'. DESCRIPTIVES VARIABLES=salbegin salary. !ENDDEFINE.
!mac2.
Макрос с параметрами. Возможность передачи в макросы аргументов (параметров) заметно повышает наш практический интерес к макроязыку. Незначительная доработка предыдущего примера даёт нам возможность мгновенно получить статистику по любой переменной из интересующего нас файла данных, какой бы файл ни был открыт в данный момент: DEFINE !mac2(vars=!CMDEND) GET FILE = !dp+'mydata.sav'. DESCRIPTIVES VARIABLES=!vars. !ENDDEFINE.
!mac2 vars=salary prevexp. !mac2 salary prevexp. В этом примере у макроса появляется аргумент vars, он определяется в скобках после имени макроса. При вызове всё, что находится после имени макроса и до точки-окончания вызова, понимается программой как значение аргумента vars. Есть некоторые особенности работы с аргументами, к которым надо привыкнуть. Несмотря на то, что мы назвали аргумент vars, в теле самого макроса надо ссылаться на него как на !vars. Хотя аргумент один, он содержит названия двух переменных, разделённых пробелом. Поскольку аргумент единственный и включает в себя всё, что находится до точки-окончания вызова, то нам (и, что самое важное, программе) безразлично, вызывать ли его с указанием на его имя, или без оного (соответственно, первый и второй варианты вызова в примере выше, эквивалентны).
Далее сформулируем несколько тезисов: 1. Макрос может принимать несколько аргументов. Второй и последующие аргументы определяются в тех же скобках, что и первый, но после знака "/". 2. Каждый аргумент может содержать одну или несколько самостоятельных "порций" информации (tokens). В примере выше аргумент vars содержал два "токена" - имена двух переменных. При вызове макроса множественные токены разделяются пробелами (как правило) или иными разделяющими знаками (что является темой отдельного разговора). Строка, заключенная в кавычки, является самостоятельным токеном. 3. Похоже, становится ясно, что значениями аргументов/токенов для макросов могут быть числа, имена переменных, текстовые строки, команды и логические выражения, и даже имена макросов. 4. Для разных ситуаций придумано несколько вариантов описания, задания и ссылок на аргументы. Эти варианты различаются ключевыми словами, стоящими в скобках при определении аргументов. Знакомое нам ключевое слово с макросимволом вначале: "!CMDEND" говорит, что значением этого аргумента будет всё, стоящее от конца имени макроса и до последней точки команды (либо от конца значения предыдущего аргумента и до последней точки команды). Рассмотрим правила, задаваемые другими ключевыми словами: !TOKENS(n) - значениями аргумента являются n "порций" информации (токенов), заключённых между значениями предыдущего и последующего аргументов (как вариант, между окончанием имени макроса и точкой, если другие аргументы отсутствуют). !ENCLOSE(символ1, символ2) - парой символов (символ1, символ2) задаются границы, в которых содержится значение аргумента. !CHAREND (символ) - значением аргумента считается всё, что находится в команде вызова макроса от окончания предыдущего аргумента до указанного символа. Особое слово - !POSITIONAL (часто сокращается до !POS) указывает, что на аргумент мы собираемся ссылаться не по его имени, а по порядку следования его в списке аргументов. В этом случае !POS ставится на место имени аргумента, а затем следует одно из 4 ключевых слов, рассмотренных выше. 5. Кроме этого, можно управлять значениями аргументов по умолчанию, "развёртыванием" аргументов в листинге синтаксиса при вызове макроса и т.д. Эти и многие другие вопросы оставим пока без внимания.
Считая, что пример задания аргументов с !CMDEND разобран выше, рассмотрим остальные 3 случая задания:
!TOKENS. В макросе присутствуют 2 аргумента с именами а и b. Первый содержит одну порцию информации, второй - две порции. Команды в теле синтаксиса подразумевают, что аргументы должны содержать имена переменных для процедуры сравнения средних. В аргументе a задаётся имя группирующей переменной, а в аргументе b - 2 имени переменных, средние которых сравниваются по подгруппам. Обратите внимание на второй пример вызова макроса !mac3. Поскольку аргумент b принимает лишь две порции информации (два имени), всё, что стоит вслед за этим, интерпретируется как текст, подставляемый в конец тела макроса. Таким образом, мы получаем при вызове дополнительную статистику - таблицу дисперсионного анализа. DEFINE !mac3(a=!TOKENS(1) /b=!TOKENS(2)) MEANS !ENDDEFINE.
!mac3 a=gender b=salary salbegin. !mac3 a=gender b=salary salbegin /STATISTICS ANOVA.
!ENCLOSE. Аналогичный пример мы рассматриваем в случае, когда первый аргумент может содержать произвольное число токенов. Значением аргумента будет считаться всё, что заключено в скобки. Второй аргумент вбирает в себя все оставшиеся значения до конца команды на вызов макроса. DEFINE !mac4(a=!ENCLOSE('(',')') /b=!CMDEND) MEANS !ENDDEFINE.
!mac4 a=(gender) b=salary salbegin. Но более наглядным примером использования !ENCLOSE является вариант с порядковым именованием аргументов. Построим матрицу корреляций не всех переменных друг с другом, а только избранных: DEFINE !mac5(!POS=!ENCLOSE('(',')') /!POS=!CMDEND) CORRELATIONS /VARIABLES=!1 WITH !2. !ENDDEFINE.
!mac5 (jobtime educ) salary salbegin. ...а теперь так: !mac5 (jobtime educ salary) salbegin. Вы можете видеть, что к порядковым аргументам мы обращаемся не по имени, а по номеру: !1, !2 и т.д. Кого-то восхитит возможность использования "собирательного" имени аргументов: !*. Такой макрос, независимо от положения скобок, построит матрицу корреляций каждой переменной с каждой: DEFINE !mac5(!POS=!ENCLOSE('(',')') /!POS=!CMDEND) CORRELATIONS /VARIABLES=!* WITH !*. !ENDDEFINE.
!mac5 (jobtime educ) salary salbegin.
!CHAREND. Вариант, рассмотренный выше (со скобками) может быть переписан иначе с использованием ключевого слова CHAREND: DEFINE !mac6(!POS=!CHAREND('/') /!POS=!CMDEND) CORRELATIONS /VARIABLES=!1 WITH !2. !ENDDEFINE.
!mac6 jobtime educ /salary salbegin.
В заключение выпуска рассмотрим чуть более сложный пример. Данный макрос генерирует полный факторный план для трёхфакторного эксперимента. Число и наименования уровней каждого фактора задаётся пользователем при вызове макроса. Поскольку токенами аргументов считается всё до условных символов или окончания команды вызова, число токенов может быть произвольным. Здесь мы используем, в принципе, знакомую подписчикам команду определения файлов INPUT PROGRAM со вложенными циклами и инструкциями LEAVE (для чего нужна? Уберите её и сравните результаты). А кроме этого, используем специальные макроциклы !DO .. !IN ... !DOEND (именно так, с восклицательными знаками). В рамках этих циклов "на лету" определяются дополнительные макропеременные !f1, !f2, !f3, пробегающие значения всех токенов из своего аргумента. Таким образом мы осуществляем полный перебор. DEFINE !mac7(!POS=!CHAREND('/') /!POS=!CHAREND('/') /!POS=!CMDEND) INPUT PROGRAM. - STRING f1 f2 f3 (A2). - !DO !f1 !IN (!1) - COMPUTE f1=!QUOTE(!f1). - !DO !f2 !IN (!2) - LEAVE f1. - COMPUTE f2=!QUOTE(!f2). - !DO !f3 !IN (!3) - LEAVE f1 f2. - COMPUTE f3=!QUOTE(!f3). - END CASE. - !DOEND. - !DOEND. - !DOEND. - END FILE. END INPUT PROGRAM. EXECUTE. !ENDDEFINE.
!mac7 A B C D F/ X Y Z/ N1 N2 N3.
Всего доброго, и с началом лета вас!
Ведущий рассылки, Балабанов Антон Новое на сайте www.spsstools.ruПереведены и добавлены примеры синтаксиса: Одна ящичковая диаграмма на каждую категорию переменной.SPS Синтаксис для анализа тестов.SPS
© См. www.spsstools.ru, 2005-2006 |
В избранное | ||