Dear SAS expert
I am wondering whether there is a format which supports the following.
Based on this example data:
1.000.200
200,25
10
500,3
10,03
I would like to identify a format which includes one decimal when a number is not an integer and also when a number is not rounded to ,0. I would also like to include a thousand seperator as shown in 1st observation above. So with the example data I would like to have it presented in the following way:
1.000.200
200,3
10
500,3
10
Does anyone know of such a format? I have worked a lot in Stata where such a format was specified in the code using the letter g (general).
Thank you
Best regards
Martin
General
As already mentioned a format just sees the number and nothing else.
You can use Proc REPORT to do what you want, use a different format depending on some other variable content.
Have a look at this example:
data newclass;
set sashelp.class;
hw_ratio = height / weight;
if sex = "M" then do;
hw_ratio = hw_ratio * 10000;
end;
run;
proc report data=newclass;
columns name sex height weight hw_ratio _dummy;
define height / display;
define weight / display;
define hw_ratio / display;
define _dummy / noprint;
compute _dummy;
if sex = "M" then do;
call define("hw_ratio", "format", "commax14.");
end;
else do;
call define("hw_ratio", "format", "percent9.1");
call define (_row_, "style", "style={background=lightgray}");
end;
endcomp;
run;
You can create your own format and use a function to create the formatted value.
You can find more on in the doc here: https://go.documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/proc/n1eyyzaux0ze5ln1k03gl338avbj.htm
An example for this (change the logic according to your needs):
/*
* create the function
*/
proc fcmp outlib=work.myformats.mypkg;
function generalFormat(number) $ 32;
length returnValue $ 32;
select;
when ( number = int(number) ) do;
returnValue = put(number, commax32.);
end;
when ( scan( put(round(number, 0.1), 32.1), -1, ".") = "0" ) do;
returnValue = put(number, commax32.);
end;
otherwise do;
returnValue = put(number, commax32.1);
end;
end;
return (left(returnValue));
endsub;
run;
/*
* make the new function available
*/
options cmplib=work.myformats;
/*
* create some data and test the function
*/
data have;
do value = 1000200, 200.25, 10, 500.3, 10.03;
value2 = value;
/* test out just the function */
newValue = generalFormat(value);
output;
end;
run;
/*
* create a format using the function
*/
proc format;
value gfmt (default=32)
low - high = [generalFormat()]
;
run;
/*
* test it out
*/
proc print data=have;
format value2 gfmt.;
run;
But why have some numbers with decimals and others not? Makes reading more difficult, I think.
Hey Bruno
Thank you for your reply.
This is a bit more complicated code than what I hoped for, but thank you providing it.
For your question at the end then yes, it does seem strange. My issue is that I have a numeric variable which includes both frequencies and percentages (organized via a categorical variable). I should correct my original post; only integer values (frequencies) should be listed without a decimal, whereas percentages should be listed with one decimal (irrespective of whether they are actually integers).
Best regards
Martin
Since a format attached to a variable applies to all of the observations you cannot really do what you want in the dataset.
Now if you are making a report out of the data then you can have more control.
As already mentioned a format just sees the number and nothing else.
You can use Proc REPORT to do what you want, use a different format depending on some other variable content.
Have a look at this example:
data newclass;
set sashelp.class;
hw_ratio = height / weight;
if sex = "M" then do;
hw_ratio = hw_ratio * 10000;
end;
run;
proc report data=newclass;
columns name sex height weight hw_ratio _dummy;
define height / display;
define weight / display;
define hw_ratio / display;
define _dummy / noprint;
compute _dummy;
if sex = "M" then do;
call define("hw_ratio", "format", "commax14.");
end;
else do;
call define("hw_ratio", "format", "percent9.1");
call define (_row_, "style", "style={background=lightgray}");
end;
endcomp;
run;
Dear Bruno
The proc report code appears to be the solution that I am looking for. Thank you very much for providing a good example of how the code works.
Best regards
Martin
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.