*! version 3.0.0 21 Apr 2026

Title

epifix -- Fix structural problems in episode-format diary files

Syntax

epifix varlist, did(varlist) [attrib(varlist) fullfix errorsonly quiet]

where varlist contains 1 to 6 activity variables to be corrected.

did(varlist) variable(s) that uniquely identify each diary; required

attrib(varlist) attribute variables to carry forward when rows are inserted; optional

fullfix also fix fully overlapping episodes (issue 1); optional

errorsonly process only diaries flagged as problematic, then reassemble the full dataset; optional

quiet reduce printed output; optional

Description

epifix corrects structural problems in episode-format diary files.

It is designed to work after epicheck. Internally, epifix uses the issue flags created by epicheck and applies a set of automatic repairs to the affected diaries.

By default, epifix addresses issues 2 to 8:

2. nested episode

3. partial overlap

4. gap at minute 0

5. gap at end of diary

6. gap between episodes

7. row with start==end

8. row with missing start or end

Fully overlapping episodes (issue 1) are not fixed unless the user specifies fullfix.
This is intentional, because full overlaps often reflect the structure of wide-interval diary files rather than genuine data errors.
In those cases, epitrans is often the better first step.

The command creates standardized internal activity layers such as __pri, __sec, and so on, applies the repairs, and prints a summary table of the fixes made.

Required variables

start must exist and contain the start minute of each episode.

end must exist and contain the end minute of each episode.

The data must already be in episode format.

Arguments

varlist specifies one to six activity variables to be corrected.
These may be numeric or string, but all supplied activity variables must be of the same type.

These variables are copied into standardized working layers and are not themselves
dropped from the dataset.

did(varlist) specifies one or more variables that jointly identify each diary uniquely.

Options

attrib(varlist) specifies attribute variables to be carried forward when inserted rows are created.

This is useful for variables such as location, co-presence, transport mode, or any
other diary field that should remain aligned with the repaired episode structure.

fullfix tells epifix to also fix fully overlapping episodes (issue 1).

Without this option, full overlaps are left untouched.

errorsonly restricts processing to diaries with at least one detected issue,
fixes only those diaries, and then appends them back into the full original dataset.

This can be useful on large files where only a small subset of diaries needs repair.

quiet reduces printed output.

The command still prints essential messages when needed, but suppresses the final
note about fixed layer names.

What the command creates

epifix returns a repaired episode-format dataset and creates standardized
activity-layer variables as needed:

Output variables

__pri primary activity layer

__sec secondary activity layer

__ter tertiary activity layer

__quat quaternary activity layer

__fif fifth activity layer

__six sixth activity layer

Only layers that contain at least one nonmissing value are kept in the final dataset.

The original activity variables supplied in varlist remain in the dataset.

How the fixes work

The command uses epicheck flags and applies repairs in place.

The main repair logic is as follows:

Issue 1: Full overlap
Only fixed when fullfix is specified. All rows sharing the same did, start, and end
are collapsed to one survivor row, and the overlapping activities are projected into the available standardized layers.

Issue 2: Nested episode
The outer episode is split around the inner one. The overlapping middle segment keeps the container activity as primary and places the nested activity in a secondary layer.

Issue 3: Partial overlap
Overlapping episodes are split into non-overlapping segments so that timing becomes
consistent and simultaneous content is represented through activity layers.

Issue 4: Gap at minute 0
A new first row is inserted covering the gap from 0 to the first observed start.

Issue 5: Gap at end of diary
A new final row is inserted covering the gap from the last observed end to minute 1440.

Issue 6: Gap between episodes
A bridging row is inserted covering the gap between two consecutive episodes.

Issue 7: Row with start==end
Zero-length rows are dropped.

Issue 8: Missing start or end
Rows with missing time bounds are dropped.

Inserted rows receive empty activity layers. If attrib() is supplied, those attribute variables are also cleared appropriately on the inserted rows.

Checks and internal workflow

If the dataset does not already contain __flag_case and __flag_diary, epifix runs epicheck internally.

If no issues are detected, the command stops without changing the data.

If errorsonly is specified, the command first identifies bad diaries using epicheck,
keeps only those diaries for the repair stage, and then rebuilds the full dataset by appending the fixed subset back to the untouched original diaries.

Dataset after running the command

The dataset remains in episode format, but structural timing problems are repaired where possible.

Depending on the issue types present, the number of rows may increase (for inserted
gap-filling rows or split episodes) or decrease (for dropped zero-length rows, dropped rows with missing bounds, or collapsed full overlaps under fullfix).

Printed summary

epifix prints a summary table showing the number of affected rows (Cases), the number of diaries affected, and the percentage of diaries affected.

The summary reports:

- full overlaps if fullfix is used

- nested episodes

- partial overlaps

- gaps at minute 0

- gaps at end of diary

- gaps between episodes

- dropped zero-length rows

- dropped rows with missing start/end

At the end, unless quiet is specified, the command also reports which
standardized activity-layer variables were created and reminds the user that
the original activity variables are still in the dataset.

Examples

Example 1: Fix standard issues but leave full overlaps untouched

. epifix main sec, did(hldid persid id) attrib(inout eloc mtrav alone child sppart oad ict)

This repairs issues 2 to 8 but does not modify fully overlapping rows.

Example 2: Also fix fully overlapping rows

. epifix main sec, did(hldid persid id) attrib(inout eloc mtrav alone child sppart oad ict) fullfix

This additionally collapses fully overlapping rows into layered activities.

Example 3: Process only problem diaries

. epifix main sec, did(hldid persid id) errorsonly

Useful for large datasets where most diaries are already clean.

Example 4: Recheck after fixing

. epicheck, did(hldid persid id)

A common workflow is to run epicheck, then epifix, and then epicheck again to confirm that the remaining structure is valid.

Remarks

1. Use epitrans first for wide-interval diaries

If full overlaps reflect survey design rather than real errors, use epitrans before epifix. This is often the right sequence for wide-interval diary data.

2. All activity variables must have the same type

If one supplied activity variable is string and another is numeric, the command stops with an error.

3. fullfix is a switch, not an option with parentheses

Use fullfix, not fullfix(). The command explicitly rejects fullfix().

4. Attributes are optional but often useful

If inserted rows should carry properly aligned diary attributes, specify them in attrib().

5. Repairs can be iterative

In practice, one pass of epifix often resolves the main problems, but it is still good practice to rerun epicheck afterward.

Stored results

epifix does not store results in r() or e(). Results are returned through the transformed dataset and the printed summary.

Author

Juana Lamote de Grignon-Pérez

Centre for Time Use Research (CTUR)

Also see

epicheck for diagnosing structural issues in episode files.

epitrans for transforming wide-interval diary data before repair.