ANALYSIS CODE AND INPUT DATA
Online Resource 7 (ESM_7.zip)

Article title:  What does 'also phonetic' mark? The Shuōwén's yìshēng label, homophony and derivation in Old Chinese
Journal:        Morphology
Authors:        Withheld for double-anonymous review
Corresponding author (affiliation, e-mail): Withheld for double-anonymous review

Caption: Analysis code: Python scripts that regenerate the result tables from the data tables, the input tables as CSV files,
the expected outputs and a self-check script.


1. WHAT THIS PACKAGE DOES

It recomputes, from the released input tables, every number of the article that rests on data analysis: the counts, tests and
models of Tables 2 and 4-11, the agreement statistics, the sensitivity analyses and Fig. 1. Nothing is downloaded and no
random draw is left to chance (all seeds are fixed in the scripts). Run everything with one command; the self-check then
compares the results with the stored expected outputs and with the numbers printed in the article.

The input tables are the same data as in Online Resources 2 and 3 (there as Excel workbooks), written as UTF-8 CSV files.
Online Resource 1 (ESM_1.pdf) is the guide to all files: it explains the variables, the coding instructions and who coded what.


2. REQUIREMENTS

Python 3.10 or later with numpy, pandas, scipy and statsmodels (matplotlib for Fig. 1); see requirements.txt.
    python -m pip install -r requirements.txt
A full run takes about one minute on an ordinary laptop. No R, no internet connection and no third-party data are needed.


3. QUICK START

From the folder that contains this README:
    python scripts/run_all.py
This runs the 13 analysis scripts in the right order (each writes into output/) and then scripts/self_check.py. The exit code
is 0 if every check passed. Useful options:
    python scripts/run_all.py --no-figure       skip Fig. 1 (no matplotlib needed)
    python scripts/run_all.py --no-check        skip the self-check
    python scripts/run_all.py --shuowen DIR     also recompute the Duan-note counts from the open Shuowen JSON data in DIR (see 7)
Every script can also be run alone (python scripts/<name>.py) once the scripts it reads from have been run; the order is the
order of the list in section 5.


4. FOLDER LAYOUT

    README.txt            this file
    NOTICE.txt            notice for the Shuowen text in the package (Apache License 2.0) and the list of the files that were changed
    LICENSE-Apache-2.0.txt   the text of the Apache License 2.0
    requirements.txt      Python packages
    data_dictionary.csv   every column of every CSV file in data/ and output/ (file, column, description)
    data/                 input tables (UTF-8 CSV, with a byte-order mark so that Excel opens them correctly)
        pairs.csv                      1,333 pairs of a Shuowen compound and its phonetic (Online Resource 2, sheet "pairs")
        recension_collation.csv        Da Xu / Xiao Xu collation of the 227 raw yisheng headwords (sheet "recension_collation")
        first_sample_codes.csv         the first blind sample of 100 pairs, blind and non-blind codes (Online Resource 3)
        ext_items_key.csv              the sampling key of the enlarged coding: batch positions of every item, group, stratum
        raw/                           the 14 raw answers returned by the coders (Claude instances) and the 2 second answers that were not used
        author_check.csv               the authors' consolidated check of 126 items
        duan_notes_precomputed.csv     counts of phrases in Duan Yucai's notes (see 7)
    scripts/              the analysis scripts (Python, English comments)
    expected/             the outputs of a reference run (CSV and text), and prompts.sha256, the SHA-256 hashes of the 14 coder prompts
    output/               written by the scripts (created on the first run; compare with expected/)


5. SCRIPTS, OUTPUTS AND WHERE THE ARTICLE USES THEM  (in the order in which run_all.py runs them)

    ext_sample.py                      Reproduces the sampling of the enlarged blind coding from the seeds, the item key and the 14 prompts
                                       (output/ext_items_key.csv, output/prompts/). Section 3.4; Table 2.
    ext_analysis.py                    Enlarged blind coding: the two passes, kappa, the primary test of H5 and the secondary and
                                       exploratory tests (output/ext_codes_long.csv, ext_kappa_output.txt, yisheng_models_ext_coding.csv,
                                       ext_items_with_answers.csv, ext_check_key.csv, ext_check_sheet_blank.csv). Sections 3.4, 4.3, 4.4;
                                       Tables 2, 7, 8; Fig. 1.
    ext_author_check.py                Agreement of the authors' consolidated check with the two passes; the tests redone with the authors'
                                       codes substituted (ext_author_check_output.txt, yisheng_models_ext_author_check.csv). Section 4.3; Tables 7, 8.
    ext_bias_sensitivity.py            Tipping-point analysis of coding bias (ext_bias_sensitivity_output.txt, yisheng_bias_sensitivity_grid.csv). Section 5.2.
    ext_second_answer_sensitivity.py   The tests redone with the second answers of two batches (ext_second_answer_sensitivity_output.txt,
                                       yisheng_models_ext_second_answer.csv, ext_second_answer_items.csv). Table 8 note; Fig. 1.
    ext_bias_reverse_scenario.py       A reverse-direction bias scenario (ext_bias_reverse_scenario_output.txt, yisheng_bias_reverse_scenario.csv).
                                       Not discussed in the article text.
    core_models.py                     Counts, Fisher tests, GEE and mixed models for H1a, H1b, H1c (yisheng_summary.csv, yisheng_models.csv).
                                       Tables 4, 6; Sections 4.1, 4.2.
    paper_checks.py                    Further analyses: the four reading categories, within-phonetic estimates, departing-tone steps,
                                       recension layers, combined checks (yisheng_models_extra_checks.csv). Tables 4, 6, 10, 11; Sections 4.5, 4.6.
    first_sample_checks.py             First-sample checks: agreement of the blind and non-blind codings, H2 on the 100 items, identity read from
                                       fanqie strings (first_sample_checks_output.txt). Sections 3.3, 4.3; Tables 7, 11.
    sensitivity_wang_yun.py            Sensitivity analysis without the nine labels rejected by Wang Yun (yisheng_models_wangyun_sensitivity.csv). Table 11.
    sensitivity_xiao_xu.py             Recension layers and the shared-labels sensitivity analysis (yisheng_models_xiaoxu_sensitivity.csv). Tables 10, 11.
    paper_counts.py                    Counts quoted in the text and in Tables 2, 3, 5, 9, each checked against the data (paper_counts_output.txt,
                                       table5_departing_tone_members.csv). It stops with an error if a count no longer matches.
    paper_figure.py                    Fig. 1 (fig1_h5_forest.png at 300 dpi, fig1_h5_forest_values.csv). Needs matplotlib.
    self_check.py                      The self-check (see 6).
    _paths.py                          Paths shared by the scripts.


6. THE SELF-CHECK

scripts/self_check.py has three parts and prints "N checks passed, 0 failed" when everything is as expected:
  1. Reproduction: every CSV and text file in expected/ is compared with the file of the same name that the scripts have just written to
     output/. Counts must match exactly; a decimal number may differ by one unit in its last printed digit (this can happen in the
     variational-Bayes columns glmm_vb_* with other library versions), and such cases are reported as notes. The 14 coder prompts are
     compared by SHA-256 hash.
  2. Paper numbers: about 190 numbers and counts printed in the article (Tables 2 and 4-11, Fig. 1 and the text) are looked up in output/ and
     compared with the value printed in the article, at the precision at which the article prints it.
  3. Package integrity: all text files are valid UTF-8, column headers are English, every column is described in data_dictionary.csv, the
     scripts compile, and no file contains an e-mail address, a local file path or a link to a repository other than the open resources cited.


7. REPRODUCIBILITY NOTES

* Random numbers: the sampling (seeds 20260930-20260933), the order of the authors' check sheet (seed 20260934) and the bootstrap intervals
  (seeds 20260935 and 20260936) are fixed in the scripts; a rerun gives identical files. The scripts do not call the coder model; the
  coders' answers are in data/raw/ (Online Resource 5 holds the prompts and the raw answers with their collection log).
* Estimation: GEE (binomial, logit link, exchangeable working correlation, clustered by phonetic, robust standard errors); if the
  exchangeable fit does not converge, the independence structure is used and the column gee_cov says so. Within-phonetic estimates are
  Mantel-Haenszel; the mixed models are variational-Bayes approximations (statsmodels BinomialBayesMixedGLM) used as a cross-check.
* Duan Yucai's notes: two analyses count phrases in Duan's notes in the open Shuowen data. The counts are stored in
  data/duan_notes_precomputed.csv, so the package runs without that data. To recompute them, clone https://github.com/shuowenjiezi/shuowen
  and run python scripts/run_all.py --shuowen path/to/shuowen/data; the output is then identical to expected/ (tested).
* The scripts keep missing values as the literal text NA in the CSV files and read them with pandas' default missing-value handling,
  as in the original analysis; do not "clean" the input files.
* The files in expected/ are the outputs of one run on Python 3.11 (see requirements.txt). A mismatch beyond the last printed digit would
  indicate a change in a library, not in the data; part 2 of the self-check (the numbers of the article) is the decisive test.


8. DATA SOURCES AND LICENCE

The released tables contain material from open resources, cited in the article (Section 3):
  - the digital Shuowen jiezi of the shuowenjiezi project (https://github.com/shuowenjiezi/shuowen, Apache License 2.0): Da Xu text, fanqie, Duan's notes;
  - Middle Chinese positions of the Guangyun from the Qieyun data of the nk2028 project (CC0) via the tshet-uinh software (MIT);
  - Old Chinese reconstructions of Baxter and Sagart (2014), as compiled in the cddb database (https://github.com/digling/cddb, GPL-3.0);
  - the Xiao Xu text (Shuowen jiezi xichuan) of the Kanseki Repository (KR1j0019).
The authors' own contributions (codings, annotations, tables and documentation) are released under CC BY 4.0, and the code in scripts/ under the
MIT licence. Columns derived from the resources above keep the terms of their sources; the notice required by the Apache License 2.0 is
given here: this package contains text from the shuowenjiezi project, Apache License 2.0, https://www.apache.org/licenses/LICENSE-2.0. The licence text is in
LICENSE-Apache-2.0.txt, and NOTICE.txt lists the files that contain text of that project and says how it was changed.
Please cite Baxter and Sagart (2014) when reusing the Old Chinese forms.


9. CONVENTIONS

Group names: labelled = a compound that the Da Xu text analyses with yisheng (the Shuowen formula 亦聲); ordinary = a plain phonetic compound (聲).
Semantic codes: Y same or near-synonymous meaning; E connected by one step of extension or inference; N no visible relation; X proper name.
"Related" = Y or E. "Near" = identical Middle Chinese readings or a tone or voicing alternation involving the departing tone.
Chinese characters appear only as data values; each character column has a companion column of Unicode code points (U+XXXX).
