RDX2 X  .Random.seed r }{b4d)F V%~vjו_iHW6`ߥj7A#vɽ7.fW;Ň,M2Iԓ}Pw;L̩Lw"q:poͯ6cA\8vbt4FF^" N|Mn0]Cr.MTcK_J(לX F= #ܠ7\oCgsїCs-^G% ƥ}26nNjl_ccϿ ?p &IP5 Jk2W9wugRtGhϒy1h"}xl)0qБM"Hb߰;V#'6nK5(W7$)(̓~E ."Xb*#]ڜ/-fÂ&fS6w.55ʯ u \{^e/rsˏ( YxN'#N#K9b~Tl3_aKuxਠ]9 $ z),@u/[l4X6 _ݩ&&u(/X|qI~УYpLڈ}A1AF[fk"V>eyB2dh9rfpoekGHLt+L%5>L~$LvcZ v~5;Uʎ8SG%P5o5u=ߘ}<c-Oc][4\ (/lc@xyTn4"2PFz<&>z.Oo6?M8{[sK##Oj6`i`K;05V-qI4 %ipoUd7nsYOYejQEJ{v\W4KceM\USveTx|UK*')uysq( sʞ7Ip&k(-2|B'YJ>jfQNMbi[|WL18JH7fG);kRH8l".+oǐ"LSɧt cioj/(zE/} _ACZ%EOHP52_ao}3/wrc?;݌I8)+@k PkT2,bDiׁHfBZFc+Phd{ zpD &2֒f?/?`_s$S-[xLx<F!VX`U @ýbէт:GUtk;<`@ի1 u Ft~!9қoѰ%t]-xWM7kvwayn0yT :U}&⭲zx7leD.{^hd:<BNJzSN$rRZN3o<E\>~YvI"^}MbM$gr=fRC SfPcMM/5$Jwʮ/ sA|V{ȥ`oqh'tc۶)26Bqf &)lh(# 8]I<4#hc\6t7405b`ټba@R9*Yx4lbD|tCB>}`/{~zt\6+B);( Te|參*[;nauf Db 2YhOw4@p)^:FG*7,$ J2M(QA)DٱHN*RIc&> >]gMvycy͏:넔o x`H܇P[RӰU}hizro4`qԽF5rhu%CBn%m'˜:UYt?;ڐ[_%8svW#bGskHz0AB^jҌp"Qix0+78@ˋY~1Cg .Traceback balmatch source( function(f,z,p,X,caliper=.2){ 2 #f is a factor to be balanced, length(f)=n ? #z 1/0 vector, length(z)=n, z=1 for treated, z=0 for control U #p is a continuous variable, usually the propensity score, used to define calipers R #X is a matrix of covariates, used in a rank based Mahalanobis distance, n rows 3 #The default caliper of 0.2 refers to .2*sd(p), 1 # that is 20% of a standard deviation of p 0 #You must have the package optmatch installed V #This program comes with no guarantees of any kind. I put it together to show Y #that balanced matching is easy to do. A decent programmer could write a better  #program.  penalty<-100  K<-1  library(optmatch)  dmat<-smahal(z,X) 9 calip<-abs(outer(p[z==1],p[z==0],"-"))>(caliper*sd(p)) , dmat<-dmat+calip*penalty*max(abs(dmat)+1)  L<-length(levels(f))  t1<-table(f[z==1])  t2<-table(f[z==0])  remove<-t2-K*t1  nt<-dim(dmat)[1]  m<-dim(dmat)[2]  0 if (min(remove)<0){ "infeasible"} else { f<-as.integer(f)  for (j in 1:L){ + who<-(f[z==0]!=j)*1 L add<-t(matrix(rep(who*10000,remove[j]),m,remove[j])) - dmat<-rbind(dmat,add)  }  }  extras<-(1:(m-nt))+(nt+m) ( rownames(dmat)[(nt+1):m]<-extras # out<-as.integer(pairmatch(dmat)) ) out[is.element(out,out[extras])]<- NA  out<-out[1:length(z)] ' out<-(rank(out,na.last="keep")+.5)/2  out  } f z p X caliper?ə { <- penalty@Y  K? library optmatch  dmat smahal  calip > abs outer [ ==? - ( *  sd  +  max?  L length levels  t1 table?  t2!  remove -"    nt dim?  m&@ if < min#  infeasible   as.integer for j :?   who !=-?  add t matrix rep/@È#-'#-  rbind1  extras.?$'%%'  rownames.%?'6  out+ pairmatch 8 is.element886  88.? 8 / rank8 na.last keep?@89 )function(distance, controls=1, tol=0.001) : {#Program from Ben Hansen Requires his optmatch package Dstopifnot(is.matrix(distance)||class(distance)[1]=="optmatch.dlist", 5 all(floor(controls)==controls), controls>0) )if (class(distance)[1]=="optmatch.dlist")  { 7nt <- unlist(lapply(distance, function(x){dim(x)[1]})) 7nc <- unlist(lapply(distance, function(x){dim(x)[2]})) omf <- (nc-controls*nt)/nc Gif (any(omf<0)) stop('not enough controls in some subclasses') } else {  nt <- dim(distance)[1]  nc <- dim(distance)[2]  omf <- (nc-controls*nt)/nc 0 if (any(omf<0)) stop('not enough controls') } 3fullmatch(distance=distance, min.controls=controls, 3 max.controls=controls, omit.fraction=omf,  tol=tol)  } distance controls? tol?PbM  stopifnot || is.matrix> class>? optmatch.dlist all floor???(D>? optmatch.dlist  % unlist lapply> function x &J? function(x){dim(x)[1]}  ncGH>IJ &J@ function(x){dim(x)[2]}  omf;$K?%K( any)L stop ¬ enough controls in some subclasses  %&>? K&>@ L;$K?%K(M)LN not enough controls fullmatch>> min.controls? max.controls? omit.fractionL@@ readme Type balmatch for instructions. Bbalmatch is intended to show that balanced matching is easy to do. ZThe balmatch program is not a polished piece of software, and it comes with no guarantees. GYou must have Hansen's optmatch package and the MASS package installed. rBased on: P. R. Rosenbaum, R. N. Ross and J. H. Silber. (2007) Minimum distance matched sampling with fine balance ^in an observational study of treatment for ovarian cancer. J. Am. Statist. Assoc., 102: 75-83. +Please cite that paper if you use balmatch. function(z,X){ <# Rank based Mahalanobis distance. Prevents an outlier from K# inflating the variance for a variable, thereby decreasing its importance. <# Also, the variances are not permitted to decrease as ties D# become more common, so that, for example, it is not more important E# to match on a rare binary variable than on a common binary variable C# z is a vector, length(z)=n, with z=1 for treated, z=0 for control @# X is a matrix with n rows containing variables in the distance X<-as.matrix(X) n<-dim(X)[1] rownames(X)<-1:n k<-dim(X)[2] m<-sum(z) !for (j in 1:k) X[,j]<-rank(X[,j]) cv<-cov(X) vuntied<-var(1:n) rat<-sqrt(vuntied/diag(cv)) cv<-diag(rat)%*%cv%*%diag(rat) out<-matrix(NA,m,n-m) Xc<-X[z==0,] Xt<-X[z==1,] rownames(out)<-rownames(X)[z==1] colnames(out)<-rownames(X)[z==0] library(MASS) icov<-ginv(cv) >for (i in 1:m) out[i,]<-mahalanobis(Xc,Xt[i,],icov,inverted=T) out }   as.matrix  n&? 7.?U  k&@ ' sum,-.?V -<-  cv cov  vuntied var.?U  rat sqrt;Z diagX X %*%_^\X^\ 83 '$U'  Xc  Xt? 787?  colnames87 MASS  icov ginvX, i.?' 8f mahalanobis`afd inverted T8