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
... View more