BookmarkSubscribeRSS Feed
statadm
Fluorite | Level 6
I'm having a problem using the random number function for dates that have missing days.
Does anyone know how to get around assigning non existent days to certain months? As it is, I had to cut the number off at 28 in order not to get errors.

Using the following code:

randday= 1+31*ranuni(1);
randday2= INT(randday);

but had to change it to:

randday= 1+28*ranuni(1);
randday2= INT(randday);

to avoid errors for non-existent days by month.
Thanks!
5 REPLIES 5
Doc_Duke
Rhodochrosite | Level 12
Assuming you know the month, then this would work (ignores leap year).

IF month IN (9,4,6,11) THEN randday= 1+30*ranuni(1);
ELSE IF month = 2 then randday= 1+28*ranuni(1);
ELSE randday= 1+31*ranuni(1);
randday2= INT(randday);
statadm
Fluorite | Level 6
This seems to be able to work for one date, but I'm using this in a macro for multiple dates with the following code:


IF DELIV&_I._DAY=. then do;
DELIV&_I._DAY=RANDDAY2;
end;


DELIV&_I._DATE=MDY(DELIV&_I._MONTH, DELIV&_I._DAY, DELIV&_I._YEAR);

I'm going to try the code using this prior to assigning radday2 to the day variable:

IF DELIV&_I._MONTH IN (9,4,6,11) THEN randday= 1+30*ranuni(1);
ELSE IF DELIV&_I._MONTH = 2 then randday= 1+28*ranuni(1);
ELSE randday= 1+31*ranuni(1);
randday2= INT(randday);

Thanks for your help! Hopefully it works.
LAP
Quartz | Level 8 LAP
Quartz | Level 8
Assuming you know the month and the year you could use the functions

end_of_month =
intnx('Month',MDY(DELIV&_I._MONTH,1, DELIV&_I._YEAR),0,'E');
maxdays = day (end_of_month);

to determine the number of days in the month and then use your random funtion
as follows

randday= int(1+maxdays*ranuni(1));

(The 0 tells SAS to advance the date specified (MDY(DELIV&_I._MONTH,1, DELIV&_I._YEAR) 0 months , the "E" sets that date to the end of the month, day returens the day part of the last date in the month.

Hope this helps
statadm
Fluorite | Level 6
Great, so this should actually account for leap year in the process.
deleted_user
Not applicable
assuming you know the min and max of allowable dates (01jan2005 - 30jun2009, for example), you can use random functions.
[pre]
data randates;
mindate='01jan2005'd;
maxdate='30jun2009'd;
range = maxdate-mindate+1;
format mindate maxdate randate date9.;
do i = 1 to 10000;
RanDate = mindate + int(ranuni(12345)*range);
output;
end;
run;
[/pre]
using this method, you don't need to find the number of days in a given month/year, SAS just knows.

a simple min/max check shows the date limits were respected
[pre]
proc sql;
select distinct
min(randate) format=date9.
, max(randate) format=date9.
from randates;
quit;
[/pre]

output
[pre]
--------------------
01JAN2005 30JUN2009
[/pre]

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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