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.
@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.
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;
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 -
Not for format unfortunately. For conversion, PUTC/PUTN work but you also need to know the variable type.
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;
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.
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 ;
@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 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.
Great, that's what I've been looking for! Thank you all - I should have stated my question more clearly at the beginning.
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.
Ready to level-up your skills? Choose your own adventure.