Создание отчётов в SAS – PROC PRINT

В предыдущих уроках мы познакомились с наиболее распространёнными статистическими процедурами PROC MEANS и PROC FREQ. Сегодня мы познакомимся с процедурой PROC PRINT, которая позволит вам создать (распечатать или PRINT) простейший отчёт на основе имеющихся данных.

PROC PRINT

Общий обзор

Процедура PRINT или PROC PRINT, существует примерно с тех времен, когда вообще появился SAS. Несмотря на то, что эта процедура была частично заменена на процедуру REPORT, есть еще много случаев, когда вы можете ею воспользоваться. Процедура PRINT является одной из первоочередных вещей, которые нужно освоить начинающему программисту SAS, поскольку она обеспечивает легкий и простой способ взглянуть на записи в датасете. Также в этом уроке мы научимся сохранять вывод из PROC PRINT в простой текстовый файл или RTF файл.

Базовый синтаксис процедуры

Базовый синтаксис процедуры такой:

PROC PRINT <option(s)>;
    WHERE <condition>;
    BY <DESCENDING> variable-1 <… <DESCENDING> variable-n><NOTSORTED>;
    PAGEBY BY-variable;
    VAR variable(s);
RUN;

Давайте рассмотрим назначение каждого оператора (выделены синим выше). Итак,

Далее рассмотрим описание опций по каждому оператору:

Statement Option Description
PROC PRINT DATA = SAS-data-set Указывает исходный набор выводимых данных (input data set)
Управление общим форматом вывода
BLANKLINE = <n> Создает пустую строку после каждых n записей в исходном датасете
DOUBLE Создает пустую строк между записями из исходного датасета
N = 'string' Печатает количество записей в исходном датасете, либо BY-группе и указывает пояснительный текст, который будет выведен вместе с количеством записей
NOOBS Позволяет не выводить колонку Obs (порядковый номер печатаемой записи) в output
OBS = 'string' Позволяет задавать заголовок колонки Obs (порядковый номер печатаемой записи)
ROUND Округляет числовые переменный (на которые не наложен формат) до 2 знаков после запятой
Управление форматом страниц
WIDTH = FULL| MINIMUM| UNIFORM| UNIFORMBY

Определяет ширину колонки для каждой выводимой переменной. Принимает такие значения:

  • FULL – использует ширину форматированного значения переменной как ширину колонки; если формат для переменной не указан ширина будет равна длине переменной
  • MINIMUM – для каждой переменной использует минимальную ширину, при которой все значения переменной будут помещаться в отчет
  • UNIFORM - использует ширину форматированного значения переменной как ширину колонки на всех страницах отчёта
  • UNIFORMBY - использует ширину форматированного значения переменной как ширину колонки в пределах BY-группы
Управление форматом колонок (столбцов)
HEADING = HORIZONTAL (H)| VERTICAL (V)

Задает ориентацию вывода заголовков колонок (горизонтально либо

в

е

р

т

и

к

а

л

ь

н

о)

По умолчанию HEADING = H

LABEL Инструкция к использованию label-ов переменных в качестве заголовков колонок
SPLIT = 'split-char' Указывает split-символ, который позволит разбивать заголовки колонок на несколько строк

Вызов процедуры и описание результатов вывода

За основу возьмем input data set SCORES, содержащий информацию об успеваемости учеников одного класса. Сохраним данные в input SAS data set используя DATA STEP и оператор DATALINES:

data scores;
  infile datalines dlm='|';
  length name $10 subject $20 score 8;
  input name subject score;
datalines;
John|Math      |98
John|English   |76
John|Biology   |81
John|Physics   |69
John|Economics |79
Tony|Math      |65
Tony|English   |34
Tony|Biology   |87
Tony|Physics   |56
Tony|Economics |90
Jeff|Math      |41
Jeff|English   |45
Jeff|Biology   |56
Jeff|Physics   |78
Jeff|Economics |34
;
run;

Выполним DATA STEP. Получим input data set вида:

6.3.1

Теперь давайте выведем информацию из датасета SCORES в окно Output. Для этого вызовем PROC PRINT без опций и оператора VAR (т.е. SAS распечатает все переменные, которые имеются в датасете):

proc print data=scores;
run;

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

6.3.2

Итак, что же мы видим. В output вывелась вся информация, которая содержится в датасете SCORES, а также колонка Obs, которая указывает порядковый номер записи в output. Заголовки колонок совпадают с именами переменных.

Теперь давайте выведем всё ту же информацию, но уже с использованием оператора BY. Группировку будем производить на основе переменной SUBJECT (предмет). Помним, что при использовании BY нужно предварительно отсортировать input data set по BY переменной:

proc sort data=scores;
  by subject;
run;

proc print data=scores;
  by subject;
run;

В итоге получим след. результат в окне Output:

6.3.3 6.3.4

Теперь мы видим, что наши данные сгруппированы по названию предмета (SUBJECT). Колонка SUBJECT трансформировалась в название секции. Для каждого значения SUBJECT (Biology, Economics, English, Math и Physics) вывелась отдельная секция.

Далее давайте сформируем отчёт, задействовав некоторые опции, описанные выше. Итак, разбивку всё также будем делать по SUBJECT, но теперь мы хотим, чтобы данные по каждому предмету начинались с новой страницы – для этого воспользуемся оператором PAGEBY и укажем в него SUBJECT. Отделим записи по каждому студенту пустой строкой с помощью опции DOUBLE. Уберем из вывода колонку Obs с помощью опции NOOBS. Выведем количество записей по каждому предмету с помощью опции N = , указав “# of students per Subject” как описательную информацию. Воспользуемся опцией LABEL для того, чтобы перенести variables’ labels в качестве заголовков колонок (предварительно в датасете нужно задать эти labels). Ну и в конечном итоге укажем пробел как split-символ в опции SPLIT (этим мы добьёмся эффекта разбиения заголовков колонок на несколько строк в тех местах, где в label был встречен пробел).

Labels для переменных зададим так:

data scores;
  infile datalines dlm='|';
  length name $10 subject $20 score 8;
  label name="Student's Name";
  label subject="Subject";
  label score="Subject's Score";
  input name subject score;
datalines;
…
;
run;

Далее вызовем PROC PRINT:

proc sort data=scores;
  by subject;
run;

proc print data=scores double noobs n='# of students per Subject = ' label split=' ';
  by subject;
  pageby subject;
run;

Как результат получим 5 страниц информации (по одной странице на каждый предмет):

Мы научились генерировать простейшие отчёты, теперь давайте рассмотрим, как проделанную работу сохранить в файл.

Сохранение результатов

Если вам нужно сохранить результаты в обычном текстовом виде можно воспользоваться направлением ODS LISTING с опцией FILE:

ods listing file="c:\Users\stina\Desktop\First report.lst";

proc print data=scores double noobs n='# of students per Subject = ' label split=' ';
  by subject;
  pageby subject;
run;

ods listing close;

где FILE = “<полный путь к файлу с расширением .lst>”. В результате будет создан файл First report.lst и выглядеть он будет так:

6.3.9 6.3.10

Для того, чтобы сохранить результаты в RTF файл воспользуемся направлением RTF с опцией FILE:

ods rtf file="c:\Users\stina\Desktop\First report.rtf";

proc print data=scores double noobs n='# of students per Subject = ' label split=' ';
  by subject;
  pageby subject;
run;

ods rtf close;

где FILE = “<полный путь к файлу с расширением .rtf>”. В результате будет создан файл First report.rtf и выглядеть он будет так:

6.3.11 6.3.12

Тоже самое можно проделать для сохранения результатов в PDF (используя ODS PDF destination) и HTML (используя ODS HTML destination).

Полный код программы с использованием PROC PRINT и сохранением отчётов в .lst и .rtf форматах:

dm log "clear";
dm odsresults "clear";
dm output "clear";

options nocenter nodate nonumber;

data scores;
  infile datalines dlm='|';
  length name $10 subject $20 score 8;
  label name="Student's Name";
  label subject="Subject";
  label score="Subject's Score";
  input name subject score;
datalines;
John|Math      |98
John|English   |76
John|Biology   |81
John|Physics   |69
John|Economics |79
Tony|Math      |65
Tony|English   |34
Tony|Biology   |87
Tony|Physics   |56
Tony|Economics |90
Jeff|Math      |41
Jeff|English   |45
Jeff|Biology   |56
Jeff|Physics   |78
Jeff|Economics |34
;
run;

proc sort data=scores;
  by subject;
run;

* Save results to .lst file;
ods listing file="c:\Users\stina\Desktop\First report.lst";

proc print data=scores double noobs n='# of students per Subject = ' label split=' ';
  by subject;
  pageby subject;
run;

ods listing close;

* Save results to .rtf file;
ods rtf file="c:\Users\stina\Desktop\First report.rtf";

proc print data=scores double noobs n='# of students per Subject = ' label split=' ';
  by subject;
  pageby subject;
run;

ods rtf close;

Дополнительные материалы: