Epidemiology & Technology

RAAB6 Surveys Stata Commands for Cataract Surgical Outcomes

The WHO Eye Care Indicator Menu has prescribed many core indicators. The Core Indicator 6 is Cataract surgical outcome (visual acuity) in the domain of Output – Eye Care Service Quality

Definition: Percentage of eyes with:

  1. Good” cataract surgical outcome: attaining a postoperative PVA of 6/12 or b e t t e r.
  2. Suboptimal” cataract surgical outcome: attaining a postoperative PVA worse than 6/12, and equal to or better than 6/60 (mild and moderate vision impairment).
  3. Poor” cataract surgical outcome: attaining a postoperative PVA worse than 6/60 (severe vision impairment or blindness).

Estimation of these indicators can be accomplished using the below Stata code

label define sex 1 Male 2 Female, replace
label value sex sex

* PERSON LEVEL DATA - wide form - default of RAAB6 CSV
gen op1 = inlist(lere,3,4,5)	
gen op2 = inlist(lele,3,4,5)


gen csoeyes1 = 0 if op1 ==1
replace csoeyes1 = 1 if csoeyes1 == 0 & inlist(pvare, 1)
replace csoeyes1 = 2 if csoeyes1 == 0 & inlist(pvare, 2,3)
replace csoeyes1 = 3 if csoeyes1 == 0 & inlist(pvare, 4,5,6,7)

gen csoeyes2 = 0 if op2 ==1
replace csoeyes2 = 1 if csoeyes2 == 0 & inlist(pvale, 1)
replace csoeyes2 = 2 if csoeyes2 == 0 & inlist(pvale, 2,3)
replace csoeyes2 = 3 if csoeyes2 == 0 & inlist(pvale, 4,5,6,7)

label define csoeyes 0 "No Inf" ///
		1 "Good  (PVA 6/12 or better)"  ///
		2 "Sub-optimal (PVA<6/12,>=6/60)" ///
		3 "Poor (PVA worse than 6/60)" , replace  

label value csoeyes1 csoeyes2 csoeyes
tab1 csoeyes1 if op1==1, mis
tab1 csoeyes2 if op2==1, mis

rename pvare  pv1
rename bvare  bv1
rename lere le1

rename   causere    cause1
rename   agere 	ageSurg1
rename   plre  plSurg1
rename   surgre  iolType1
rename   costre  costSurg1
rename   outlowre outSurgCause1
rename pvale  pv2
rename bvale  bv2
rename lele le2
rename   causele    cause2
rename   agele 	ageSurg2
rename   plle  plSurg2
rename   surgle  iolType2
rename   costle  costSurg2
rename   outlowle outSurgCause2

* EYE WISE DATA - Long form
reshape long  pv  bv le cause ageSurg plSurg iolType costSurg outSurgCause op csoeyes, i( id ) j(eye)
tab le op, mis
tab le csoeyes, mis
tab op, mis

tab csoeyes
tab csoeyes, gen(csoeyesType)
label var csoeyesType1 "Good"
label var csoeyesType2 "Sub-optimal"
label var csoeyesType3 "Poor"


cap drop HospSurg
gen HospSurg = inlist(plSurg, 1,2,3) if op==1 
label var HospSurg "Hospital Surgery"
cap drop freeSurg
gen freeSurg = inlist(costSurg, 1,2) if op==1
label var freeSurg "Total/Partially Free Surgery"

* Age of surgery
replace ageSurg = . if ageSurg ==0
cap drop ageSurgCat
egen  ageSurgCat = cut(ageSurg), at(0 40 50 60 70 80 105 ) lab
tab ageSurgCat 
tab ageGrp ageSurgCat


* Time since surgery
cap drop timeSinceSurg
gen timeSinceSurg = age - ageSurg if  op==1
cap drop timeSinceSurgCat
egen  timeSinceSurgCat = cut(timeSinceSurg), at(0 2 4 6 11  100 ) lab
tab timeSinceSurgCat
label var timeSinceSurgCat "Time Since Surgery"
label define yn 1 Yes 2 No
label val op yn

label var op "Operated (eyes)"
label var ageSurgCat "Age at Surgery"
label var HospSurg "Operated in Hospital"

cap drop surgDetailsavailable
gen surgDetailsavailable = ageSurg !=0 & plSurg !=0 & iolType !=0 & costSurg !=0 & outSurgCause !=0 if op==1
tab surgDetailsavailable

gen iolImplant = iolType ==2 if  iolType  !=0

replace costSurg = . if costSurg==0

// ANALYSIS
keep if status ==1

duplicates report id
tab   op
tab   op sex, col nokey
tab   surgDetailsavailable sex, col nokey

* Uniform N
replace csoeyes = . if surgDetailsavailable !=1

tab   ageSurgCat sex if  surgDetailsavailable ==1, col nokey
tab   timeSinceSurgCat sex if  surgDetailsavailable ==1, col nokey
tab   plSurg  sex if  surgDetailsavailable ==1, col nokey
tab   HospSurg  sex if  surgDetailsavailable ==1, col nokey
tab   iolType  sex if  surgDetailsavailable ==1, col nokey
tab   costSurg sex if  surgDetailsavailable ==1, col nokey
tab   freeSurg sex if  surgDetailsavailable ==1, col nokey
tab   csoeyes sex if  surgDetailsavailable ==1, col nokey
tab   outSurgCause sex if  surgDetailsavailable ==1 , col nokey

* Binomial Confidence Intervals
bysort sex: ci prop csoeyesType1 csoeyesType2 csoeyesType3 if  surgDetailsavailable ==1

* table 1
ssc install table1_mc
table1_mc if  surgDetailsavailable ==1, by(sex) ///
	vars(ageGrp cat \ option1 cat \ rural cat \  ageSurg contn %4.1f \ surgDetailsavailable  bin \ ageSurgCat cat \  timeSinceSurgCat cat \ plSurg cat \  HospSurg bin \ iolType cat \	costSurg cat \ freeSurg bin \ csoeyes cat	) ///
	onecol nospace total(after)


* CUSTOM Program for Cluster sampling adjusted  analysis by sex
cap program drop clustercibysexwtEyes
program define clustercibysexwtEyes , rclass
	args outcome 
	return clear 
	qui svy linearized : proportion `outcome',  over(sex)
	cap mat drop all
	mat all  = r(table)
	mat all  = all' //	mat list all
	qui svy linearized : proportion `outcome'
	cap mat drop all2
	mat all2  = r(table)
	mat all2  = all2'
	qui	levelsof `outcome', local(outcomeLevels)
	qui	levelsof sex, local(sexLevels)
	local x = 1 // COUNTER FOR OUTCOME RESULTS IN SEX-WISE ANALYSIS - TWO ROWS PER OUTCOME LEVEL (ONE FOR EACH SEX)
	local y = 1 // COUNTER FOR OUTCOME RESULTS IN OVERALL ANALYSIS - ONE ROW PER OUTCOME LEVEL
  foreach o of local outcomeLevels  {  // of local levels    in 1 
	return local outcomeName`o' : label(`outcome') `o' // local outcome = ustrregexra(`"`outcomeName'"', " ", "_") 
	return local outcomeCode`o' = `o' 	//di  "`outcomeName'              `outcomeCode'"
	return local prop_`o'_M : di  %4.1f  all[`x',1]*100 // Cluster-adjusted  prevalence outcome level for Male 
	return local lb_`o'_M : di  %4.1f  all[`x',5]*100 // Cluster-adjusted  prevalence lower CI  for that Male 
	return local ub_`o'_M : di  %4.1f  all[`x',6]*100 // Cluster-adjusted  prevalence lower CI  for that Male
	local x = `x' + 1
	return local prop_`o'_F : di  %4.1f  all[`x',1]*100 // Cluster-adjusted  prevalence outcome level for Female 
	return local lb_`o'_F : di  %4.1f  all[`x',5]*100 // Cluster-adjusted  prevalence lower CI  for that Female 
	return local ub_`o'_F : di  %4.1f  all[`x',6]*100 // Cluster-adjusted  prevalence lower CI  for that Female
	local x = `x' + 1
	return local prop_`o'_T : di  %4.1f  all2[`y',1]*100 // Cluster-adjusted  prevalence outcome level overall
	return local lb_`o'_T : di  %4.1f  all2[`y',5]*100 // Cluster-adjusted  prevalence lower CI  overall 
	return local ub_`o'_T : di  %4.1f  all2[`y',6]*100 // Cluster-adjusted  prevalence lower CI  overall
	local y = `y' + 1
	qui count if sex==1 & `outcome'!=. //male
	return local denomM = r(N)	
	qui count if sex==2 & `outcome'!=. //Female
	return local denomF = r(N)	
	qui count if  `outcome'!=. //Total
	return local denomT = r(N)	
	qui count if sex==1  //male
	return local sampleM = r(N)	
	qui count if sex==2  //Female
	return local sampleF = r(N)	
	qui count  //Total
	return local sampleT = r(N)		
	return local indicator = "`outcome'"
  }
  return local levelsOfOutcome = `y'-1
end


* CUSTOM Program for Cluster sampling adjusted  analysis by Categorical risk factors
cap program drop clustercibyRFwtEyes
program define clustercibyRFwtEyes , rclass
	args outcome  byVar
	return clear 
	return local indicator = "`outcome'"
	return local byVar = "`byVar'"
	qui svy linearized : proportion `outcome',  over(`byVar')
	cap mat drop all
	mat all  = r(table)
	mat all  = all' //	mat list all
	qui svy linearized : proportion `outcome'
	cap mat drop all2
	mat all2  = r(table)
	mat all2  = all2'
	qui	levelsof `outcome', local(outcomeLevels)
	qui	levelsof `byVar', local(byVarLevels)
	local x = 1 // COUNTER FOR OUTCOME RESULTS IN ByVar-WISE ANALYSIS -  ROWS PER OUTCOME LEVEL (ONE FOR EACH SEX)
  foreach o of local outcomeLevels  {  // of local levels    in 1 
	local outcomeName`o' : label(`outcome') `o' // local outcome = ustrregexra(`"`outcomeName'"', " ", "_") 
	local outcomeCode`o' = `o' 	//di  "`outcomeName'              `outcomeCode'"
	foreach byVarLevel of local byVarLevels  {
		local byVarLevelName`byVarLevel' : label(`byVar') `byVarLevel'    // local outcome = ustrregexra(`"`outcomeName'"', " ", "_") 
		local byVarLevelCode`byVarLevel' = `byVarLevel' 	                //di  "`outcomeName'              `outcomeCode'"
		qui count if `byVar'==`byVarLevel' & `outcome'!=. //male
		local denom`byVarLevel' = r(N)	
		qui count if `byVar'==`byVarLevel'  //male
		local sample`byVarLevel' = r(N)	
		local prop_`o'_`byVarLevel' : di  %4.1f  all[`x',1]*100 // Cluster-adjusted  prevalence outcome level  
		local lb_`o'_`byVarLevel' : di  %4.1f  all[`x',5]*100 // Cluster-adjusted  prevalence lower CI  
		local ub_`o'_`byVarLevel' : di  %4.1f  all[`x',6]*100 // Cluster-adjusted  prevalence lower CI 
		local x = `x' + 1
	}
	local y = `y' + 1
  }
  local levelsOfOutcome = `y'
  local levelsOfbyVar = (`x' - 1 )/ `y'
 
  local  headings ""
    foreach o of local outcomeLevels  {
		local  headings   "`headings' `outcomeName`o'' "    
	} 
   di "`headings'"
  foreach byVarLevel of local byVarLevels  {  
    local  result "`denom`byVarLevel''  "
    foreach o of local outcomeLevels  {
		local  result   "`result' `prop_`o'_`byVarLevel'' (`lb_`o'_`byVarLevel'', `ub_`o'_`byVarLevel'')      " 
	}
	local  result " `result'  -  `byVarLevelName`byVarLevel''  "
	di "`result'"
  }

end


* SVY SET - ADJUST AS PER YOUR WEIGHTS
svyset cluster, vce(linearized) singleunit(certainty) weight(wtRAABEnroll2Dist)


* Generate Cluster adjusted estimates
clustercibysexwtEyes csoeyes


* Risk factor Analysis


**** UNIVARIATE ANALYSIS *******
tab  ageGrp csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes ageGrp

tab  sex csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes sex

tab  option1 csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes option1

tab  ageSurgCat csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes ageSurgCat

tab  timeSinceSurgCat csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes timeSinceSurgCat

tab  HospSurg csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes HospSurg

tab  iolImplant csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes iolImplant


tab  costSurg csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes costSurg

tab  rural csoeyes, row chi nokey
clustercibyRFwtEyes   csoeyes rural



svy linearized : logistic csoeyesType3 i.ageGrp, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 i.sex, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 ib4.option1, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 ib2.ageSurgCat, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 i.timeSinceSurgCat, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 ib1.HospSurg, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 ib1.iolImplant, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 ib3.costSurg , baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 i.rural, baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)
svy linearized : logistic csoeyesType3 i.ageGrp   i.sex ib4.option1   ib2.ageSurgCat  i.timeSinceSurgCat  ib1.HospSurg ib1.iolImplant ib3.costSurg   i.rural        ib5.distZone  , baselevels cformat(%5.2f) pformat(%5.3f) sformat(%8.3f)

est store e1

ssc install estout
estout e1 ,   cells (" b(fmt(2))    ci(par( ( , ) )) p(fmt(3)) ") label   eform  




Code language: Stata (stata)

I have data of multiple surveys and in order to generate survey-area wise results, following code is helpful


tab areacode2
cap mkdir adj

cap program drop resultsByDistandCountryCSVeyes
program define   resultsByDistandCountryCSVeyes 
	args outcome2
	cap file close myfile
	file open myfile using "adj\\`outcome2'.csv", write replace
	* SET HEADERS
	local colnames = "district,areacode2,sampleT,sampleM,sampleF,denomT,denomM,denomF,indicator"
	qui	levelsof `outcome2', local(outcomeLevels2)
	foreach o2 of local outcomeLevels2  { 
		local colnames = "`colnames',prop_`o2'_M,lb_`o2'_M,ub_`o2'_M,prop_`o2'_F,lb_`o2'_F,ub_`o2'_F,prop_`o2'_T,lb_`o2'_T,ub_`o2'_T"
	}
  	file write myfile "`colnames'" _n
	* dISTRICT WISE DATA
	qui	levelsof areacode2, local(districts)
		foreach district of local districts  {   
			qui preserve 
			qui keep if areacode2==`district'	
			local DistName : label(areacode2) `district'
			local DistName = ustrregexra(`"`DistName'"', " ", "-") 
			local distCode = `district'
			
			qui svyset cluster, vce(linearized) singleunit(certainty) weight(wtRAABEnroll2Dist)
			* set district name and n
		    clustercibysexwtEyes    `outcome2'	 // return list			di "value = :" r(sampleT)
			local colvalues = "`DistName',`district',`r(sampleT)',`r(sampleM)',`r(sampleF)',`r(denomT)',`r(denomM)',`r(denomF)',`r(indicator)'"				//di "`colvalues'"
			qui	levelsof `outcome2', local(outcomeLevels2)	
			* set outcome level wise results for each sex and total
			foreach o2 of local outcomeLevels2  { 
				clustercibysexwtEyes    `outcome2'	 // for some reason porevious reults were not getting pushed into the next loop
				local colvalues = "`colvalues',`r(prop_`o2'_M)',`r(lb_`o2'_M)',`r(ub_`o2'_M)',`r(prop_`o2'_F)',`r(lb_`o2'_F)',`r(ub_`o2'_F)',`r(prop_`o2'_T)',`r(lb_`o2'_T)',`r(ub_`o2'_T)'"  //			di "INNER `colvalues'"
			}
			di "`colvalues'" , 
			file write myfile "`colvalues'" _n
			restore
			
		}	
	qui svyset areacode2, fpc(numDists)   vce(linearized) singleunit(missing) || cluster,  weight(wtRAABEnroll2Dist)
	clustercibysexwtEyes    `outcome2'
	local colvalues = "Country,0,`r(sampleT)',`r(sampleM)',`r(sampleF)',`r(denomT)',`r(denomM)',`r(denomF)',`r(indicator)'"				//di "`colvalues'"
	qui	levelsof `outcome2', local(outcomeLevels2)	
	* set outcome level wise results for each sex and total
	foreach o2 of local outcomeLevels2  { 
		clustercibysexwtEyes    `outcome2'	 // for some reason porevious reults were not getting pushed into the next loop
		local colvalues = "`colvalues',`r(prop_`o2'_M)',`r(lb_`o2'_M)',`r(ub_`o2'_M)',`r(prop_`o2'_F)',`r(lb_`o2'_F)',`r(ub_`o2'_F)',`r(prop_`o2'_T)',`r(lb_`o2'_T)',`r(ub_`o2'_T)'"  //			di "INNER `colvalues'"
	}
	di "`colvalues'" , 
	file write myfile "`colvalues'" _n
	file close myfile
	preserve
	import delimited "adj\\`outcome2'.csv", case(preserve) clear 
	save "adj\\`outcome2'.dta", replace
	list , noobs clean
	restore
end

drop if surgDetailsavailable ==0
resultsByDistandIndiaCSVeyes csoeyes if  surgDetailsavailable ==1


cd adj
use "csoeyes.dta", clear
gen male1 = string(prop_1_M ) + "(" + string( lb_1_M) + ", " + string( ub_1_M) + ")"
gen male2 = string(prop_2_M ) + "(" + string( lb_2_M) + ", " + string( ub_2_M) + ")"
gen male3 = string(prop_3_M ) + "(" + string( lb_3_M) + ", " + string( ub_3_M) + ")"

gen female1 = string(prop_1_F ) + "(" + string( lb_1_F) + ", " + string( ub_1_F) + ")"
gen female2 = string(prop_2_F ) + "(" + string( lb_2_F) + ", " + string( ub_2_F) + ")"
gen female3 = string(prop_3_F ) + "(" + string( lb_3_F) + ", " + string( ub_3_F) + ")"


gen total1 = string(prop_1_T ) + "(" + string( lb_1_T) + ", " + string( ub_1_T) + ")"
gen total2 = string(prop_2_T ) + "(" + string( lb_2_T) + ", " + string( ub_2_T) + ")"
gen total3 = string(prop_3_T ) + "(" + string( lb_3_T) + ", " + string( ub_3_T) + ")"

cap drop dist2 
gen dist2 = district + " (" + string(sampleT) + ")"
order  dist2  denomM male1 male2 male3 denomF female1 female2 female3
order  dist2  denomT total1 total2 total3


cd ..


Code language: PHP (php)

Related posts