SPB Git

spb/metrika Public

Stata-class statistics, GPU-accelerated by Apple Silicon. Native Swift — no Electron, no Python runtime, no compromises.

Swift 92.4% HTML 3.3% R 3% Shell 1.3%
18.8 KB · 366 lines swift
Raw Blame History
1//2//  CommandHelp.swift3//  Metrika4//5//  Author:  Simon-Pierre Boucher6//  Contact: contact@spboucher.ai7//  Copyright © 2026 Simon-Pierre Boucher. All rights reserved.8//910/// The in-app command reference (CLAUDE.md §13 v1.0: `help regress`11/// in-app). One registry serves both the console `help` command and the12/// app's Manual pane, so they can never drift apart.13public struct ZQCommandDoc: Identifiable, Equatable, Sendable {14    public var id: String { verb }15    public var verb: String16    /// Shortest accepted abbreviation ("reg" for regress); nil if none.17    public var abbreviation: String?18    public var category: String19    public var summary: String20    public var syntax: String21    public var options: [(name: String, meaning: String)]22    public var examples: [String]23    public var notes: String?2425    public init(26        verb: String, abbreviation: String? = nil, category: String,27        summary: String, syntax: String,28        options: [(name: String, meaning: String)] = [],29        examples: [String] = [], notes: String? = nil30    ) {31        self.verb = verb32        self.abbreviation = abbreviation33        self.category = category34        self.summary = summary35        self.syntax = syntax36        self.options = options37        self.examples = examples38        self.notes = notes39    }4041    public static func == (lhs: ZQCommandDoc, rhs: ZQCommandDoc) -> Bool {42        lhs.verb == rhs.verb43    }44}4546public enum ZQCommandReference {47    public static let categories = [48        "Data management", "Descriptive statistics", "Estimation",49        "Machine learning", "Resampling & simulation", "Post-estimation",50        "Graphics", "Panel data", "Session & scripting", "User commands",51    ]5253    public static func doc(for verb: String) -> ZQCommandDoc? {54        all.first { $0.verb == verb || $0.abbreviation == verb }55    }5657    public static let all: [ZQCommandDoc] = [58        // ------------------------------------------------ Data management59        ZQCommandDoc(60            verb: "use", category: "Data management",61            summary: "Load a dataset into memory. Format is inferred from the extension: .parquet, .csv, .tsv, .json, .arrow, and Stata .dta (formats 117–119).",62            syntax: "use filename",63            examples: ["use sales.parquet", "use ~/data/panel.dta"],64            notes: "Loading goes through DuckDB for columnar formats and a native reader for .dta. The sandboxed app reads user-selected files and its own container."65        ),66        ZQCommandDoc(67            verb: "sysuse", category: "Data management",68            summary: "Load a sample dataset shipped with Metrika. Bare `sysuse` lists what is available.",69            syntax: "sysuse [name]",70            examples: ["sysuse sales", "sysuse mtcars"],71            notes: "sales: 200-firm × 5-year panel (revenue, price, region, employees). mtcars: the R classic, with a string model column."72        ),73        ZQCommandDoc(74            verb: "save", category: "Data management",75            summary: "Write the working dataset to disk (.parquet, .csv, or Stata .dta format 118).",76            syntax: "save filename [, replace]",77            options: [("replace", "overwrite an existing file")],78            examples: ["save results.dta, replace"]79        ),80        ZQCommandDoc(81            verb: "clear", category: "Data management",82            summary: "Drop the working dataset from memory.",83            syntax: "clear"84        ),85        ZQCommandDoc(86            verb: "describe", abbreviation: "d", category: "Data management",87            summary: "List variables with their storage types and missing counts.",88            syntax: "describe"89        ),90        ZQCommandDoc(91            verb: "list", abbreviation: "l", category: "Data management",92            summary: "Print observations (first 50 shown).",93            syntax: "list [varlist] [if] [in]",94            examples: ["list revenue price in 1/10"]95        ),96        ZQCommandDoc(97            verb: "count", abbreviation: "cou", category: "Data management",98            summary: "Count observations satisfying a condition.",99            syntax: "count [if]",100            examples: ["count if revenue > 100 & !missing(price)"]101        ),102        ZQCommandDoc(103            verb: "generate", abbreviation: "gen", category: "Data management",104            summary: "Create a new variable from an expression. Observations excluded by `if` become missing.",105            syntax: "generate newvar = expression [if] [in]",106            examples: [107                "gen log_rev = ln(revenue)",108                "gen high = revenue > 120 if !missing(revenue)",109            ],110            notes: "Functions: ln, log, log10, exp, sqrt, abs, floor, ceil, round, int, min, max, missing. Missing values propagate through arithmetic; division by zero and ln of a nonpositive number yield missing."111        ),112        ZQCommandDoc(113            verb: "replace", category: "Data management",114            summary: "Overwrite values of an existing variable; reports the number of real changes.",115            syntax: "replace varname = expression [if] [in]",116            examples: ["replace flag = 0 if missing(flag)"]117        ),118        ZQCommandDoc(119            verb: "drop", category: "Data management",120            summary: "Remove variables, or observations with `if`/`in`.",121            syntax: "drop varlist | drop if expression | drop in range",122            examples: ["drop temp1 temp2", "drop if price < 0"]123        ),124        ZQCommandDoc(125            verb: "keep", category: "Data management",126            summary: "Keep only the listed variables, or only observations satisfying a condition.",127            syntax: "keep varlist | keep if expression | keep in range",128            examples: ["keep in 1/1000"]129        ),130131        // ------------------------------------------ Descriptive statistics132        ZQCommandDoc(133            verb: "summarize", abbreviation: "su", category: "Descriptive statistics",134            summary: "Means, standard deviations, and ranges; `detail` adds percentiles, skewness, and kurtosis (Stata definitions).",135            syntax: "summarize [varlist] [if] [in] [, detail]",136            options: [("detail", "percentiles p1–p99, skewness, kurtosis")],137            examples: ["summarize revenue price, detail"]138        ),139        ZQCommandDoc(140            verb: "tabulate", abbreviation: "tab", category: "Descriptive statistics",141            summary: "One-way frequency table or two-way cross-tabulation with totals.",142            syntax: "tabulate varname [varname2] [if] [, missing]",143            options: [("missing", "include missing values as a category")],144            examples: ["tab region", "tabulate region purchase"]145        ),146        ZQCommandDoc(147            verb: "correlate", abbreviation: "cor", category: "Descriptive statistics",148            summary: "Pearson correlation matrix with listwise deletion.",149            syntax: "correlate [varlist] [if]",150            examples: ["correlate revenue price orders"]151        ),152153        // ------------------------------------------------------ Estimation154        ZQCommandDoc(155            verb: "regress", abbreviation: "reg", category: "Estimation",156            summary: "Ordinary least squares via LAPACK QR. Factor variables (i.var) expand to indicators; c.a#c.b forms continuous interactions.",157            syntax: "regress depvar [indepvars] [if] [in] [, robust hc2 hc3 cluster(varname) noconstant level(#)]",158            options: [159                ("robust", "HC1 heteroskedasticity-consistent SE (Stata's robust)"),160                ("hc2 / hc3", "leverage-adjusted sandwich estimators"),161                ("cluster(var)", "cluster-robust SE, t on G−1 df"),162                ("noconstant", "suppress the intercept"),163                ("level(#)", "confidence level, default 95"),164            ],165            examples: [166                "reg log_rev price, robust",167                "reg log_rev price i.region, cluster(firm_id)",168                "reg wage c.age#c.age education",169            ],170            notes: "Results match R to 1e-10. Listwise deletion is reported explicitly."171        ),172        ZQCommandDoc(173            verb: "logit", category: "Estimation",174            summary: "Logistic regression by Fisher scoring; reports LR χ², McFadden pseudo-R², z statistics.",175            syntax: "logit depvar indepvars [if] [, robust cluster(varname) level(#)]",176            examples: ["logit purchase price, robust"]177        ),178        ZQCommandDoc(179            verb: "probit", category: "Estimation",180            summary: "Probit regression (normal link), same options as logit.",181            syntax: "probit depvar indepvars [if] [, robust cluster(varname)]",182            examples: ["probit purchase price"]183        ),184        ZQCommandDoc(185            verb: "poisson", category: "Estimation",186            summary: "Poisson regression for counts (log link).",187            syntax: "poisson depvar indepvars [if] [, robust cluster(varname)]",188            examples: ["poisson orders price, robust"]189        ),190        ZQCommandDoc(191            verb: "ivregress", category: "Estimation",192            summary: "Two-stage least squares. Endogenous regressors and their instruments go in the parenthesized group.",193            syntax: "ivregress 2sls depvar [exogvars] (endogvars = instruments) [, robust cluster(varname)]",194            examples: ["ivregress 2sls log_rev (price = z1 z2), robust"],195            notes: "Residuals come from the original regressors; inference follows Stata's `small` convention (t statistics on N−K df)."196        ),197        ZQCommandDoc(198            verb: "xtreg", category: "Estimation",199            summary: "Panel fixed-effects (within) estimator. Declare the panel with xtset first.",200            syntax: "xtreg depvar indepvars, fe [cluster(panelvar)]",201            options: [202                ("fe", "fixed effects (required — the only estimator so far)"),203                ("cluster(panelvar)", "panel-clustered SE, t on G−1 df"),204            ],205            examples: ["xtset firm_id", "xtreg log_rev price, fe cluster(firm_id)"]206        ),207208        // ------------------------------------------------ Machine learning209        ZQCommandDoc(210            verb: "lasso", category: "Machine learning",211            summary: "L1-penalized linear regression (coordinate descent, glmnet conventions). Selects variables by zeroing coefficients.",212            syntax: "lasso depvar indepvars, lambda(#)",213            options: [("lambda(#)", "penalty strength; omit it to see lambda_max for your data")],214            examples: ["lasso log_rev price z1 z2 orders, lambda(0.05)"]215        ),216        ZQCommandDoc(217            verb: "elasticnet", category: "Machine learning",218            summary: "Elastic-net linear regression mixing L1 and L2 penalties.",219            syntax: "elasticnet depvar indepvars, lambda(#) [alpha(#)]",220            options: [221                ("alpha(#)", "1 = lasso, 0 = ridge; default 1"),222                ("lambda(#)", "penalty strength"),223            ],224            examples: ["elasticnet log_rev price z1 z2, alpha(0.4) lambda(0.02)"],225            notes: "Matches R glmnet, including its gaussian y-standardization convention (ridge penalties scale with sd of the response)."226        ),227228        ZQCommandDoc(229            verb: "boost", category: "Machine learning",230            summary: "Gradient-boosted regression trees (xgboost-style exact greedy, squared loss). Deterministic — no subsampling.",231            syntax: "boost depvar features, rounds(#) [eta(#) maxdepth(#) lambda(#)]",232            options: [233                ("rounds(#)", "number of trees"),234                ("eta(#)", "learning rate, default 0.3"),235                ("maxdepth(#)", "tree depth, default 6"),236                ("lambda(#)", "L2 regularization on leaf weights, default 1"),237            ],238            examples: ["boost log_rev z1 z2 orders, rounds(100) eta(0.1) maxdepth(3)", "predict yhat"],239            notes: "Matches R xgboost predictions on identical settings. Training R² is in-sample — expect it to be optimistic."240        ),241242        // ------------------------------------------ Resampling & simulation243        ZQCommandDoc(244            verb: "bootstrap", category: "Resampling & simulation",245            summary: "Pairs bootstrap of a regression. Large replication counts run batched on the Apple GPU; results are identical either way for a given seed.",246            syntax: "bootstrap, reps(#) [seed(#)]: regress depvar indepvars",247            options: [248                ("reps(#)", "number of replications"),249                ("seed(#)", "Philox seed — full reproducibility across CPU and GPU"),250            ],251            examples: ["bootstrap, reps(10000) seed(42): reg log_rev price"],252            notes: "Replicates are counter-addressable: any subset recomputes identically regardless of chunking or backend. The planner dispatches ≥500 reps to the GPU when available."253        ),254        ZQCommandDoc(255            verb: "bayes", category: "Resampling & simulation",256            summary: "Bayesian linear regression by Gibbs sampling: posterior means, standard deviations, and 95% credible intervals.",257            syntax: "bayes [, mcmcsize(#) burnin(#) seed(#) normalprior(#)]: regress depvar indepvars",258            options: [259                ("mcmcsize(#)", "posterior draws after burn-in (default 10000)"),260                ("burnin(#)", "discarded warm-up iterations (default 2500)"),261                ("seed(#)", "Philox seed — chains are exactly reproducible"),262                ("normalprior(#)", "prior variance of the N(0, #) coefficient priors (default 10000)"),263            ],264            examples: ["bayes, mcmcsize(20000) seed(42): reg log_rev price"],265            notes: "Priors: coefficients N(0, normalprior), variance InvGamma(0.01, 0.01) — Stata's bayes defaults. With diffuse priors the posterior reproduces OLS."266        ),267        ZQCommandDoc(268            verb: "permute", category: "Resampling & simulation",269            summary: "Permutation test: the response is permuted, the model refit, and empirical two-sided p-values reported per coefficient.",270            syntax: "permute, reps(#) [seed(#)]: regress depvar indepvars",271            examples: ["permute, reps(1000) seed(42): reg log_rev orders"]272        ),273        ZQCommandDoc(274            verb: "set", category: "Resampling & simulation",275            summary: "Set session parameters. `set seed` fixes the Philox key used by bootstrap and permute.",276            syntax: "set seed #",277            examples: ["set seed 42"]278        ),279280        // ------------------------------------------------- Post-estimation281        ZQCommandDoc(282            verb: "predict", category: "Post-estimation",283            summary: "Generate predictions from the last estimation over all current observations.",284            syntax: "predict newvar [, xb residuals pr n]",285            options: [286                ("xb", "linear prediction (default after regress/ivregress)"),287                ("residuals", "response residuals"),288                ("pr", "predicted probability (default after logit/probit)"),289                ("n", "predicted mean count (default after poisson)"),290            ],291            examples: ["reg log_rev price", "predict yhat", "predict e, residuals"]292        ),293        ZQCommandDoc(294            verb: "margins", abbreviation: "marg", category: "Post-estimation",295            summary: "Average marginal effects with delta-method standard errors. After OLS/IV the effect is the coefficient; after logit/probit/poisson it averages dμ/dx over the estimation sample.",296            syntax: "margins, dydx(varlist) [level(#)]",297            examples: ["logit purchase price", "margins, dydx(price)"],298            notes: "Continuous regressors only for now; factor and interaction terms are rejected with a message."299        ),300301        // ------------------------------------------------------- Graphics302        ZQCommandDoc(303            verb: "scatter", category: "Graphics",304            summary: "Scatter plot (also available as `graph scatter`). `by()` splits into colored series.",305            syntax: "scatter yvar xvar [if] [, by(varname)]",306            examples: ["scatter log_rev price, by(region)"]307        ),308        ZQCommandDoc(309            verb: "histogram", abbreviation: "hist", category: "Graphics",310            summary: "Frequency histogram of one variable (Sturges bins by default).",311            syntax: "histogram varname [if] [, bins(#)]",312            options: [("bins(#)", "override the bin count")],313            examples: ["histogram revenue, bins(12)"]314        ),315        ZQCommandDoc(316            verb: "kdensity", abbreviation: "kden", category: "Graphics",317            summary: "Kernel density estimate (Epanechnikov kernel, Silverman bandwidth).",318            syntax: "kdensity varname [if]",319            examples: ["kdensity revenue"]320        ),321        ZQCommandDoc(322            verb: "graph", abbreviation: "gr", category: "Graphics",323            summary: "General plotting front end: graph scatter, graph line, graph histogram.",324            syntax: "graph scatter|line yvar xvar [if] [, by(varname)]",325            examples: ["graph line gdp year"]326        ),327328        // ------------------------------------------------------ Panel data329        ZQCommandDoc(330            verb: "xtset", category: "Panel data",331            summary: "Declare the panel structure (unit and, optionally, time variable) for xtreg.",332            syntax: "xtset panelvar [timevar]",333            examples: ["xtset firm_id year"]334        ),335336        // ---------------------------------------------- Session & scripting337        ZQCommandDoc(338            verb: "display", abbreviation: "di", category: "Session & scripting",339            summary: "Evaluate and print an expression.",340            syntax: "display expression",341            examples: ["display 2 + 2 * 3", "display ln(100)"]342        ),343        ZQCommandDoc(344            verb: "log", category: "Session & scripting",345            summary: "Record commands and output to a text file.",346            syntax: "log using filename | log close",347            examples: ["log using session.log"]348        ),349        ZQCommandDoc(350            verb: "help", category: "Session & scripting",351            summary: "Show this reference, or the entry for one command.",352            syntax: "help [command]",353            examples: ["help regress"]354        ),355356        // ---------------------------------------------------- User commands357        ZQCommandDoc(358            verb: "zscore", category: "User commands",359            summary: "Sample native plugin: generates z_varname, the standardized version of a variable.",360            syntax: "zscore varname",361            examples: ["zscore revenue"],362            notes: "Native plugins are Swift types conforming to ZQCommandPlugin, compiled into the app. Script commands are .zyq files in ~/Library/Application Support/Metrika/Commands/ — an optional leading `args name…` line names positional arguments, referenced as `name' or `1' in the body."363        ),364    ]365}366