DATA Step, Macro, Functions and more

madness with PUTC and PUTN

Posts: 0

madness with PUTC and PUTN

I'm going crazy trying to figure out a highly customized risk dimensions program. There is one paticular line of the code that involves using the PUTC (or PUTN on numeric values). The orriginal program is extremely complex but I have simplified it down to this for example purposes;

Data frank;
input num1 num2 num3 ;
1 2 3
4 5 6
7 8 9

data postfrank;
set frank;
length a1 a2 a3 $32. ;
array thenums{3} a1-a3 ('num1','num2','num3');

When I run this code in an EG or PC SAS session the variable myresult is null just as I would expect, null. Except in our production environment, which runs this code in DI studio, the code seems to work.

The way I understand PUTN/PUTC is that the variable myfmt holds the format name to apply to the contents of myvar. This is true in the documentation and when I run it in PC SAS or EG.

But the way the orriginal code is working in our production environment is the myvar holds the name of the variable whos contents should be formated. That variable can change depending on other information in the observation. Based on the way things are working in prod, but not in my PC SAS or EG session, is that myresult in POSTFRANK should have the following values;

obs 1: '001'
obs 2: '005'
obs 3: '009'

Has any one come accross this kind of functionality or had to deal with this? Am I making sense or have I gone loco?
Respected Advisor
Posts: 3,893

Re: madness with PUTC and PUTN

Hi Jeff

The array statement you use in your code is not correct (have a look at the log). To get the desired result you have to write something like:

array thenums{3} num1-num3 ;

You can't initialise array vars using other variables. An array is created and array elements are initialised during data step initialisation - but you have only during data step iteration values for variables (and that's too late).

You don't need the variables a1-a3.

If you use the array statement as above you're getting the expected result.

What you're doing is initialising the variables a1-a3 in the following way:
a1='myvar1'; as value, the string 'myvar1' passed to the variable a1
a2='myvar2'; ......

And then you're using the format z3. on a string which is not a number. That just can't work.
I was quite astonished that SAS didn't throw a ERROR when I was running your original code (in SAS 8.2).

By the way:
Running a Job in SAS DI and in SAS EG creates sessions exactly in the same way (using the SAS object spawner to create a session on the SAS workspace server). PC SAS works a bit different.

You run jobs in DI normally only during development in a session. SAS DI is a development tool. The final jobs are most of the time run in batch.


P.S: You don't have to use 'putn' and 'putc' in SAS Base. The 'put' statement works for both numeric and character.

data postfrank;
set frank;
array thenums{3} num1-num3 ;

Hope you're aware that an additional line of data would lead to an error 'out of array subscript'

SAS code generated by DI is often quite hard to understand. You best get the DI project and look at the job flow from within SAS DI to understand what's going on. Message was edited by: Patrick
Posts: 8,743

Re: madness with PUTC and PUTN

PUTN and PUTC (along with their siblings INPUTN and INPUTC) do have a purpose in SAS code. Because the regular PUT/INPUT are not available with %SYSFUNC, you must use the PUTN/PUTC form of the PUT function with that macro function.

Also, a MAJOR difference between PUTN and PUTC and regular PUT (as you have rewritten the code) is that the format Z3 is hardcoded into the program. PUTN and PUTC allow the format to be specified at RUN time, not at COMPILE time. The doc for PUTN shows a good example of this: (see Example 1)

Posts: 0

Re: madness with PUTC and PUTN

I agree with everything you said as that what I was expecting. But that's not how things are currently running in some very old jobs in our production environment. When I run the code above it does error just like I expect in PC SAS, or EG in our development environment.

But in the production environment the above code in DI studio, in a much more complicated version, does without errors. How is it doing this? How can the production job defy the basic function of PUTN/PUTC?
Posts: 8,743

Re: madness with PUTC and PUTN

I suspect that you are comparing apples and oranges. You would have to run the EXACT same code on the two systems to be able to say that it was working correctly or incorrectly or differently on one system over the other.

It seems to me that your much more complicated code in DI studio is probably using PUTN and PUTC for a specific reason and if you want to find out what the reason is, you should open a track with Tech Support and have them work with you on the a test case that you can run on both systems to see whether the results are the same or not.

Without looking at the whole production job, it is impossible for anyone to answer your questions. The people best qualified to help you with a question of this type (especially with production questions) are the folks in Tech Support.

(if you used the VVALUEX function, you would get the expected results as shown in the log below -- run on PC SAS 9.1.3)


786 data postfrank;
787 set frank;
788 length a1 a2 a3 $32. ;
789 array thenums{3} a1-a3 ('num1','num2','num3');
790 myvar=thenums(_N_);
791 myfmt='Z3';
792 myresult=putn(vvaluex(myvar),myfmt);
793 put '*********';
794 put a1= a2= a3= _n_= myvar= myfmt= myresult=;
795 put '*********';
796 run;

NOTE: Character values have been converted to numeric values at the places given by: (Line)Smiley SadColumn).
a1=num1 a2=num2 a3=num3 _N_=1 myvar=num1 myfmt=Z3 myresult=001
a1=num1 a2=num2 a3=num3 _N_=2 myvar=num2 myfmt=Z3 myresult=005
a1=num1 a2=num2 a3=num3 _N_=3 myvar=num3 myfmt=Z3 myresult=009
NOTE: There were 3 observations read from the data set WORK.FRANK.
NOTE: The data set WORK.POSTFRANK has 3 observations and 9 variables.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds

Ask a Question
Discussion stats
  • 4 replies
  • 3 in conversation