BookmarkSubscribeRSS Feed
17 REPLIES 17
Astounding
PROC Star

There may be better ways, but here is something that works.

 

data all_weekdays;

set have;

original_record_num = _n_;

do day = begdate to enddate;

   random_num = ranuni(12345);

   if (2 <= weekday(day) <= 6) then output;

end;

run;

proc sort data=all_weekdays;

   by original_record_num random_num;

run;

data want;

set all_weekdays;

by original_record_num;

if first.original_record_num;

drop original_record_num random_num;

format day mmddyyd10.;

run;

 

The variable DAY is the one that contains the randomly selected weekday.

trungcva112
Obsidian | Level 7

Hi. I tried your code, but each time I run it, it gave me the same day for each group. So the "day" is not random. How can we fix it?

Astounding
PROC Star

Yes, the day is randomly selected.  If you want it to select a different random day each time you run the program, change the seed to the random number generator, using:

 

ranuni(0)

 

However, once you do that you can never replicate your results.  If asked to demonstrate that your results are correct, you will be unable to do so.

andreas_lds
Jade | Level 19

Are those dates sas-dates in your dataset?

 

From the documentation of the outdated (see https://blogs.sas.com/content/iml/2013/07/10/stop-using-ranuni.html) ranuni-function:

The RANUNI function returns a number that is generated from the uniform distribution on the interval (0,1) [...]

You can use a multiplier to change the length of the interval and an added constant to move the interval. For example,

random_variate=a*ranuni(seed)+b; 

returns a number that is generated from the uniform distribution on the interval (b,a+b).

 

Because SAS-dates are numbers you can use begdate and enddate in the calculation. Replacing ranuni with rand('uniform') is recommended. The function weekday returns 1 for Sunday and 7 for Saturday, so you have to repeat calling rand-function until weekday returns 2-5.

trungcva112
Obsidian | Level 7

Hi. Yes it is SAS date (numeric format). I tried your method but there is always a weekend dates.

 

Now suppose I have a list of dates for each group (that already filter all weekends, holiday etc)

Group Date
A02-01-02
A03-01-02
A04-01-02
A….
B
B
B
B

 

How can I pick 1 random date (random observation) for each group from this list. Is it easier to do?

andreas_lds
Jade | Level 19

@trungcva112 wrote:

Hi. Yes it is SAS date (numeric format). I tried your method but there is always a weekend dates.

 

Now suppose I have a list of dates for each group (that already filter all weekends, holiday etc)

Group  Date
A 02-01-02
A 03-01-02
A 04-01-02
A ….
B
B
B
B

 

How can I pick 1 random date (random observation) for each group from this list. Is it easier to do?


@Astounding does exactly this.

trungcva112
Obsidian | Level 7
But it gave me the same random date each time I run it
andreas_lds
Jade | Level 19

See the documentation of ranuni, the same random numbers are generated if parameter seed is constant, to avoid this use 0, instead of 12345.

Ksharp
Super User
data have;
infile cards expandtabs;
input Group	$ Begdate : ddmmyy10. enddate : ddmmyy10. ;
format Begdate enddate  ddmmyy10. ;
cards;
A	12-03-2005	25-08-2008
B	03-06-2001	10-09-2003
C	05-02-2011	21-06-2013
;
run;
data want;
 if _n_=1 then do;
   declare hash h();
   h.definekey('n');
   h.definedata('date');
   h.definedone();
 end;
set have;
n=0;h.clear();
do date=begdate to enddate;
  if weekday(date) not in (1 7) then do;n+1;h.add();end;
end;
n=ceil(h.num_items*rand('uniform'));
h.find();
format date ddmmyy10.;
drop n ;
run;
trungcva112
Obsidian | Level 7
@Ksharp
Thank you very much for your help. But it seems that your code select dates randomly with no replacement. Could you show me how to choose random dates with replacement?

I am truly appreciate your support
Ksharp
Super User

I don't understand what you mean. My code indeed did replace sample.

 

n=ceil(h.num_items*rand('uniform'));

this code randomly pick up a date from the valid weekday . 

Patrick
Opal | Level 21

@trungcva112

Or here a combination of what @Astounding and @Ksharp posted:

data have;
  infile cards expandtabs;
  input Group $ Begdate : ddmmyy10. enddate : ddmmyy10.;
  format Begdate enddate  ddmmyy10.;
  cards;
A 12-03-2005  25-08-2008
B 03-06-2001  10-09-2003
C 05-02-2011  21-06-2013
;
run;

data want(drop=_:);
  set have;
  format ran_date ddmmyy10.;
  do _i=1 to 1000;
    ran_date=Begdate +  floor(rand('uniform')*(enddate-Begdate+1));
    if weekday(ran_date) not in (1,7) then leave;
    else call missing(ran_date);
  end;
run;

N.B: The code above includes random selection of a date which is exactly the begin or end date (=borders included).

 

Ksharp
Super User

Patrick,

That is not rigorously random sample  yet .

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
  • 17 replies
  • 1285 views
  • 6 likes
  • 7 in conversation