В предыдущей статье мы познакомились с интерфейсом SAS UE, терминологией SAS Base, типами данных, основными требованиях к синтаксису SAS Base, а также рассмотрели распространенные синтаксические ошибки.

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



Что такое библиотеки SAS?


Библиотека в SAS – это метод централизованного хранения и прозрачного использования данных в программах SAS. Библиотека может быть папкой или каталогом на вашем компьютере или располагаться на внешнем жестком диске, FLASH-накопителе или компакт-диске и так далее.

Существует два типа библиотек: постоянные и временные. Постоянные библиотеки SAS сохраняются до тех пор, пока вы их не удалите. Постоянная библиотека доступна для обработки в последующих сеансах SAS. Временная библиотека SAS существует только для текущего сеанса SAS.

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

Назначаем пользовательскую библиотеку.


Рассмотрим простой случай назначения библиотеки: наборы данных SAS находятся в одной директории c:\habrahabr. Есть два способа решения этой задачи.

1 способ:


Настроить библиотеку без программного кода. Во вкладке «Библиотеки» в SAS UE выбрать «Новая библиотека»:


Далее появится окно для настройки пользовательской библиотеки:


Имя библиотеки – library reference (или libref). Libref – это «псевдоним» (ссылка) для «хранилища», в котором находятся файлы. Название библиотеке задается в соответствии с правилами именования переменных в SAS (см. Урок 1), но на него выделяется не более 8 символов.

Правила именования библиотек, переменных, наборов данных и пр. в SAS можно изучить в справочнике SAS 9.4 and SAS Viya 3.3 Programming Documentation SAS Language Reference: Concepts в разделе Names in the SAS Language.

Обратите внимание, что библиотека назначена на все время сеанса SAS, но переопределять ее параметры можно.

Далее задаем путь к наборам данных SAS.


После назначения библиотеки она появляется в левой панели SAS UE.


2 способ:


Назначить библиотеку программным путем. Назначение библиотеки SAS реализуется с помощью глобального оператора LIBNAME. Информацию по указанному оператору можно изучить в справочнике SAS 9.4 and SAS Viya 3.3 Programming Documentation / Global Statements.

Рассмотрим общий синтаксис глобального оператора LIBNAME.

LIBNAME libref <engine> 'SAS-library' < options > <engine/host-options>;

libref – имя библиотеки.
engine — имя «движка», например, для наборов данных SAS – это BASE (но его можно не указывать, он задан по умолчанию). Если вы хотите создать новую библиотеку с другим «движком», отличным от механизма по умолчанию, вы можете отменить автоматический выбор.

Справочники, которые могут вам пригодиться при изучении механизмов подключения: SAS/ACCESS for Relational Databases и SAS Engines.

«Движки» SAS/ACCESS являются механизмами оператора LIBNAME, которые обеспечивают доступ к чтению, записи и обновлению более чем 60 реляционных и нереляционных баз данных, файлов ПК, устройств хранения данных и распределенных файловых систем.

'SAS-library' – путь к библиотеке, если путь задается с помощью макропеременной (будет рассматриваться в данном цикле статей), используются парные двойные кавычки. Во всех остальных случаях можно использовать парные одинарные кавычки.

options — допустимые опции. Простейшим примером является опция ACCSESS=READONLY, которая назначает атрибут «только для чтения» для всей библиотеки SAS. Со всем перечнем допустимых опций можно ознакомиться в справочнике SAS 9.4 and SAS Viya 3.3 Programming Documentation /Global Statements.

engine/host-options — являются одним или несколькими параметрами, которые перечислены в общей форме keyword = value.

Рассмотрим синтаксис оператора LIBNAME на практике. Назначим библиотеку Habr только для чтения:

libname Habr "c:\habrahabr" access=readonly;

Запустим код и проверим Log:


Сообщения в журнале указывают, что библиотека успешна назначена. В качестве библиотек можно подключать данные, которые физически находятся не в формате наборов данных SAS (промышленные БД, excel, access).

Просматриваем содержимое библиотеки SAS.


Один из вариантов просмотра содержимого библиотеки – использование процедуры PROC CONTENTS. Ознакомиться с процедурами, используемыми в SAS, можно в справочнике SAS 9.4 Procedures by Name and Product.

Процедура PROC CONTENTS позволяет создавать вывод, который описывает либо содержимое библиотеки SAS, либо информацию дескриптора для отдельного набора данных SAS. Чтобы просмотреть содержимое библиотеки SAS, мы можем использовать следующую общую форму процедуры:

proc contents data = libref._ALL_ nods;
run; 

Параметр NODS (который означает «no details») подавляет печать подробной информации о каждом файле при указании опции _ALL_.

Для конкретной библиотеки код будет выглядеть следующим образом:

proc contents data=habr._all_ nods;
run; 

Фрагмент вывода процедуры:


Обратите внимание, что в библиотеке также хранятся другие типы файлов, например catalog, index. О них можно прочитать в справочнике SAS 9.4 Companion for Windows, Fifth Edition.

Файлы с member type DATA являются стандартными наборами данных SAS. Второй вариант просмотра содержимого библиотеки – использовать процедуру PROC DATASETS:

proc datasets lib=habr;
quit; 

Просмотр информации о конкретном наборе данных SAS реализуется следующим образом:

proc contents data=habr.charities;
run;

Обратите внимание на обращение к таблице в пользовательской библиотеке. Имя после data= двухуровневое: имя_библиотеки.имя_таблицы. В случае набора данных, хранящемся во временной библиотеке WORK, в обращении после data= можно использовать одноуровневое имя.

Например, в случае кода:

proc contents data=charities;
run;

выведется информация о наборе данных charities, находящемся во временной библиотеке WORK.

Рассмотрим вывод процедуры для набора данных charities в пользовательской библиотеке HABR:


Служебная информация о таблице, получаемая в результате вывода, называется дескриптором.
Дескриптор содежит общую информацию о наборе данных: его название и имя библиотеки, типе, «движке», дате и времени создания и последнего изменения, количестве наблюдений и переменных, общей длине наблюдений, индексах, сортировке, сжатии, размере страницы и их количестве, информацию об атрибутах переменных.

Читаем электронные таблицы.


Чтение файла EXCEL можно реализовать несколькими способами. В этой статье мы рассмотрим назначение библиотеки для файла excel.

Для назначения библиотеки SAS будем использовать электронную таблицу products.xlsx, хранящуюся в директории c:\workshop\habrahabr\products.xlsx. Данный документ выглядит следующим образом: он содержит 4 листа, каждый из которых станет отдельным набором данных SAS. Фрагмент данного документа представлен ниже:


Общий синтаксис назначения библиотеки такой же, как и в случае наборов данных SAS, меняется только механизм подключения:

LIBNAME libref <engine> 'SAS-library' < options > <engine/host-options>;

Существует несколько механизмов для обработки файла excel, у всех свои особенности и настройки, с которыми можно ознакомиться в документации.

  1. Excel

    libname XL excel "c:\workshop\habrahabr\products.xlsx";

    Результат выполнения оператора libname представлены ниже. Фрагмент Log:


    Информацию о библиотеке посмотрим через процедуру PROC CONTENTS:

    proc contents data=xl._all_ nods;
    run; 

    В зависимости от механизма дескриптор заполняется по-разному:

  2. XLSX

     libname xl xlsx "c:\workshop\habrahabr\products.xlsx";

    Результат выполнения оператора LIBNAME представлены ниже. Фрагмент Log:


    Информацию о библиотеке посмотрим через PROC CONTENTS:

    proc contents data=xl._all_ nods;
    run; 

    В зависимости от механизма дескриптор заполняется по-разному:

  3. PC Files

    libname XL pcfiles path='c:\workshop\habrahabr\products.xlsx';

    Результат выполнения оператора libname представлены ниже.

    Фрагмент Log:


    Информацию о библиотеке посмотрим через PROC CONTENTS:

    proc contents data=xl._all_ nods;
    run; 

    В зависимости от механизма дескриптор заполняется по-разному:


Создаем детализированные отчеты.


После получения доступа к требуемым данным рассмотрим процедуру для создания отчетов PROC PRINT. Подробную информацию о ней можно получить в справочнике SAS 9.4 Procedures by Name and Product. Распечатаем детализированный отчет, используя таблицу German из системной библиотеки sasuser.

Для начала изучим дескриптор указанной таблицы, нас интересуют атрибуты столбцов:

proc contents data=sasuser.german;
run;

Фрагмент вывода процедуры:


Создадим детализированный отчет, удовлетворяющий представленным ниже требованиям:

  1. Не включайте переменные Change и Retain в отчет:

    proc print data=sasuser.german;
    var ID Pre Group Gender;
    run; 

    Оператор VAR определяет переменные для печати. Оператор выводит их в том порядке, в котором вы их перечислили.

    Фрагмент вывода:


  2. Распечатайте только те наблюдения, значения переменной Pre в которых не превышает 70.00 и значения переменной Group равны Treatment.

    В данном условии нам необходимо использовать фильтр в операторе WHERE.

    proc print data=sasuser.german;
    var ID Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    run;
    

    Обратите внимание, что при работе с текстовыми переменными важен регистр, а также вы обязательно заключаете требуемое значение в парные кавычки (двойные или одинарные).
    Вывод данной программы SAS:


  3. Не выводите номера строк.

    По умолчанию процедура PROC PRINT выводит номера строк, для того, чтобы убрать данный столбец, можно использовать опцию NOOBS (‘no observation’). В этом случае программный код выглядит следующим образом:

    proc print data=sasuser.german noobs;
    var ID Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    run;
    

    Операторы сравнения вы можете записывать привычными символами, а можете использовать мнемоники, как представлено в примере. Вывод данной программы представлен ниже:


  4. Переменную ID определите идентифицирующим столбцом.

    Идентификатором наблюдения можно определить любую переменную. Когда вы указываете одну или несколько переменных в операторе ID, он использует форматированные значения этих переменных для идентификации строк. Обратите внимание, что если одновременно переменная указана в операторе VAR и в операторе ID, то она выведется два раза. Также при использовании оператора ID нет необходимости в опции NOOBS.

    В нашем случае программа SAS будет иметь следующий вид:

    proc print data=sasuser.german;
    var Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    ID ID;
    run;
    

    Результаты выполнения кода представлены ниже:


  5. Задайте переменным ярлыки

    Стоит отметить, что при задании атрибутов таких как ярлык и формат, они будут использованы только на определенном шаге PROC для создания требуемого отчета.

    Для задания ярлыка используется оператор LABEL.

    Общий синтаксис оператора LABEL выглядит следующим образом:

    LABEL variable-1=label-1...<variable-n=label-n>;

    В ярлыке вы можете использовать любые символы, в том числе и пробелы, количество символов не должно превышать 256. Ярлыки переменных будут использованы для создания отчетов.
    Не все процедуры «видят» ярлыки. Для того, чтобы процедура PROC PRINT выводила в отчет ярлыки, а не имена переменных, в опциях необходимо указать label (или split=). Опция SPLIT указывает разделитель, который контролирует разрывы в заголовках столбцов. Используем оператор LABEL в нашем программном коде:

    1 вариант


    proc print data=sasuser.german label;
    var Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    ID ID;
    label   ID = 'Identifier' 
            Pre = 'Pre credit'
            Group = 'Customer Group'
            Gender = 'Customer Gender';
    run;
    


    2 вариант


    (с использованием опции split=)

    В опции split= указывается разделитель (обязательно в кавычках). Код в данном случае выглядит следующим образом (обратите внимание на использование разделителей в операторе Label):

    proc print data=sasuser.german split='*';
    var Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    ID ID;
    label   ID = 'Identifier' 
            Pre = 'Pre credit'
            Group = 'Customer*Group'
            Gender = 'Customer*Gender';
    run;
    


  6. Задайте отчету заголовок и нижний колонтитул

    Оператор TITLE задает заголовок в отчете, оператор FOOTNOTE задает нижний колонтитул.

    Как и в случае оператора LIBNAME, данные операторы являются глобальными и действуют во время всего сеанса SAS до тех пор, пока вы не переопределите их значения. Вы можете использовать TITLE и FOOTNOTE как вне шагов PROC, так и непосредственно в них.

    Общий синтаксис операторов:

    TITLE<1...10> <text-options> 
                 <"text-string–1"> ... <text-options> <"text-string-n"> ;

    FOOTNOTE<1...10> <text-options> 
                 <"text-string–1"> ... <text-options > <"text-string-n"> ;

    Text-string – данный аргумент является строкой, которая может содержать до 512 символов. Вам необходимо заключать такие строки в одиночные или двойные кавычки. Текст отображается точно так же, как вы вводите его в операторе, включая прописные, строчные буквы и пробелы.

    Для заголовка в отчете вы можете использовать 10 операторов TITLE (аналогично с FOOTNOTE). Важно понимать, как переопределяются значения. Логика выполнения операторов одинаковая. Рассмотрим переопределение значений заголовков на примере оператора TITLE.
    Код Результат Примечание
    TITLE 'String number one'; String number one TITLE и TITLE1 эквивалентны
    TITLE 'String number three' String number one

    String number three
    Строка №2 пустая
    TITLE2 'String number two'; String number one
    String number two
    TITLE2 задал значение заголовку на второй строке и удалил значения заголовков ниже.
    TITLE1 'New Title'; New Title TITLE1 задал значение заголовку на 1 строке и удалил значения заголовков ниже.
    TITLE; Пустой оператор TITLE удаляет все заголовки.3

    Другими словами, оператор TITLEn переопределяет значение заголовка в строке n и удаляет значения заголовков строк c n+1 до 10.

    Также для настройки заголовков и нижних колонтитулов можно использовать стили:

    title bold Italic 	
    color=brown bcolor=darkseagreen 
    height=5'Habrahabr';
    

    Результат выполнения:


    Итак, возвращаясь к разрабатываемому отчету:

    title 'Example for Habrahabr';
    footnote 'Created by Anna Dobrychenko';
    proc print data=sasuser.german split='*';
    var Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    ID ID;
    label   ID = 'Identifier' 
            Pre = 'Pre credit'
            Group = 'Customer*Group'
            Gender = 'Customer*Gender';
    run;
    /*Clear title and footnote*/
    title; footnote;
    

    Результат выполнения программы:


  7. Задайте переменной Pre формат

    Формат – это правило вывода значений переменных в отчет. Необходимо понимать, что формат не меняет значения в наборе данных SAS. Типы форматов соответствуют типу данных, но разбиты на категории: числовые, символьные, даты, время, дата-время.

    Всю информацию о форматах можно найти в справочнике SAS 9.4 Formats and Informats: Reference. Также поддерживается возможность создания пользовательских форматов, об этом мы поговорим в следующих статьях.

    Общий синтаксис оператора FORMAT.

    FORMAT variable-1 <...variable-n> <format> <DEFAULT=default-format>;

    variable – одна или несколько переменных, к которым небходимо применить формат.

    DEFAULT=default-format – определяет временный формат по умолчанию для отображения значений переменных, которые не указаны в операторе FORMAT, используется в шаге DATA.

    format – определяет формат, который используется для отображения переменных.

    Общий синтаксис использованиея формата в операторе FORMAT следующий:

    <$>format<w>.<d>

    $ — признак текстового формата
    Format – название формата
    w — ширина формата, количество всех выводимых символов в значении
    d — количество десятичных знаков

    Формат всегда оканчивается на точку или на количество десятичных знаков. Стоит отметить, что при неверном выборе ширины формата значения в выводе могут «обрезаться». Давайте рассмотрим пример:
    Значение переменной Формат Результат
    34566.78 DOLLAR10.2 $34,566.78
    34566.78 DOLLAR9.2 $34566.78
    34566.78 DOLLAR8.2 34566.78
    34566.78 DOLLAR7.2 34566.8
    34566.78 DOLLAR6.2 34567
    34566.78 DOLLAR4.2 35E3

    При этом значение в наборе данных SAS остается неизменным:

    data test;
    Var=34566.78;
    CurrentValue=Var;
    FORMAT Var dollar4.2;
    run;
    proc print data=test noobs;
    run;
    

    Результат выполнения шага:


    Итак, применим формат к переменной Pre:

    title 'Example for Habrahabr';
    footnote 'Created by Anna Dobrychenko';
    proc print data=sasuser.german split='*';
    var Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    ID ID;
    label   ID = 'Identifier' 
            Pre = 'Pre credit'
            Group = 'Customer*Group'
            Gender = 'Customer*Gender';
    format Pre dollar6.2;
    run;
    /*Clear title and footnote*/
    title; footnote;
    

    Отчет выглядит следующим образом:


  8. Сгруппируйте отчет по переменной Gender, и оставьте в отчете переменные Pre, Group и Gender

    Для группировки переменных используется оператор BY. Группировка переменных по определенным значениям подразумевает сортировку таблицы. Это связано с обработкой данных SAS Base.

    Отсортировать набор данных можно с помощью процедуры PROC SORT.

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

    Давайте проверим вышеизложенное. Если посмотреть на отчет, выводимый в п.7 данной статьи, столбец Gender отсортирован по полу по убыванию. Так ли это?

    title 'Example for Habrahabr';
    footnote 'Created by Anna Dobrychenko';
    proc print data=sasuser.german split='*';
    var Pre Group Gender;
    where Pre le 70 and Group='Treatment';
    ID ID;
    label   ID = 'Identifier' 
            Pre = 'Pre credit'
            Group = 'Customer*Group'
            Gender = 'Customer*Gender';
    format Pre dollar6.2;
    BY descending Gender;
    run;
    /*Clear title and footnote*/
    title; footnote;
    

    Результат выполнения процедуры представлен ниже:


    Добавим несколько опций для создания итогового отчета: nobyline и #byVAL()

    options nobyline;
    title 'Example for Habrahabr';
    title2 'Report for Gender: #BYVAL(Gender) and for Group: Treatment';
    footnote 'Created by Anna Dobrychenko';
    proc print data=sasuser.german split='*';
    var Pre;
    where Pre le 70 and Group='Treatment';
    ID ID;
    label   ID = 'Identifier' 
            Pre = 'Pre credit';
    format Pre dollar6.2;
    BY descending Gender;
    run;
    /*Clear title and footnote*/
    title; footnote;
    options byline;
    

    Таким образом, мы получили требуемый детализированный отчет на основании набора German в библиотеке Sasuser.



Итак, это кратко об организации доступа к данным и созданию детализированных отчетов. В следующей статье мы рассмотрим чтение внешних файлов, изучим операторы INFILE и INPUT, а также процедуру PROC IMPORT.

И, конечно, традиционно — Grow with SAS!

Комментарии (2)


  1. LuciferF
    27.02.2018 13:16

    Анна, добрый день! Я являюсь студентом-магистрантом из Казахстана и решил попробовать себя на поприще бизнес-аналитики. С огромным интересом прочитал ваши первые статьи в рамках цикла статей по SAS, с большим нетерпением жду новых познавательный статей по SAS, особенно хотелось бы прочитать материал от профессионала по макросам и «включении» различных процедур proc. Заранее вам очень признателен, спасибо за ту работу, что вы проделываете!


    1. AnnaDobrychenko Автор
      28.02.2018 15:00

      Владимир, большое спасибо за обратную связь! Статьи по macro планируются, обязательно опубликуем. Несложные кейсы и наборы данных можно скачать вместе с бесплатным курсом про программированию на SAS Base (часть 1)
      Еще есть бесплатный курс по статистике
      На каждой странице необходимо дойти до таблицы с e-Learning и нажать Start. Бесплатное программное обеспечение можно скачать по ссылке.
      С уважением, Анна Добрыченко.