Repository navigation
MPT article, ppp(), mpt_data_reshape() and mpt() API changes (MPT 6/6, #255) - #489
Conversation
1d8cc90 to
6d41218
Compare
…ons (#255) vignettes/articles/bmm_mpt.Rmd with its references and pkgdown entry; the Processing-tree models sections of README.Rmd and the bmm overview article; README.md and the task map re-knit.
The package site moved from venpopov.github.io to popov-lab.github.io; the two links to the m3 article still pointed at the old address.
The dependency badge counts graphics, which the plot level imports: 15/25 direct dependencies on develop's base of 25.
…s() (#255) native_parameters() returns MPT parameters on the probability scale: on real fits it matched plogis()/pnorm() of posterior_linpred(nlpar = ) for logit and probit parameters and a hand-built stick-breaking map for simplex members (ratio to 1 within 6e-16). The article and the MPTinR/TreeBUGS table use it; posterior_linpred() keeps one sentence for latent-scale work.
…n the model comparison (#255) fit_ol_pb1 reached a minimum bulk ESS of 243 with the default 1000 draws per chain. With iter = 4000 and warmup = 1000 the minimum over all parameters, random effects included, is 2032 for fit_ol and 797 for fit_ol_pb1 (one run, seeds unset). The flagged rows are now counted inline. Moment matching was measured and left out: on fit_ol it lowered the count from 120 to 108 of 120 rows and took 2397 s on one core, so the article names the result and keeps plain loo(); save_pars(all = TRUE) is not needed without it.
…255) The run that measured moment matching finished fit_ol_pb1 after the previous commit: 105 -> 56 of 120 flagged rows (2460 s), against 120 -> 108 for fit_ol (2397 s); elpd_diff -281.1 plain, -288.2 moment-matched (SE 48). The sentence said moment matching does not help; it helps in part.
… person-effect structures (#255) ?mpt now says the MPT article computes the T1 statistic and its posterior predictive p-value; the article gains that section, computed live on fit_ol from posterior_predict() and posterior_epred() (Klauer, 2010, Eq. 17). The 2HTM fit said (1 | id) in two formulas estimates their correlation, which contradicts ?mpt: it now says the effects are independent, like the simulation, and that (1 |p| id) correlates them. The OL2019 fits say why they stay uncorrelated. The covariate paragraph says bmm() stops on a row-wise branch-sum violation.
6d41218 to
5b929ba
Compare
…#255) The article said plot() sees the restricted expressions; it now draws the trees as written and labels the restricted edges, and the sentence says so.
… the MPT article (#255) The article said a 2HTM with separate detection parameters becomes identifiable with the order constraint Do > Dn. It does not: replacing Do by a sub-parameter leaves three free parameters against two degrees of freedom, so the rank deficit remains and Dn is identified mainly by the prior and the order. The sentence now offers the two routes that do identify the model and says what the order constraint gives instead, and the order-constraint section says the same where the formula is shown. print() has reported a Jacobian rank check since the identifiability round, so describing its last line as the classical parameters-versus-categories bound no longer matched the output. It is now described as two checks, a new paragraph explains what each answers and when bmm() messages rather than warns, and the migration table names the rank check. The moment-matching Pareto-k figures came from a different run than the counts computed one sentence earlier, so 'from 120' and 'from 105' contradicted the rendered 119 and 107. They are now attributed to that run, with the run-to-run drift stated.
N1 beta-MPT bullet, N2 PPP() row, N3 plot of the g = 0.5 model, N4 'exact' dropped for folded fractions, N6 data row plus a wide-to-long example, N7 impossible and tree_names, N8 plot(model_ol), N9 unsourced JAGS claim dropped, N10 log odds ratio, N11 the two steps the Al Hadhrami fits took, N15/N16 restrictions.filename and FE, N17 logit vs probit sigma, N18 the EQN first line. N5 withdrawn, N12 is the site-wide Pages domain, N19 fixed by #509 (probe on this head).
The documentation said ppp() reports "the statistics that TreeBUGS' PPP() reports" and NEWS "as TreeBUGS' PPP() does". The statistics are the same, but their values are not: T1 sums the counts, so it is T times TreeBUGS' value with T participants per cell, and T2 now uses the expected sample covariance instead of TreeBUGS' sigma. The wording now says so.
mpt(restrictions = "g = 0.5", links = list(g = "probit")) set the link of D instead, because the link matcher read the removed name 'g' as the parameter one edit away and only warned about the spelling. A links entry that names a restricted parameter now stops with a message that says so.
The seven MPT bullets again state that branches can be a named list of strings, that a restrictions file may hold equalities and constants only, that printing shows the simplex prior, that the TreeBUGS priors give the first simplex member prior mean 0.5, that the importers take impossible, and that the model text can be readLines() output. Every bullet stays under 100 words.
The article still said the link function is chosen once per model, which mpt(links = list(D = "probit")) now contradicts. The paragraph names both forms; the code chunk is unchanged.
MPT surface: named links list, restrictions second in both importers, mpt_data_reshape(), consolidated NEWS (#255)
Update 2026-10-12: stack merged forward, add-ons folded in (head d2186d7)This branch now carries the whole MPT line as it will merge into develop:
Measured at this head: every R file parses, One more PR lands on this branch before the develop merge: the outcome of the read of the whole MPT user-facing surface (named Still to come before the window: one re-merge of develop once #536 (kfold fix) and the lifted |
The hint that points to mpt_tree(impossible = ) was written with glue line continuations but interpolated into the message, so the error showed a backslash and the source indentation. The test now matches the hint as one line.
mpt(links = NULL) stopped with "The links argument must be a single link function" since the named-list form arrived, while every other model constructor takes NULL for its default links. NULL now gives the logit link again.
The running two-high-threshold example named its trees "old" and "new",
the same strings as the response categories, so a reader took
mpt_tree("old", old ~ ..., new ~ ...) for one tree per response. The trees
are now "target" and "lure" in the article and in every MPT help page
(mpt_tree, mpt, dmpt/rmpt, ppp, plot, mpt_from_string, mpt_from_eqn,
mpt_data_reshape); the responses stay old/new.
The article introduction now says the model has one tree per probe type,
because different processes are assumed for targets and lures, and shows
the tree diagram there. The source-monitoring tree "new" becomes
"newitem" so it no longer clashes with the category New.
The 2HTM article fit is refitted with the new labels under a new name,
fits/mpt_2htm_v2, which has to be added to the article-fits release.
Full test suite: 51 files, 0 failed. R CMD check (tests skipped): OK.
The macOS and Windows pull-request jobs ship no CmdStan since #546.
# Conflicts: # tests/testthat/test-model_mpt.R
Both fits sample, so they live in tests/local/test-ppp-fits.R (ADR 0004 R1); test-conventions.R drops the test-ppp.R count. The MPT stack now adds no real-backend site to tests/testthat.
Part of #255, and #497. PR 6 of 6 in the MPT stack; base
255-mpt-plot. Head 2e5c4a7.This description replaces the earlier one, which still said this level adds no code. It does: since 2026-10-09 the level took in
ppp()(#497), a reshaping helper for wide count tables, and the API changes of the MPT surface review. Measured against the base: 37 files, +3673/−426.What merges
New exported functions
ppp()(R/ppp.R, +471): the goodness-of-fit statistics T1 (category frequencies) and T2 (their covariances across participants) of Klauer (2010) with posterior predictive p-values, the checks TreeBUGS'PPP()reports. It is not MPT-specific: it coversmpt(),m3(),sdt_yn(),sdt_rating(),sdt_mafc(),sdt_ranking()andsdt_cdp().level = "participant"gives one T1 per participant. Cells, participants and categories that are impossible in every draw are handled as described in?ppp.mpt_data_reshape(data, model, id, columns)(R/model_mpt_data.R, +333): reshapes the wide frequency tables of MPTinR and TreeBUGS (one row per participant, one column per category) into one row per participant and tree, with 0 for the categories a tree cannot produce.columns = "mptinr"reads MPTinR's unnamed, sorted columns.print_model_details()is exported.API changes to functions added lower in the stack
mpt_tree()accepts formulas,mpt_tree("old", old ~ D + (1 - D) * g, new ~ (1 - D) * (1 - g)), as well as the named list of strings. The signature becomesmpt_tree(name, branches, ..., impossible = NULL).mpt(links =)takes a named list for links per parameter,links = list(D = "probit");links = NULLgives the default logit. A link for a parameter thatrestrictionsremoved is refused.mpt_from_string()takesrestrictionsas its second argument, asmpt_from_eqn()already did.pp_check(group = <tree column>)facets an mpt fit by tree.Shared code touched
R/bmmformula.Rgains the internal genericgenerated_parameters()(the derived last member of a simplex group);R/pp_check.R,R/summary.R,R/distributions.RandR/helpers-model.Rhave small changes for the points above.Documentation
bmm_mpt(+716): specification, data format, fitting and default priors, interpretation, constraints, design-fixed covariates, a real-data example, non-linear parameters, goodness of fit withppp(), importing, and migrating from MPTinR or TreeBUGS.README.Rmdandbmm.Rmd, the re-knitREADME.mdand the task-map PNG;_pkgdown.ymlentries.mpt_data_reshape(), the article andppp().Tests
test-ppp.R(15 tests): T1 and T2 computed by hand on fixed draws (T2 as in Klauer, 2010), each replicated data set compared with its own draw, cells with a single possible category, impossible categories and zero expected counts, participants without a full set of cells, the participant level, and argument checks on the m3 fixture.test-model_mpt_data.R(17 tests), plus new cases intest-model_mpt.R(formula trees, named links),test-model_mpt_import.R,test-pp_check.Randtest-links.R.ppp()checks on real mpt fits (a well-specified model is not flagged and a misspecified one is; impossible categories) sample, so they are intests/local/test-ppp-fits.R(ADR 0004 R1). All MPT fits of the stack are intests/localnow;tests/testthatgains no real-backend site.Article fits
The article loads three fits from the
article-fitsrelease:fits/mpt_2htm_v2(refit 2026-10-13 after the trees were renamed by probe type),fits/mpt_olandfits/mpt_ol_pb1(2026-10-09).bmm(file =)loads a cached fit without checking it by default, so I checked them against the current code at this head:file_refit = "on_change"the article's code runs to the end without a refit, so Stan code, Stan data and data match for all three; the check does refit when a formula is changed;ppp(),print()andnative_parameters()read.The render at this head (cached fits, nothing refitted) has the same text as the render after the tree rename. No fit needs re-uploading. The release asset of the 2HTM fit from before the rename can be deleted once the stack has merged.
Gates at 2e5c4a7
restructure), 132 s; no MPT orppp()test is among the slowest.R CMD checkon a clean export: 0 errors, 0 warnings, 0 notes.document(): no drift (also at the five lower heads).tests/local: the five MPT andppp()fits pass.Review focus
ppp()as a cross-model function (its T2 definition and the handling of impossible categories), and the API changes above, which change functions the lower PRs add.Closes #255. Closes #497.