DATA Step, Macro, Functions and more

"PUT" function and Formats

Posts: 0

"PUT" function and Formats

I have a variable of diagnosis codes called "Diag" it has different values ranging from 2 digits to 5 digits ( e.g. 72, 359, 3388, 23995). I am defining a CC and I was changing DIAG to a "character value" as in the following statement :
CC = LEFT(PUT(put(DIAG,5.),$I&VR.C.));

The problem from the output is that it recognizes "Diag" with 5 digits only. I want it to do the same with other "Diag " codes. What could I do to make sure it recognizes each of the codes whether they have 2, 3, 4 or 5 digits?
Posts: 8,743

Re: "PUT" function and Formats

SAS functions resolve from the innermost function call to the outermost function call. So your LEFT function isn't being applied
until after the PUT using $DIAG.

You have a couple of choices as shown in the progam below. If DIAG is a numeric variable, then you could just
make a numeric format for diagnosis codes and that would simplify everything (see NDIAG format and the CC_FROM_NUM
variable in the output.

Putting the LEFT in a different position works (CC_LEFT variable) also, using STRIP, COMPRESS or SCAN
functions return the desired results. However, the TRIM function does NOT work, because you need to remove ALL
blanks or have all blanks disregarded, not just the trailing blanks.

The program:
data diagcode;
infile datalines;
input name $ diag;
Alan 72
Bob 359
Carla 3388
Dana 23995

proc format;
value $diag '72'='Tennis Elbow'
'359' = 'Migraine'
'3388' = 'Imaginary Voices'
'23995' = 'Text Messaging Thumb';

value ndiag 72 = 'Tennis Elbow'
359 = 'Migraine'
3388 = 'Imaginary Voices'
23995 = 'Text Messaging Thumb';

options nodate nonumber nocenter;
title 'Use Diag Format';
data putdiag;
set diagcode;

cc_orig= LEFT(PUT(put(DIAG,5.),$diag.));
** break your original creation into 3 steps;
** you can see that the 2nd PUT of the character value;
** does NOT result in the desired code because;
** the numbers are still right justified when the;
** second PUT is performed. The LEFT function does not;
** have an effect after the second PUT.;
orig_2 = PUT(orig_1,$diag.);
orig_3 = left(orig_2);

* use a numeric format instead of a character format;
cc_from_num = put(diag,ndiag.);

** if you do use a character format, make sure to use;
** functions that result in your "trailing" spaces being ;
** ignored or disregarded for the put of $DIAG.;
** note how the LEFT function is used AFTER the first put;
** and BEFORE the second PUT (nested functions resolve from the inside out);
cc_left = put(left(put(diag,8.)),$diag.);
cc_str = put(strip(put(diag,8.)),$diag.);
cc_comp = put(compress(put(diag,8.)),$diag.);
cc_scan = put(scan(put(diag,8.),1),$diag.);

** trim does not produce the desired results;
cc_trim = put(trim(put(diag,8.)),$diag.);


options linesize=200;
proc print data=putdiag;

The output:
Use Diag Format

Obs name diag cc_orig orig_1 orig_2 orig_3 cc_from_num cc_left cc_str cc_comp cc_scan cc_trim

1 Alan 72 72 72 72 72 Tennis Elbow Tennis Elbow Tennis Elbow Tennis Elbow Tennis Elbow 72
2 Bob 359 359 359 359 359 Migraine Migraine Migraine Migraine Migraine 359
3 Carla 3388 3388 3388 3388 3388 Imaginary Voices Imaginary Voices Imaginary Voices Imaginary Voices Imaginary Voices 3388
4 Dana 23995 Text Messaging Thumb 23995 Text Messaging Thumb Text Messaging Thumb Text Messaging Thumb Text Messaging Thumb Text Messaging Thumb Text Messaging Thumb Text Messaging Thumb 23995

Posts: 0

Re: "PUT" function and Formats

Hi Cynthia,

You made my day. It worked perfectly. Thank you very much.

Ask a Question
Discussion stats
  • 2 replies
  • 2 in conversation