Row matching for duplicate-key strategies keep_all and all_pairs (ks_match_rows_keep_all(), ks_match_rows_all_pairs()) now pre-allocates the per-group parts list and caches the level factor used for splitting, removing O(n^2) list-copy churn on data sets with many unique keys.
The main comparison loop in ks_compare() now pre-allocates the value_parts accumulator and uses order(..., method = "radix") for the final stable sort of value_diff, materially speeding up wide comparisons (many matched column pairs) and large diff tables.
ks_schema_diff() no longer rescans meta_b$name / meta_c$name for every column pair; it builds a name-indexed lookup once and reuses per-row metadata, and it hoists the compare_labels / compare_formats option checks out of the per-column loop.
ks_value_diff_one() now slices the unequal cells once and reuses the result for ks_explain_diffs(), format_cell(), and ks_na_flow(), avoiding three redundant subsets on large columns; the type-mismatch branch likewise slices base_col / comp_col only once.
Internal
No user-facing API changes; all optimisations are behaviour-preserving.
ksCompare 0.1.0
Initial development release. ksCompare is a tidyverse-native engine for comparing two data frames in the spirit of SAS PROC COMPARE, with extensions for clinical/pharma workflows. Highlights:
ks_compare() orchestrator with explicit by keys, by = "auto" uniqueness inference, and explicit column mapping.
ks_tol() with absolute, relative, and ULP tolerance plus per-column overrides.
ks_comp_options() for NA semantics, SAS special-missing handling, label/format comparison, string trim/case/normalize toggles, and an optional path that pins every downstream ks_report_*() artefact to a single output folder. Every field also falls back to a getOption("ksCompare.<arg>") global, and ks_set_comp_options() forwards to options() for project-wide defaults.
Per-type cell diff for numeric (with ULP-aware compare), character, factor, date/datetime, and haven_labelled columns; encoding-safe string comparison.
Schema diff including label and SAS-format mismatches; format comparison is trailing-dot- and case-tolerant so haven import artefacts do not surface as false diffs.
Manifest with input hashes and package version for QC traceability.
Smart features: auto-key inference, fuzzy column rename suggestions (Suggests-gated on stringdist), duplicate-key strategies (first, last, keep_all, all_pairs, error), and pattern detection (constant_offset, constant_scale, sign_flip, integer_round, whitespace_only, trim_only, case_only, factor_recoded).
Reports: ks_report_html() (self-contained htmltools + reactable page with sticky TOC, KPI cards, status pill, themed tables, an optional group_by_key mode that renders one collapsed block per key value, and a print-friendly stylesheet) and ks_report_xlsx() (openxlsx2 multi-sheet workbook with conditional formatting on OUT_DIF). The HTML report inlines every JS/CSS dependency into a single file, so no sibling lib/ folder is written next to the report.
Documentation: pkgdown site, five long-form vignettes (getting-started, from-proc-compare, smart-features, reports, pipeline-gates), and CI workflows for R-CMD-check, pkgdown, and test-coverage.