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

По сути PROC REPORT является усовершенствованной версией PROC PRINT. В настоящее время этот уникальный продукт сочетает в себе возможности PROC PRINT, SORT, FREQ и MEANS. Из-за смеси своих специальных возможностей, PROC REPORT зачастую является самым простым способом сгенерировать элегантный data-листинг или сводную таблицу. В этом уроке мы рассмотрим наиболее распространённые варианты применения этой процедуры.

PROC REPORT

Общий обзор

PROC REPORT представляет собой очень мощное, и в тоже время простое средство, которое используется для создания довольно «привлекательных» отчётов. Т.к. программист сам контролирует порядок вывода, а также содержимое каждой колонки – процедура является очень гибкой и удобной.

Каждый SAS программист знает, что подсчёт descriptive statistics либо frequency counts – это лишь одна из составных частей нашей работы. Просто голые числа никому не интересны, а в некоторых случаях даже бессмысленны. Именно поэтому при изучении PROC MEANS и PROC FREQ я приводила примеры форматирования результатов. И именно эти «подготовленные» результаты мы научимся представлять в виде полноценного отчёта, на основе которого уже можно будет делать выводы об анализируемых данных не только вам, но и собственно заказчикам. Как правило заказчик в первую очередь смотрит именно на сводные таблицы и data-листинги, поэтому впечатление о вас как о профессионалах формируется исходя из качества этих самых таблиц и листингов. Ну а качество в свою очередь напрямую зависит от того, насколько хорошо вы освоите данный урок.

Также в этом уроке мы научимся сохранять отчёты, сгенерированные PROC REPORT в простой текстовый файл или RTF файл.

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

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

PROC REPORT <option(s)>;
	WHERE <condition>;
	BY <DESCENDING> variable-1 <… <DESCENDING> variable-n><NOTSORTED>;
	COLUMN  column-specification(s);
	DEFINE report-item / <option(s)>;
	BREAK location break-variable / <option(s)>;
RUN;

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

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

Statement Option Description
PROC REPORT DATA = SAS-data-set Указывает исходный набор выводимых данных (input data set)
WINDOWS | NOWINDOWS Выбираем в каком режиме сработает PROC REPORT – с открытием окна
Управление общим форматом вывода
CENTER | NOCENTER Указывает каким образом выводить данные в отчёте – по центру (CENTER) либо по левому краю (NOCENTER)
FORMCHAR = 'formatting-character(s)' Указывает список символов, которые будут использованы для прорисовки разделительных линий в отчёте. В наших проектах по умолчанию используются такие символы как |_---|+|---+=|-/\<>*
LS = line-size Определяет длину строки выводимого отчёта (в символах). В наших проектах по умолчанию LS = 140 символов.
PS = page-size Определяет количество строк, выводимых на одну страницу. Применяется только для LISTING outputs. В наших проектах по умолчанию PS = 45 строк.
SPACING = space-between-columns Определяет расстояние (в символах) между колонками отчёта. Применяется только для LISTING outputs.
STYLE Применяется для вывода в формате RTF. Задает стиль отчёта. Подробности изучим ниже на примере.
Управление заголовками колонок
NOHEADER Если вы укажете эту опцию – SAS не станет выводить заголовки колонок
SPLIT = 'character' Указывает split-символ, который позволит разбивать заголовки колонок на несколько строк
HEADLINE Подчёркивает все заголовки колонок, а также расстрояния между ними. Применяется только для LISTING outputs.
HEADSKIP Выводит пустую строку под всеми заголовками колонок. Применяется только для LISTING outputs.
Выравнивание значений в колонках, а также заголовки колонок
DEFINE LEFT | CENTER | RIGHT Задает выравнивание значений в колонках по левому краю (LEFT), по центру (CENTER) либо по правому краю (RIGHT)
‘column-header’ Задает заголовок для выводимой колонки
Управление внешним видом выводимой колонки
FORMAT = format Накладывает на выводимую переменную заранее определенный SAS format
ORDER = DATA | FORMATTED | FREQ | INTERNAL

Упорядочивает значения ORDER или GROUP переменных согласно выбранному порядку:

  • ORDER = DATA – в том порядке, в котором значения идут в input data set;
  • ORDER = FORMATTED – по форматированному значению переменной;
  • ORDER = FREQ – по частоте, таким образом, что значения с наибольшей частотой пойдут первыми;
  • ORDER = INTERNAL – по неформатированному значению переменной, как правило именно этот вид сортировки используется при создании отчёта.
SPACING = horizontal-positions Используется для LISTING output. Задает количество символов, которое будет вставлено перед выводом текущей колонки. Так, например, для вывода самой первой колонки в отчёте spacing будет равен 0, т.е. вывести колонку, не отступая от левого края.
WIDTH = column-width Указывает ширину выводимой колонки (в символах для LISTING ouput). Помним, что сумма ширин всех колонок + spacings между колонками должны сходиться к тому числу, что записано в опции LS оператора PROC REPORT для LISTING output.
STYLE Применяется для вывода в формате RTF. Задает стиль вывода конкретной колонки. Тут обычно задают ширину колонки в %. Подробности изучим ниже на примере.
Управление использованием выводимой колонки
DISPLAY Определяет выводимую переменную, как DISPLAY колонку, т.е. значения переменной будут просто «показаны» в отчёте
GROUP Определяет выводимую переменную, как GROUP колонку, т.е. в процессе формирования отчёта одинаковые значения переменной будут сгруппированы
ORDER Определяет выводимую переменную, как ORDER колонку, т.е. в процессе формирования отчёта значения переменной будут отсортированы в порядке, указанном в опции ORDER =
FLOW Дает возможность “разнести” длинный текст в колонке на несколько строк. Если ваши значения не влезут в определённую вами длину колонки (WIDTH = ) и вы не укажете опцию FLOW, то выводимы текст обрежется. Также опция может быть использована для переноса значений переменной на несколько строк в местах, где встречается SPLIT символ
ID Указывает, что выводимая переменная – это ID-переменная. Удобно использовать в случаях, когда информация не может быть представлена на одной странице, и чтобы не повторять определение колонок на след. странице – можно указать начальные колонки, как ID, тогда SAS повторит их за вас автоматически на всех последующих страницах.
NOPRINT Указывает, что данную колонку не нужно выводить в отчёт. NOPRINT-колонки (они же переменные), как правило используют для сортировки данных прямо в PROC REPORT.
BREAK location

Указывает в каком месте нужно вставить новую строку и/или страницу. Возможные значения:

  • BEFORE – т.е. пустая строка и/или новая страница будет вставлена ПЕРЕД каждым встреченным значением break-variable;
  • AFTER - пустая строка и/или новая страница будет вставлена ПОСЛЕ каждого встреченного значения break-variable;
break-variable Указывает имя переменной, перед/после каждого встреченного значения которой будет вставлен BREAK. Переменная должна быть предварительно объявлена в операторе COLUMN, а также описана как ORDER или GROUP в операторе DEFINE.
SKIP Вставляет пустую строку BEFORE/AFTER each break-variable’s value. Применяется для LISTING outputs.
PAGE Вставляет новую страницу BEFORE/AFTER each break-variable’s value. Применяется как для LISTING outputs, так и для RTF outputs. Для корректной работы с RTF нужно указать опцию STARTPAGE = YES в ODS RTF statement.

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

За основу возьмем все тот же 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.4.1

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

proc report data=scores;
run;

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

6.4.2

Итак, что же мы видим. В окно REPORT вывелась вся информация, которая содержится в датасете SCORES. Заголовки колонок совпадают с именами переменных, но различить визуально где заголовки, а где сами данные - трудно. Общее впечатление – вывод ничем не отличается от использования PROC PRINT, поэтому дальше будем работать с процедурой без вывода в окно REPORT, а сам отчёт сразу сохраним в простой текстовый файл.

Давайте кастомизируем наш вызов PROC REPORT таким образом, чтобы:

Для этого выполним такой код:

ods listing file="U:\SAS Training Project\list\Kristina Levi (teacher)\REPORT.lst";

title1 "                                             Listing of Students' Progress";
title2 "____________________________________________________________________________________________________________________________________";

footnote1 "____________________________________________________________________________________________________________________________________";
footnote2 "Note: Students' scores for the following subjects are listed: Math, English, Biology, Economics";

proc report data=scores nowd nocenter split='@' headline headskip spacing=0 ls=132 ps=45;
  column name subject score;

  define name/order order=internal "Student's@Name" left width=44;
  define subject/display "Subject" left width=44;
  define score/display "Subject's@Score" left width=44;

  break after name/skip;
run;

Итак, что же мы видим:

После выполнения вышеприведенного кода отчёт будет выглядеть так:

6.4.3

С выводом в обычный текстовый файл разобрались, теперь давайте перейдем к выводу в формате RTF.

Для этого выполним такой код:

ods rtf file="c:\Users\stina\Desktop\REPORT.rtf" style=minimal startpage=yes;
options orientation=landscape;

title1 justify=c "Listing of Students' Progress";
footnote1 justify=l "Note: Students' scores for the following subjects are listed: Math, English, Biology, Economics";

proc report data=scores nowd center split='@';
  column name subject score;

  define name/order order=internal "Student's@Name" left style=[width=30%];
  define subject/display "Subject" left style=[width=30%];
  define score/display "Subject's@Score" left style=[width=30%];

  compute after name;
    line '';
  endcomp;
run;

ods rtf close;

Теперь давайте откроем наш REPORT.rtf и посмотрим, что получилось:

6.4.4

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

Код программы создания отчёта в форматах .lst и .rtf:

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;

* Creating .lst report;
ods listing file="U:\SAS Training Project\list\Kristina Levi (teacher)\REPORT.lst";

title1 "                                             Listing of Students' Progress";
title2 "____________________________________________________________________________________________________________________________________";

footnote1 "____________________________________________________________________________________________________________________________________";
footnote2 "Note: Students' scores for the following subjects are listed: Math, English, Biology, Economics";

proc report data=scores nowd nocenter split='@' headline headskip spacing=0 ls=132 ps=45;
  column name subject score;

  define name/order order=internal "Student's@Name" left width=44;
  define subject/display "Subject" left width=44;
  define score/display "Subject's@Score" left width=44;

  break after name/skip;
run;

* Creating .rtf report;
ods rtf file="c:\Users\stina\Desktop\REPORT.rtf" style=minimal startpage=yes;
options orientation=landscape;

title1 justify=c "Listing of Students' Progress";
footnote1 justify=l "Note: Students' scores for the following subjects are listed: Math, English, Biology, Economics";

proc report data=scores nowd center split='@';
  column name subject score;

  define name/order order=internal "Student's@Name" left style=[width=30%];
  define subject/display "Subject" left style=[width=30%];
  define score/display  "Subject's@Score" left style=[width=30%];

  compute after name;
    line '';
  endcomp;
run;

ods rtf close;

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