BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
Quodly
Obsidian | Level 7
data a;
  x1 = "asdf";

  y = "1";
  z = vvaluex(cats("x", y)); /* get value of variable whose name contains value of another variable */
run;

/**/

%let x1 = asdf;
data b;
  y = "1";
  z = symget(cats("x", y)); /* get value of macro vaiable whose name contains value of a variable */
run;

/**/

proc format;
  value $ x1_fmt
    "asdf" = "fdsa"
  ;
run;

data c1;
  z = "asdf";
  format z x1_fmt.; /* this is what i want */
run;

data c2;
  y = "1";
  z = "asdf";
  format z function(cats("x", y, "_fmt")); /* is there such a function? */
run;

i know the function vvaluex for variables and the function symget for macro variables, as in the example above. is there a similar function for formats? i'd like to avoid if-then and select-when.

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

@Quodly wrote:

thank you for your help.

 

my example is misleading for my actual intention: i want to use formats for table lookups. for example:

 

data c1;
  z1 = "asdf";
  z2 = put(z1, x1_fmt.);
run;

for that, i don't need to change the metadata of a data set. the format which i want to use for the table lookup depends on another variable (variable y in my example). of course, i can just use if-then to choose the right format, but i was curious if there is another method as with vvaluex or symget in a similar context.

 


Then you can use PUTC/PUTN where you can generate the name via a string and pass that to the PUTC/PUTN function. 

View solution in original post

10 REPLIES 10
PaigeMiller
Diamond | Level 26

You could use a macro variable, but this will take two consecutive data steps.

 

data c2;
  y = "1";
  call symputx('y',y);
run;
data c3;
  z = "asdf";
  format z x&y._fmt.; 
run;
--
Paige Miller
Oligolas
Barite | Level 11

Hi,

 

not directly, since several formats could contain the value 'asdf'.

In a dataset, the function vformat returns the format that is associated with the specified variable. But I bet you already know this.

You could write out the formats and search for the ones that contain the value you look for.

 

ods listing;
proc format cntlout=work.myformats;
run;
%let seek=%upcase(asdf);
%let fmtnames=;
PROC SQL noprint;
   SELECT distinct FMTNAME INTO :fmtnames SEPARATED BY ' '
   FROM myformats
   WHERE index(upcase(strip(label)),"&seek.")
   OR index(upcase(start),"&seek.")
   OR index(upcase(end),"&seek.")
   ORDER BY fmtname
   ;
QUIT;
%put Formats containing "&seek.": &=fmtnames.;

 

 

________________________

- Cheers -

Reeza
Super User

Not for format unfortunately. For conversion, PUTC/PUTN work but you also need to know the variable type.

Tom
Super User Tom
Super User

You cannot modify the metadata of a dataset in during the execution of the step that is making the dataset.

So if you want to modify the format attached to a variable based on the value in the data you will need at least two steps.  One to determine the name of the format and another to attach that format to a variable.

 

You could add a pre-processing step to determine the format and use that information to attach the format in the step that generates the dataset.  Or add a post processing step to modify the format that is attached.

 

data want;
  set have;
 call symputx('fmt',cats('$x',y,'_fmt.'));
run;

Now you will have a macro variable named FMT with a name based on the LAST value of the variable Y read from the dataset HAVE.  You can use that to modify the metadata of the dataset WANT to indicate that Z should use that format to display its values.

proc datasets nolist lib=work;
  modify want;
    format z &fmt ;
  run;
quit;
Quodly
Obsidian | Level 7

thank you for your help.

 

my example is misleading for my actual intention: i want to use formats for table lookups. for example:

 

data c1;
  z1 = "asdf";
  z2 = put(z1, x1_fmt.);
run;

for that, i don't need to change the metadata of a data set. the format which i want to use for the table lookup depends on another variable (variable y in my example). of course, i can just use if-then to choose the right format, but i was curious if there is another method as with vvaluex or symget in a similar context.

 

Quentin
Super User

This works:

data c1;
  z1 = "asdf";
  z2 = put(z1, x1_fmt.);
run;

Because the PUT statement works while the step is executing, processing data.

 

 

This could not work:

 

data c2;
  y = "1";
  z = "asdf";
  format z function(cats("x", y, "_fmt")); /* is there such a function? */
run;

 

Because the FORMAT statement works while the data step is compiling, before the step has read in any data.  

 

But I'm confused by your clarification.  If you're not trying to assign a format to a variable, but you just want to use a format that already exists, you could do that with the PUTC function and use the VFORMAT function to look up the format.  That will work because they work at execution time.  Do you want something like this?

 

proc format ;  
  value $ z1_fmt 
    'asdf'='hi' 
    'jkl' ='mom' 
  ;
run ;

data c1 ;
  z1='asdf' ;
  format z1 $z1_fmt. ;
  z2='jkl' ;
  z3=putc(z2,vformat(z1)) ;
run ;

proc print ;
run ;

 

 

The Boston Area SAS Users Group is hosting free webinars!
Next up: Lisa Mendez & Richann Watson present Get Tipsy with Debugging Tips for SAS® Code: The After Party on Wednesday Jul 16.
Register now at https://www.basug.org/events.
Tom
Super User Tom
Super User

@Quodly wrote:

thank you for your help.

 

my example is misleading for my actual intention: i want to use formats for table lookups. for example:

 

data c1;
  z1 = "asdf";
  z2 = put(z1, x1_fmt.);
run;

for that, i don't need to change the metadata of a data set. the format which i want to use for the table lookup depends on another variable (variable y in my example). of course, i can just use if-then to choose the right format, but i was curious if there is another method as with vvaluex or symget in a similar context.

 


You seem to have left out the variable the value of 1 in this example.  If you have that variable then just use the PUTC() function.  If Z1 was a numeric variable you would use the PUTN() function.   Or if you wanted Z2 to be numeric and Z1 was character then use the INPUTN() function.  All four of those functions allow the format to passed as a string instead of as part of the code.

 

Also character variables need character formats.  The names of character formats start with a $.

 

  z2 = putc(z1, cats('$x',y,'_fmt.'));
Quodly
Obsidian | Level 7
And thank you for the reminder that character formats start with a dollar sign. I'm always a bit confused by value/invalue, put/input; and now that I've learned of putc/putn...
Reeza
Super User

@Quodly wrote:

thank you for your help.

 

my example is misleading for my actual intention: i want to use formats for table lookups. for example:

 

data c1;
  z1 = "asdf";
  z2 = put(z1, x1_fmt.);
run;

for that, i don't need to change the metadata of a data set. the format which i want to use for the table lookup depends on another variable (variable y in my example). of course, i can just use if-then to choose the right format, but i was curious if there is another method as with vvaluex or symget in a similar context.

 


Then you can use PUTC/PUTN where you can generate the name via a string and pass that to the PUTC/PUTN function. 

Quodly
Obsidian | Level 7

Great, that's what I've been looking for! Thank you all - I should have stated my question more clearly at the beginning.

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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
  • 10 replies
  • 2139 views
  • 5 likes
  • 6 in conversation