BookmarkSubscribeRSS Feed
edag
Calcite | Level 5

Hi,

 

I want to write numbers with a minimum of two decimal numbers. For example:

 

1   -> 1.00

1/2 -> 0.50

1/3 -> 0.3333333333

1/4 -> 0.25

1/5 -> 0.20

 

Which number format does it need for this in SAS? Thanks in advance!

8 REPLIES 8
Tom
Super User Tom
Super User

@edag wrote:

Hi,

 

I want to write numbers with a minimum of two decimal numbers. For example:

 

1   -> 1.00

1/2 -> 0.50

1/3 -> 0.3333333333

1/4 -> 0.25

1/5 -> 0.20

 

Which number format does it need for this in SAS? Thanks in advance!


That is not how formats work.  You tell it the total number of characters and the MAXIMUM number of decimal places to display.

 

edag
Calcite | Level 5

Sure, with "maximum" it would be easy. But for a special problem I need the "minimum", and I hope there is a solution for this.

Tom
Super User Tom
Super User

Do you need a FORMAT or are you just making a report?  If the later then use IF/THEN logic to decide which format to use.

data test;
  do d=1 to 5 ;
    x=1/d ;
    if mod(x,0.01) then put d= x= best12.;
    else put d= x=12.2 ;
    output;
  end;
run;
d=1 x=1.00
d=2 x=0.50
d=3 x=0.3333333333
d=4 x=0.25
d=5 x=0.20

If you need a format then use PROC FCMP to build a function that you can call in a format.

https://www.sas.com/content/dam/SAS/support/en/sas-global-forum-proceedings/2018/2403-2018.pdf

edag
Calcite | Level 5

Hi,

 

I have tried several number formats, but none of them helped me with my problem.

I want a number format that gives a minimum number of decimal places.

 

In my example I want a number format with a minimum number of two decimal places:

 

1   ----> 1.00

1/2 ----> 0.50

1/3 ----> 0.3333333333

1/4 ----> 0.25

1/5 ----> 0.20

 

Is there any format that could do this?

I use SAS Enterprise Guide 8.2 (Update 5).

 

Thanks in advance!

Bernd

Tom
Super User Tom
Super User

@edag wrote:

Hi,

 

I have tried several number formats, but none of them helped me with my problem.

I want a number format that gives a minimum number of decimal places.

 

In my example I want a number format with a minimum number of two decimal places:

 

1   ----> 1.00

1/2 ----> 0.50

1/3 ----> 0.3333333333

1/4 ----> 0.25

1/5 ----> 0.20

 

Is there any format that could do this?

I use SAS Enterprise Guide 8.2 (Update 5).

 

Thanks in advance!

Bernd


Note that the tool you use to edit and submit SAS code does not matter. What might matter is the version of SAS that your Enterprise Guide program is connecting to to run the SAS code.

 

But there is no SAS defined format that will behave in that way.

 

Why do you want this?  What is the purpose?  If you need to create those strings then perhaps it would be better to store them into a new character variable instead of trying to create a format that will display the numbers in that way.

 

Example:

data have;
  do d=1 to 5;
    number = 1/d;
    if mod(number,0.01) = 0 then string = put(number,12.2);
    else string=put(number,best12.);
    output;
  end;
run;

 

Result:

OBS    d     number       string

 1     1    1.00000            1.00
 2     2    0.50000            0.50
 3     3    0.33333    0.3333333333
 4     4    0.25000            0.25
 5     5    0.20000            0.20

 

edag
Calcite | Level 5

Thanks to all.
Those are prices in Euros and Cents. Most of them are prices like 23 Euros 20 Cent. This should be shown not at 23.2, but as 23.20, because in our company everyone wants it like this. But for some reasons there are also a few prices like 17 Euros and 14.33333 Cent. (Actually it's prices per year divided through 12, so this can sometimes happen.) This should be shown not as 17.14, because information would be missing, but as 17.1433333333.
Creating another format is no option because it is not THAT important and many other people use this database as well, so explaining this to them (and always having to load this new format) would be too difficult.
Making strings out of it is also no option because those variables are numbers and we have to calculate with them, add them, make a sum, etc.
Using 23.2000000000 and 17.1433333333 would technically be an option, but looks weird and overloaded.
We just hoped we could get rid of those silly 23.2 numbers. I was told "please make 23.20 out of it, everything else should stay the same".
All other variables in Euros and Cent are like 23.20, only this one is different.
In case there is no built-in function in SAS for this, it doesn't make sense.
Again thanks to all.

Patrick
Opal | Level 21

What you want is just not how SAS formats work. But you can always create a custom format and IF you are someone who can amend the autoexec then you can make such formats available environment wide.

For what you need it would require a custom function that gets used within a custom format. Such constructs allow to implement data step level if/then functionality as part of a SAS format.

 

In below example if you would want to provide such a custom format you would need to store the custom function and custom format in a permanent library (one of job) and then add the custom function library and custom format library to the environment (autoexec, options cmplib and append in code below). Once you do this you can add the format permanently to the table and whoever uses the table will print the data using the format you "attached" ...as long as they create a SAS session that also adds the function and format library (=creates the session using the autoexec where you defined these).

options dlcreatedir;
libname perm "%sysfunc(pathname(work))/perm";

option CMPLIB=perm.funcs;
options append=(fmtsearch=perm);

proc fcmp outlib=perm.funcs.demo;
  function f_min_two_dec(val_num) $;
    length val_char $16;
    if int(val_num*100)=val_num*100 then val_char=put(val_num,f32.2);
    else val_char=put(val_num,best32.);
    return(val_char);
  endsub;
  run;


proc format lib=perm;
  value min_two_dec(default=17)
  other=[f_min_two_dec()]
  ;
run;

data test;
  format a min_two_dec.;
  a=14.222229;output;
  a=14; output;
  a=14.1; output;
run;

proc print data=test;
run;

Patrick_0-1662393835075.png

 

Tom
Super User Tom
Super User

In that case the simplest answer is to just use the BEST format and leave it at that.  That is recognizable to humans.  There is no need to tell a human 1 euro per unit is the same as 1.00 euro per unit.

 

But there are probably other issues you need to address.  What ever method you use to represent a number like 1/3 that cannot be expressed exactly as a binary number will be non-exact.  So you need to know how many decimal places will be used by the algorithms that use those numbers.  Then just display ALL of the values to that number of decimal places.

 

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 8 replies
  • 968 views
  • 3 likes
  • 3 in conversation