ietoolkit icon indicating copy to clipboard operation
ietoolkit copied to clipboard

[iebaltab]: Allow multiple if-conditions

Open bbdaniels opened this issue 4 years ago • 0 comments

This is important where there are different levels in the data. For example see a suggested syntax that has village, household, and individual here:

iebaltab ///
  /// village stats
  (vil_t39v3 vil_t39v4 vil_t39v5 vil_t39v11 vil_t39v6 vil_edu_primary ///
    vil_fem_secondary vil_t39v23 vil_t39v18 vil_t39v22 vil_t39v21 vil_infra ///
    if tag_village == 1) ///
  /// household stats
  (hh_stats_electricity_pre hh_water_inhouse_pre hh_perm_house_pre /// hh stats
    hh_stats_market_pre hh_stats_water_dist_pre hh_stats_medical_pre ///
    hh_stats_privateschool_pre hh_stats_govtschool_pre ///
    if tag_hh == 1) ///
  /// individual stats
  (indiv_male_height indiv_female_height indiv_male_age indiv_female_age ///
    indiv_edu_primary_m indiv_edu_primary_f ///
    if indiv_dead == 0 & indiv_age > 17 ) ///

I have implemented this for other commands with the following:

  • Subprogram to parse the lists:
// Program to parse on parenthesis -------------------------------------------------------------
cap prog drop parenParse
program def parenParse , rclass
  syntax anything
  local N = length(`"`anything'"')
  local x = 0
  local parCount = 0
  // Run through string
  forv i = 1/`N' {
    local char = substr(`"`anything'"',`i',1) // Get next character
    // Increment unit and counter when encountering open parenthesis
    if `"`char'"' == "(" {
      if `parCount' == 0 {
        local ++x // Start next item when encountering new block
      }
      else {
        local string`x' = `"`string`x''`char'"'
      }
      local ++parCount
    }
    // Otherwise de-increment counter if close parenthesis
    else if `"`char'"' == ")" {
      local --parCount
      if `parCount' != 0 local string`x' = `"`string`x''`char'"'
    }
    // Otherwise add character to string block
    else {
      local string`x' = `"`string`x''`char'"'
    }
  }
  // Return strings to calling program
  return scalar nStrings = `x'
  forv i = 1/`x' {
    return local string`i' = `"`string`i''"'
  }
end
// End -----------------------------------------------------------------------------------------
  • Code chunk to handle in the main program:
// Parse dependent variable lists
  parenParse `anything'
  forvalues i = 1/`r(nStrings)' {
    local string`i' = "`r(string`i')'"
    // Get if-condition
    if regexm("`string`i''"," if ") {
      local ifcond`i' = substr("`string`i''",strpos("`string`i''"," if "),.)
      local string`i' = subinstr("`string`i''","`ifcond`i''","",.)
    }
    unab string`i' : `string`i''
  }

local nStrings = `r(nStrings)'
forvalues i = 1/`nStrings' {
 ... DOING STUFF with `string`i'' ...
}

bbdaniels avatar May 07 '20 17:05 bbdaniels