spicy (development version)
New features
Covariate adjustment in table_continuous_lm()
- New
covariatesargument adds additive covariates to each per-outcome model (lm(y ~ by + cov1 + cov2 + ...)). Estimate, SE, p-value and CI onbybecome covariate-adjusted; effect sizes adapt accordingly (see below). Accepts tidyselect expressions or a literal character vector; covariates that overlapselectare auto-excluded from the outcome list. v1 supports additive terms only — formula syntax with interactions / transforms raisesspicy_unsupported. - New
adjustmentargument selects the estimand for the covariate-adjusted marginal means (theemmean*columns):"proportional"(default) for G-computation over the observed covariate distribution (matches Statamargins,marginaleffects::avg_predictions(variables)), or"balanced"for synthetic-grid equal-weight averaging (matchesemmeans::emmeans()default, SPSS UNIANOVA, SAS LSMEANS). The two methods coincide when there are no factor covariates or non-uniform proportions. - Effect-size dispatch under adjustment:
"f2"and"omega2"become partial f² / ω² viastats::drop1()restricted to the focal term;"d"and"g"are undefined under adjustment and raisespicy_unsupportedwith a pointer to the partial-F generalisations. - The default ASCII print emits an APA footer
Note. Adjusted for <covs> (<method>).whenever the model is covariate-adjusted. New result attributescovariatesandadjustmentcarry the metadata downstream. - See
?table_continuous_lmand the Covariate adjustment section ofvignette("table-continuous-lm")for the full semantics, defaults rationale, and runnable examples. -
emmeansandmarginaleffectsadded toSuggestsas oracle packages for the cross-validation tests (no runtime dependency change).
Internal
-
R/table_continuous_lm.R(3394 lines) split into four files on a strict shared / specific naming convention, so the upcomingtable_regression()(planned for 0.13) can reuse the inferential backbone without duplication. No behaviour change, no rename, no signature change; only file moves.-
R/lm_compute.R(shared) — vcov family (classical,HC*,CR*, bootstrap, jackknife), single-coef and Wald inference, model stats, noncentral effect-size CIs. -
R/lm_helpers.R(shared) — input-resolution helpers (is_supported_lm_predictor,coerce_lm_factor,detect_weights_column_name,resolve_cluster_argument). -
R/table_continuous_lm_render.R(specific) — bivariate-layout rendering (raw / display data frames + 8 output formats). -
R/table_continuous_lm.R(specific) — publictable_continuous_lm()+ per-outcome / per-predictor row orchestrators.
-
spicy 0.11.0
CRAN release: 2026-05-04
New features
table_continuous_lm()
- Cluster-robust SEs via
clusterand fourvcovchoices ("CR0"–"CR3"), dispatched toclubSandwichwith Satterthwaite df (clubSandwichinSuggests). -
vcov = "bootstrap"(nonparametric or cluster) andvcov = "jackknife"(leave-one-out / leave-one-cluster-out) variance estimators in pure base R, controlled byboot_n. - Three new
effect_sizechoices alongside"f2": Cohen’s"d", Hedges’"g"(two-group only), Hays’"omega2". Neweffect_size_ciadds noncentral t / F CIs rendered inline as0.18 [0.07, 0.30]. -
HC*estimators delegate tosandwich::vcovHC(); rank-deficient fits return a clean rank-by-rank covariance.
Harmonisation across the table family
- Shared reporting vocabulary (
decimal_mark,p_digits,align, named-labels) now spanscross_tab(),freq()and the threetable_*()helpers, including APA-style p-value notation (<.001/.045, no leading zero). -
table_categorical()’sassoc_measureaccepts a per-variable spec. When measures differ across rows the column collapses to"Effect size"and an APA-styleNote.line documents the per-variable measure;phion a non-2x2 errors. - All three
table_*()functions gainas.data.frame(),tibble::as_tibble(),broom::tidy()andbroom::glance()methods (broominSuggests).
Quality and robustness
-
Classed conditions. Errors and warnings now carry stable classes (
spicy_error/spicy_warningplus 11 leaf classes documented in?spicy), so downstream code can dispatch viatryCatch()/withCallingHandlers()instead of matching message strings.rlang (>= 1.1.0)required. -
Structured cli messages. Multi-line errors and warnings (vcov fallbacks, bootstrap/jackknife failures,
paddingmigration,labelslength mismatch) render as cli bullets. -
Locale-deterministic ordering. Sorts in
varlist(),freq(),cross_tab()andtable_*()usemethod = "radix". Output is byte-stable across locales and platforms, matching Stata / SPSS guarantees. -
Edge-case hardening. A new length-guarded sort helper makes
varlist()/code_book()/cross_tab()/freq()survive zero-length or all-NADate/POSIXct/charactercolumns and factors with no observed levels. -
Snapshot-locked rendering.
tests/testthat/test-snapshots.Rpins the exact console output of every spicy print method, so any unintended formatting drift surfaces as a PR diff. -
API stability contract.
?spicydocuments which exports are stable, stabilising or internal. pkgdown reference groups exports via four@familytags. -
Cross-software validation. All 13 association measures agree with PSPP 2.0 (
CROSSTABS /STATISTICS=ALL, 65 / 65 statistics on four datasets); Cohen’s d and Hedges’ g noncentral CIs are tested numerically againsteffectsize::cohens_d()/effectsize::hedges_g()(tolerance = 1e-6); point-estimate formulas and asymptotic standard errors followDescTools(Signorell et al.).
Improvements
-
cross_tab()warns whencorrect = TRUEis ignored on a non-2x2 sub-table, whenweightscontainsNA, and notes statistics computed on a sub-table after empty rows / columns are pruned. -
cross_tab()validatesdecimal_mark,p_digitsandsimulate_Bup front;freq()validatesdecimal_markand tightensdigitsto a non-negative integer. - A user category literally named
"N"or"Total"is no longer mis-rendered as the totals row incross_tab(). -
table_continuous_lm(output = "long")returnsn,df1,df2as integer columns;predictor_labelpreserved on the degenerate-model fallback path. -
cramer_v()/phi()doc states the CI uses the Fisher z-transformation (point estimate and p-value identical toDescTools/ SPSS). -
uncertainty_coef()doc states entropy uses0 log 0 = 0(matching SPSS, PSPP, Stata, Cover & Thomas).
Bug fixes
-
label_from_names()raises actionable errors on duplicate or empty new column names; trims whitespace and preserves the input class. -
table_continuous_lm(output = "data.frame")names contrast CI columns fromci_level(was hardcoded to 95 %). - The categorical-predictor global Wald F degrades to
NAon a singular coefficient covariance submatrix. - The degenerate-table branch of
cramer_v(),yule_q(),gamma_gk(),kendall_tau_b()andsomers_d()respectsdetail: scalarNA_real_by default, fully shapedspicy_assoc_detailwhendetail = TRUE. -
uncertainty_coef()returns a finite estimate (wasNaN) when a marginal is zero. -
somers_d(direction = "symmetric")returns the harmonic mean of the two asymmetric values, matching SPSS / PSPPCROSSTABS. -
print.spicy_assoc_detail()/print.spicy_assoc_table()use APA-strict<.001/.045notation, matching the rest of the package. -
varlist()/code_book()honourfactor_levels = "all"forhaven_labelledcolumns: declared-but-unobserved labels appear in theValuessummary. -
copy_clipboard()rejectsrow.names.as.colvectors of length ≠ 1 and empty strings; accumulates all messages fromclipr::write_clip()instead of overwriting. -
mean_n()/sum_n()reject non-integermin_valid >= 1andmin_valid > ncol; theirdigitsrequires a non-negative integer.
Breaking changes
-
table_continuous_lm()andtable_categorical()default to decimal-point alignment for numeric columns (align = "decimal"). Passalign = "auto"for the previous behaviour. -
build_ascii_table()/spicy_print_table():paddingswitches from a string enum to a non-negative integer. Default2L(was+5L); printed tables are roughly 40 % narrower. Migration:"compact" -> 0L,"normal" -> 2L,"wide" -> 4L. -
table_categorical(assoc_measure = "auto")on a 2x2 table picksphiinstead ofcramer_v. Numeric value unchanged (|phi| = V on 2x2); only the column label changes. -
freq()drops observations withNAweights (with a warning) instead of recoding them to zero. Aligns withcross_tab(). -
table_continuous_lm(output = "long")returnsNAines_type/es_valuewheneffect_size = "none"(was"f2"), and renamessum_wtoweighted_n.
spicy 0.10.0
CRAN release: 2026-04-27
New features
code_book()now accepts tidyselect-style variable selectors through..., matchingvarlist()andvl().code_book()gains afilenameargument for the base name of CSV, Excel, and PDF exports. WhenNULL(the default), the filename is derived fromtitleand falls back to"Codebook"when needed. Filenames are sanitized to portable ASCII consistently across platforms.varlist()now summarizes matrix and array columns by their dimensions, and counts valid, missing, and distinct observations by rows.freq()gains afactor_levelsargument that mirrorsvarlist()andcode_book(). Withfactor_levels = "all", declared-but-unobserved factor and labelled levels appear in the output withn = 0, matching SPSSFREQUENCIES; the default"observed"preserves the previous Statatab-style behavior.
Improvements
varlist()now displays missing values as<NA>and<NaN>in theValuessummary wheninclude_na = TRUE, and quotes literal"NA","NaN", and empty-string values so they cannot be confused with the missing markers.varlist()now emits a column-named warning and marks the failing cell as<error: ...>when a column cannot be summarized, instead of silently writing"Invalid or unsupported format". Remaining columns are unaffected.varlist()produces more precise Viewer titles for extraction, pipe, and literalget("name")expressions, while keeping ambiguous dynamic calls anonymous (vl: <data>).code_book()now rejects partial-match names in...(e.g.val = TRUE,tit = "x") that would otherwise be silently treated as tidyselect expressions, and surfacesvarlist()selection errors directly.freq()now resolves theweightsargument via tidy-eval, so column references nested in compound expressions (e.g.weights = if (use_w) col else NULL) work as expected. Qualified expressions likeweights = df2$wcontinue to take precedence over column lookup.freq()validatesdigits,sort,weights, and the logical scalar arguments (valid,cum,rescale,styled) more strictly at the public boundary, with clearer error messages for non-finite values,NA, multi-element inputs, and non-numeric weight vectors.freq()now documents the interaction ofweightscontainingNAwithrescale = TRUE(Statapweightsemantics) and the dropping of unused factor / labelled levels (Statatabsemantics, withcode_book(factor_levels = "all")as the schema-style alternative).
Bug fixes
varlist()now displays labelled values in the same prefixed-label order for compact andvalues = TRUEsummaries; previously the compact summary used data order.varlist(values = TRUE)now deduplicates element types when summarizing list-columns. Previouslylist(1L, 2L, "a")produced"List(3): character, integer, integer"; now produces"List(3): character, integer".include_na = TRUEnow correctly appends<NA>markers for list-columns in bothvarlist()modes; previously it had no effect on this column type.varlist()now validates column names up front and gives clearer errors for missing, empty,NA, or duplicate names.varlist()now errors clearly when tidyselect expressions try to rename columns;...is for selecting variables, not renaming.freq(data, x, weights = NULL)now correctly treats the explicitNULLas “no weighting” instead of emitting a misleading"variable 'NULL' not found"error. Parameterized patterns likeweights = if (use_w) wts else NULLare now supported.print()forspicy_freq_tableno longer crashes when thevar_labelattribute isNA_character_, numeric, or multi-element; theLabel:line is silently skipped for any value that is not a single non-empty string.freq()no longer surfaces the name of the ignoreddatavector in the printed footer when bothdataandxare passed as vectors. The footer now consistently shows the analyzed vector’s name.
spicy 0.9.0
CRAN release: 2026-04-20
Breaking changes
table_continuous()now enables inferential output by default whenbyis supplied. With a grouping variable, thepcolumn fromtestis shown automatically (previous default hid it). This aligns the two table helpers:table_continuous()stays descriptive whenbyis absent, and reports the test p-value whenbyis supplied, matchingtable_continuous_lm()’s inferential default. To preserve the previous behavior, passp_value = FALSEexplicitly.statisticandeffect_sizeremainFALSEby default and must still be enabled consciously.varlist()now displays observed factor levels by default inValues, matching its role as a quick inspection of the current data. Usefactor_levels = "all"to display unused factor levels as well, which was the previous default behavior and remains the default incode_book().
Minor improvements
code_book()gains afactor_levelsargument. It defaults to"all"so exported codebooks continue to document all declared factor levels, including unused levels; use"observed"to mirrorvarlist()output.freq()now prints theFreq.column as integers regardless ofdigits, which continues to control percentage precision. This matches the convention of SPSS, Stata, and SASPROC FREQfor weighted counts and keeps the two numeric concepts (discrete counts vs. continuous percentages) visually distinct.freq(..., styled = FALSE)now returns a genuinely plaindata.framewith nospicy_freq_tablerendering metadata clinging to it, sostr(),dput(), and downstream programmatic use see only the tabulation columns. The metadata attributes (digits,data_name,var_name,var_label,class_name,n_total,n_valid,weighted,rescaled,weight_var) are now documented in@returnand remain available on the invisibly returnedspicy_freq_tableobject whenstyled = TRUE(the default).table_continuous_lm()documentation now clarifies whyp_value = TRUEandr2 = "r2"are the defaults, and robust-variance fallback warnings are now more explicit when a model matrix is singular.
Bug fixes
freq()now correctly resolves qualified weight expressions such asweights = other$worweights = other[["w"]]even when the referenced column name also exists indata. Previously the bare-name fallback could silently pull the weight vector from the wrong data frame when column names collided.freq()withsortand missing values now keeps theNArow at the end of the tabulation so the printedCum. PercentandCum. Valid Percentcolumns stay monotonic and match the Valid → Missing → Total display layout. Sorting previously could push theNArow between valid rows and make cumulative percentages appear to jump.varlist()now preserves literal"NA"and empty-string values in theValuessummary instead of removing them as if they were missing values.varlist()now distinguishes actualNAvalues fromNaNin theValuessummary wheninclude_na = TRUE.varlist(values = TRUE)now preserves factor level order in theValuessummary, matching the default compact factor display.varlist()now validatesvalues,tbl, andinclude_naup front and gives a clear error when one of them is notTRUEorFALSE.
spicy 0.8.0
CRAN release: 2026-04-10
New features
-
table_continuous_lm()adds APA-style bivariate linear-model tables for continuous outcomes. It acts as the model-based companion totable_continuous()for reporting fitted mean comparisons or slopes in anlmframework, with one predictor per model, model-based means for categorical predictors, optional case weights, classical or HC0-HC5 variance estimators, multiple output formats (ASCII, tinytable, gt, flextable, Excel, clipboard, and Word),output = "data.frame"for the wide raw table,output = "long"for the analytic long table, and configurable display of tests, confidence intervals, fit statistics, and effect sizes.
Minor improvements
Installed package vignettes now avoid embedding heavy HTML table and codebook widgets during CRAN builds, reducing package size while preserving rich pkgdown article rendering.
Website and vignette coverage now includes
table_continuous_lm(), using the bundledsochealthdata throughout and adding a dedicated article for model-based continuous summary tables.table_continuous()andtable_continuous_lm()now support dedicated display precision for effect-size columns, andtable_continuous_lm()also supports separate precision forR²columns, so model fit and effect sizes can be formatted independently from descriptive values and test statistics.table_continuous_lm()now keepsnas the unweighted analytic sample size in wide and rendered outputs, and can optionally add a separateWeighted ncolumn reporting the sum of case weights.
spicy 0.7.0
CRAN release: 2026-03-30
New features
table_continuous()is a new helper for continuous summary tables. It computes descriptive statistics (mean, SD, min, max, confidence interval of the mean, and n) for numeric variables, with tidyselect column selection, optional grouping viaby, and multiple output formats (ASCII, tinytable, gt, flextable, Excel, clipboard, and Word).table_continuous()gainseffect_sizeandeffect_size_ciarguments. Whenbyis used,effect_size = TRUEadds an “ES” column with the appropriate measure (Hedges’ g, eta-squared, rank-biserialr_rb, or epsilon-squared) chosen automatically based on the test method and number of groups, andeffect_size_ci = TRUEappends the confidence interval in brackets.table_continuous()gains atestargument ("welch","student", or"nonparametric") to choose the group-comparison method, along with independentp_valueandstatisticdisplay toggles so users can request either or both outputs whenbyis used.ASCII console tables now split oversized outputs into stacked horizontal panels, repeating the left-most identifier columns so wide
freq(),cross_tab(),table_categorical(), andtable_continuous()prints stay readable in narrow consoles.
Breaking changes
table_categorical()replacestable_apa()as the public helper for categorical summary tables. It usesselectandby, supports grouped cross-tabulation or one-way frequency-style tables whenby = NULL, and consolidates output formats under a singleoutputargument. Migrate existingtable_apa()calls totable_categorical(), useoutput = "default"for ASCII tables andoutput = "data.frame"for plain data frames, and replace formeroutput = "wide"/style = "report"paths with the formatted output engines.Excel export now uses
openxlsx2instead ofopenxlsxfor a lighter dependency footprint (no Rcpp compilation required).
Minor improvements
Package citation metadata now uses the current package title and CRAN DOI, so
citation("spicy")matchesDESCRIPTIONand points to the package DOI.table_categorical()andtable_continuous()now print shorter ASCII titles without appending the input data frame name, and no longer requireofficerforoutput = "flextable"alone;officeris now required only for Word export paths that actually write.docxfiles.table_continuous()now accepts tidyselect syntax inexcludein addition to character vectors, and no longer warns thattestis ignored when it is still needed to compute effect sizes.
spicy 0.6.0
CRAN release: 2026-03-23
New features
New family of association measure functions for contingency tables:
assoc_measures(),contingency_coef(),gamma_gk(),goodman_kruskal_tau(),kendall_tau_b(),kendall_tau_c(),lambda_gk(),phi(),somers_d(),uncertainty_coef(), andyule_q(). Each returns a numeric scalar by default; passdetail = TRUEfor a named vector with estimate, confidence interval, and p-value.cross_tab()gainsassoc_measureandassoc_ciarguments. When both variables are ordered factors, it automatically selects Kendall’s Tau-b instead of Cramer’s V. The note format changes fromChi-2: 18.0 (df = 4)toChi-2(4) = 18.0. Numeric attributes (chi2,df,p_value,assoc_measure,assoc_value,assoc_result) are now attached to the output data frame.table_apa()now dynamically labels the association measure column based on the measure used, instead of always showing “Cramer’s V”. Newassoc_measureandassoc_ciarguments are passed through tocross_tab().table_apa()gainsoutput = "gt"to produce agt_tblobject with APA-style formatting, column spanners, and alignment.table_apa()now correctly centers spanner labels over their column pairs intinytableandflextableoutput.All association measure functions and
assoc_measures()gain adigitsargument (default 3) that controls the number of decimal places when printed. The p-value always uses 3 decimal places or< 0.001.detail = TRUEresults now print with formatted output (aligned columns, fixed decimal places) via a newprint.spicy_assoc_detail()method.assoc_measures()output uses a newprint.spicy_assoc_table()method with the same formatting.New bundled dataset
sochealth: a simulated social-health survey (n = 1200, 24 variables) with variable labels, ordered factors, survey weights, and missing values. Includes four Likert-scaled life satisfaction items (life_sat_health,life_sat_work,life_sat_relationships,life_sat_standard) for demonstratingmean_n(),sum_n(), andcount_n().
Bug fixes
count_n()now correctly countsNAvalues whencount = NAandstrict = TRUEare both used. List columns are now reported in verbose mode instead of causing silent errors.cross_tab()rescale logic now operates on complete cases only, so the weighted total N matches the unweighted N when missing values are present (consistent with Stata behavior).freq()now uses trueNAconsistently (instead of the"<NA>"string) in both weighted and unweighted paths.cum_valid_propis now correctlyNAfor missing rows. Invaliddigitsandsortvalues are rejected with clear error messages.mean_n()andsum_n()now validatemin_validanddigitsarguments, rejecting non-numeric, negative, or multi-element values.mean_n(),sum_n(), andcount_n()no longer trigger a tidyselect deprecation warning whenselectreceives a character vector. Character vectors are now automatically wrapped withall_of().table_apa()now preserves the original factor level order in row variables instead of sorting alphabetically. Whendrop_na = FALSE, the(Missing)category is placed at the bottom of each variable’s levels.percent_digits,p_digits, andv_digitsare now validated.table_apa()p-values no longer wrap across lines intinytableHTML output.
Breaking changes
-
cramer_v()now accepts adetailargument. By default it returns a numeric scalar (as before). Passdetail = TRUEto get a 4-element named vector (estimate,ci_lower,ci_upper,p_value), ordetail = TRUE, conf_level = NULLfor a 2-element vector (estimate,p_value) without CI.
spicy 0.5.0
CRAN release: 2026-03-14
New features
- New
table_apa()helper to build APA-ready cross-tab reports with multiple output formats (wide,long,tinytable,flextable,excel,clipboard,word). -
table_apa()exposes keycross_tab()controls for weighting and inference (weights,rescale,correct,simulate_p,simulate_B) and now handles missing values explicitly whendrop_na = FALSE.
Bug fixes
-
count_n()no longer crashes whenspecial = "NaN"is used with non-numeric columns. Passingcount = NAnow errors with a message directing tospecial = "NA". -
cross_tab()fixes a spurious rescale warning for explicit all-ones weights and aligns the Cramer’s V formula withcramer_v(). -
table_apa()no longer leaks global options on error. Thesimulate_pdefault is aligned toFALSE. -
varlist()title generation no longer crashes on unrecognizable expressions.
Minor improvements
-
copy_clipboard()parametermessagerenamed toshow_message. -
freq()now dispatches printing correctly via S3. - Removed unused
collapseandstringifromImports.
spicy 0.4.2
CRAN release: 2026-03-06
-
cross_tab()hardening: improved vector-mode detection (including labelled vectors), stricter weight validation, safer rescaling, and clearer early errors (e.g., explicity = NULL). -
cross_tab()statistics are now computed on non-empty margins in grouped tables, avoiding spuriousNAresults; internal core path refactored to removedplyr/tibblefrom computation while preserving user-facing behavior. -
freq()now errors clearly whenxis missing for data.frame input and validates rescaling when weight sums are zero/non-finite. -
count_n(),mean_n(), andsum_n()regex mode is hardened (regex = TRUEnow validates/defaultsselectsafely). -
mean_n()andsum_n()now returnNA(with warning) when no numeric columns are selected. -
label_from_names()now validates input type (data.frame/tibble required). -
cramer_v()now returnsNAwith warning for degenerate tables. - Dependency optimization:
DTandcliprmoved toSuggests; optional runtime checks added incode_book()andcopy_clipboard(). - Tests expanded with regression coverage for all the above edge cases.
spicy 0.4.1
CRAN release: 2025-12-21
- Fixed CRAN incoming check notes by removing non-standard top-level files.
spicy 0.4.0
Print methods have been fully redesigned to produce clean, aligned ASCII tables inspired by Stata’s layout. The new implementation improves formatting, adds optional color support, and provides more consistent handling of totals and column spacing.
Output from
freq()andcross_tab()now benefits from the enhancedprint.spicy()formatting, offering clearer, more readable summary tables.Documentation and internal tests were updated for clarity and consistency.
cross_tab()gains an explicitcorrectargument to control the use of Yates’ continuity correction for Chi-squared tests in 2x2 tables. The default behavior remains unchanged.The documentation of
cross_tab()was refined and harmonized, with a clearer high-level description, improved parameter wording, and expanded examples.Minor cosmetic improvements were made to
varlist()output: the title prefix now usesvl:instead ofVARLIST, and the column nameNdist_valwas renamed toN_distinctfor improved readability and consistency.Minor cosmetic improvement: ASCII table output no longer includes a closing bottom rule by default.
spicy 0.3.0
CRAN release: 2025-10-22
- New function
code_book(), which generates a comprehensive variable codebook that can be viewed interactively and exported to multiple formats (copy, print, CSV, Excel, PDF).
spicy 0.2.1
CRAN release: 2025-10-04
-
label_from_names()now correctly handles edge cases when the separator appears in the label or is missing.
spicy 0.2.0
CRAN release: 2025-09-25
- New function
label_from_names()to derive and assign variable labels from headers of the form"name<sep>label"(e.g."name. label"). Especially useful for LimeSurvey CSV exports (Export results -> CSV -> Headings: Question code & question text), where the default separator is". ".
spicy 0.1.0
CRAN release: 2025-05-05
Initial release
- Introduces a collection of tools for variable inspection, descriptive summaries, and data exploration.
- Provides functions to:
- Extract variable metadata and display compact summaries (
varlist()). - Compute frequency tables (
freq()), cross-tabulations (cross_tab()), and Cramer’s V for categorical associations (cramer_v()). - Generate descriptive statistics such as means (
mean_n()), sums (sum_n()), and counts (count_n()) with automatic handling of missing data. - Copy data (
copy_clipboard()) directly to the clipboard for quick export.
- Extract variable metadata and display compact summaries (