BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
AndersS
Lapis Lazuli | Level 10

I have a question: What tools are there in the Data-step make a Relative Rounding of a numeric number?

I know about the ROUND, ROUNDE and ROUNDZ functions.
But they make an Absolute rounding. 

Example:

Population is some countries:

345,123456  

  34,123456

   3,123456

      123456

        23456

But the user rather wants relative rounding to e.g.3 digits, like

345,000000

 34,100000

  3,120000

    123000

      23400

   

(Yes I have some ideas about to achieve this - if it is not already solved.
 Please omit any misprint - Some Covid-19 look alike here)

/Br Anders Sköllermo - Skollermo in English

Anders Sköllermo (Skollermo in English)
1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

If you want to keep N digits for any magnitude number then first use LOG10() to figure out the magnitude of the number.  Then you can adjust the factor your multiple/divide by in that formula.

 

So if you set the macro variable NDIGITS to represent the number of digits you want to keep the formula could be:

factor = 10 ** (floor(log10(X))-(&ndigits-1));
X_round=round(X/factor)*factor;

Example;

%let ndigits=3;
data test;
  input n;
  log=floor(log10(n));
  factor = 10 ** (log-(&ndigits-1));
  n_round=round(n/factor)*factor;
cards;
345123456
34512345
3451234
345123
34512
3451
345.1
34.51
3.451
.3451
.03451
.003451
;

proc print;
  format n best20.3 n_round comma20.6 ;
run;

Tom_0-1762615571722.png

Note you can skip the multiplication and division and just let the ROUND() function do it for you by using the optional second argument.

  n_round=round(n,10 ** (floor(log10(n))-(&ndigits-1)));

View solution in original post

6 REPLIES 6
quickbluefish
Barite | Level 11
data test;
input n;
cards;
345123456  
34123456
3123456
123456
23456
;
run;

data want;
set test;
n_round=round(n/1000)*1000;
run;

proc print data=want; run;
AndersS
Lapis Lazuli | Level 10
Hi! Yes this solves the simple example problem.
BUT next level - decimal numbers.
Third level: A mix of Relative and Absolute rounding.
Anders Sköllermo (Skollermo in English)
Tom
Super User Tom
Super User

If you want to keep N digits for any magnitude number then first use LOG10() to figure out the magnitude of the number.  Then you can adjust the factor your multiple/divide by in that formula.

 

So if you set the macro variable NDIGITS to represent the number of digits you want to keep the formula could be:

factor = 10 ** (floor(log10(X))-(&ndigits-1));
X_round=round(X/factor)*factor;

Example;

%let ndigits=3;
data test;
  input n;
  log=floor(log10(n));
  factor = 10 ** (log-(&ndigits-1));
  n_round=round(n/factor)*factor;
cards;
345123456
34512345
3451234
345123
34512
3451
345.1
34.51
3.451
.3451
.03451
.003451
;

proc print;
  format n best20.3 n_round comma20.6 ;
run;

Tom_0-1762615571722.png

Note you can skip the multiplication and division and just let the ROUND() function do it for you by using the optional second argument.

  n_round=round(n,10 ** (floor(log10(n))-(&ndigits-1)));
AndersS
Lapis Lazuli | Level 10

Hi! VERY nice solution.
I had an idea of using PUT and SUBSTR. 
I will have a look at this nice solution and my own (unfinished) work.
Nice discussions!    /Br Anders Sköllermo - Skollermo in English

Anders Sköllermo (Skollermo in English)
ballardw
Super User

I have a silly (?) question: why do you only have one comma in 345,123456  and several other of your example values? Normally when I see a single comma in a value with that many digits I have to assume comma is from one of the languages that uses a comma for separating the decimal and a . for the thousands separator.

 

Another approach would be use a custom format with differing digit selectors based on range of values but that would normally have multiple commas in those values.

AndersS
Lapis Lazuli | Level 10
Hi! Good question about the comma. You are quite right. /Br AndersS
Anders Sköllermo (Skollermo in English)

sas-innovate-2026-white.png



April 27 – 30 | Gaylord Texan | Grapevine, Texas

Registration is open

Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!

Register now

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