BookmarkSubscribeRSS Feed
edomachowske
Calcite | Level 5

Hello,

 

I was wondering if there was a way to create a demographic table like this one in SAS? I know frequency tables are possible but I wasnt sure if it was able to create tables with other formatting (not shown in the example) such as a row named age, and 3 age groups indented underneath it?  example.png

7 REPLIES 7
ballardw
Super User

The short answer is "yes". The longer answer is since you have different statistics in each row that the nice reporting procedures like tabulate and report will not be able to do them as SAS table generators want one of either Row or Column to be of a single statistic.

 

Indented grouping is possible:

proc format library=work;
value agerange
0 - <5 = '   0 to 5'
5 - <10= '   5 to 10'
10- high='  10+';
run;

/* just to make some example to show ages*/
data example;
   do age= 0 to 10;
      c= rand('table',.1,.2,.3,.4); /* selects a random integer 1 to 4 with probabilities*/
      do i= 1 to c;
         output;
      end;
   end;
   keep age c;
run; 

proc tabulate data=example;
   class age;
   classlev age / style=[asis=on];
   format age agerange.;
   var c;
   table all= 'All Ages' age='',n='Count' c*(range max min);
run;

though if you want to do a row title and then do statistics such as range, max min you will need two variables in procedure like tabulate, one to control the row label appearance (the class variable) and another to be used for calculating the statistics.

 

 

I was going to paste an example of one of my report tables but the forum reformatted it something terrible.

 

 
Reeza
Super User

Search LEXJANSEN.COM for demographic tables. You'll find a ton of resources on how to create the tables, including sample code and macros. 

rogerjdeangelis
Barite | Level 11
Flexible complex clinical demographics report

Style template at end of message.
You need to execute
%utl_rtflan100; * to build style;

This is a very old tip (2001?)
You can now get the median using sql, which cuts out 3 steps?

HAVE
====

Up to 40 obs from dm total obs=91

Obs     TRT     PAT     WGT       HGT     RCD    AGE    SEX

  1   Aspirin     1     77.1    138.78      1     50     2
  2   Aspirin    50     76.2    137.16      1     49     2
  3   Placebo     2     71.4    128.52      1     58     2
  4   Placebo    51    112.0    201.60      1     67     2
  5   Aspirin     3     56.0    100.80      1     61     2
  6   Placebo    52     84.4    151.92      1     61     2
  7   Aspirin     4     76.2    137.16      1     38     2
  8   Aspirin    53     70.3    126.54      1     64     2
  9   Aspirin     5     88.9    160.02      1     54     2
....

 87   Placebo    45     59.5    107.10      1     59     2
 88   Placebo    48     62.6    112.68      1     44     2
 89   Placebo    46     40.8     73.44      1     55     2
 90   Placebo    49     74.4    133.92      1     60     2
 91   Aspirin    47     64.2    115.56      1     55     2

LAYOUT OF REPORT
================

SEX
   a. First page
   b. First two rows
   c. Major heading Sex n (%)
   d. minor heading Male/Female


  value sex
     1  ='SEX @Page @01 @Order @010 @Sex - n (%)  @\li360 Male'
     2 = 'SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female';


proc format;
  value sex
     1  ='SEX @Page @01 @Order @010 @Sex - n (%)  @\li360 Male'
     2 = 'SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female';
  value rcd
     1 = "RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian"
     2 = "RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American"
     3 = "RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino"
     4 = "RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian"
     5 = "RCD @Page @01 @Order @080 @Race - n (%) @\li360 Japanese"
     6 = "RCD @Page @01 @Order @090 @Race - n (%) @\li360 American Indian or Alaska Native"
     7 = "RCD @Page @01 @Order @100 @Race - n (%) @\li360 Native Hawaiian or Other Pacific Islander"
    88 = "RCD @Page @01 @Order @110 @Race - n (%) @\li360 Other";
  value rcx
    2, 3, 4, 5, 6, 7, 88
        = "RCX @Page @01 @Order @022 @Race - n (%) @\li360 Non-White or Caucasian"
    1   = "RCX @Page @XX @Order @0XX @Race - n (%) @\li360 White Caucasian";    /* not in report */
  value age_n
    1  = "AGE @Page @02 @Order @010 @Age    @\li360 N"        @N
    2  = "AGE @Page @02 @Order @020 @Age    @\li360 Mean(SD)" @MEAN STD
    3  = "AGE @Page @02 @Order @030 @Age    @\li360 Median"   @MEDIAN
    4  = "AGE @Page @02 @Order @040 @Age    @\li360 Min, Max" @MIN MAX   ;  /* 8th item means univariate stat */
  value wgt_n
    1  = "WGT @Page @02 @Order @050 @Weight @\li360 N"        @N
    2  = "WGT @Page @02 @Order @060 @Weight @\li360 Mean(SD)" @MEAN STD
    3  = "WGT @Page @02 @Order @070 @Weight @\li360 Median"   @MEDIAN
    4  = "WGT @Page @02 @Order @080 @Weight @\li360 Min, Max" @MIN MAX  ;
  value hgt_n
    1  = "HGT @Page @02 @Order @090 @Height @\li360 N"        @N
    2  = "HGT @Page @02 @Order @100 @Height @\li360 Mean(SD)" @MEAN STD
    3  = "HGT @Page @02 @Order @110 @Height @\li360 Median"   @MEDIAN
    4  = "HGT @Page @02 @Order @120 @Height @\li360 Min, Max" @MIN MAX   ;
    /* expects all variables to have the same stats*/
    /* but can be generalized */

run;

WANT
====

see for rtf report

https://dl.dropboxusercontent.com/u/15716238/utl_datnul.rtf

Text version

PAGE 1

                                      Table : Demographics
                                   (Intent to Treat Population)

                                               Aspirin     Placebo     All
                                               (N= 45)     (N= 46)     (N= 91)
Sex - n (%)
  Male                                         9(20%)      12(26%)     21(23%)
  Female                                       36(80%)     34(74%)     70(77%)

Race - n (%)
  Non-White or Caucasian                       11(24%)     5(11%)      16(18%)
  White or Caucasian                           34(76%)     41(89%)     75(82%)
  Black or African American                    3(7%)       4(9%)       7(8%)
  Hispanic or Latino                           5(11%)      1(2%)       6(7%)
  Asian                                        2(4%)       0(0%)       2(2%)
  Japanese                                     0(0%)       0(0%)       0(0%)
  American Indian or Alaska Native             0(0%)       0(0%)       0(0%)
  Native Hawaiian or Other Pacific Islander    0(0%)       0(0%)       0(0%)
  Other                                        1(2%)       0(0%)       1(1%)

                                                                     Page 1 of 2
  Program: c:/utl/dm.sas_09FEB17
  Log: c:/utl/dm.log_09FEB17
  see Protocol 1013.6(Oncology)


PAGE 2
                                    Table : Demographics
                                 (Intent to Treat Population)

                                              Aspirin     Placebo     All
                                              (N= 45)     (N= 46)     (N= 91)
Age
  N                                              45          46          91
  Mean(SD)                                    52(8.6)     51(9.6)     51(9.1)
  Median                                      31, 68      26, 71      26, 71

Weight
  N                                              45          46         91
  Mean(SD)                                    74(15.2)    78(19.7)   76(17.7)
  Median                                      49, 125     41, 120    41, 125

Height
  N                                              45          46         91
  Mean(SD)                                    133(27.3    141(35.5)  137(31.8)
  Median                                      88, 224     73, 216    73, 224

                                                                   Page 2 of 2
  Program: c:/utl/dm.sas_09FEB17
  Log: c:/utl/dm.log_09FEB17
  see Protocol 1013.6(Oncology)

 *
 ____        _       _   _
/ ___|  ___ | |_   _| |_(_) ___  _ __
\___ \ / _ \| | | | | __| |/ _ \| '_ \
 ___) | (_) | | |_| | |_| | (_) | | | |
|____/ \___/|_|\__,_|\__|_|\___/|_| |_|

;

/* T002600 LATEST ATTEMPT TO CREATE COMPLEX REPORT WITH MINIMAL LINES OF CODE 10/7/2001 */

%let output1=d:/rtf/utl_datnul.rtf;

options validvarname=upcase; /* will not work without this */
proc sql;
   Create table dm(pat float, wgt float, hgt float, rcd float, trt varchar(8), age float, sex float);
   Insert into dm(pat, wgt, hgt, rcd, trt, age, sex)
   Values(1, 77.1, 138.78, 1, "Aspirin" 50, 2)    Values(50, 76.2, 137.16, 1, "Aspirin" 49, 2)
   Values(2, 71.4, 128.52, 1, "Placebo" 58, 2)    Values(51, 112.0, 201.60, 1, "Placebo" 67, 2)
   Values(3, 56.0, 100.80, 1, "Aspirin" 61, 2)    Values(52, 84.4, 151.92, 1, "Placebo" 61, 2)
   Values(4, 76.2, 137.16, 1, "Aspirin" 38, 2)    Values(53, 70.3, 126.54, 1, "Aspirin" 64, 2)
   Values(5, 88.9, 160.02, 1, "Aspirin" 54, 2)    Values(54, 87.1, 156.78, 2, "Placebo" 54, 2)
   Values(6, 119.8, 215.64, 2, "Placebo" 50, 2)   Values(55, 89.4, 160.92, 1, "Placebo" 49, 2)
   Values(7, 66.7, 120.06, 1, "Placebo" 43, 2)    Values(56, 88.5, 159.30, 1, "Aspirin" 56, 2)
   Values(8, 111.6, 200.88, 1, "Placebo" 66, 2)   Values(57, 67.5, 121.50, 1, "Placebo" 42, 2)
   Values(9, 67.4, 121.32, 1, "Placebo" 47, 2)    Values(58, 102.5, 184.50, 1, "Placebo" 48, 2)
   Values(10, 92.1, 165.78, 1, "Placebo" 59, 2)   Values(59, 81.1, 145.98, 1, "Placebo" 53, 2)
   Values(11, 102.1, 183.78, 1, "Aspirin" 56, 2)  Values(60, 72.6, 130.68, 1, "Aspirin" 59, 2)
   Values(12, 66.2, 119.16, 1, "Placebo" 45, 2)   Values(61, 124.5, 224.10, 1, "Aspirin" 47, 2)
   Values(13, 112.5, 202.50, 2, "Placebo" 57, 2)  Values(62, 70.0, 126.00, 1, "Placebo" 43, 2)
   Values(14, 103.9, 187.02, 2, "Aspirin" 47, 2)  Values(63, 62.6, 112.68, 3, "Aspirin" 53, 2)
   Values(15, 70.8, 127.44, 1, "Placebo" 56, 2)   Values(64, 60.8, 109.44, 4, "Aspirin" 50, 2)
   Values(17, 79.8, 143.64, 1, "Aspirin" 68, 2)   Values(65, 58.7, 105.66, 1, "Placebo" 47, 2)
   Values(18, 65.1, 117.18, 1, "Placebo" 35, 2)   Values(66, 63.7, 114.66, 1, "Aspirin" 43, 2)
   Values(19, 100.7, 181.26, 1, "Placebo" 45, 2)  Values(67, 77.1, 138.78, 88, "Aspirin" 49, 2)
   Values(20, 61.7, 111.06, 1, "Aspirin" 54, 1)   Values(68, 53.5, 96.30, 1, "Placebo" 49, 2)
   Values(21, 79.2, 142.56, 2, "Placebo" 50, 1)   Values(69, 95.7, 172.26, 1, "Aspirin" 55, 2)
   Values(22, 89.8, 161.64, 1, "Placebo" 54, 1)   Values(70, 68.0, 122.40, 3, "Aspirin" 57, 2)
   Values(23, 63.1, 113.58, 2, "Aspirin" 38, 1)   Values(71, 54.0, 97.20, 3, "Aspirin" 66, 2)
   Values(24, 67.8, 122.04, 1, "Placebo" 57, 1)   Values(72, 85.3, 153.54, 3, "Aspirin" 44, 2)
   Values(25, 82.6, 148.68, 1, "Aspirin" 53, 1)   Values(74, 52.2, 93.96, 1, "Aspirin" 55, 2)
   Values(26, 90.7, 163.26, 1, "Placebo" 38, 1)   Values(75, 86.2, 155.16, 1, "Aspirin" 58, 2)
   Values(27, 73.0, 131.40, 1, "Aspirin" 60, 1)   Values(76, 59.0, 106.20, 3, "Placebo" 46, 2)
   Values(28, 64.4, 115.92, 1, "Placebo" 38, 1)   Values(77, 59.0, 106.20, 4, "Aspirin" 45, 2)
   Values(29, 59.4, 106.92, 1, "Placebo" 51, 1)   Values(78, 116.6, 209.88, 1, "Placebo" 51, 2)
   Values(30, 70.8, 127.44, 1, "Aspirin" 61, 1)   Values(79, 55.1, 99.18, 1, "Placebo" 39, 2)
   Values(31, 72.1, 129.78, 1, "Aspirin" 56, 1)   Values(80, 64.9, 116.82, 1, "Aspirin" 40, 2)
   Values(32, 54.0, 97.20, 1, "Aspirin" 56, 1)    Values(81, 85.3, 153.54, 1, "Aspirin" 53, 2)
   Values(33, 62.8, 113.04, 1, "Aspirin" 37, 1)   Values(82, 45.8, 82.44, 1, "Placebo" 57, 2)
   Values(34, 62.6, 112.68, 1, "Placebo" 37, 1)   Values(83, 71.7, 129.06, 2, "Aspirin" 52, 2)
   Values(35, 79.4, 142.92, 1, "Placebo" 44, 1)   Values(84, 61.9, 111.42, 1, "Aspirin" 34, 2)
   Values(36, 60.8, 109.44, 1, "Placebo" 50, 1)   Values(85, 82.1, 147.78, 1, "Aspirin" 46, 2)
   Values(37, 89.8, 161.64, 3, "Aspirin" 50, 1)   Values(86, 58.5, 105.30, 1, "Aspirin" 53, 2)
   Values(38, 76.8, 138.24, 1, "Placebo" 40, 1)   Values(87, 68.9, 124.02, 1, "Aspirin" 66, 2)
   Values(39, 87.1, 156.78, 1, "Placebo" 51, 1)   Values(88, 68.9, 124.02, 1, "Aspirin" 42, 2)
   Values(40, 64.3, 115.74, 1, "Placebo" 26, 1)   Values(89, 104.8, 188.64, 1, "Placebo" 69, 2)
   Values(41, 109.0, 196.20, 1, "Placebo" 58, 2)  Values(90, 79.4, 142.92, 1, "Placebo" 65, 2)
   Values(42, 77.2, 138.96, 1, "Placebo" 44, 2)   Values(91, 87.1, 156.78, 1, "Aspirin" 58, 2)
   Values(43, 78.0, 140.40, 1, "Aspirin" 57, 2)   Values(92, 89.8, 161.64, 1, "Placebo" 71, 2)
   Values(44, 49.0, 88.20, 1, "Aspirin" 31, 2)    Values(93, 75.3, 135.54, 1, "Aspirin" 52, 2)
   Values(45, 59.5, 107.10, 1, "Placebo" 59, 2)   Values(48, 62.6, 112.68, 1, "Placebo" 44, 2)
   Values(46, 40.8, 73.44, 1, "Placebo" 55, 2)    Values(49, 74.4, 133.92, 1, "Placebo" 60, 2)
   Values(47, 64.2, 115.56, 1, "Aspirin" 55, 2)
 ;quit;

proc print width=min;
run;quit;

/* report layout */
/* need formats because not all levels are in the data

    'SEX@Page @01 @Order @01 @Sex - n (%)  @\li360 Male'

      SEX variable and format for variable
      Page   1 of reprt
      Order  1 first lne on page 1
      Sex - n(%) Major Heading
      Male- Minor heading

      formats that end in _n are  univariate stats -> mean(sd)
      8th items on univariate variables are the requires stats
*/

/* cannot have formats prior to this code - could backup and restore */
proc datasets library=work mt=catalog;
  delete formats;
run;quit;

/* this method does require that you layout the entire report - see non format method for work around */
/* it might be better in the future to add a treatment format - even though it is not needed */
proc format;
  value sex
     1  ='SEX @Page @01 @Order @010 @Sex - n (%)  @\li360 Male'
     2 = 'SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female';
  value rcd
     1 = "RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian"
     2 = "RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American"
     3 = "RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino"
     4 = "RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian"
     5 = "RCD @Page @01 @Order @080 @Race - n (%) @\li360 Japanese"
     6 = "RCD @Page @01 @Order @090 @Race - n (%) @\li360 American Indian or Alaska Native"
     7 = "RCD @Page @01 @Order @100 @Race - n (%) @\li360 Native Hawaiian or Other Pacific Islander"
    88 = "RCD @Page @01 @Order @110 @Race - n (%) @\li360 Other";
  value rcx
    2, 3, 4, 5, 6, 7, 88
        = "RCX @Page @01 @Order @022 @Race - n (%) @\li360 Non-White or Caucasian"
    1   = "RCX @Page @XX @Order @0XX @Race - n (%) @\li360 White Caucasian";    /* not in report */
  value age_n
    1  = "AGE @Page @02 @Order @010 @Age    @\li360 N"        @N
    2  = "AGE @Page @02 @Order @020 @Age    @\li360 Mean(SD)" @MEAN STD
    3  = "AGE @Page @02 @Order @030 @Age    @\li360 Median"   @MEDIAN
    4  = "AGE @Page @02 @Order @040 @Age    @\li360 Min, Max" @MIN MAX   ;  /* 8th item means univariate stat */
  value wgt_n
    1  = "WGT @Page @02 @Order @050 @Weight @\li360 N"        @N
    2  = "WGT @Page @02 @Order @060 @Weight @\li360 Mean(SD)" @MEAN STD
    3  = "WGT @Page @02 @Order @070 @Weight @\li360 Median"   @MEDIAN
    4  = "WGT @Page @02 @Order @080 @Weight @\li360 Min, Max" @MIN MAX  ;
  value hgt_n
    1  = "HGT @Page @02 @Order @090 @Height @\li360 N"        @N
    2  = "HGT @Page @02 @Order @100 @Height @\li360 Mean(SD)" @MEAN STD
    3  = "HGT @Page @02 @Order @110 @Height @\li360 Median"   @MEDIAN
    4  = "HGT @Page @02 @Order @120 @Height @\li360 Min, Max" @MIN MAX   ;
    /* expects all variables to have the same stats*/
    /* but can be generalized */

run;

/* put the layout into a sas table */
proc format library=work.formats cntlout=unv1st;
run;

/* normalize the data                                                   */
/* you could generate this data step from the format - I choose to KISS */
data nrm1st;
  keep    trt question answer;
  length  question  $96;
  set dm;
  question=put(sex,sex.); answer=1;   link all;
  question=put(rcd,rcd.); answer=1;   link all;
  question=put(rcd,rcx.); answer=1;   link all;
  question='AGE'        ; answer=age; link all;
  question='WGT'        ; answer=wgt; link all;
  question='HGT'        ; answer=hgt; link all;
return;
all:
  output;
  savtrt=trt;
  trt="All";
  output;
  trt=savtrt;
return;
run;

/*
Up to 40 obs WORK.NRM1ST total obs=1,092

 Obs QUESTION                                                              TRT            ANSWER

   1 SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female                Aspirin             1
   2 SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female                All                 1
   3 RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian    Aspirin             1
   4 RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian    All                 1
   5 RCX @Page @XX @Order @0XX @Race - n (%) @\li360 White Caucasian       Aspirin             1
   6 RCX @Page @XX @Order @0XX @Race - n (%) @\li360 White Caucasian       All                 1
   7 AGE                                                                   Aspirin            50
   8 AGE                                                                   All                50
   9 WGT                                                                   Aspirin          77.1
  10 WGT                                                                   All              77.1
  11 HGT                                                                   Aspirin        138.78
  12 HGT                                                                   All            138.78
*/

/* need the shell so missing categories can be represented in the report         */
/* note we use the format to generate all combinations                           */
/* answer will be the weights missing categories will have 0 counts and percents */
data shl;
 length  question  $96;
 keep trt question answer;
 set unv1st(where=(scan(label,8,'@') eq ''));      /* only categorical variables */
 trt="Placebo"; question=label; answer=0; output;
 trt="Aspirin"; question=label; answer=0; output;
 trt="All"    ; question=label; answer=0; output;
run;

/*
Up to 40 obs WORK.SHL total obs=54

Obs  QUESTION                                                                   TRT            ANSWER

  1  RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian         Placebo             0
  2  RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian         Aspirin             0
  3  RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian         All                 0
  4  RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American  Placebo             0
  5  RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American  Aspirin             0
  6  RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American  All                 0
*/

/* fill in the missing categories with 0 answers(weights) */
proc sql;
 create
   table shldat  as
 select
   coalesce(dat.trt,shl.trt)                                   as trt
  ,coalesce(substr(dat.question,1,3),substr(shl.question,1,3)) as grp       length=3
  ,coalesce(dat.question,shl.question)                         as question
  ,coalesce(dat.answer,shl.answer)                             as answer
 from
  (select distinct * from shl) as shl left join nrm1st as dat
 on
  shl.question = dat.question  and
  shl.trt      = dat.trt
 order
  by grp, trt, question;
;quit;

/*
All Obs(560) from dataset shldat
                                                                                                              Weights
Obs  TRT      GRP  QUESTION                                                                                    ANSWER

133  Aspirin  RCD  RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                               1
134  Aspirin  RCD  RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                               1
135  Aspirin  RCD  RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                               1
136  Aspirin  RCD  RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                               1
137  Aspirin  RCD  RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian                                            1
138  Aspirin  RCD  RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian                                            1
139  Aspirin  RCD  RCD @Page @01 @Order @080 @Race - n (%) @\li360 Japanese                                         0 Not in data
140  Aspirin  RCD  RCD @Page @01 @Order @090 @Race - n (%) @\li360 American Indian or Alaska Native                 0 Not in data
141  Aspirin  RCD  RCD @Page @01 @Order @100 @Race - n (%) @\li360 Native Hawaiian or Other Pacific Islander        0
142  Aspirin  RCD  RCD @Page @01 @Order @110 @Race - n (%) @\li360 Other                                            1
*/


/* categorical n(pct) variables */
proc sql;
   create
     table cntpct as
   select
    distinct
     l.trt
    ,l.grp
    ,l.question
    ,r.sumgrp
    ,cats(put(sum(l.answer),4.),'(',put(sum(l.answer)/r.sumgrp,percent.),')') as answer
  from
     shldat as l, (select trt, grp, sum(answer) as sumgrp from shldat group by trt, grp) as r
  where
     l.trt        =  r.trt  and
     l.grp        =  r.grp
  group
     by l.trt, l.grp, l.question
;quit;

/*
Up to 40 obs WORK.CNTPCT total obs=36

Obs    TRT        GRP    QUESTION                                                                                  SUMGRP   ANSWER

  1    All        RCD    RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian                            91   75(82%)
  2    All        RCD    RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American                     91   7(8%)
  3    All        RCD    RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                            91   6(7%)
  4    All        RCD    RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian                                         91   2(2%)
  5    All        RCD    RCD @Page @01 @Order @080 @Race - n (%) @\li360 Japanese                                      91   0(0%)
  6    All        RCD    RCD @Page @01 @Order @090 @Race - n (%) @\li360 American Indian or Alaska Native              91   0(0%)
  7    All        RCD    RCD @Page @01 @Order @100 @Race - n (%) @\li360 Native Hawaiian or Other Pacific Islander     91   0(0%)
  8    All        RCD    RCD @Page @01 @Order @110 @Race - n (%) @\li360 Other                                         91   1(1%)
  9    All        RCX    RCX @Page @01 @Order @022 @Race - n (%) @\li360 Non-White or Caucasian                        91   16(18%)
 10    All        RCX    RCX @Page @XX @Order @0XX @Race - n (%) @\li360 White Caucasian                               91   75(82%)
 11    All        SEX    SEX @Page @01 @Order @010 @Sex - n (%)  @\li360 Male                                          91   0(0%)
 12    All        SEX    SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female                                        91   91(100%)
 13    Aspirin    RCD    RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian                            45   34(76%)
 14    Aspirin    RCD    RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American                     45   3(7%)
 15    Aspirin    RCD    RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                            45   5(11%)
 16    Aspirin    RCD    RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian                                         45   2(4%)
*/

/* lets get the statistics we need from the format */
proc sql;
  select distinct(scan(label,8,'@')) into :unvanl separated by ' ' from unv1st where index(fmtname,'_N')>0;
  select distinct(quote(strip(scan(label,1,'@')))) into :unvvar separated by ' ' from unv1st where index(fmtname,'_N')>0;
quit;
%put &=unvanl;
%put &=unvvar;

/*
UNVANL=MEAN STD MEDIAN MIN MAX N
UNVVAR="AGE" "HGT" "WGT"
*/

ods output summary=demunv;
proc means data=nrm1st(where=(scan(question,1,'@') in (&unvvar))) &unvanl nway;
format question $3.;
class trt question;
var answer;
run;
ods output close;

/*
Up to 40 obs from demunv total obs=9

                                                          ANSWER_         ANSWER_
Obs    TRT         QUESTION  NOBS     ANSWER_MEAN          STDDEV          MEDIAN      ANSWER_MIN      ANSWER_MAX        ANSWER_N

 1     All         AGE         91    51.164835165    9.0740946733              52              26              71              91
 2     All         HGT         91    137.14021978    31.816178344          130.68           73.44           224.1              91
 3     All         WGT         91    76.189010989    17.675654635            72.6            40.8           124.5              91

 4     Aspirin     AGE         45    51.733333333    8.5610109853              53              31              68              45
 5     Aspirin     HGT         45         133.056    27.306971338          129.78            88.2           224.1              45
 6     Aspirin     WGT         45           73.92    15.170539632            72.1              49           124.5              45

 7     Placebo     AGE         46    50.608695652    9.6112856369              50              26              71              46
 8     Placebo     HGT         46    141.13565217    35.530819151          136.08           73.44          215.64              46
 9     Placebo     WGT         46    78.408695652    19.739343973            75.6            40.8           119.8              46
*/

* normalize;
data nrmunv;
 keep trt grp question answer;
 length question answer $96;
 do until (dne);
   set demunv end=dne;
   format _all_;
   grp=question;
   fmt=strip(question)!!'_n';
   question=putn(1,fmt);
   answer=put(answer_n,5.);
   output;
   question=putn(2,fmt);
   answer=cats(put(answer_mean,??5.),'(',put(answer_stddev,??5.1),')');
   output;
   question=putn(3,fmt);
   answer=strip(put(answer_min,5.))!!', '!!strip(put(answer_max,5.));
   output;
 end;
 do until (dn1);
   set cntpct end=dn1;
   format _all_;
   output;
 end;
 stop;
run;

/*
Obs    QUESTION                                                                                     ANSWER       TRT        GRP

  1    AGE @Page @02 @Order @010 @Age    @\li360 N        @N                                           91        All        AGE
  2    AGE @Page @02 @Order @020 @Age    @\li360 Mean(SD) @MEAN STD                                 51(9.1)      All        AGE
  3    AGE @Page @02 @Order @030 @Age    @\li360 Median   @MEDIAN                                   26, 71       All        AGE
  4    HGT @Page @02 @Order @090 @Height @\li360 N        @N                                           91        All        HGT
  5    HGT @Page @02 @Order @100 @Height @\li360 Mean(SD) @MEAN STD                                 137(31.8)    All        HGT
  6    HGT @Page @02 @Order @110 @Height @\li360 Median   @MEDIAN                                   73, 224      All        HGT
  7    WGT @Page @02 @Order @050 @Weight @\li360 N        @N                                           91        All        WGT
  8    WGT @Page @02 @Order @060 @Weight @\li360 Mean(SD) @MEAN STD                                 76(17.7)     All        WGT
  9    WGT @Page @02 @Order @070 @Weight @\li360 Median   @MEDIAN                                   41, 125      All        WGT
 28    RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian                           75(82%)      All        RCD
 29    RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American                    7(8%)        All        RCD
 30    RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                           6(7%)        All        RCD
 31    RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian                                        2(2%)        All        RCD
 32    RCD @Page @01 @Order @080 @Race - n (%) @\li360 Japanese                                     0(0%)        All        RCD
 33    RCD @Page @01 @Order @090 @Race - n (%) @\li360 American Indian or Alaska Native             0(0%)        All        RCD
 34    RCD @Page @01 @Order @100 @Race - n (%) @\li360 Native Hawaiian or Other Pacific Islander    0(0%)        All        RCD
 38    SEX @Page @01 @Order @010 @Sex - n (%)  @\li360 Male                                         21(23%)      All        SEX
 39    SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female                                       70(77%)      All        SEX

proc sort data=nrmunv out=srt nodupkey;
  by question trt;
run;

proc transpose data=srt out=xpo(drop=_name_) ;
 by question;
 id trt;
 var answer;
run;

/*
proc print width=min;
run;quit;

Obs    QUESTION                                                                                     ALL          ASPIRIN      PLACEBO

  1    AGE @Page @02 @Order @010 @Age    @\li360 N        @N                                           91           45           46
  2    AGE @Page @02 @Order @020 @Age    @\li360 Mean(SD) @MEAN STD                                 51(9.1)      52(8.6)      51(9.6)
  3    AGE @Page @02 @Order @030 @Age    @\li360 Median   @MEDIAN                                   26, 71       31, 68       26, 71
  4    HGT @Page @02 @Order @090 @Height @\li360 N        @N                                           91           45           46
  5    HGT @Page @02 @Order @100 @Height @\li360 Mean(SD) @MEAN STD                                 137(31.8)    133(27.3)    141(35.5)
  6    HGT @Page @02 @Order @110 @Height @\li360 Median   @MEDIAN                                   73, 224      88, 224      73, 216
  7    RCD @Page @01 @Order @030 @Race - n (%) @\li360 White or Caucasian                           75(82%)      34(76%)      41(89%)
  8    RCD @Page @01 @Order @050 @Race - n (%) @\li360 Black or African American                    7(8%)        3(7%)        4(9%)
  9    RCD @Page @01 @Order @060 @Race - n (%) @\li360 Hispanic or Latino                           6(7%)        5(11%)       1(2%)
 10    RCD @Page @01 @Order @070 @Race - n (%) @\li360 Asian                                        2(2%)        2(4%)        0(0%)
 11    RCD @Page @01 @Order @080 @Race - n (%) @\li360 Japanese                                     0(0%)        0(0%)        0(0%)
 12    RCD @Page @01 @Order @090 @Race - n (%) @\li360 American Indian or Alaska Native             0(0%)        0(0%)        0(0%)
 13    RCD @Page @01 @Order @100 @Race - n (%) @\li360 Native Hawaiian or Other Pacific Islander    0(0%)        0(0%)        0(0%)
 14    RCD @Page @01 @Order @110 @Race - n (%) @\li360 Other                                        1(1%)        1(2%)        0(0%)
 15    RCX @Page @01 @Order @022 @Race - n (%) @\li360 Non-White or Caucasian                       16(18%)      11(24%)      5(11%)
 16    RCX @Page @XX @Order @0XX @Race - n (%) @\li360 White Caucasian                              75(82%)      34(76%)      41(89%)
 17    SEX @Page @01 @Order @010 @Sex - n (%)  @\li360 Male                                         21(23%)      9(20%)       12(26%)
 18    SEX @Page @01 @Order @020 @Sex - n (%)  @\li360 Female                                       70(77%)      36(80%)      34(74%)
 19    WGT @Page @02 @Order @050 @Weight @\li360 N        @N                                           91           45           46
 20    WGT @Page @02 @Order @060 @Weight @\li360 Mean(SD) @MEAN STD                                 76(17.7)     74(15.2)     78(19.7)
 21    WGT @Page @02 @Order @070 @Weight @\li360 Median   @MEDIAN                                   41, 125      49, 125      41, 120
*/

proc sql;
 create
   table prerpt as
 select
    input(scan(question,3,'@'),5.) as pge
   ,scan(question,5,'@')           as odr length=3
   ,scan(question,6,'@')           as mjr length=64
   ,scan(question,7,'@')           as mnr length=64
   ,aspirin  length=24
   ,placebo  length=24
   ,all      length=24
 from
   xpo
 where
   scan(question,5,'@') ne 'XX'
 order
   by pge, odr
;quit;

proc sql;select max(pge) into :maxpge separated by '' from prerpt;quit;

%put &=maxpge;
/* MAXPGE=2 */

/* lets get big N's */
proc sql;
  select resolve('%Let '!!trt!!'=%sysfunc(compbl('!!trt!!'#(N='!!Put(Count(answer),4.)!!');))')
  from nrm1st where question='AGE'  Group by Trt
;quit;

%put &=all;
%put &=aspirin;
%put &=placebo;

/*
ALL=All #(N= 91)
ASPIRIN=Aspirin #(N= 45)
PLACEBO=Placebo #(N= 46)
%put &=sysdate;
*/

%let ttl1=Table : Demographics;
%let TTL2=Safety Dataset;
%let TTL3=(Intent to Treat Population);
%let TTL4=Placebo-Aspirin;

/*
%put &=ttl1;

%utl_rtflan100;

options nodate nonumber orientation=portrait;
title;footnote;
ods escapechar='^';
ods listing close;
ods rtf file="&output1" style=utl_rtflan100 notoc_data;
%macro mny(pgemax);
 %do pge=1 %to &pgemax;
  ods rtf prepage="^S={outputwidth=100% just=c font_size=11pt font_face=arial} {&ttl1}^{newline}{&ttl3}";
  proc report data=prerpt (where=(pge=&pge)) nowd split='#' missing;
     cols  mjr mnr aspirin placebo all;
      define mjr           / order    noprint order=data;
      define mnr           / display  ""         style={cellwidth=30%  just=l } order=data;
      define aspirin       / display  "&aspirin" style={cellwidth=22%  just=c } order=data;
      define placebo       / display  "&placebo" style={cellwidth=22%  just=c } order=data;
      define All           / display  "&All"     style={cellwidth=23%  just=c } order=data;
      compute before mjr / style=[just=l];
        line mjr $96.;
      endcomp;
  run;quit;
  ods rtf text="^S={outputwidth=100% just=r font_size=9pt} Page &pge of &pgemax";
  ods rtf text="^S={outputwidth=100% just=l font_size=8pt font_style=italic}  {Program: c:/utl/dm.sas_&sysdate}";
  ods rtf text="^S={outputwidth=100% just=l font_size=8pt font_style=italic}  {Log: c:/utl/dm.log_&sysdate}";
  ods rtf text="^S={outputwidth=100% just=l font_size=8pt font_style=italic}  {see Protocol 1013.6(Oncology)}";
  run;quit;
 %end;
%mend mny;
%mny(&maxpge);
ods rtf close;
ods listing;


/*

PAGE 1

                                      Table : Demographics
                                   (Intent to Treat Population)

                                               Aspirin     Placebo     All
                                               (N= 45)     (N= 46)     (N= 91)
Sex - n (%)
  Male                                         9(20%)      12(26%)     21(23%)
  Female                                       36(80%)     34(74%)     70(77%)

Race - n (%)
  Non-White or Caucasian                       11(24%)     5(11%)      16(18%)
  White or Caucasian                           34(76%)     41(89%)     75(82%)
  Black or African American                    3(7%)       4(9%)       7(8%)
  Hispanic or Latino                           5(11%)      1(2%)       6(7%)
  Asian                                        2(4%)       0(0%)       2(2%)
  Japanese                                     0(0%)       0(0%)       0(0%)
  American Indian or Alaska Native             0(0%)       0(0%)       0(0%)
  Native Hawaiian or Other Pacific Islander    0(0%)       0(0%)       0(0%)
  Other                                        1(2%)       0(0%)       1(1%)

                                                                     Page 1 of 2
  Program: c:/utl/dm.sas_09FEB17
  Log: c:/utl/dm.log_09FEB17
  see Protocol 1013.6(Oncology)


PAGE 2
                                      Table : Demographics
                                   (Intent to Treat Population)

                                              Aspirin     Placebo     All
                                              (N= 45)     (N= 46)     (N= 91)
Age
  N                                              45          46          91
  Mean(SD)                                    52(8.6)     51(9.6)     51(9.1)
  Median                                      31, 68      26, 71      26, 71

Weight
  N                                              45          46         91
  Mean(SD)                                    74(15.2)    78(19.7)   76(17.7)
  Median                                      49, 125     41, 120    41, 125

Height
  N                                              45          46         91
  Mean(SD)                                    133(27.3    141(35.5)  137(31.8)
  Median                                      88, 224     73, 216    73, 224

                                                                   Page 2 of 2
  Program: c:/utl/dm.sas_09FEB17
  Log: c:/utl/dm.log_09FEB17
  see Protocol 1013.6(Oncology)


*____ _______   ___     _____
/ ___|_   _\ \ / / |   | ____|
\___ \ | |  \ V /| |   |  _|
 ___) || |   | | | |___| |___
|____/ |_|   |_| |_____|_____|

;



%Macro utl_rtflan100
    (
      style=utl_rtflan100,
      frame=box,
      rules=groups,
      bottommargin=1.0in,
      topmargin=1.5in,
      rightmargin=1.0in,
      cellheight=10pt,
      cellpadding = 7,
      cellspacing = 3,
      leftmargin=.75in,
      borderwidth = 1
    ) /  Des="SAS Rtf Template for CompuCraft";

options orientation=landscape;run;quit;

ods path work.templat(update) sasuser.templat(update) sashelp.tmplmst(read);

Proc Template;

   define style &Style;
   parent=styles.rtf;


        replace body from Document /

               protectspecialchars=off
               asis=on
               bottommargin=&bottommargin
               topmargin   =&topmargin
               rightmargin =&rightmargin
               leftmargin  =&leftmargin
               ;

        replace color_list /
              'link' = blue
               'bgH'  = _undef_
               'fg'  = black
               'bg'   = _undef_;

        replace fonts /
               'TitleFont2'           = ("Arial, Helvetica, Helv",11pt,Bold)
               'TitleFont'            = ("Arial, Helvetica, Helv",11pt,Bold)

               'HeadingFont'          = ("Arial, Helvetica, Helv",10pt)
               'HeadingEmphasisFont'  = ("Arial, Helvetica, Helv",10pt,Italic)

               'StrongFont'           = ("Arial, Helvetica, Helv",10pt,Bold)
               'EmphasisFont'         = ("Arial, Helvetica, Helv",10pt,Italic)

               'FixedFont'            = ("Courier New, Courier",9pt)
               'FixedEmphasisFont'    = ("Courier New, Courier",9pt,Italic)
               'FixedStrongFont'      = ("Courier New, Courier",9pt,Bold)
               'FixedHeadingFont'     = ("Courier New, Courier",9pt,Bold)
               'BatchFixedFont'       = ("Courier New, Courier",7pt)

               'docFont'              = ("Arial, Helvetica, Helv",10pt)

               'FootFont'             = ("Arial, Helvetica, Helv", 9pt)
               'StrongFootFont'       = ("Arial, Helvetica, Helv",8pt,Bold)
               'EmphasisFootFont'     = ("Arial, Helvetica, Helv",8pt,Italic)
               'FixedFootFont'        = ("Courier New, Courier",8pt)
               'FixedEmphasisFootFont'= ("Courier New, Courier",8pt,Italic)
               'FixedStrongFootFont'  = ("Courier New, Courier",7pt,Bold);

        replace GraphFonts /
               'GraphDataFont'        = ("Arial, Helvetica, Helv",8pt)
               'GraphAnnoFont'        = ("Arial, Helvetica, Helv",8pt)
               'GraphValueFont'       = ("Arial, Helvetica, Helv",10pt)
               'GraphUnicodeFont'     = ("Arial, Helvetica, Helv",10pt)
               'GraphLabelFont'       = ("Arial, Helvetica, Helv",10pt,Bold)
               'GraphLabel2Font'      = ("Arial, Helvetica, Helv",10pt,Bold)
               'GraphFootnoteFont'    = ("Arial, Helvetica, Helv",8pt)
               'GraphTitle1Font'      = ("Arial, Helvetica, Helv",11pt,Bold)
               'GraphTitleFont'       = ("Arial, Helvetica, Helv",11pt,Bold);

        style table from table /
                outputwidth=100%
                protectspecialchars=off
                asis=on
                background = colors('tablebg')
                frame=&frame
                rules=&rules
                cellheight  = &cellheight
                cellpadding = &cellpadding
                cellspacing = &cellspacing
                bordercolor = colors('tableborder')
                borderwidth = &borderwidth;

         replace Footer from HeadersAndFooters

                / font = fonts('FootFont')  just=left asis=on protectspecialchars=off ;

                replace FooterFixed from Footer
                / font = fonts('FixedFootFont')  just=left asis=on protectspecialchars=off;

                replace FooterEmpty from Footer
                / font = fonts('FootFont')  just=left asis=on protectspecialchars=off;

                replace FooterEmphasis from Footer
                / font = fonts('EmphasisFootFont')  just=left asis=on protectspecialchars=off;

                replace FooterEmphasisFixed from FooterEmphasis
                / font = fonts('FixedEmphasisFootFont')  just=left asis=on protectspecialchars=off;

                replace FooterStrong from Footer
                / font = fonts('StrongFootFont')  just=left asis=on protectspecialchars=off;

                replace FooterStrongFixed from FooterStrong
                / font = fonts('FixedStrongFootFont')  just=left asis=on protectspecialchars=off;

                replace RowFooter from Footer
                / font = fonts('FootFont')  asis=on protectspecialchars=off just=left;

                replace RowFooterFixed from RowFooter
                / font = fonts('FixedFootFont')  just=left asis=on protectspecialchars=off;

                replace RowFooterEmpty from RowFooter
                / font = fonts('FootFont')  just=left asis=on protectspecialchars=off;

                replace RowFooterEmphasis from RowFooter
                / font = fonts('EmphasisFootFont')  just=left asis=on protectspecialchars=off;

                replace RowFooterEmphasisFixed from RowFooterEmphasis
                / font = fonts('FixedEmphasisFootFont')  just=left asis=on protectspecialchars=off;

                replace RowFooterStrong from RowFooter
                / font = fonts('StrongFootFont')  just=left asis=on protectspecialchars=off;

                replace RowFooterStrongFixed from RowFooterStrong
                / font = fonts('FixedStrongFootFont')  just=left asis=on protectspecialchars=off;

                replace SystemFooter from TitlesAndFooters / asis=on
                        protectspecialchars=off just=left;

    end;
run;

quit;

%Mend utl_rtflan100;

Reeza
Super User

@rogerjdeangelis Solution assumes you are using SAS 9.4+

Cynthia_sas
SAS Super FREQ
Hi:
In addition to Reeza's comment, the REPLACE statement in PROC TEMPLATE was changed between 9.1 and 9.2. Essentially, REPLACE works just like STYLE, but just in case anyone thinks of using REPLACE in the future, read this paper: http://www2.sas.com/proceedings/sugi31/053-31.pdf footnote of interest is on Page 1.

cynthia
heatherjae15
Obsidian | Level 7

I need to make a demographics table with two columns: the first column is measure and the rows are age, gender, race, ethnicity, height, weight and bmi.  the second column must include numbers are mean +/- SD, median, min, max for continuous variables and Percent (count/n)

 

Here is the code that isn't working

 

%Let output = c=\Prgram\datnul.rtf;

options validvarname=upcase;

Proc sql;

Create table demographics  (age sex race ethnicity weight height BMI);

Insert into demographics (age sex race ethnicity weight height BMI);

proc print width=min; run; quit;

 

proc datasets library=work mt=catalog;

delete formats;

run; quit;

Proc format;

value age_n

1= "age @Page @01  @order @010 @Age @\li360 N"  @N

2= "age @Page @01  @order @020 @Age @\li360 Mean(SD)" @Mean SD

3= "age@Page @01  @order @030 @Age @\li360 MINMAX" @MINMAX

4= "age @Page @01  @order @040 @Age @\li360 Median" @Median;

value sex

1 = 'sex @Page @01 @order @050@ sex-n(%) @\li360 Male'

2 = 'sex @Page @01 @order @060@ sex-n(%) @\li360 Female';

value race

1 = 'race @Page @01 @order @070@race-n(%) @\li360 Caucasian'

2 = 'race @Page @01 @order @080@race-n(%) @\li360 Black or African American'

3 = 'race @Page @01 @order @090@race-n(%) @\li360 American Indian or Alaska Native'

4 = 'race @Page @01 @order @100@race-n(%) @\li360 Asian'

5 = 'race @Page @01 @order @110@race-n(%) @\li360 Hawaiian or Pacific Islander'

6 = 'race@Page @01 @order @120@race-n(%) @\li360 Other'

7 = 'race @Page @01 @order @130@race-n(%) @\li360 NA';

value ethnicity

1 = 'ethnicity  @Page @01 @order @140@ethnicity -n(%) @\li360 Caucasian'

2 = 'ethnicity  @Page @01 @order @150@ethnicity -n(%) @\li360 Black or African American'

3 = 'ethnicity @Page @01 @order @160@ethnicity -n(%) @\li360 American Indian or Alaska Native';

 

value height_n

1= "Height @Page @02  @order @010 @Height @\li360 N" @N

2= "Height @Page @02  @order @020 @Height @\li360 Mean(SD)" @Mean SD

3= "Height @Page @02  @order @030 @Height @\li360 MINMAX" @MINMAX

4= "Height @Page @02  @order @040 @Height @\li360 Median" @Median;

value weight_n

1= "Weight @Page @02  @order @050 @Weight @\li360 N" @N

2= "Weight @Page @02  @order @060 @Weight @\li360 Mean(SD)" @Mean SD

3= "Weight @Page @02  @order @070 @Weight @\li360 MINMAX" @MINMAX

4= "Weight @Page @02  @order @080 @Height @\li360 Median" @Median;

 

value BMI_n

1= "BMI @Page @02  @order @090 @BMI @\li360 N" @N

2= "BMI @Page @02  @order @100 @BMI @\li360 Mean(SD)" @Mean SD

3= "BMI @Page @02  @order @110 @BMI @\li360 MINMAX" @MINMAX

4= "BMI @Page @02  @order @120 @BMI @\li360 Median" @Median;

run;

proc format library=work.formats cntlout=unv1st;

run;

data nrm1st;

keep age sex race ethnicity height weight BMI;

length question $96;

set dm;

 

proc format library=work.formats cntlout=un1st;

run;

data nrm1st;

keep trt;

return;

output;

savtrt=trt;

trt= "All";

output;

trt=savtrt;

return;

run;

 

Cynthia_sas
SAS Super FREQ
Hi: Without data, no one can test your code. And you've posted a program in a 2 year old track and your code does not bear any relation to the previously posted code. My recommendation is that you with work with Tech Support on this question because they can look at ALL your data and ALL your code and help you figure out whether this is the best approach. Or you should open a new, posting with both code and data. I note that your code has an opening ODS RTF statement, but only the PROC PRINT output would go to the RTF file, so I am not entirely sure that you've posted ALL your code since there is not a closing ODS RTF statement.

Cynthia

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 7 replies
  • 20550 views
  • 3 likes
  • 6 in conversation