BookmarkSubscribeRSS Feed
deleted_user
Not applicable
Hello,

Lets say I have the variable "sifmt" which has the format values 4.1 , 5.1, 3.2, 7.2 etc for each lab test as below:

Test Sifmt
Albumin 4.1
Protein 5.1
WBC 6.2
........
.....
etc.

I am doing calculation with the format as below:
put(result*factor, 4.1) for Albumin and put(result*factor, 5.1) for Protien, etc. I don't want to use repetitive if conditions becuase these format values may change.

Any help would be appreciated !!!

Thanks,
/Sukanya
6 REPLIES 6
sbb
Lapis Lazuli | Level 10 sbb
Lapis Lazuli | Level 10
What result do you expect (and want) to see? Suggest you share what code you are executing to be a bit more specific here.

Scott Barry
SBBWorks, Inc.
LinusH
Tourmaline | Level 20
I suggest that you create a macro that will dynamically generate the code (if-then/select/case), based on the values in your look-up table (with Test and Sifmt columns).

/Linus
Data never sleeps
DanielSantos
Barite | Level 11
Hi.

Depending on the number of tests/formats, you could automate the format transformation by loading everything into one or two macro lists.
[pre]
proc sql noprint;
select TEST, SIFMT into :L_TESTS separated by ' ' , :L_TESTS_FMT separated by ' ' from TESTSLIST;
quit;

%put L_TESTS=&L_TESTS;
%put L_TESTS_FMT=&L_TESTS_FMT;
[/pre]
This will populate two macro vars (L_TEST and L_TESTS_FMT) each other with a list of elements (one with the test name, and the other with the corresponding format) separated by blanks.

Then you need to make a match when processing data with the corresponding test name to obtain its index position on the list. Then, the second list (the one with the formats) will hold at the same position the adequate format. Just pass it to the putn function, and its a done deal.

Something like this:
[pre]
data OUTDATA;
set INDATA;

* cycle through the list, match the test name and retrieve the element index;
IDX=0;
do until(scan("&L_TESTS",IDX) eq TEST or scan("&L_TESTS",IDX) eq '');
IDX+1;
end;
if scan("(&L_TESTS",IDX) eq '' then IDX=0; * test name not matched, IDX=0;

* apply automatically the correct format;
FINAL=putn(result*factor,scan(symget('L_TESTS_FMT'),IDX,' '));

run;
[/pre]
Completely automatic and not quite complex as it may seem.

Cheers from Portugal.

Daniel Santos @ www.cgd.pt
Cynthia_sas
SAS Super FREQ
Hi:
I don't believe you need fancy macro coding at all for this. The PUT function does not allow a variable or constant as the value of a format name. However, the PUTN function does. So you have to make a variable to hold the name of the format and then -use- that variable with the PUTN function, as shown in the program below.

Basically, the PUT statement:
[pre]
applyfmt = put(test,$appfmt.);
[/pre]

does the lookup and then the PUTN statement -uses- APPLYFMT to create the new variable:
[pre]
newval = putn(result*factor,applyfmt);
[/pre]

The entire program and results are below. I wasn't sure about the values for result and factor, so I just made up some numbers. Remember that when you assign the format size, that you must account for all the characters, numbers and punctuation in the size. So, this number 111.1 would be a size of 5.1, meaning 5 total characters with a decimal point and 1 character after the decimal. If you needed 11111.1, then the format would be 7.1 -- 7 total characters with a decimal point and 1 character after the decimal point.

cynthia
[pre]
** Program;
data testdata;
infile datalines;
input Test $ result factor;
return;
datalines;
Albumin 11 2
Protein 111 2
WBC 111 2
;
run;

proc format;
value $appfmt 'Albumin'= '4.1'
'Protein'= '5.1'
'WBC'= '6.2';
run;

data domult;
length newval $12;
set testdata;

** One approach -- use cascading IF statements or macro variables;

** Alternate approach -- associate the numeric format with particular TEST;
** Note -- use the PUTN function because it allows a variable to supply the name of a format;
applyfmt = put(test,$appfmt.);
newval = putn(result*factor,applyfmt);
run;

options nodate nonumber;
ods listing;
proc print data=domult;
title 'Using APPLYFMT to supply format value for PUTN';
run;

** Results;
Using APPLYFMT to supply format value for PUTN

Obs newval Test result factor applyfmt
1 22.0 Albumin 11 2 4.1
2 222.0 Protein 111 2 5.1
3 222.00 WBC 111 2 6.2
[/pre]
DanielSantos
Barite | Level 11
Cynthia, interesting approach.

I would stick with this one (easier to understand), unless the test/format list is quite extensive. In that case you could code the lookup format through the contents of a table, but then, everything gets more complex also.

Cheers from Portugal

Daniel Santos @ www.cgd.pt
deleted_user
Not applicable
Thank you guys... It is working...

/SUkanya

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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