BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
GreggB
Pyrite | Level 9

I keep reading conflicting info.  Does CALL SYMPUTX automatically convert the value assigned to the macro variable to character (assuming it is numeric) or is the numeric format preserved?

1 ACCEPTED SOLUTION

Accepted Solutions
Astounding
PROC Star

Both SYMPUT and SYMPUTX convert the value to character before assigning to a macro variable.

 

SYMPUT gives you a message on the log about the conversion, while SYMPUTX does not.

 

SYMPUTX takes the additional step of removing any leading blanks that were caused by the conversion.

View solution in original post

13 REPLIES 13
Astounding
PROC Star

Both SYMPUT and SYMPUTX convert the value to character before assigning to a macro variable.

 

SYMPUT gives you a message on the log about the conversion, while SYMPUTX does not.

 

SYMPUTX takes the additional step of removing any leading blanks that were caused by the conversion.

Rick_SAS
SAS Super FREQ

I assume you are asking about the DATA step? You can read about the differences between SYMPUT and SYMPUTX in the SAS doc.

 

According to the SAS documentation,  the DATA step will use BEST12. to convert the numeric value to a character value.

 

Not every SAS language does an automatic conversion, so SYMPUTX is more robust. See: http://blogs.sas.com/content/iml/2011/10/17/does-symput-work-in-iml.html

 

GreggB
Pyrite | Level 9

yes, in the DATA step.

hashman
Ammonite | Level 13

Rick,

 

Methinks the part of the SAS doc you've cited re: automatic type conversion is relevant only to the particular situation described there, i.e. "If you specify a variable in an expression, but the variable value does not match the type called for". This appears not to be the case with SYMPUTX (nor with CAT*), and so using BEST12. for the conversion doesn't apply to them. Consider:

data _null_ ;                          
  call symputx ("x", 123456789012345) ;
run ;                                  
%put &=x ;                             

which prints in the log: X=123456789012345.If BEST12. were used, we would see X=1.2345679E14 instead. The docs for SYMPUTX and CAT* give no explicit indication as to which format is used internally; yet I recall Rick L telling me in Denver it's 32. At any rate, it's obviously longer than 12.

 

Paul D.

Tom
Super User Tom
Super User

Thanks. Another reason to favor CALL SYMPUTX() over the older CALL SYMPUT().

hashman
Ammonite | Level 13

@Tom: Agreed. The auto-stripping of the leading/trailing blanks doesn't hurt, either.

ScottBass
Rhodochrosite | Level 12

SAS will never say SYMPUT is deprecated.  After all, that 40+ year old code still needs to work. 

Yet IMO SYMPUT is deprecated.  I can't think of any reason to use it over SYMPUTX.


Please post your question as a self-contained data step in the form of "have" (source) and "want" (desired results).
I won't contribute to your post if I can't cut-and-paste your syntactically correct code into SAS.
Tom
Super User Tom
Super User

@ScottBass wrote:

SAS will never say SYMPUT is deprecated.  After all, that 40+ year old code still needs to work. 

Yet IMO SYMPUT is deprecated.  I can't think of any reason to use it over SYMPUTX.


The main use case is when you want to store the leading/trailing spaces into the macro variable. 

data _null_;
   set metadata ;
   call symput('left',put(chapter,$20.));
   call symput('middle',put(title,$40.-c));
   call symput('right',put(catx(' ','Page',pageno),$20.-R));
run;
title "&left.&middle.&right";
Tom
Super User Tom
Super User

CALL SYMPUT() and CALL SYMPUTX() will convert numbers to text using BEST12. format.

If you want to preserve the format attached to a number then either convert it to character yourself or use the VVALUE() (or VVALUEX()) function to get the formatted value.

data _null_;
  x=123456.890123456;
  format x dollar12.2 ;
  call symputx('v1',x);
  call symputx('v2',put(x,best32.));
  call symputx('v3',vvalue(x));
  dt=date();
  format dt yymmdd10.;
  call symputx('d1',dt);
  call symputx('d2',put(dt,date9.));
  call symputx('d3',vvalue(dt));
run;
26  %put &=v1 &=v2 &=v3 &=d1 &=d2 &=d3;
V1=123456.89012 V2=123456.890123456 V3=$123,456.89 D1=21020 D2=20JUL2017 D3=2017-07-20
ChrisNZ
Tourmaline | Level 20

@Tom  >CALL SYMPUT() and CALL SYMPUTX() will convert numbers to text using BEST12. format.

 

Only decimal numbers use format best12., integer precision seems better conserved by symputx() as @hashman  pointed out.

 

data _null_;
  INT=1234567890123456;
  format INT dollar22.0 ;
  call symput ('i1',INT);
  call symputx('i2',INT);
  call symputx('i3',put(INT,best12.));
  call symputx('i4',put(INT,best32.));
  call symputx('i5',vvalue(INT));
  DEC=123456.890123456;
  format DEC dollar12.2 ;
  call symput ('f1',DEC);
  call symputx('f2',DEC);
  call symputx('f3',put(DEC,best12.));
  call symputx('f4',put(DEC,best32.));
  call symputx('f5',vvalue(DEC));
  DTE=date();
  format DTE yymmdd10.;
  call symput ('d1',DTE);
  call symputx('d2',DTE);
  call symputx('d3',put(DTE,date9.));
  call symputx('d4',vvalue(DTE));
run;
%put INT Symput         &i1;
%put INT Symputx        &i2;
%put INT Symputx best12 &i3;
%put INT Symputx best32 &i4;
%put INT Symputx vvalue &i5;
%put DEC Symput         &f1;
%put DEC Symputx        &f2;
%put DEC Symputx best12 &f3;
%put DEC Symputx best32 &f4;
%put DEC Symputx vvalue &f5;
%put DTE Symput         &d1;
%put DTE Symputx        &d2;
%put DTE Symputx date9  &d3;
%put DTE Symputx vvalue &d4;

 

INT Symput         1.2345679E15
INT Symputx        1234567890123456
INT Symputx best12 1.2345679E15
INT Symputx best32 1234567890123456
INT Symputx vvalue $1,234,567,890,123,456
DEC Symput 123456.89012 DEC Symputx 123456.89012 DEC Symputx best12 123456.89012 DEC Symputx best32 123456.890123456 DEC Symputx vvalue $123,456.89
DTE Symput 21668 DTE Symputx 21668 DTE Symputx date9 29APR2019 DTE Symputx vvalue 2019-04-29

 

Tom
Super User Tom
Super User
CALL SYMPUTX() uses BEST32. instead of BEST12.
ChrisNZ
Tourmaline | Level 20

@Tom  > CALL SYMPUTX() uses BEST32. instead of BEST12.

 

No it doesn't necessarily do that. That's the point I am making.

It uses best12. for (some?) decimal numbers.

 

data _null_;
  INT=1234567890123456;
  put INT= best32. INT= best12.;
  call symputx('int',INT);
run;
%put &=int ;
data _null_; DEC=123456789.123456; put DEC= best32. DEC= best12.; call symputx('dec',DEC); run; %put &=dec;

INT=1234567890123456 INT=1.2345679E15
INT=1234567890123456

 

DEC=123456789.123456 DEC=123456789.12
DEC=123456789.12

 

Tom
Super User Tom
Super User

It does seem to only use the longer width for integers (or values that are close enough to an integer that the decimal part wouldn't print anyway).

SAS Innovate 2025: Register Now

Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 13 replies
  • 61219 views
  • 26 likes
  • 7 in conversation