Changes in version 0.1.0 (2026-09-28) Initial release. CRAN resubmission fixes - DESCRIPTION: reworded the Description field so it no longer starts with "Tools for", and added method references (de Bie 2004 doi:10.1016/j.scienta.2003.11.017; Kamkar et al. 2025 doi:10.1016/j.agsy.2025.104392). - Replaced \dontrun{} with self-contained, runnable \donttest{} examples in plot_all_graphs(), save_results_excel(), and save_field_level_excel(). - plot_contribution_shares() no longer writes an unsuppressable console message when there is nothing to plot; it now raises a warning() instead. - save_results_excel(), save_field_level_excel(), and plot_all_graphs() no longer default to writing into the current working directory; their path/directory arguments now default to tempdir(). - check_assumptions() now restores graphics par() settings via an immediate on.exit() rather than a manual call after plotting, so the user's graphics state is restored even if plotting fails. Update: bootstrap confidence intervals for the CPA decomposition Added bootstrap_cpa(), which uses case resampling (nonparametric bootstrap) to compute percentile confidence intervals for the overall yield gap and for each variable's Gap_Component and Share_Percent in the CPA table. The significant-variable set is held fixed across resamples so the intervals describe the uncertainty of the decomposition itself; an optional check_selection_stability diagnostic reports how often each variable would be independently re-selected across resamples. bootstrap_cpa() correctly includes the model intercept when computing Yield_Mean/Yield_Opt for each resample, so these are reported on the actual yield scale (an early internal version omitted it, which zeroed out only these two summary rows while leaving Yield_Gap and the per-variable Gap_Component/Share_Percent values unaffected, since the intercept's own contribution to the gap is always zero). bootstrap_cpa() now auto-tunes top_percentile and min_top_samples from the sample size using the exact same thresholds as yield_gap_analysis(), instead of a fixed top_percentile = 0.99 and min_top_samples = 20. On datasets smaller than 100 rows, the fixed defaults did not match what yield_gap_analysis() actually used internally, producing a different high-yield subset and therefore different Yield_Mean/Yield_Opt/Gap_Component values than the analysis being bootstrapped. Both parameters can still be set explicitly to override the auto-tuned value. Update: bundled example datasets Three real field-trial datasets are now bundled with the package and used throughout the documentation and vignette in place of synthetic data: - wheat1 - 200 fields, 13 variables, clean (no missing values). The primary worked example for the full preprocessing/analysis workflow. - wheat2 - 40 fields, 29 variables, kept in its original, unedited form (including a non-predictor ID column and a real leading/trailing whitespace inconsistency in Cultivar). Illustrates trim_whitespace(), ordinal-variable handling via ordinal_level_orders, high-cardinality grouping, and the small-sample/ high-dimensionality auto-tuning behavior of prep_yield_gap(). - sugarcane1 - 371 fields, 30 variables, a different crop and a larger, clean dataset. Illustrates a genuinely ordinal variable (crop_type: PC < R1 < ... < R9) and a perfectly collinear ("aliased") derived column (total_urea_kg_ha, the exact sum of four other columns) - both select_vars_ftest() and select_vars_aic() handle the latter gracefully. See ?wheat1, ?wheat2, and ?sugarcane1 for full column descriptions. Update: variable selection method choice yield_gap_analysis() now supports selection_method = "aic" as an alternative to the default "ftest": - select_vars_aic() selects variables by minimizing AIC via stats::step() (new function), with a new aic_direction argument ("both", "forward", "backward"). - F-test-based selection (fixed F-to-Enter/F-to-Remove or p-value threshold, similar to SigmaPlot) and AIC-based selection encode different criteria for what counts as a useful predictor and will normally select a different number of variables - neither is universally "correct". In testing against real field data, the default AIC selection tended to retain MORE variables than the default F-test settings, since AIC's implicit penalty is typically more lenient than a fixed F-to-Enter threshold around 4; this can go the other way if AIC is compared against a much stricter criterion (e.g. BIC, or a low significance threshold). Update: whitespace trimming and small-sample/high-dimensionality fixes - New trim_whitespace() function, run automatically (default trim_whitespace = TRUE) at the very start of prep_yield_gap(). Protects against a very common real-world data-entry artifact where a single true category (e.g. "Sirvan" vs. "Sirvan ") is silently split into two distinct levels by accidental leading/trailing whitespace. - Fixed a crash (max_dummy_levels must be a single integer >= 2) that occurred for small, high-dimensional datasets (many predictor columns relative to the number of rows) - a common profile for real agricultural field-trial data with few fields but many recorded management variables. Overview VeraCrop provides an end-to-end workflow for yield gap analysis using Comparative Performance Analysis (CPA): automatic variable-type detection, preprocessing (missing-value handling, encoding, scaling, filtering), regression diagnostics, variable selection with cross-validation, and yield gap decomposition with reporting (Excel export, plots). Key functions - prep_yield_gap() - end-to-end preprocessing pipeline - detect_variable_types() - automatic variable type detection - encode_variables() - encoding for linear regression (binary, ordinal, nominal, high-cardinality, continuous, date) - handle_missing_values() - imputation with optional missing indicators - scale_variables() / back_transform_coefficients() - standardization with correct back-transformation of regression coefficients - remove_constant_vars() / remove_near_zero_variance() / remove_highly_correlated() - variable filtering - check_assumptions() - the five classical linear regression assumption checks (linearity, independence, homoscedasticity, normality, multicollinearity) plus influential-point diagnostics - select_vars_ftest() / validate_model_with_cv() - stepwise variable selection and k-fold cross-validation - yield_gap_analysis() - full CPA yield gap computation, including optimal-value estimation, min-max effect sizes, relative importance, and Pareto analysis - save_results_excel() / save_field_level_excel() - Excel reporting - plot_contribution_shares(), plot_observed_vs_predicted(), plot_yield_gap_distribution(), plot_minmax_effects(), plot_relative_importance(), plot_all_graphs() - visualization Notes on correctness The following were identified and corrected during development, primarily through end-to-end testing against real agronomic data rather than static code review alone. They are listed here because they affect the numeric results a user would get from earlier development snapshots of this code, not because they represent changes in the current public API. - The response variable is now always protected from being scaled by scale_variables() / prep_yield_gap(), and by default binary/dummy (0/1) columns produced by encoding are excluded from scaling as well, since standardizing a 0/1 indicator has no meaningful interpretation and previously produced an incorrect "optimal value" for such variables in the yield gap decomposition. - calculate_opt_values() now derives the optimal value of a binary/dummy variable from its own observed maximum/minimum, rather than assuming the two states are always literally 0 and 1 (true only when the variable has not been scaled). - Categorical (nominal) variable encoding no longer fails for variables with more than two levels. - Near-zero-variance filtering (remove_near_zero_variance()) now actually runs instead of raising an internal error on every call. - check_assumptions() and validate_model_with_cv() accept an optional seed for reproducible sampling / fold assignment, and always restore the caller's global random state afterward rather than leaving it altered. - Name-based automatic detection of ordinal variables now requires an explicit level order (ordinal_level_orders) for character/factor columns; without one, the variable is conservatively treated as nominal instead of guessing an order from row order in the raw data (which is not reproducible and can silently reverse the true ordinal relationship). - All verbose arguments are honored consistently: computed results (e.g. data_ready, filtering decisions) no longer depend on whether progress messages are printed, and functions that previously always printed to the console regardless of caller settings (pareto_analysis(), save_results_excel(), save_field_level_excel(), plot_all_graphs()) now respect verbose = FALSE. - plot_all_graphs() degrades gracefully (skipping unavailable panels) instead of raising an error when one of its inputs is unavailable. Testing The package ships with a testthat suite covering preprocessing, encoding, filtering, scaling, diagnostics, variable selection, yield gap computation, and the end-to-end pipeline.