Question

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?

Was it helpful?

Solution

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_.

OTHER TIPS

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;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top