← All posts

Dummy Variables + mfp in Stata: A Practical Guide (with xi: and mfpa)

Clinical Epidemiology ResearchUniqcret doctor knowledgesData Analytics or StatisticsStata [Data Analytics]
On this page

Introduction

This short “how-to” is written for researchers who hit the same wall you did:

The solution is usually simple: pre-create dummy variables (best practice) or use xi: (quick fix). mfpa is an alternative when you need factor variables.


1) What is a dummy variable?

A dummy variable is a 0/1 indicator representing membership in a category.

Key rule: preserve missingness

In Stata, expressions like (thal==1) will return 0 when thal is missing (because . is not equal to 1). That silently misclassifies missing values.

✅ Always do:

gen thal_trait = (thal==1) if !missing(thal)
replace thal_trait = . if missing(thal)

Or simpler (same effect):

gen thal_trait = .
replace thal_trait = 1 if thal==1
replace thal_trait = 0 if thal!=. & thal!=1

2) How to create dummy variables (three common methods)

Method A — Manual gen (most transparent; best for papers)

Example: thal has three levels: 0 = no, 1 = trait, 2 = disease. Reference = “no thalassemia” (0). Create two dummies:

gen thal_trait   = (thal==1) if !missing(thal)
gen thal_disease = (thal==2) if !missing(thal)

label var thal_trait   "Thalassemia trait"
label var thal_disease "Thalassemia disease"

Example: cirrhosis has 3 levels: 0=no, 1=compensated, 2=decompensatedReference = 0:

gen cir_comp = (cirrhos==1) if !missing(cirrhos)
gen cir_decomp = (cirrhos==2) if !missing(cirrhos)

label var cir_comp   "Compensated cirrhosis"
label var cir_decomp "Decompensated cirrhosis"

✅ This is the easiest to interpret and to report.

Method B — tab var, gen(prefix) (fast)

tab thal, gen(thal_)

Stata will create thal_1, thal_2, thal_3 ... based on the levels it sees.

You must choose a reference and drop one dummy (or omit it from the model).

Also check missingness handling—tab, gen() does not always behave the way you want with missing categories, so always verify:

misstable sum thal thal_*
tab thal, missing

Method C — xi: prefix (automatic expansion; quick fix)

xi: expands i.var into dummy variables before the model runs.

Example:

xi: logistic group_gimalig age hb i.thal i.cirrhos

Creates internal variables like Ithal1, Ithal2 ...

✅ Useful when you want speed ❌ Less readable output and harder to control references ❌ For prediction modeling / TRIPOD reporting, manual dummies are usually preferred.


3) Why this matters for mfp

The limitation

mfp does NOT accept factor-variable or time-series operators.So these will fail:

Typical error:

factor-variable and time-series operators not allowed

4) How to use mfp correctly with dummy variables

The syntax pattern (what mfp expects)

mfp [options] : regression_cmd y xvarlist

Important points:

That “joint testing” is very important for dummy sets.


5) Three mfp patterns you said you use frequently

Pattern 1 — Default MFP (shape + selection)

mfp logistic group_gimalig ///
    age hb wbc plt mcv rdw ferritin si ///
    male pain wtloss abnbm gib ///
    thal_trait thal_disease ///
    cir_comp cir_decomp

What it does:

Best used for:

Not ideal if you need a “full” pre-specified model.

Pattern 2 — Full model (no variable removal): select(1)

mfp, select(1) : logistic group_gimalig ///
    age hb wbc plt mcv rdw ferritin si ///
    male pain wtloss abnbm gib ///
    thal_trait thal_disease ///
    cir_comp cir_decomp

What it does:

Best used for:

Pattern 3 — Force some predictors + allow selection in others

Example: force age and hb in the model, but allow selection of the rest:

mfp, select( ///
      wbc plt mcv rdw ferritin si male pain wtloss abnbm gib ///
      (thal_trait thal_disease) (cir_comp cir_decomp) : 0.05, ///
      age hb : 1 ///
    ) df(age hb:4) : ///
    logistic group_gimalig ///
      age hb wbc plt mcv rdw ferritin si ///
      male pain wtloss abnbm gib ///
      (thal_trait thal_disease) (cir_comp cir_decomp)

What it does (conceptually):

Why parentheses matter here:


6) Using xi: with mfp (quick compatibility mode)

If you don’t want to manually create dummies, this usually works:

xi: mfp, select(1) : logistic group_gimalig ///
    age hb wbc plt mcv rdw ferritin si ///
    male pain wtloss abnbm gib ///
    i.thal i.cirrhos

Why it works

When I recommend xi: vs manual dummies


7) MI error: “mfp on m=1” and how to fix it

You mentioned:

“an error occurred when mi estimate executed mfp on m=1”

This usually happens because:

Fix 1 (best practice): create dummies as passive under MI

If thal or cirrhos are imputed, your dummies should be passive (derived from the imputed parent variable):

mi passive: gen thal_trait   = (thal==1) if !missing(thal)
mi passive: gen thal_disease = (thal==2) if !missing(thal)

mi passive: gen cir_comp   = (cirrhos==1) if !missing(cirrhos)
mi passive: gen cir_decomp = (cirrhos==2) if !missing(cirrhos)

Then:

mi estimate: mfp, select(1) : logistic group_gimalig ///
    age hb wbc plt mcv rdw ferritin si ///
    male pain wtloss abnbm gib ///
    thal_trait thal_disease cir_comp cir_decomp

Fix 2 (quick fix): xi: inside MI

Often works:

mi estimate: xi: mfp, select(1) : logistic group_gimalig ///
    age hb wbc plt mcv rdw ferritin si ///
    male pain wtloss abnbm gib ///
    i.thal i.cirrhos

If it runs, it’s fine for teaching and quick work. For publication, I still prefer passive dummies because it’s explicit and reproducible.


8) Where mfpa fits (and why people use it)

What mfpa adds

When to use mfpa

Why some people avoid mfpa for performance validation

Not because validation is impossible—you can still:

…but because:

For many clinical papers, manual dummies + official mfp remains the cleanest “standard”.


Practical checklist (what to do in real life)

If you use mfp and have categorical variables:

✅ Create dummies manually (best) OR use xi: (quick)

For multi-level categorical predictors:

✅ Use k−1 dummies

✅ Consider testing as a block: (d1 d2 ... dk-1)

Under MI:

✅ Make dummies passive

or ✅ use mi estimate: xi: ... as a shortcut

If you see:

factor-variable and time-series operators not allowed
0
Message for International and Thai ReadersUnderstanding My Medical Context in ThailandRead more →Message for International and Thai ReadersUnderstanding My Broader Content Beyond MedicineRead more →

Comments

No comments yet. Be the first to share your thoughts.

Sign in to comment