Hi all,
I need help with the following:
PRE-Matching
My treatment cohort is 427 and the control 4079
POST-Matching
My treatment cohort is 1281 and the control 1281
I am wanting to do a 3:1 match, and not sure why I ended up with the last numbers.
I am using this macro by Marcelo Coca Perraillon Paper 185-2007:
%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;
And I am invoking it :
%PSMatching(datatreatment=PNET._MIPD_YES, datacontrol=PNET._MIPD_NO,
method=NN, numberofcontrols=3, caliper=0.1, replacement=NO, out=MATCHES); RUN;
Any ideas?
Thanks,
J
You stared with: N=427, so if you want a 1:3 match, that becomes 1281 records.
Each treatment is matched with 3 controls. If you have a unique variable that identifies your rows, check your data and you should find that you have duplicates of your case data, triplicates and each control should be unique.
EDIT:
Please include code in a code block in the future and if you're using SAS 9.4 TSM5+ there is a PROC PSMATCH now available to do these types of matching as well.
Source of macro: http://www2.sas.com/proceedings/forum2007/185-2007.pdf
@Jarot741 wrote:
Hi all,
I need help with the following:
PRE-Matching
My treatment cohort is 427 and the control 4079
POST-Matching
My treatment cohort is 1281 and the control 1281
I am wanting to do a 3:1 match, and not sure why I ended up with the last numbers.
I am using this macro by Marcelo Coca Perraillon Paper 185-2007:
%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; *And I am invoking it; %PSMatching(datatreatment=PNET._MIPD_YES, datacontrol=PNET._MIPD_NO, method=NN, numberofcontrols=3, caliper=0.1, replacement=NO, out=MATCHES); RUN;
Any ideas?
Thanks,
J
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.