BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
ciro
Quartz | Level 8

Hi,

I am not sure whether this is right forum to ask this question.

 

I have a dataset like the following:

 

data have;
object=1; place='A'; prob=0.6;output;
object=1; place='B'; prob=0.3;output;
object=1; place='C'; prob=0.1;output;
object=2; place='A'; prob=0.2;output;
object=2; place='D'; prob=0.4;output;
object=2; place='E'; prob=0.3;output;
object=2; place='F'; prob=0.1;output;
run;

 

that is object 1 is in place A with probability 0.6, in place B with probability 0.3, in place C with probability 0.1.

 

I want to assign randomly each subject in only one place based on the probability. that is the output dataset should be like this.


data want;
object=1; place='A'; prob=0.6; in=1;output;
object=1; place='B'; prob=0.3; in=0;output;
object=1; place='C'; prob=0.1; in=0;output;
object=2; place='A'; prob=0.2; in=0;output;
object=2; place='D'; prob=0.4; in=0;output;
object=2; place='E'; prob=0.3; in=1;output;
object=2; place='F'; prob=0.1; in=0;output;
run;

 

in this example object 1 was assigned to place A and object 2 to place E. the assignation should be random.

 

the real dataset is quite big, each object has possibly a long list of places, and the list of places is different for each object.

 

Any advice is much appreciated and, if possible, I would also like to compare different kind of solutions: data steps, iml, OR(?)...

 

Thank you very much in advance

1 ACCEPTED SOLUTION

Accepted Solutions
PaigeMiller
Diamond | Level 26

This seems like a job for the RAND function with tabled distribution.

https://documentation.sas.com/doc/en/pgmmvacdc/9.4/lefunctionsref/p0fpeei0opypg8n1b06qe4r040lv.htm#p...

 

data have;
object=1; place='A'; prob=0.6;output;
object=1; place='B'; prob=0.3;output;
object=1; place='C'; prob=0.1;output;
object=2; place='A'; prob=0.2;output;
object=2; place='D'; prob=0.4;output;
object=2; place='E'; prob=0.3;output;
object=2; place='F'; prob=0.1;output;
run;
proc transpose data=have out=have_t;
    by object;
    var prob;
run;
data want;
    merge have have_t;
    retain z;
    by object;
    if first.object then do; 
        seq=0;
        z=rand('tabled',of col:);
    end;
    seq+1;
    if seq=z then in=1;
    else in=0;
    keep object place prob in;
run;
--
Paige Miller

View solution in original post

6 REPLIES 6
PaigeMiller
Diamond | Level 26

This seems like a job for the RAND function with tabled distribution.

https://documentation.sas.com/doc/en/pgmmvacdc/9.4/lefunctionsref/p0fpeei0opypg8n1b06qe4r040lv.htm#p...

 

data have;
object=1; place='A'; prob=0.6;output;
object=1; place='B'; prob=0.3;output;
object=1; place='C'; prob=0.1;output;
object=2; place='A'; prob=0.2;output;
object=2; place='D'; prob=0.4;output;
object=2; place='E'; prob=0.3;output;
object=2; place='F'; prob=0.1;output;
run;
proc transpose data=have out=have_t;
    by object;
    var prob;
run;
data want;
    merge have have_t;
    retain z;
    by object;
    if first.object then do; 
        seq=0;
        z=rand('tabled',of col:);
    end;
    seq+1;
    if seq=z then in=1;
    else in=0;
    keep object place prob in;
run;
--
Paige Miller
FreelanceReinh
Jade | Level 19

Hi @ciro,


@ciro wrote:

(...) if possible, I would also like to compare different kind of solutions: data steps, iml, OR(?)...


I don't have a SAS/IML or SAS/OR license, so here's another data step solution:

data want(drop=_:);
call streaminit(27182818);
do until(last.object);
  set have;
  by object;
  if ~_a then do;  /* i.e., if the object has not been assigned yet */
    in=rand('bern',fuzz(prob/(1-coalesce(_cp,0))));
    _cp=sum(_cp,prob); /* "cumulative probability" */
    _a=in;
  end;
  else in=0;
  output;
end;
run;

The FUZZ function serves as a safety measure against rounding errors (up to 1E-12) -- assuming that there are no cases with 0<prob<=1E-12.

Ksharp
Super User

"the assignation should be random."

It is randomly according to variable 'prob' , or just equal probability random ?

 

data have;
object=1; place='A'; prob=0.6;output;
object=1; place='B'; prob=0.3;output;
object=1; place='C'; prob=0.1;output;
object=2; place='A'; prob=0.2;output;
object=2; place='D'; prob=0.4;output;
object=2; place='E'; prob=0.3;output;
object=2; place='F'; prob=0.1;output;
run;
proc surveyselect data=have sampsize=1 seed=123 outrandom out=temp;
strata object;
run;
data want;
 merge have temp(keep=object place in=inb);
 by object  place;
 in=inb;
run;
ciro
Quartz | Level 8
thanks Ksharp. It should be random according to variable prob.
Ksharp
Super User

OK. How about this one ?

 

data have;
object=1; place='A'; prob=0.6;output;
object=1; place='B'; prob=0.3;output;
object=1; place='C'; prob=0.1;output;
object=2; place='A'; prob=0.2;output;
object=2; place='D'; prob=0.4;output;
object=2; place='E'; prob=0.3;output;
object=2; place='F'; prob=0.1;output;
run;
proc surveyselect data=have sampsize=1 seed=123 method=pps out=temp;
strata object;
size prob;
run;
data want;
 merge have temp(keep=object place in=inb);
 by object  place;
 in=inb;
run;
ciro
Quartz | Level 8

Thank you guys. all solutions seem to work fine!

sas-innovate-white.png

Missed SAS Innovate in Orlando?

Catch the best of SAS Innovate 2025 — anytime, anywhere. Stream powerful keynotes, real-world demos, and game-changing insights from the world’s leading data and AI minds.

 

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
  • 1116 views
  • 9 likes
  • 4 in conversation