DATA Step, Macro, Functions and more

Looking up a value that is between to other values. Used in simualtion in a do loop

Accepted Solution Solved
Reply
Contributor
Posts: 32
Accepted Solution

Looking up a value that is between to other values. Used in simualtion in a do loop

Hi I'm trying to simulate descrete events forward in time and the simulate a different value for each of these events. In real life this is to create a schedule and take in consideration events that have not been detected yet.

 

The inline code works but is a bit hard to make completly robust. E.g. i have hardcoded 4 groups of values, but in real life it might be more or less. This can be done in a macro but might be hard to debug.

 

Another solution is to join in the from to values for the univarite drawing, test if it is between and then dropping the lines where it is not between. Howvwer this will expand the data and can lead to other errors.

 

Does anybody have a more elegent method. I was thinking about reading the proportion, hrs_darw into an array but do not get it to run.

 

I do not have IML avalialable

 

%let avg_mnth=10;
data WORK.CUM_PROB;
  infile datalines dsd truncover;
  input Proportion:BEST10.9 hrs_draw:32. cum:32.;
datalines4;
0.51818182,6,0.5181818182
0.05909091,7,0.5772727273
0.21363636,10,0.7909090909
0.20909091,18,1
;;;;
run;

data cum_prob;
	set cum_prob;
	
	prop_name='prop'||put(_n_,z2.);
	hrs_name='hrs'||put(_n_,z2.);

	call symput(prop_name,cum);
	call symput(hrs_name,hrs_draw);


	keep proportion cum hrs_draw ;
run;


%put pr1= &prop01  hrs=&hrs01;
%put pr1= &prop04  hrs=&hrs04;

Data events;
	prob_by_day=30/&avg_mnth;
	do i=0 to 5000 by 1;
		date = intnx('day','01jul2017'd,i);
		p=rand('POISSON',1/prob_by_day);
		if p > 0 then do;
			do j=1 to p by 1;
				draw=rand('UNIFORM');
				if draw =< &prop01 then hrs=&hrs01;
				else if draw =< &prop02 then hrs=&hrs02;
				else if draw =< &prop03 then hrs=&hrs03;
				else if draw =< &prop04 then hrs= &hrs04;
				c=1;
				output;
			end;
		end;
		else do;
			draw =.;
			hrs=.;
			c=0;
			output;
		end;
		
	end;
	drop j;

	format date date9.;
run;

 


Accepted Solutions
Solution
‎06-22-2017 09:06 AM
Super User
Posts: 7,854

Re: Looking up a value that is between to other values. Used in simualtion in a do loop

Posted in reply to PaalNavestad

How about creating value formats with ranges and apply those to determine groups?

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers

View solution in original post


All Replies
Solution
‎06-22-2017 09:06 AM
Super User
Posts: 7,854

Re: Looking up a value that is between to other values. Used in simualtion in a do loop

Posted in reply to PaalNavestad

How about creating value formats with ranges and apply those to determine groups?

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Contributor
Posts: 32

Re: Looking up a value that is between to other values. Used in simualtion in a do loop

Posted in reply to KurtBremser

Thanks a million works like a dream.

 

Easy to forget these nice functions that have been around since forever,

 

Here is the revised code.

%let avg_mnth=15;
data WORK.CUM_PROB;
  infile datalines dsd truncover;
  input Proportion:BEST10.9 hrs_draw:32. cum:32.;
datalines4;
0.51818182,6,0.5181818182
0.05909091,7,0.5772727273
0.21363636,10,0.7909090909
0.20909091,18,1
;;;;
run;

data to_fmt;
	set cum_prob;
	retain start end;
	prev=lag(proportion);
	if _n_=1 then do;
		start=0;
		end=proportion;
		SEXCL='N';
	end;
	else do;
		start=end;
		end=start+proportion;
		sexcl='Y';
	end;
	label=put(hrs_draw,best.);
	type='I';
	fmtname='hrsval';
run;

proc format cntlin=to_fmt;
run;


Data events;
	prob_by_day=30/&avg_mnth;
	do i=0 to 5000 by 1;
		date = intnx('day','01jul2017'd,i);
		p=rand('POISSON',1/prob_by_day);
		if p > 0 then do;
			do j=1 to p by 1;
				draw=rand('UNIFORM');
				hrs=input(draw,hrsval.);
				c=1;
				output;
			end;
		end;
		else do;
			draw =.;
			hrs=.;
			c=0;
			output;
		end;
		
	end;
	drop j;

	format date date9.;
run;
☑ This topic is solved.

Need further help from the community? Please ask a new question.

Discussion stats
  • 2 replies
  • 100 views
  • 0 likes
  • 2 in conversation