BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Cathy8
Fluorite | Level 6

Hello,

 

I need to randomly round a count number to a base of 5, which means a number such as 32 can round down to 30 or up to 35 depending on the probability of rounding up and down. Any idea how to do it in SAS v9.4? Below is the sample of data set.

 

data table;

input count;

datalines;

23

178

456

8231

;

run;

 

Thank you very much!

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Cathy8
Fluorite | Level 6

That's right. For my project, 1 output is enough instead of 10. 10-time outputs are just for my understanding of concept of random rounding.

Very appreciate!

View solution in original post

11 REPLIES 11
Astounding
PROC Star

Not sure what "the probability of rounding up or down" means, but this ought to be in the running:

 

numvar = round(numvar, 5);

PaigeMiller
Diamond | Level 26
roundedvar = 5 * floor(count/5) + /* start by rounding down */
     5 * (rand('uniform')>0.5); /* randomly add five to round up */
--
Paige Miller
FreelanceReinh
Jade | Level 19

Hello @Cathy8 and welcome to the SAS Support Communities!

 

I think @PGStats's solution (which received 9 likes!) in this January thread is likely applicable to your problem, depending on how you define the "probability of rounding up and down."

 

Here's a combination of that solution (or rather a variant of it) and @Astounding's suggestion:

data want;
call streaminit(27182818);
set table;
rcount=round(count+ifn(rand('uniform')<mod(count,5)/5,2,-2),5);
run;

 

Cathy8
Fluorite | Level 6

It works. Not sure if that's what I exactly want. Thanks a lot!

Rick_SAS
SAS Super FREQ

I interpret the question as "round a number to the nearest unit of 5 with probability proportional to the distance from the number to the possible rounding values."

 

Thus 

31 rounds to 30 with probability 4/5 and rounds to 35 with probability 1/5.

32 rounds to 30 with probability 3/5 and rounds to 35 with probability 2/5.

33 rounds to 30 with probability 2/5 and rounds to 35 with probability 3/5.

34 rounds to 30 with probability 1/5 and rounds to 35 with probability 4/5.

 

See SAS code for the "random estimator" in the article "Predict a random integer."

I wrote it to round to the nearest integer, but you can just divide your number by 5, round to the nearest integer using the code I provide, and then multiply the result by 5.

 

Cathy8
Fluorite | Level 6

Thank you very much Rick!

The probability proportion is what I need. I twisted your code posted at Predict a random integer as the below.

%let NumGuesses = 10;

data Guess(keep = x PredRound diffRound PredRand diffRand Frac count k Frac);

set table;

call streaminit(12345);

array prob[4] _temporary_ (0.2, 0.4, 0.6, 0.8); /* P(X=i) */

k = int(count/5)*5;

Frac = (count - k)/10; /* distance from E(X) to x. divided by 10 to fit the Bernoulli */

do i = 1 to &NumGuesses;

PredRound = round(count); /* guess the nearest integer */

PredRand = k + rand("Bern", Frac)*5; /* random guesses between k and k+1, weighted by Frac */

/* The guesses are made. Now generate a new instance of X and compute residual difference */

x = rand("Table", of prob[*]);

diffRound = x - PredRound; /* rounding estimate */

diffRand = x - PredRand; /* unbiased estimate */

output;

end;

;

run;

 

Seem the PredRand is generated from the Bernoulli distribution; the x is generated from random probability. So I should use x as the random rounding number. Am I right?

 

I am not sure how to revise x = rand("Table", of prob[*]) for my case. Can you proviea bit more instruction?

Thank you so much!!!!

 

 

Rick_SAS
SAS Super FREQ

I applaud your effort, but I don't think you quite understood the details of my program. I am assuming this is for an assignment, so let me provide hints instead of an immediate solution:

 

  1. Let y be the value you want to round to the nearest multiple of 5.
  2. Define z = y/5. Your goal is to round z to the nearest integer. You will then multiple that integer by 5 to obtain the result.
  3. Let L be the integer that is less than or equal to z.
  4. Then p = z - L is the probability that you will round up.
  5. For each guess you want to make (up to *NumGuesses), do the following:
    1. x = L + (random 0 or 1). Hint: Use the Bernoulli distribution with prob p.
    2. Your guess is 5*x

Now see if you can use those hints to write a SAS program.

Cathy8
Fluorite | Level 6

Thanks Rick for your hint.

Here is my code.

%let NumGuesses = 10;

data method_3;

set death;

z=count/5;

L=int(z);

if mod(count, 5) ne 0 then do;

do i = 1 to &NumGuesses;

if mod(count, 5)=1 then x = L + RAND('BERNoulli',0.8);

if mod(count, 5)=2 then x = L + RAND('BERNoulli',0.6);

if mod(count, 5)=3 then x = L + RAND('BERNoulli',0.4);

if mod(count, 5)=4 then x = L + RAND('BERNoulli',0.2);

y=5*x;

output;

end;

end;

if mod(count, 5)= 0 then do; y=count; output; end;

run;

Any suggestions?

Thank you very much!

Cathy8
Fluorite | Level 6

Should change the probability in rand().

 

%let NumGuesses = 10;

data method_3;

set death;

z=count/5;

 

L=int(z);

if mod(count, 5) ne 0 then do;

do i = 1 to &NumGuesses;

if mod(count, 5)=1 then x = L + RAND('BERNoulli',0.2);

if mod(count, 5)=2 then x = L + RAND('BERNoulli',0.4);

if mod(count, 5)=3 then x = L + RAND('BERNoulli',0.6);

if mod(count, 5)=4 then x = L + RAND('BERNoulli',0.8);

y=5*x;

output;

end;

end;

if mod(count, 5)= 0 then do; y=count; output; end;

run;

 

Rick_SAS
SAS Super FREQ

It looks to me like the calculations are correct. The only question I have is whether the numbers that are already multiples of 5 should be output &NumGuesses times instead of once. My guess is that you should output those numbers 10 times as well, but reread the problem specification.  

Cathy8
Fluorite | Level 6

That's right. For my project, 1 output is enough instead of 10. 10-time outputs are just for my understanding of concept of random rounding.

Very appreciate!

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

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.

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
  • 11 replies
  • 1586 views
  • 3 likes
  • 5 in conversation