BookmarkSubscribeRSS Feed
0 Likes
When processing character in a data step, SAS silently truncates the result when assigning it to a variable with length shorter than the result. I know this is standard, documented behavior and that SAS programmers are generally aware of it. However in even mildly complex data steps, a small oversight can lead to truncations that are difficult to detect at all, let alone quickly find the source problem. So the idea is to add an option to report errors or warnings whenever a DATA step assignment statement truncates the value.
 
I'd guess that in 99% of these cases, the truncation is clearly undesired behavior, like in this example:

 

 

/* definition of shortvar; in practice, this may be imported or
heavily processed data, so it isn't obvious what length it has */
data example1;
    shortvar = "short";
run;

data example2;
    set example1;
    shortvar = shortvar || ' long'; /* silently truncates */
run;

proc print data=example2;
run;

/* output:

obs   shortvar
1     short

*/

 

 
This type of truncation is obviously not desired because it happens when we try to add more characters. The result is that the variable appears unchanged and it isn't obvious why.
1 Comment
ballardw
Super User

Actually length has little to do with what is going on with this particular case. It is the behavior of the || operator.

data example1;
    length shortvar $ 15;
    shortvar = "short";
run;

data example2;
    set example1;
    shortvar = shortvar || ' long'; /* silently truncates */
run;

The variable is "long enough" but the operator appends to the full length of the the existing variable which is PADDED for the || operation with blanks.

So to ever have a chance you would need to use code like

data example2;
    set example1;
    shortvar = trim(shortvar) || ' long'; /* silently truncates */
run;

or Strip,  or one of CATS or CATT functions.

WHEN the actual cause of the truncation is the length of the variable then add a length statement before the SET but you still to address the behavior of || .

data example1;
    shortvar = "short";
run;

data example2;
    length shortvar $ 15;
    set example1;
    shortvar = trim(shortvar) || ' long'; /* silently truncates */
run;