Microeconometrics

Material 2 · Stata assignment

An Ordered Probit PMT Model

Objectives. This exercise has five: (a) to become familiar with Susenas, BPS's national socio-economic survey and the source of Indonesia's official poverty and consumption figures, whose March round covers about 340,000 households, and of which four rounds, 2022 to 2025, are used here; (b) to be able to handle Susenas data, from importing the files in their original dBase format and reading the questionnaire and the metadata, to collapsing person records to households, reshaping the consumption module, and merging the parts into one analysis file per round; (c) to be able to build a proxy means test mimicking exactly how it is done in practice, thirty-nine proxies with district fixed effects, as a linear model on log per-capita consumption, estimated on the pooled rounds and applied to a round outside the estimation sample; (d) to do the same with an ordered probit on the welfare decile, with its nine cutpoints and ten predicted probabilities, and the step from those probabilities to a single predicted decile; and (e) to compute the inclusion and exclusion error of each model for the poorest half, weighted by people, and say which specification targets better.

Illustration: a wall of light shaped like a distribution curve rising over a dark plain, with one small figure standing at its foot
Contents
  1. The task
  2. The data package
  3. The do files and what is yours to write
  4. Building the analysis file
  5. Variable definitions
  6. Model specifications
  7. Targeting measures
  8. The reference output and checkpoints
  9. Rules, runtime and submission
  10. Group competition and submission
  11. Downloads

1. The task

A proxy means test (PMT) predicts a household's welfare from things a programme officer can see or ask at the door: the house, its water and sanitation, the assets, who lives there. The welfare measure itself, per-capita consumption expenditure, is only known from a survey. The PMT is fitted on survey data and then applied to households outside the survey.

In this assignment the survey is Susenas March, four rounds. You will:

The data are synthetic: no record belongs to a real household. Treat them as you would treat real microdata; the skills are the same.

The four rounds are split in two. Every model is estimated on 2022, 2023 and 2024 pooled. This assignment calls those three rounds the training sample. No model is estimated on 2025; that round is used only to measure how well the predictions work, and is called the test sample. The words come from the machine learning literature. In econometric terms the training sample is the estimation sample, and everything measured on the test sample is out-of-sample prediction. The do files use a flag called train, so the words are kept here.

The split exists because a PMT predicts consumption for households whose consumption has not been measured, so its performance has to be measured on households the model did not use. An R² computed on the estimation sample cannot do that: it never falls when a proxy is added, and part of it comes from noise in that sample which will not repeat.

The round held out is the latest one rather than a random subsample of the four, because a programme estimates the formula once and then uses it for several years. Over those years real welfare changes, the questionnaire changes, and the relation between the proxies and consumption drifts. A random split puts the same years on both sides and hides all of it; holding out 2025 measures it. For the same reason the 2025 decile is computed within 2025 alone (section 4.6): if 2025 were ranked together with the training rounds, information from the test period would enter the training ranking.

From step 2 on, the two samples sit in one file with the flag train: train == 1 on the 2022–2024 rows, train == 0 on the 2025 rows. Estimate every model with if train == 1, predict for every row including the test rows, and measure every error on train == 0 only.

2. The data package

Four stacks of lit slabs standing on a dark plain, the fourth one unlit, with a small figure at the foot of the nearest

One folder per round, laid out as a Silastik download from BPS:

2022_maret/  2023_maret/  2024_maret/  2025_maret/
    KOR/            the household file (RT) and the individual file(s) (IND), dBase
    KP/             consumption: BLOK43 (household totals) and BLOK42 (three items only)
    kuesioner/      the questionnaires of the round
    metadata_bps/   the BPS variable lists
    Metadata_Synthetic_Susenas_YYYYMM.xlsx
                    the variable list of this release, with value labels
poverty_line_2022_2025.csv
                    the published BPS poverty line by year, province and urban/rural

2.1 Read the questionnaire and the metadata before the data

Every variable in these files is an answer to a question on a form. The habit this exercise builds is to go to the form first, and to the data second. In each round's folder:

Working order for every field you use: the question in the questionnaire → its field name and codes in the workbook of that round → a tabulation of the field in Stata to see that the codes are what the workbook says → only then the code. Variable definitions in section 5 name the 2022 fields; for the other rounds the workbook is the authority, not this page.

The four files of a round carry different units of observation:

FileOne row isKeyWhat you take from it
KOR household (RT)a householduruthousing, sanitation, lighting, fuel, the thirteen assets, household size r301, province r101, district r102, urban/rural r105
KOR individual (IND)a personurut, r401relationship to the head, sex, age, marital status, schooling, certificate, job sector, phone and internet use
BLOK43a householdurutfood, nonfood, expend (monthly, rupiah), kapita (per head), the weights wert (households) and weind (people)
BLOK42a household × itemurut, kodequantity b42k3 and value b42k4 for three items: electricity, phone credit, internet packages
Not all rounds are the same File names, the number of files a module is split into, and variable names all change between rounds. In some rounds the individual file comes in two column halves. A variable name that no longer exists does not always produce an error: a hard-coded item code that is not in the file gives zeros, silently. Read each round's folder and its metadata workbook before you write its block.

Where to get the data

The package is one zip, 323 MB, on the course repository's release page:

Unzip it anywhere. The folder that holds the four YYYY_maret folders and poverty_line_2022_2025.csv is the path to put in the pkg line at the top of s0_import.do.

Optional: the Stata program that generates the synthetic data is here. Not needed for the assignment.

3. The do files and what is yours to write

Every file is complete for the first case and stops where the pattern repeats. The places where your code goes are marked >>> write ... here <<<. There is no master file: run the four files one after another, in order, each with do. Each file opens with the one or two path lines to edit and writes its own log into the work folder.

In steps 0 and 1 the given 2022 block is the pattern: follow it line by line for the other rounds and change only what the data require. In steps 2 and 3 no model is given; section 6 specifies each one and section 7 the targeting rule, precisely enough to write the code from. Keep every variable name as specified: later steps read them.

4. Building the analysis file

Scattered groups of people on a dark plain, each group condensing into one point of light, the points forming a single line

Each round becomes one file, analysis_YYYY.dta, with one row per household. The steps, in the order the given 2022 block does them:

4.1 Person counts

From the individual file, build 0/1 indicators per person and collapse (sum) them by household. The head of the household is the person with relationship code 1; the head's age and certificate are taken with (max) after keeping them only on the head's row. Two questions asked of every person, phone ownership and internet use, are carried as household characteristics by taking the first listed member. Count the members with (count); this count is checked later against the household file.

4.2 BLOK42 from long to wide

BLOK42 has one row per household per item. Keep the three items, put the quantity of electricity and the values of phone credit and internet packages into three variables, and collapse (max) by household. Households that bought none of the three items still have one all-zero row in the module; keep that row, so that these households come out with zeros rather than disappear.

Item codes In the March 2022 file the three items are code 205 (electricity, quantity in kWh in b42k3), 236 (phone credit, value in b42k4) and 238 (internet packages, value in b42k4). Check the codes of every other round in its metadata workbook or by tabulating kode.

4.3 Merge

Start from the household file, rename the housing and asset fields to the common names of section 5, then merge one-to-one on urut: BLOK43 (keep food nonfood expend kapita wert weind), the person counts, the BLOK42 variables. Then merge the poverty line many-to-one on year, province and urban/rural. Every merge must match every household; the given code keeps matched rows only and the checks below catch a failed merge.

4.4 Check before trusting

Household size can be got three ways: round(expend / kapita), the household file's r301, and the number of person rows. All three agree in these data. The given code asserts this, and that food + nonfood = expend and weind = wert × hhsize. If an assert fails in a round you wrote, the error is in that round's merge or collapse.

4.5 The welfare measure

rpcexp = kapita × 738 955 / povline    lnrpcexp = ln(rpcexp)

Monthly per-capita expenditure is deflated by the poverty line of the household's year, province and urban/rural cell, and re-expressed in the prices of one cell: DKI Jakarta urban, March 2022, whose poverty line is Rp 738 955 (the do file reads that value from the poverty-line table; it is not typed in). One decile ranking then means the same living standard in every province and every year.

4.6 Deciles

Two rules. The training rounds 2022, 2023 and 2024 are appended and ranked together into ten weighted deciles of rpcexp, so that decile 1 means the same in each year. The 2025 round is ranked on its own: it is the test round, and nothing from it may enter the training ranking. Deciles are weighted with weind, the individual weight, so that a decile is a tenth of people, not of households. weind is rounded to an integer first because xtile takes frequency weights.

5. Variable definitions

A small house at night with its roof, wall, water, toilet, electricity meter and cooking fire each picked out in light, household goods in a row beside it, and a figure with a clipboard at the door

Field names are those of the March 2022 files. The same variable may have another name in another round; the definition does not change. Categorical variables enter the models as factor variables (i.) with their original codes.

5.1 Household file (RT)

Name2022 fieldDefinition
h_houser1802Tenure of the dwelling: 1 owned, 2 rented, 3 rent-free, 4 official housing, 5 other
h_luaslantair1804Floor area of the dwelling, m²
h_roofr1806Main roof material, 8 codes (concrete, tiles, zinc, asbestos, bamboo, wood, thatch, other)
h_wallr1807Main wall material, 7 codes (brick, plastered bamboo/wire, wood, woven bamboo, logs, bamboo, other)
h_floorr1808Main floor material, 9 codes (marble/granite, ceramic, parquet/vinyl/carpet, tiles, wood, cement/brick, bamboo, earth, other)
h_toiletr1809aToilet facility, 6 codes (own, shared, communal, public, has but not used, none)
h_closetr1809bType of closet, 4 codes; blank when there is no toilet
h_sewager1809cFinal disposal of excreta, 6 codes; blank when there is no toilet
h_waterr1810aMain source of drinking water, 11 codes
h_lightr1816Main source of lighting: 1 PLN metered, 2 PLN unmetered, 3 non-PLN electricity, 4 not electricity
h_epowerr1816b1Installed capacity of the first meter: 1 = 450 W, 2 = 900 W, 3 = 1 300 W or more; blank when lighting is not PLN metered
h_fuelr1817Main cooking fuel, 12 codes (0 does not cook at home, 1 electricity, 2–4 LPG sizes, 5 city gas, 6 biogas, 7 kerosene, 8 briquettes, 9 charcoal, 10 firewood, 11 other)
h_asset_a … h_asset_mr2001a … r2001mOwns: a gas cylinder of 5.5 kg or more; a refrigerator; air conditioning; a water heater; a landline; a computer or laptop; gold or jewellery of 10 g or more; a motorcycle; a boat; a motor boat; a car; a flat-screen TV of 30 inch or more; land. Coded 1 yes, 5 no in the raw file; recoded to 1/0 before modelling
urbanr1051 if urban, 0 if rural
kode_kabr101, r102District code, r101 × 100 + r102; 514 districts

5.2 Counts from the individual file (IND)

Name2022 fieldDefinition
n_age04, n_age519, n_age2064, n_age65upr407Members aged 0–4, 5–19, 20–64, 65 and over
n_femaler405Female members (code 2)
n_workerr705Members with a main job sector recorded (the field is not blank)
h_married, h_widowedr404Members currently married (code 2); members widowed (code 4)
h_neverschool, h_stillschoolr610Members who never attended school (code 1); members still in school (code 2). Asked of members aged 5 and over only
head_femaler403, r4051 if the head (relationship code 1) is female
hd_ager403, r407Age of the head
hd_edur403, r614Highest certificate of the head, the 25-code list of the questionnaire, entered as one numeric variable; blank for heads with no certificate recorded
hhsizeexpend, kapitaround(expend / kapita), checked against r301 and the person count

5.3 Consumption (BLOK43, BLOK42)

NameSourceDefinition
expend, kapitaBLOK43Monthly household expenditure and its per-head value, rupiah
wert, weindBLOK43Household weight and individual weight (= wert × hhsize)
povlinepoverty_line_2022_2025.csvPoverty line of the household's year × province × urban/rural, rupiah per head per month
kwhBLOK42, electricityElectricity bought last month, kWh (quantity field)
credit, packageBLOK42, phone credit; internet packagesSpending last month, rupiah (value field)
elec_kwh_pc, telecom_cons_pcderivedkwh / hhsize; (credit + package) / hhsize

5.4 Transformed terms

NameDefinition
ln_hhsize, ln_hhsize_2ln(hhsize) and its square
ln_h_luaslantai, ln_h_luaslantai_2ln(h_luaslantai + 0.1) and its square
ln_elec_kwh_pc, ln_elec_kwh_pc_2ln(elec_kwh_pc + 0.1) and its square
ln_telecom_cons_pc, ln_telecom_cons_pc_2ln(telecom_cons_pc + 0.1) and its square
h_epower2, h_epower31 if the meter is 900 W; 1 if 1 300 W or more (450 W is the base; households without a PLN meter are 0 on both)
ln_elec_kwh_pc_h_epower2, ln_elec_kwh_pc_h_epower3ln_elec_kwh_pc × h_epower2; ln_elec_kwh_pc × h_epower3
h_asset_car, h_asset_computer, h_asset_land1 if h_asset_k, h_asset_f, h_asset_m equals 1 (yes)

The +0.1 inside each logarithm keeps households with a zero in the sample; without it ln(0) is missing and the household drops out of every model.

5.5 Structural missing values

Four variables are blank for a reason, not at random: h_closet and h_sewage when the household has no toilet, h_epower when lighting is not PLN metered, and hd_edu for heads with no certificate recorded. A factor variable with a blank drops the household from the regression without a message. Step 2 recodes all four to the explicit category 99 and prints how many households each recode keeps; those counts are part of the reference output.

6. Model specifications

A line of light running to the horizon, cut by vertical gates into segments of unequal length, with a small figure standing beside it

This section is the specification you write the code from. Nothing in steps 2 and 3 beyond the sample assembly and the recodes is given.

6.1 Sample and variables common to all four models

6.2 The two regressor sets

The PMT — thirty-nine proxies (the global $baseline_39, given in the do file). Four continuous terms, eleven factor variables, thirteen asset dummies, six household counts, four schooling and marital counts, and three head characteristics:

ln_hhsize ln_hhsize_2 ln_h_luaslantai ln_h_luaslantai_2
i.h_house i.h_roof i.h_wall i.h_floor i.h_toilet i.h_closet i.h_sewage
i.h_water i.h_light i.h_fuel i.h_epower
h_asset_a h_asset_b h_asset_c h_asset_d h_asset_e h_asset_f h_asset_g
h_asset_h h_asset_i h_asset_j h_asset_k h_asset_l h_asset_m
n_age04 n_age519 n_age2064 n_age65up n_female n_worker
h_married h_widowed h_neverschool h_stillschool
head_female hd_age hd_edu

The parsimonious model — fifteen terms from eight underlying variables (the global $predictors_7): household size, electricity per head and telecom spending per head each with its square; the two meter-capacity dummies and their interactions with electricity; three assets; floor area with its square:

ln_hhsize ln_elec_kwh_pc ln_telecom_cons_pc
ln_hhsize_2 ln_elec_kwh_pc_2 ln_telecom_cons_pc_2
h_epower2 h_epower3 ln_elec_kwh_pc_h_epower2 ln_elec_kwh_pc_h_epower3
h_asset_car h_asset_computer h_asset_land
ln_h_luaslantai ln_h_luaslantai_2

Every variable is defined in section 5 and built in step 1; the globals are the same lists, written out.

Model 1 — the PMT, linear, district fixed effects

lnrpcexph = αd(h) + Xhβ + γ·urbanh + εh

Model 2 — the parsimonious model, linear, district fixed effects

The same equation, estimator, sample and district dummies, with X = the fifteen parsimonious terms. Prediction stored as yhat_pars.

Step 2 ends by saving the file with both predictions; the given save line does that.

Model 3 — ordered probit on the decile, the PMT, district fixed effects

decileh = k  if  κk−1 < αd(h) + Xhβ + γ·urbanh + uh ≤ κk,   u ~ N(0, 1),  k = 1 … 10

Model 4 — ordered probit on the decile, the parsimonious model, district fixed effects

The same as model 3 with X = the fifteen parsimonious terms. Probabilities named ops1 … ops10, expected decile ops_expected, summarized on the test round.

7. Targeting measures

Rows of people on a dark plain lit in horizontal bands, a vertical beam marking where the lit group ends, one figure standing at that edge

Section 5 of step 3 applies one targeting rule to each of the four predictions and reports its error. Write it for all four scores: yhat_pmt, yhat_pars, op_expected, ops_expected. The procedure below is complete; the numbers in it are checkpoints from the reference run, so you can verify each step before the next.

Step 0 — where you are

You are in step 3, in the file that step 2 saved (step2_predictions.dta): the four rounds in one file with the flag train, the two linear predictions from step 2, and, after models 3 and 4, the twenty probabilities and the two expected deciles. Everything in this section is computed on the test round only, train == 0: 343 460 households, who stand for 287 771 246 people (the sum of weind over those households).

Step 1 — the true decile (already built)

The true decile is the variable decile that step 1 built for the 2025 round: real per-capita expenditure rpcexp ranked into ten weighted deciles within 2025, with Stata's xtile, ten quantiles, and the individual weight weind as a frequency weight (weind was rounded to an integer for this). Decile 1 is the poorest tenth of people, decile 10 the richest; each decile holds about 28.8 million people but a different number of households, because poor households are larger.

The eligible households are those with decile from 1 to 5: the true bottom half of the population. They stand for E = 143 887 916 people — half of 287.8 million, as they must.

Step 2 — the score of each model

A score is one number per household; a higher score means a better-off household.

Step 3 — the predicted decile

Rank each score the same way the true decile was ranked. With xtile: a new variable, equal to the score, with weind as a frequency weight in square brackets, restricted by an if to train == 0, and the option nquantiles(10). The if matters: it ranks the 2025 households among themselves and leaves the new variable missing for the training rows. The result is the predicted decile of that model, 1 to 10, for every 2025 household. Make one such variable per score: four in all.

The predicted decile of an ordered probit For models 3 and 4 the score is op_expected (ops_expected), a number between 1 and 10 — and it is treated exactly like yhat_pmt: it goes through xtile on the test round, with weind as frequency weight and ten quantiles, and the result is the predicted decile. Three things that are not the predicted decile, though each looks like one: the decile with the largest of the ten probabilities (the most likely decile); op_expected rounded to the nearest whole number; op_expected cut at fixed bounds such as 1.5, 2.5, … None of these puts exactly a tenth of the population in each decile, so none can select exactly the bottom half, and the errors computed from them do not match the reference output. Rank, do not round.

Check, model 1: tabulating the predicted decile on the test round gives 23 119 households in predicted decile 1, rising to 61 711 in predicted decile 10 — unequal in households, equal in people (about 28.8 million each), which is what the weight does.

The rule selects the households with predicted decile 1 to 5: the predicted bottom half of the population.

Step 4 — count people, not households

"People" means the sum of weind over a set of 2025 households. In Stata, summarize weind with the right if condition and the meanonly option leaves that sum in r(sum); store it in a scalar before the next command overwrites it. For each model compute:

Step 5 — the error

IE50 = 100 × W / S

The inclusion error: of the people the rule selects, the share that are not eligible. Model 1: 100 × 35 325 508 / 143 886 559 = 24.55 per cent. Store it as a scalar, one per model (ie_pmt, ie_pars, ie_op, ie_ops).

The exclusion error — of the eligible people, the share the rule misses — is the same number, so it is not computed separately. The selected are the bottom five predicted deciles and the eligible the bottom five true deciles of the same population, so the two groups are the same size (S ≈ E); every person wrongly selected takes the place of one eligible person who is wrongly missed, so the number missed equals W. Check it once if you like: the sum of weind over households with predicted decile > 5 and true decile ≤ 5 is 35 326 865 for model 1, and 100 × 35 326 865 / 143 887 916 = 24.55 — equal to the second decimal.

What the number means: the inclusion error is what a programme pays for people who should not be in it; the equal exclusion error is what the poor lose when they are missed.

Step 6 — the table

Finish with one table on the 2025 test round, printed with display: a title, one header line, then one line per model in the order 1 to 4 — the model's name in a left-aligned column and its IE50 (= EE50) in a right-aligned column with two decimals. The reference output shows the exact layout and the four values: 24.55, 21.05, 24.52, 21.09.

8. The reference output and checkpoints

reference_output.txt is what the four completed do files print, one after another, when run on this package. It is the answer: every number in your log must equal it. It is ordered as your work is ordered, so a mismatch tells you where to look.

StepWhat is printedIf yours differs
0The row count of every imported file, one line per file or appended set; then the first four rows of the poverty-line tableA file was not read, or a split was not appended
1First the deflator base read from the poverty-line table (Rp 738 955). Then per round: households in BLOK42, households built, and a table of mean, SD, min and max of nine variables (hhsize expend kwh credit package h_luaslantai n_worker hd_age lnrpcexp); then the two decile tabulationsThe round's collapse, reshape or merge; a wrong item code shows as zeros in kwh, credit or package
2The year × train tabulation, the four missing-value counts; for models 1 and 2 the full regression output: the ANOVA header, N, F, R², adjusted R², root MSE and the whole coefficient table, district dummies includedThe sample differs: a round is missing, or a structural blank was not recoded
3For models 3 and 4 the full ordered probit output: the iteration log, N, LR χ², pseudo R², log likelihood and the whole coefficient table with the cutpoints; the summary of each expected decile; the table of the inclusion error (= exclusion error)The score, its ranking or the weights; check that the ranking used the test round only and the frequency weight

Two row counts you will meet early: the 2022 household file has 339 584 rows and its individual file 1 237 768. The pooled training sample has 1 024 865 households; the 2025 test round has 343 460.

9. Rules, runtime and submission

Two questions to answer in a short note with your submission: model 2 has a higher R² than model 1 — why might a programme still prefer model 1? And modelling the decile directly (models 3 and 4) does not target better than modelling expenditure and cutting it afterwards — what information does the ordered model throw away before it starts?

10. Group competition and submission

Small groups of people crossing one long line of light on a dark plain, at very different distances

This is a group assignment, run as a competition. Form groups of five. The goal of every group is the same: four do files that run from start to end and reproduce the reference output exactly. What differs is when a group gets there.

The submission form and the live board are on the assignment site: sdgcenter.unpad.ac.id/aay/miktrik/pmtprobit.html.

11. Downloads

The two large files are on the repository’s release page; the rest are in materials/stata.