SAS ODS RTF - лучший вариант для вставки заголовка / сноски в таблицу

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

введите здесь описание изображения

Варианты, изученные на данный момент

1) ОТЧЕТ О ПРОЦЕССЕ - ВЫЧИТАЙТЕ СТРАНИЦУ ПЕРЕД (КОМПЬЮТЕР не поддерживает параметр выравнивания и не нашел надежного варианта для выравнивания текста "страница x из y" по правому краю в title1, например, вычисление и вставка ПУСТОГО пробела. Вдобавок мне нужно по центру выровнять заголовок)

2) ODS RTF - параметр BODYTITLE и BODYTITLE_AUX (отображает заголовок / сноску как часть тела, но не точно как часть таблицы - нелегко выбрать как один объект)


person R007    schedule 03.12.2019    source источник
comment
Пожалуйста, добавьте несколько примеров данных и текущий код Proc REPORT, с которым вы наиболее близки на данный момент.   -  person Richard    schedule 03.12.2019
comment
Вы можете заглянуть в PROC ODSTEXT, чтобы добавить текст в отчет в указанных форматах. Номера страниц немного сложнее.   -  person Reeza    schedule 04.12.2019


Ответы (2)


Возможно, будет проще отредактировать RTF.

  1. прочтите файл и подсчитайте количество вхождений cf1 {Page
    {\ field {* \ fldinst {PAGE}}} из {\ field {* \ fldinst {NUMPAGES
    }}} \ cell}

  2. затем снова прочитайте и измените эти строки при записи нового файла
    .

person data _null_    schedule 03.12.2019

Директива встроенного стиля SAS ODS ^{PAGEOF} создаст в выходном файле вывод Страница x из y. Поскольку выходные данные представляют собой поле Word, вам может потребоваться Ctrl-A, F9 для вычисления значений полей при открытии документа.

Назначение RTF отображает TITLE и FOOTNOTE в верхней и нижней части документов, поэтому необходимы уловки для создания «заголовков» и «нижних колонтитулов» для каждой таблицы. С моей точки зрения как читателя документов, лучшее место для PAGEOF было бы в разделе заголовка, а не как часть заголовка таблицы.

ods escapechar = '^';
title justify=right '^{PAGEOF}';  

ODS TEXT = может использоваться для добавления абзацев до и после Proc TABULATE, который выполняет статистическую отчетность. ODS TEXT = будет обрабатывать встроенные директивы форматирования ODS (включая PAGEOF). См. Руководство пользователя по системе доставки: SAS® 9.4. Заявление ODS ESCAPECHAR для получения дополнительной информации.

ods text='
Narrative before tabular output via ODS TEXT=
^{NEWLINE} Inline styling directives will be processed.
^{NEWLINE} ^{STYLE [color=green]Mix and match}
^{NEWLINE} Let''s see why.
';

ods text='Here you are at ^{STYLE ^{PAGEOF}}';
* This might require Word field computation or print preview to get proper numbers;

В зависимости от места назначения STYLE =, например ods rtf style=plateau … ODS TEXT, могут быть некоторые обводки или другие артефакты стиля.

Если вы заядлый любитель rtf, ODS TEXT= также может вводить коды rtf непосредственно в целевой поток для создания любой возможной продукции rtf. В следующем примере:

  • Функция устаревшего стиля ^S{attr-name=attr-value} используется, чтобы заставить текстовый контейнер занимать 100% ширины страницы.
  • функция текущего стиля ^{RAW функция используется для введения необработанного кодирования rtf. Каждый { фактического rtf вводится с использованием {RAW. Обратите внимание на то, как RAW могут быть (и есть) вложенными.

ods text = '^S={outputwidth=100% just=c} ^{RAW \rtf1\ansi\deff0^{RAW \fonttbl^{RAW \f0 Arial;}} 
\qc\f0\fs20\i\b
 This output created with ODS TEXT=\line
 Injecting raw RTF coding\line
 Such as ^{RAW \cf11\ul colored and underlined}\line
 Not for the casual coder.
}'; 

Some procedures, such as Proc PRINT have style options such as style(table)=[ … ] in which a pretext= and posttext= can be specified, and such texts will be rendered before and after the rtf table -- the texts are not part of the table and would not be 'picked up' in a single click of Word's 'table select' icon (Table select icon). Also, unfortunately, the pretext= and posttext= values are not processed for ODS styling directives. However, the values can be raw rtf!

PRETEXT, демонстрирующий встроенный стиль, не уважается:

proc print
  data=sashelp.class (obs=3)
  noobs
  style(table)=[
   pretext='^{STYLE [color=Red]Above 1 ^{NEWLINE}Above 2 - Pretext= is unprocessed ODS directives}' 
   posttext='^{STYLE [color=Green] Below}'
  ]
;
run;

выходной рисунок

PRETEXT демонстрируется как переданный необработанный rtf (когда первый символ {)

proc print 
  data=sashelp.class (obs=3)
  noobs
  style(table)=[
    pretext='{\rtf1\ansi\deff0{\fonttbl{\f0 Arial;}}
\qc\f0\fs20\i\b This output created with SAS PRETEXT=
\line Injecting raw RTF coding
\line Not for the casual coder.
}'
    posttext='{\rtf1\ansi\deff0{\fonttbl{\f0 Arial;}}
\qc\f0\fs20\i\b This output created with SAS POSTTEXT=
\line Injecting raw RTF coding
\line Not for the casual coder.
}'
  ]
;
run;

выходной рисунок

Proc TABULATE не имеет параметра style(table), но оператор TABLE имеет параметры:

  • / CAPTION= (rendered when OPTION ACCESSIBLETABLE; active)
    • Note: Caption value is rendered in the page dimension container, so the caption value be overwritten if your TABLE statement has a page dimension in it's crossings.
  • / STYLE=[PRETEXT='...' POSTTEXT='...']
    • Same caveats as mentioned earlier

TABULATE не:

  • иметь любую функцию, которая позволит вам аннотировать заголовок столбца статистикой строки (в данном случае ваш (N = ###) как часть значения категории). Шаг предварительного вычисления, который суммирует пересечения, которые должны быть сведены в таблицу, позволит вам разместить там статистику.
  • предоставить любой механизм для вставки пустой строки или строки метки, охватывающей таблицу (например, оператор LINE в Proc REPORT)

Рассмотрим этот пример таблицы с включенным accessibletable для некоторых медицинских данных. Некоторые из переменных предназначены для:

  • категориальные демографические данные (например, пол),
  • непрерывные измерения (например, стоимость возраста),
  • бинарные флаги о состоянии.
data have;
  call streaminit(123);

  do _n_ = 1 to 1e3 - 300 + rand('uniform',600);
    patientId + 1;

    category = ceil(rand('uniform',4));

    age = 69 + floor(rand('uniform',20));
    cost = 500 + floor(rand('uniform',250));

    length sex $1;
    sex = substr('MF', 1+rand('uniform',2));

    array flags flag1-flag3; * some flags asserting some medical state is present;
    do over flags; flags = rand('uniform', 4) < _i_; end;

    output;
  end;

  label age = 'Age' cost = 'Cost' sex = 'Sex';
run;

* Precomputation step;
* Use SQL to compute the N= crossings and make that part of a
* new variable that will be in the tabulation column dimension;

proc sql;
  create table for_tabulate as
  select 
    *
    , catx(' ', 'Category', category, '( n =', count(*), ')') 
      as category_counted_columnlabel
  from have
  group by category
  ;
quit;

Табличный отчет

options accessibletable;

proc tabulate data=for_tabulate ;

  class 
    category_counted_columnlabel 
    sex
  /
    missing style=[fontsize=18pt]
  ;

  var age cost flag1-flag3;

  table

    /* row dimension */
    age * ( mean std min max median n*f=8.) * [style=[cellwidth=0.75in]]
    N='Sex' * sex
    cost * ( mean std min max median n*f=8. ) 
    (flag1 - flag3) * mean = '%' * f=percent5.1

    ,

    /* column dimension */
    category_counted_columnlabel = ''

    /

    /* options */
    nocellmerge
    caption = "This is caption text is ^{STYLE [color=green]from Mars}^{NEWLINE}Next line"
  ;

run;

введите здесь описание изображения

Для версий SAS до 9.4M6 вы можете добавить переменную размера страницы (значение которой представляет собой встроенный текст, стилизованный под ODS в качестве заголовка) к выходным данным этапа предварительного вычисления и указать эту переменную в операторе таблицы. Что-то вроде

,    '^{NEWLINE}title1'  /* SQL step */
  || '^{NEWLINE}title2'
  || '^{NEWLINE}title3'
  || '^{NEWLINE}title4'
  as pagedim_title

а также

/* tabulate step */
class pagedim_title / style = [background=lightgray fontfamily=Arial textalign=right];
table pagedim_title, …, category_counted_columnlabel = '' … ;
person Richard    schedule 12.12.2019