BookmarkSubscribeRSS Feed
bollibompa
Quartz | Level 8

Hi,

Does anyone know if there are any macro for propensity score matching with replacement, where you  have on option to limit (set a maxium value) the number of times a subject can be a control?

 

Thanks

Thomas

1 REPLY 1
bollibompa
Quartz | Level 8

Hi again,

Marcelo Coca-Perraillon has developed a PS macro where you can match with replacement. It uses hash-programming not so familiar to me. I attch the whole macro at the end of this message.

 

In this macro you can specify if you would like to match with or without replacement. Does anyone have a suggestion how you can update this macro so you only can use each control a maximum number of times (e.g. 10 times)?

 

In this code-part the macro removes the control if you match without replacement (=NO). I am trying to modify the code by including a AND-statement like:

 

%if %upcase(&replacement)=YES AND (IdSelectedControl + something like : occurs < 10 times) %then %do rc1=h.remove(key:IdSelectedControl);

 

 

%if %upcase(&replacement) = NO %then %do;
rc1 = h.remove(key: IdSelectedControl);
%end;
end;
%end;

 

Thanks in advance for help on this!

/Thomas

 

 

%macro PSMatching(datatreatment=, datacontrol=, method=, numberofcontrols=, caliper=,
 replacement=, out=);

/* Create copies of the treated units if N > 1 */;
 data _Treatment0(drop= i);
  set &datatreatment;
  do i= 1 to &numberofcontrols;
  RandomNumber= ranuni(12345);
output;
end;
run;
/* Randomly sort both datasets */
proc sort data= _Treatment0 out= _Treatment(drop= RandomNumber);
by RandomNumber;
run;
data _Control0;
set &datacontrol;
RandomNumber= ranuni(45678);
run;
proc sort data= _Control0 out= _Control(drop= RandomNumber);
by RandomNumber;
run;

 data Matched(keep = IdSelectedControl PScoreControl MatchedToTreatID PScoreTreat);
  length pscoreC 8;
  length idC 8;
/* Load Control dataset into the hash object */
  if _N_= 1 then do;
declare hash h(dataset: "_Control", ordered: 'no');
declare hiter iter('h');
h.defineKey('idC');
h.defineData('pscoreC', 'idC');
h.defineDone();
call missing(idC, pscoreC);
end;
/* Open the treatment */
set _Treatment;
%if %upcase(&method) ~= RADIUS %then %do;
retain BestDistance 99;
%end;
/* Iterate over the hash */
rc= iter.first();
if (rc=0) then BestDistance= 99;
do while (rc = 0);
/* Caliper */
%if %upcase(&method) = CALIPER %then %do;
if (pscoreT - &caliper) <= pscoreC <= (pscoreT + &caliper) then do;
ScoreDistance = abs(pscoreT - pscoreC);
if ScoreDistance < BestDistance then do;
BestDistance = ScoreDistance;
IdSelectedControl = idC;
PScoreControl =  pscoreC;
MatchedToTreatID = idT;
PScoreTreat = pscoreT;
end;
end;
%end;
/* NN */
%if %upcase(&method) = NN %then %do;
ScoreDistance = abs(pscoreT - pscoreC);
if ScoreDistance < BestDistance then do;
BestDistance = ScoreDistance;
IdSelectedControl = idC;
PScoreControl =  pscoreC;
MatchedToTreatID = idT;
PScoreTreat = pscoreT;
end;
%end;

%if %upcase(&method) = NN or %upcase(&method) = CALIPER %then %do;
rc = iter.next();
/* Output the best control and remove it */
if (rc ~= 0) and BestDistance ~=99 then do;
output;
%if %upcase(&replacement) = NO %then %do;
rc1 = h.remove(key: IdSelectedControl);
%end;
end;
%end;
/* Radius */
%if %upcase(&method) = RADIUS %then %do;
if (pscoreT - &caliper) <= pscoreC <= (pscoreT + &caliper) then do;
IdSelectedControl = idC;
PScoreControl =  pscoreC;
MatchedToTreatID = idT;
PScoreTreat = pscoreT;
output;
end;
rc = iter.next();
%end;
end;
run;
/* Delete temporary tables. Quote for debugging */
proc datasets;
delete _:(gennum=all);

run;
 data &out;
   set Matched;
 run;
%mend PSMatching;

 

 

sas-innovate-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

What is ANOVA?

ANOVA, or Analysis Of Variance, is used to compare the averages or means of two or more populations to better understand how they differ. Watch this tutorial for more.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 1 reply
  • 1607 views
  • 0 likes
  • 1 in conversation