*! Version 1.1 4 June 2019
*! Jean-Benoit Hardouin
************************************************************************************************************
* Stata program : descscale
* Description of a scale and covariates
* Release 1.1 : June 4, 2019  
*
*
* Historic :
* Version 1 (April 12, 2019) [Jean-Benoit Hardouin]
* Version 1.1 (June 4, 2019) [Jean-Benoit Hardouin]
*
* Jean-benoit Hardouin, PhD, Assistant Professor
* Team of Methods in Patient Centered Outcomes and Health Research  (INSERM U1246-SPHERE)
* University of Nantes - Faculty of Pharmaceutical Sciences
* France
* jean-benoit.hardouin@anaqol.org
*
*
* News about this program :http://www.anaqol.org
*
* Copyright 2019 Jean-Benoit Hardouin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
***********************************************************************************************************
program define descscale , rclass
version 8.2
syntax varlist [if] [in] [,MIN(int 0) CONTinuous(varlist) CATegorical(varlist) All PARTition(numlist) Large MEAN MAXlevels(int 20)]

preserve
marksample touse,novarlist
label variable `touse' "selection"

tokenize `varlist'
local nbitems: word count `varlist'
if "`partition'"=="" {
    local partition `nbitems'
}
local nbdim:word count `partition'
forvalues i=1/`nbdim' {
   local nbitemsdim`i': word `i' of `partition'
}
qui count if `touse'
local N=r(N)
local maxr=0
forvalues i=1/`nbitems' {
   qui levelsof ``i'' if `touse'
   local r`i'=r(r)
   qui su ``i'' if `touse'
   local max`i'=r(max)
   local mean`i'=r(mean)
   qui count if ``i''!=0&``i''!=1&``i''!=2&``i''!=3&``i''!=4&``i''!=5&``i''!=6&``i''!=7&``i''!=8&``i''!=9&``i''!=10&``i''!=.
   local ninc=r(N)
   local ok`i'=1
   if `r`i''>11&"`large'"=="" {
       di in red "The number of answer categories to the items ``i'' is large (>11). Use the -large- option or correct the list of items." 
       local ok`i'=0
	   exit
   }
   if `ninc'>0 {
       di in red "The variable ``i'' has incompatible values with an items (integers between 0 and 10)." 
       local ok`i'=0
	   exit
   }
   if `r`i''>`maxr' {
      local maxr `r`i''
   }	  
}
*di "maxr=`maxr'"
di
di in green "Number of individuals : " as result `N'

di
di in green "Decription of the items"
local long=(`maxr'+1-`min')*8+40
di in green "{hline `long'}"

di in green "Items" _col(23) "Obs" _c 
local col=33
forvalues j=`min'/`maxr' {
    di _col(`col') "`j'" _c
	local col=`col'+8
}
di _col(`col') "." _col(`=`col'+4') "Mean"
di in green "{hline `long'}"

local deb=1
forvalues d=1/`nbdim' {
    local loi`d' 
    *di "local fin=`deb'+`nbitemsdim`d''-1"
    local fin=`deb'+`nbitemsdim`d''-1
	forvalues i=`deb'/`fin' {
        if `ok`i''==1 {
			local loi`d' `loi`d'' ``i'' 
			qui count if `touse'&``i''!=.
			local k=abbrev("``i''",20)
			di in green "`k'" _col(22) as result %4.0f `r(N)' _c
			local col=28
			forvalues j=`min'/`maxr' {
				qui count if `touse'&``i''==`j'
				local per=round(`r(N)'/`N'*100, 0.1)
				di _col(`col') %5.1f `per' "%" _c
				local col=`col'+8
			}
			qui count  if `touse'&``i''==.
			local per=round(`r(N)'/`N'*100,0.1)
			di _col(`col') %5.1f `per' "%" _col(`=`col'+9') %4.2f `mean`i''
		}
	}
	if `d'!=`nbdim' {
	   di in green "{dup `long':-}"
	}
	local deb=`fin'+1
}
di in green "{hline `long'}"

di
di in green "Decription of the scores"
local long2=72
di in green "{hline `long2'}"
di in green "Scores" _col(22)  "Obs" _col(33)  "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max"
di in green "{hline `long2'}"

forvalues d=1/`nbdim' {
   tempname score`d'
   genscore `loi`d'' if `touse', score(`score`d'') `mean' `standardized'
   qui su `score`d'' if `touse'
   di in green "score`d'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' 
}
di in green "{hline `long2'}"


if "`continuous'"!=""|"`categorical'"!="" {
   local continuous2
   foreach i of varlist `continuous' {
      local candidate=1
	  forvalues j=1/`nbitems' {
	     if "`i'"=="``j''" {
		    local candidate=0
		 }
      }
	  local type : type `i'
	  local type=substr("`type'",1,3)
	  if "`type'"=="str" {
		 local candidate=0
	  }
	  if `candidate'==1 {
		 qui levelsof `i' if `touse'
		 local r=r(r)
         local continuous2 `continuous2' `i'
	  }
   }
   local continuous `continuous2'
   local categorical2
   foreach i of varlist `categorical' {
      local candidate=1
	  forvalues j=1/`nbitems' {
	     if "`i'"=="``j''" {
		    local candidate=0
		 }
      }
	  if `candidate'==1 {
		 qui levelsof `i' if `touse'
		 local r=r(r)
         local categorical2 `categorical2' `i'
	  }
   }
   local categorical `categorical2'
}

if "`all'"!="" {
   *local continuous
   *local categorial
   foreach i of varlist * {
      local candidate=1
	  forvalues j=1/`nbitems' {
	     if "`i'"=="``j''" {
		    local candidate=0
		 }
      }
	  local type : type `i'
	  local type=substr("`type'",1,3)
	  if "`type'"=="str" {
		 local candidate=0
	  }
      qui levelsof `i' if `touse'
 	  local r=r(r)
      if `r'>7&`candidate'==1 {
		 local continuous `continuous' `i'
	  }
	  else {
         local categorical `categorical' `i'
	  }
   }
}

*di "CONTINUOUS : `continuous'"
*di "CATEGORICAL : `categorical'"

if "`continuous'"!="" {
    di
    di "Descriptive analysis of continuous covariates"
	local long2=72
	di in green "{hline `long2'}"
	di in green "Variables" _col(22)  "Obs" _col(33)  "Mean" _col(40) "Std. Dev." _col(58) "Min" _col(70) "Max"
	di in green "{hline `long2'}"
	foreach i of varlist `continuous' {
	   qui su `i' if `touse'
	   local k=abbrev("`i'",18)
	   *di in green "`k'" _c
	   di in green "`k'" _col(20) as result %5.0f `r(N)' _col(30) %7.2f `r(mean)' _col(42) %7.2f `r(sd)' _col(54) %7.2f `r(min)' _col(66) %7.2f `r(max)' 
	}
	di in green "{hline `long2'}"
}
if "`categorical'"!="" {
    di
	*set trace on
    di "Descriptive analysis of categorical covariates"
	local long2=55
	di in green "{hline `long2'}"
	di in green "Variables" _col(25)  "Levels" _col(37) "Freq." _col(49) "Percent" 
	di in green "{hline `long2'}"
	local nbc: word count `categorical'
	local m=1
    local nonret
	foreach i of varlist `categorical' {
	   local type : type `i'
	   local type=substr("`type'",1,3)
	   qui levelsof `i'
	   local lev "`r(levels)'"
	   local nblev=r(r)
	   if (`maxlevels'>=`nblev') {
		   local k=abbrev("`i'",20)
		   di in green "`k'" _c
		   if "`type'"=="str" {
			  foreach j in `lev' {
				 qui count if `touse'&`i'=="`j'"
				 local k=abbrev("`j'",10)
				 di _col(21) %10s in green "`k'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%"
			  }
			  qui count if `touse'&`i'==""
			  if `r(N)'!=0 {
			     di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%"
			  }
		   }  
		   else {
			  foreach j in `lev' {
				 qui count if `touse'&`i'==`j'
				 di _col(21) %10s in green "`j'" as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%"
			  }
			  qui count if `touse'&`i'==.
			  if `r(N)'!=0 {
			     di as result %5.0f _col(37) `r(N)' %6.2f _col(49) `=`r(N)'/`N'*100' "%"
			  }
		   }
		   if `m'==`nbc' {
			  di in green "{hline `long2'}"
		   }
		   else {
			  di in green "{dup `long2':-}"
		   }
	   }
	   else {
	      local nonret `nonret' `i'
	      *di "local nonret `nonret' `i'"
		  *di "non retenu `i'"
		  if `m'==`nbc' {
			  di in green "{hline `long2'}"
          }
	   }
	   local ++m
	}
	if "`nonret'"!="" {
	   di in green "Not described variables (too more levels) : " as result "`nonret'"
	}
}
end
