2

I am using PROC REPORT to compare two fields and store a result in a third computed field. Some of my fields are numeric and some are character. I don't want to show the fields to compare, just the result, so I applied the NOPRINT option when I defined the fields.

The character fields work just fine, but if I don't sort or group on the numeric fields then I get missing values back. Here is an SSCCE to illustrate the problem:

(Please note that the example below is extremely simplified - my actual code is significantly more complex. I am hoping for a canonical answer rather than a workaround.)

Sample Data

DATA Work.Example;

    INFILE  DATALINES
            DELIMITER = ','
            ;

    INPUT   N1
            N2
            C1      $
            C2      $
            ;

DATALINES;
2,1,A,B
1,2,G,S
2,6,J,P
3,9,L,Q
5,3,X,T
5,8,X,E
4,0,T,S
5,7,K,W
;
RUN;

The result:

N1  N2  C1  C2
 2   1   A   B
 1   2   G   S
 2   6   J   P
 3   9   L   Q
 5   3   X   T
 5   8   X   E
 4   0   T   S
 5   7   K   W

PROC REPORT

PROC REPORT DATA=Work.Example;

    COLUMNS     N1
                N2
                ID_N
                C1
                C2
                NAME
                ;

    DEFINE      N1      /   NOPRINT
                            ORDER
                        ;

    DEFINE      N2      /   NOPRINT
                        ;

    DEFINE      ID_N    /   'ID'
                            COMPUTED
                        ;

    DEFINE      C1      /   NOPRINT
                            ORDER
                        ;

    DEFINE      C2      /   NOPRINT
                        ;

    DEFINE      NAME    /   'Name'
                            COMPUTED
                        ;

    COMPUTE ID_N / CHARACTER LENGTH=3;
        * I am sorting on N1, but I want to repeat N1 for each row
        * so carry the value from one row to the next when it is missing  ;
        IF NOT MISSING(N1) THEN N1_tmp = N1;

        ID_N = CATX( '.', N1_tmp, N2 );
    ENDCOMP;

    COMPUTE NAME / CHARACTER LENGTH=7;
        * I am sorting on C1, but I want to repeat C1 for each row
        * so carry the value from one row to the next when it is missing  ;
        IF NOT MISSING(C1) THEN C1_tmp = C1;

        NAME = CATX( '-', C1_tmp, C2 );
    ENDCOMP;

RUN;

Here is the result...

ID  Name
1.. G-S
2.. A-B
2.. J-P
3.. L-Q
4.. T-S
5.. K-W
5.. X-T
5.. X-E

As far as I can see, there is no difference at all between how I am treating the character field versus how I am treating the numeric field, so why is there a difference in the result?

JDB
  • 25,172
  • 5
  • 72
  • 123

2 Answers2

1

I am not a PROC REPORT expert (or even intermediate user). However, I would work around this with a datastep to create your "computed" columns.

Like so:

data temp;
set example;
format C1_tmp $7. ID_N $3. NAME $7.;
retain N1_tmp C1_tmp;
IF NOT MISSING(N1) THEN N1_tmp = N1;

ID_N = CATX( '.', N1_tmp, N2 );

IF compress(C1) ^= "" THEN C1_tmp = C1;

NAME = CATX( '-', C1_tmp, C2 );

run;

PROC REPORT DATA=Work.temp nowindows;

    COLUMNS     N1
                ID_N
                C1
                NAME
                ;

    DEFINE      N1      /   NOPRINT
                            ORDER
                        ;
    DEFINE      ID_N    /   'ID'
                        ;

    DEFINE      C1      /   NOPRINT
                            ORDER
                        ;
    DEFINE      NAME    /   'Name'
                        ;
RUN;
DomPazz
  • 12,415
  • 17
  • 23
  • I appreciate the reply, but I want to avoid workarounds. My actual code is very complex and I want to avoid "workarounds" that just add clutter to the codebase if at all possible. (My actual code is using ODS to manipulate the output formatting as well as the value, so I really *must* have the COMPUTE statement working.) – JDB Sep 13 '13 at 17:29
1

You need to define N2 as display, so

DEFINE      N2      /   display NOPRINT;

N2 as numeric defaults to ANALYSIS (see Analysis Variables), so you technically can't access N2 (but can access N1, which you defined as ORDER) but rather N2.SUM, N2.MEAN, whatnot (N2.SUM is default, I believe).

You also could ask for _C2_.

JDB
  • 25,172
  • 5
  • 72
  • 123
Joe
  • 62,789
  • 6
  • 49
  • 67
  • `DISPLAY NOPRINT`? Sometimes SAS gives me migraines. – JDB Sep 13 '13 at 17:55
  • Indeed. `NOPRINT` is not actually a cell type - only DISPLAY, ACROSS, ANALYSIS, COMPUTED, or ORDER are. Even better, ORDER may have to appear twice on the same statement (ORDER and ORDER=DATA or whatever). Regular `ORDER=DATA` doesn't set it to an order variable... – Joe Sep 13 '13 at 18:01
  • Thanks - my colleagues and I were a but dumbstruck by this solution, but it works perfectly. Oh SAS... you've managed to hide my wallet in the toybox yet again. – JDB Sep 13 '13 at 18:18
  • When you say that the default is COMPUTED, do you mean that the default is ANALYSIS? – JDB Sep 13 '13 at 18:28
  • Yes, that is what I meant... :) – Joe Sep 13 '13 at 18:44