You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
5.9 KiB
Plaintext

capture program drop fitstat_ers
*!version 1.0 22aug 2011
*!christian a. gregory, economic research service
***********************************************************************************************
*this program computes outfit and infit statistics for the conditional maximum likelihood (cml)
*rasch model, using formulas outlined in the documentation. these fit statistics differ from
*those computed by the raschtest. for more information on the fit statistics, see documentation
*or contact mark nord @ marknord@ers.usda.gov, or christian gregory @ cgregory@ers.usda.gov.
************************************************************************************************
*the gammasym module is required to run this program. to get this module, type "findit gammasym"
*in stata. if you wish to keep the fit statistics in an excel file, install xml_tab.ado; if you wish
*to keep them in a LaTex file, install outtable.ado.
************************************************************************************************
program define fitstat_ers, rclass
version 9.0
syntax varlist(min=2) [if] [in], ///
[excel(string) ///
latex(string) ///
replace ]
tempfile fitstat
qui save `fitstat', replace
marksample touse
qui keep if `touse'
qui keep `varlist'
*compute score
tempvar score
genscore `varlist', score(`score')
*prep data to reshape
g id = _n
local r 0
foreach x of local varlist {
local `++r'
rename `x' item`r'
}
local nbitems: word count `varlist'
*total obs before reshape
qui count if `score'!=0 & `score'!=`nbitems'
local totalobs = r(N)
*get size of groups by score
forvalues i=0/`nbitems' {
qui count if `score'==`i' //& item==1
local realscore`i'=r(N)
}
local t = `nbitems'-1
*reshape
qui reshape long item, i(id) j(rep)
forvalues i = 1/`nbitems' {
qui {
g item`i' = rep==`i'
replace item`i' = -item`i'
}
}
*estimate parameters
qui clogit item item1-item`t', group(id)
matrix beta = e(b)
forvalues i=1/`t' {
local beta`i' = beta[1,`i']
}
local beta`nbitems' = 0
tempname Pi
matrix define `Pi'=J(`nbitems',`t',0)
tempname Obs Obs2 Th Th2
matrix define `Obs'=J(`nbitems',`t',0)
matrix define `Th'=J(`nbitems',`t',0)
local listofitemsc
******************************************************************************************************
*estimation of the gamma symetrical functions. i use these to calculate the expected values of the
*model, conditional on the score. hardouin (07) and glas(88) use these forms. the current stata module
*-raschtest- uses them for general cml models and R tests.
*******************************************************************************************************
forvalues j=1/`nbitems' {
local listini`j'
local listofitemsc "`listofitemsc' `beta`j''"
forvalues k=1/`nbitems' {
local listini`j'k`k'
if `k'!=`j' {
local listini`j' "`listini`j'' `beta`k''" //vector w/o current item paramter--diags of vcv
}
forvalues l=1/`nbitems' {
if `l'!=`j'&`l'!=`k' {
local listini`j'k`k' "`listini`j'k`k'' `beta`l''" //vector w/o current item parameter--off diags of vcv
}
}
}
}
qui gammasym `listofitemsc' //gamma function of full vector of difficulty parameters
*estimation of probabilities (pi) and expected (th), as well as observed (obs)
forvalues s=1/`nbitems' {
local denom`s'=r(gamma`s')
}
local m = `nbitems'-1
local p = `m'-1
forvalues j=1/`nbitems' {
forvalues s=1/`m' {
local r=`s'-1
qui count if rep==`j'& item==1 &`score'==`s'
matrix `Obs'[`j',`s']=r(N)
gammasym `listini`j''
local num`j'=r(gamma `r') //gamma function of vector w/o item j, for score s-1
matrix `Pi'[`j',`s']=exp(-`beta`j'')*`num`j''/`denom`s''
matrix `Th'[`j',`s']=`Pi'[`j',`s']*`realscore`s''
}
}
//local totalobs = _N
matrix outstat = J(`nbitems',2,0)
forvalues j = 1/`nbitems' {
local outfit_j = 0
local infit_j = 0
local outfit_num = 0
local outfit_denom = 0
local infit_num = 0
local infit_denom = 0
forvalues s = 1/`m' {
local n_score = `realscore`s''
disp "frac score = " `n_score'/`totalobs'
local obs_js = `Obs'[`j',`s']
local pred_js = `Th'[`j',`s']
local p_obs_js = `obs_js'/`n_score'
local p_exp_js = `pred_js'/`n_score'
local fitnum = `p_obs_js'*(1-`p_exp_js')^2 + (1-`p_obs_js')*`p_exp_js'^2
local fitdenom = `p_exp_js'*(1-`p_exp_js')
local outfit_j = `outfit_j'+ ((`n_score'/`totalobs')*(`fitnum'/`fitdenom'))
local infit_num = `infit_num'+ (`n_score'/`totalobs')*(`fitnum')
local infit_denom = `infit_denom'+ (`n_score'/`totalobs')*(`fitdenom')
}
local infit_j = `infit_j' + (`infit_num'/`infit_denom')
local outfit_j = `outfit_j'
matrix outstat[`j',1] = `outfit_j'
matrix outstat[`j',2] = `infit_j'
}
matrix rownames outstat = `varlist'
matrix colnames outstat = Outfit Infit
if "`excel'"!="" {
local rand = round(1000*runiform(),1)
if "`replace'"!="" {
xml_tab outstat, save(`excel') replace
}
else {
capture confirm new file `excel'
if _rc {
xml_tab outstat, save(outstat`rand')
di in green "`excel' already exists; results saved in outstat`rand'.xml"
}
else {
xml_tab outstat, save(`excel')
}
}
}
if "`latex'"!=""{
local rand = round(1000*runiform(),1)
if "`replace'"!="" {
outtable using `latex', mat(outstat) nobox replace
}
else {
capture confirm new file `latex'.tex
if _rc {
outtable using `latex'`rand', mat(outstat) nobox
di in green "`latex' already exists; results saved in outstat`rand'.tex"
}
else {
outtable using `latex'`rand', mat(outstat) nobox
}
}
}
return matrix outstat = outstat
use `fitstat', clear
end