Skip to contents
CafriplotsR 1.8.1 (2025-12-12)
New Features
Taxonomic backbone caching system for improved performance
Local caching for taxonomic backbone dramatically improves performance with slow internet
After first download, subsequent app launches load backbone from cache (~1 second vs 5-30 seconds)
Performance improvement: 10-70x faster on subsequent runs
Interactive modal allows choosing between cached or fresh backbone
Cache displays age and file size for informed decision-making
Cache location: platform-appropriate user cache directory via rappdirs
New exported function delete_backbone_cache() for manual cache clearing
Added rappdirs package dependency
Row-level security improvements with created_by migration
New created_by column tracks which user created each plot
Migration function migrate_add_created_by() safely adds column and updates policies
Simplified import function: automatic privilege management
Users automatically get access to plots they create
Function check_created_by_migration() checks migration status
Enhanced define_user_policy() with automatic privilege grants
Automatically grants necessary table privileges (SELECT, INSERT, UPDATE) when creating policies
Eliminates manual privilege management for administrators
Covers all relevant tables: plots, subplots, individuals, features, traits
Improved plot ID query with multi-column matching
Plot retrieval now matches on multiple identifying columns beyond just id_table_liste_plots
Handles admin_code, plot_code, and plot_name for flexible querying
Reduces need to know exact internal IDs
Bug Fixes
Fixed query_plots() ignoring provided database connections
Function now properly respects con parameter when provided
Prevents unnecessary connection creation when using connection pools
Critical for Shiny apps using reactive database connections
Fixed .link_subplotype() missing connection parameter
Function now accepts and uses provided database connection
Ensures transaction consistency during imports
Prevents connection errors in multi-step workflows
Fixed multiple RLS policy issues preventing imports
INSERT operations now work correctly for non-admin users
RETURNING clause properly returns inserted plot IDs despite RLS restrictions
SELECT policy adjusted to allow RETURNING without exposing other users’ data
All users can now import plots regardless of RLS configuration
Fixed Import Wizard lookup matcher performance issues
Eliminated UI freeze when matching large lookup tables
Enhanced name matching with better fuzzy algorithms
Improved responsiveness during interactive matching
Fixed Import Wizard validation and conversion issues
Exact-matched lookup values now properly converted to IDs before validation
Prevents validation errors for values that were successfully matched
Duplicate column mapping now detected and prevented in Step 3
Fixed multiple i18n reactive call errors in Import Wizard
Corrected reactive i18n calls in Step 1, Step 2, and other modules
Fixed missing i18n parameters in module calls
Removed duplicate translations from translation.json
Fixed graphics parameter error in mapview map creation
Added error handling for graphics device issues
Required BIOMASS >= 2.2.4 to prevent par() parameter errors
Graceful fallback when map creation fails
Documentation
Added critical security warnings for database credentials
CLAUDE.md now includes prominent warnings about credential management
Clear guidelines for using placeholder credentials in examples
Instructions for credential leak response
Updated Import Wizard documentation
Vignettes restructured to feature Shiny Import Wizard prominently
Added i18n and translation management guidelines to CLAUDE.md
Added package citation information
Citation section added to README files (EN and FR)
Updated DESCRIPTION with proper author roles and ORCID
Package now citable via citation("CafriplotsR")
Infrastructure
Cleaned up version control
Removed xlsx, csv, gpkg data files from tracking
Removed geospatial temporary and KML files
Removed R Markdown cache and generated files
Removed RStudio Connect deployment files
Added working .Rmd files to .gitignore to prevent credential leaks
Added .Rprofile to .gitignore
GitHub Actions workflows
Added Claude Code Review workflow for automated code review
Added Claude PR Assistant workflow for pull request automation
Code Refactoring
Improved Step 7 messaging in Import Wizard
Clearer explanations of row-level security and access models
Better guidance on admin contact for access grants
Updated UI based on user feedback
CafriplotsR 1.8.0 (2025-01-15)
New Features
Interactive Import Wizard Shiny App - Complete 7-Step Workflow
New launch_import_wizard() function provides comprehensive plot metadata import interface
Full internationalization support (English/French)
Reuses existing validation and import functions for consistency
See version 1.7.2 entries below for detailed step-by-step feature descriptions
Plot Statistics & Visualizations module
New “Statistics” tab in launch_query_plots_app() with comprehensive summaries
Summary statistics: number of plots, individuals, species, families
Diameter statistics: mean, median, min, max
Interactive visualizations with ggplot2 + plotly:
Diameter distribution histogram with hover tooltips
Top N species composition bar chart (adjustable slider: 5-30 species)
Download summary statistics as CSV
Fully bilingual (EN/FR) with i18n support
Smart column mapping adapts to different output styles
Code preview and export features
Query plots app now includes code preview for reproducibility
Generated R code can be copied or downloaded
Helps users transition from GUI to programmatic workflows
Bug Fixes
Fixed census date parsing error with missing/invalid data
Gracefully handles missing year/month values in census dates
Prevents errors when date components are NA or invalid
Returns NA for unparseable dates instead of crashing
Infrastructure
Added stringdist package dependency
Required for fuzzy string matching in import wizard
Fixes import wizard initialization errors
Updated pkgdown website
Documentation website updated with latest function references
Added logo to package site
All vignettes updated with new features
CafriplotsR 1.7.2 (2024-12-15)
New Features
Import Wizard: Duplicate plot detection during validation
New validation step checks for potential duplicate plots in database
Matches on method, country, and coordinates (rounded to 3 decimals ≈ 111m precision)
Prevents re-importing existing plots with different names (e.g., “FND32” vs “Releve32”)
Returns warnings (not errors) with existing plot names for user awareness
Respects row-level security (only checks plots user can access)
Import Wizard: UTM coordinate detection and conversion
Two-stage detection system for UTM coordinates:
Stage 1 (Validation) : Detects coordinates > 1000 with specific error message
Stage 2 (Preview) : Interactive converter with zone and hemisphere inputs
Uses sf package for coordinate transformation (EPSG 326XX/327XX → 4326)
Converts in-place and updates preview map automatically
Guides users to convert rather than rejecting data
Import Wizard: Interactive map preview in Step 6
Leaflet map displays plot locations with marker clustering
Auto-zoom to plot extent
Clickable popups show plot details (name, coordinates, method, country)
Warnings for invalid coordinates and unusual ranges
Info box guides users to fix reversed lat/lon by switching column mappings
Helps catch common errors: reversed coordinates, wrong coordinate system
Interactive Import Wizard Shiny App for Plot Metadata
New launch_import_wizard() function provides comprehensive 7-step workflow for importing plot metadata
Step 1: Choose Type - Select import type (plots or individuals)
Step 2: Upload Data - Upload Excel/CSV files or download template
Step 3: Map Columns - Intelligent fuzzy column mapping with confidence scores and descriptions
Step 4: Match Lookups - Proactive lookup matching before validation
Analyzes all lookup columns (method, country, people fields)
Identifies exact matches vs. values needing matching
Interactive fuzzy matching with similarity scores for all possibilities
Displays method descriptions when selecting matches
Supports comma-separated people values (e.g., “Gilles Dauby, Hugo Leblanc”)
Each person matched individually and aggregated back
Step 5: Validate - Comprehensive data validation using matched values
Validates both IDs (after matching) and names (before matching)
Clear error reporting with actionable messages
Step 6: Preview - Preview cleaned data with readable names
Displays lookup names instead of IDs for user-friendly preview
Handles comma-separated people fields (shows aggregated names)
Download enriched data as Excel or CSV with human-readable values
Step 7: Execute Import - Live import with transaction support
Dry run mode for testing without database changes
Uses existing import_plot_metadata() function
Displays admin code for row-level security access
Copy to clipboard and download as .R file options
New module files: R/mod_step1_choose_type.R, R/mod_step2_upload.R, R/mod_step3_mapping.R, R/mod_step4_lookup_matching.R, R/mod_step5_validation.R, R/mod_step6_preview.R, R/mod_step7_import.R, R/mod_lookup_matcher.R
Reuses existing validation and import functions for consistency
Full connection pool support with proper cleanup
Plot Statistics & Visualizations module for Query Plots Shiny App
New “Statistics” tab in launch_query_plots_app() displays comprehensive plot statistics
Smart column mapping system automatically adapts to different output styles (minimal, standard, permanent_plot, etc.)
Detects column names regardless of renaming (e.g., stem_diameter/dbh/D, tax_sp_level/species)
Summary statistics cards: number of plots, individuals, species (richness), families
Diameter statistics: mean, median, min, max (when diameter data available)
Interactive visualizations using ggplot2 + plotly:
Diameter distribution histogram with hover tooltips
Top N species composition bar chart (adjustable slider: 5-30 species)
Graceful degradation: sections automatically hide when data unavailable
Download summary statistics as CSV
Fully bilingual (EN/FR) with integrated i18n support
New module files: R/mod_plot_statistics.R (UI/server functions)
Added 24 translation strings to inst/translations/translation.json
Designed for easy expansion (guild analysis, height-diameter plots, basal area, etc.)
Bilingual support for Taxonomic Matching Shiny App
Implemented full internationalization using shiny.i18n package
French and English interfaces with instant language switching
French is now the default language
Migrated all 7 modules to use centralized i18n translation system:
mod_auto_matching - Auto matching tab
mod_column_select - Column selection
mod_data_input - Data upload/input
mod_fuzzy_suggestions - Fuzzy match suggestions
mod_name_review - Manual review interface
mod_results_export - Results export
mod_traits_enrichment - Traits enrichment
Added utils_i18n.R with init_translator() and translation utilities
Created inst/translations/translation.json with comprehensive translations
Language toggle located in top-right corner of app
Set via launch_taxonomic_match_app(language = "fr") or language = "en"
Taxonomic Matching: Backbone caching system for improved performance
Added local caching for taxonomic backbone to dramatically improve performance with slow internet connections
After first download, subsequent app uses load backbone from local cache (~1 second) instead of downloading from database (5-30 seconds)
Performance improvement: 10-70x faster on subsequent runs
Users can choose between cached or fresh backbone via modal dialog
Cache displays age (e.g., “3 days ago”) and file size for informed decision-making
Cache location: rappdirs::user_cache_dir('CafriplotsR') (platform-appropriate)
New exported function delete_backbone_cache() allows manual cache clearing
Added rappdirs package dependency
Taxonomic Matching: Improved similarity threshold UI
Similarity threshold now displays as percentage (0-100%) instead of decimal (0-1)
Default value: 60% (previously 0.6)
More explicit help text: “Minimum similarity percentage for fuzzy matching. Names with similarity below this threshold will not be matched. Higher values = more strict matching (fewer but more accurate matches).”
Label updated to “Minimum similarity (%)” for clarity
Internal calculations still use decimal format (0-1) for compatibility with matching algorithms
Bug Fixes
Taxonomic Matching: Fixed progress bar not updating after manual review
Progress bar calculation now correctly includes manually reviewed names in completion percentage
Previously only counted automatically matched names (exact/genus/fuzzy), causing progress to appear stuck at ~60% even after reviewing all remaining names
Connected progress tracker to review module results instead of auto-matching results
Added “Manually reviewed” line (displayed in green) to progress breakdown when manual reviews are performed
Progress now correctly shows 100% when all names are either auto-matched or manually reviewed
Import Wizard: Fixed mixed IDs and names in people column preview
Preview was showing mix of numeric IDs (169, 85) and text names (Théophile Ayol)
Now processes each value individually in comma-separated lists
Converts numeric IDs to names, keeps text names as-is
Applies to all lookup columns (method, country, people fields)
Import Wizard: Fixed skipped columns still appearing in preview
Columns set to “skip” in column mapping were still appearing in data preview
Now properly filters out NA mappings in both validation and preview steps
Removed skipped columns from data before processing
Import Wizard: Fixed mapping state not persisting on navigation
Manual changes (e.g., skipping columns) were lost when navigating back
Added persistent user_modified_mappings ReactiveVal to track changes
Observers now track dropdown changes without cascade triggering
Returns both mappings (no NAs) and mappings_with_skips (includes NAs)
Fixed import failing with unmapped columns
Import now filters out columns that were skipped during column mapping
Prevents “ERROR: column ‘X’ of relation ‘data_liste_plots’ does not exist”
Only mapped columns are included in database insertion
Fixed type mismatch error when joining subplot features
Added explicit character type conversion for plot_name before joins
Prevents “Can’t join due to incompatible types” errors
Applies to both people features and other subplot features
Fixed poolWithTransaction() warning in Shiny app imports
Import now properly handles connection pools by checking out dedicated connections
Uses pool::poolCheckout() and pool::poolReturn() for proper pool management
Eliminates “Please use poolWithTransaction() instead” warnings
Fixed validation errors after lookup matching
Validation now correctly handles both IDs (after Step 4 matching) and names (before matching)
Detects if values are numeric (IDs) or character (names) and validates accordingly
Applies to method, country, and people column validation
Fixed preview and downloads showing IDs instead of names
Preview now enriches lookup columns by replacing IDs with readable names
Method IDs → Method names (e.g., 18 → “Plot_40x40”)
Country IDs → Country names (e.g., 5 → “Cameroon”)
People IDs → People names with comma-separated aggregation
Excel and CSV downloads export enriched data with names
Fixed query_individual_features() ignoring trait_ids parameter with large datasets
When querying more than 1000 individuals, the chunking mechanism was not passing trait_ids filter
This caused all traits to be returned instead of only the requested ones
Fixed by passing trait_ids parameter through fetch_with_chunking() to build_trait_query()
Affects individual_features_function.R:1319 and individual_features_function.R:1270
Documentation
Updated Taxonomic App vignettes for bilingual support
English vignette (taxonomic-app.Rmd) now documents language switching feature
French vignette (taxonomic-app-fr.Rmd) includes parallel documentation
Documented EN/FR toggle button usage
Documented programmatic language selection
Noted French as default language
Code Refactoring
Removed obsolete table_taxa_tb dataset
Deleted data/table_taxa_tb.RData and associated documentation
Data is no longer needed as taxonomy queries now use direct database connections
Reduced package size and maintenance burden
CafriplotsR 1.7.1 (2025-11-18)
New Features
New get_user_accessible_plots() function
Extracts plot IDs that a user can access based on row-level security policies
Parses policy expressions to return clean vector of accessible plot IDs
Useful for checking user permissions and debugging access issues
Bug Fixes
Fixed Shiny apps crashing RStudio when browser is closed
Fixed list_user_policies() returning empty results
Added ::name type cast for proper comparison with PostgreSQL name[] array
Function now correctly filters policies by username
Documentation
New vignette: “Database Connections Guide”
Complete guide to database connection workflows
Explains both call.mydb() and call.mydb.taxa() functions
Credential management options (interactive, .Renviron, direct)
Connection cleanup best practices with cleanup_connections()
Row-level security and checking plot accessibility
Troubleshooting common connection issues
Best practices summary for users
CafriplotsR 1.7 (2025-01-13)
New Features
Interactive Shiny app for plot querying and data extraction
New launch_query_plots_app() function provides user-friendly interface for query_plots()
Two-stage workflow: (1) filter and discover plots, (2) select and extract individual data
Filter interface: query by country, plot name, locality, method, tags, and IDs (including comma-separated values)
Interactive leaflet map with multiple basemaps showing plot locations
Metadata table viewer with sortable/searchable columns
Plot selection: all plots selected by default, users can deselect specific plots
Configurable extraction options: output styles, census strategies, data organization, trait extraction
Results viewer with dynamic tabs for each data table
Multi-format download: Excel (.xlsx), CSV (zipped), R object (.rds), and shapefile (.zip) formats
Row-level security aware: filter options respect user’s database access permissions
Modular architecture with dedicated UI/server modules for extensibility
Database login integration with support for saved credentials from .Renviron
Complete individual tree data import workflow
New import_individual_data() function with transaction-based imports and automatic rollback on errors
Interactive column mapping with map_individual_columns() - automatically matches user columns to database schema
Comprehensive validation with validate_individual_data() - checks plots, taxonomy, tags, traits before import
Template generation with get_individual_template() - creates Excel templates with guidance
Dry-run mode to preview imports without committing changes
Support for both flat table and two-table (individuals + features) data structures
Auto-generates sequential tags when missing
Imports into data_individuals and data_traits_measures tables
See new vignette “Importing Plot Data into the Database” for complete workflow
Intelligent column mapping system
Fuzzy matching of user column names to database columns and traits
Interactive classification: feature/trait vs individual identification columns
Manual selection with ranked suggestions based on similarity scores
Synonym support for common column name variations
Automatic detection of linking columns (plot_name, tag)
Mapping audit trail preserved for reproducibility
Comprehensive data validation before import
Required columns validation (plot_name, idtax_n)
Plot existence verification with exact name matching
Taxonomy ID validation against database
Tag uniqueness within plots
Tag conflict detection with existing database records
Trait value validation (numeric vs categorical)
Feature-to-individual linkage verification
Method-specific requirements validation
Detailed error reporting with actionable messages
query_plots() exact name matching
New exact_match parameter (default FALSE) for precise plot name filtering
Prevents unintended pattern matching (e.g., “41” matching “Plot-41”, “4100”)
Uses SQL IN clause for exact matching vs LIKE for pattern matching
Applied throughout PlotFilterBuilder pipeline
Taxonomic matching app: Class-level taxonomic support
Now recognizes and matches class-level taxa (e.g., names ending in -opsida, -psida)
Searches in tax_famclass column for class names
Both exact and fuzzy matching supported for classes
Expands hierarchical matching beyond family/order/genus/species
Taxonomic matching app: Improved large dataset handling
Excel file reading now uses guess_max = 30000 for better column type detection
Prevents type mismatches when taxonomic names appear late in large datasets
Ensures consistent data type inference across entire dataset
Documentation
New vignette: “Importing Plot Data into the Database”
Complete workflow from plot metadata to individual tree data
Step-by-step examples with expected output
Interactive and programmatic workflows
Common issues and troubleshooting guide
Best practices for data import
Advanced topics: custom column synonyms
Bug Fixes
Fixed Shiny apps crashing RStudio when browser is closed
Fixed query_plots() with output_style throwing errors on missing columns
Changed column selection from all_of() to any_of() in output style transformations
Functions now gracefully handle missing columns instead of throwing errors
Applies to .extract_metadata_table(), .extract_individuals_table(), and .extract_height_diameter_pairs()
Dynamic column selection for height_of_stem_diameter (POM) when creating height-diameter pairs
Output styles (permanent_plot, standard, etc.) now work reliably with varying data structures
Fixed .find_cat() return value handling in column mapping
Interactive column selection was returning wrong columns due to table reordering
Now correctly extracts selected value from result$sorted_matches instead of original table
Applies to both individual column and trait column selection
Fixed traits_list() column name
Changed description to traitdescription to match actual column name
Prevents errors during trait column display
Fixed tag propagation from individuals to features
Auto-generated tags now correctly synced to features sheet during validation
Ensures features can link to individuals via tag column
Infrastructure
query_plots() improvements for Shiny integration
New con parameter accepts optional database connection (defaults to call.mydb() if NULL)
Enables Shiny apps to pass reactive connection pools without triggering reactive context errors
Consistent metadata naming in return list regardless of output_style (previously meta_data for “full” style, metadata for others)
Ensures predictable list structure for programmatic access
Improved package dependency management
Moved getPass and dm from Imports to Suggests
Reduces installation requirements - only needed for specific optional features
getPass: Used only for secure password prompts (has fallbacks to rstudioapi and readline)
dm: Used only for database structure visualization with get_database_fk()
Both packages now checked with requireNamespace() before use with helpful error messages
Fixes installation errors for users without these packages: “ERROR: dependencies ‘getPass’, ‘dm’ are not available”
Breaking Changes
Taxonomic matching app: Stricter default similarity threshold
Default min_similarity increased from 0.3 to 0.7 in launch_taxonomic_match_app()
Reduces false positive matches by requiring higher similarity scores
Previous behavior available by setting min_similarity = 0.3 explicitly
Action required : Users relying on low-quality fuzzy matches may need to adjust threshold or improve input data quality
Rationale: Quality over quantity - fewer but more reliable matches improve data integrity
CafriplotsR 1.5
New Features
Interactive validation with fuzzy matching for plot metadata import
validate_plot_metadata() now has interactive = TRUE and fix_on_fly = TRUE parameters (both default to TRUE)
Integrates with existing resolve_multiple_values() for on-the-fly fixing of lookup mismatches (Country, Method)
Returns enhanced structure with three data versions:
original_data: Unchanged user input
cleaned_data: Data with interactive fixes applied
changes_made: Complete audit trail of all corrections (column, row, original, corrected, method)
Eliminates tedious manual Excel editing - users interactively match mismatches (e.g., “Cameroun” → “CAMEROON”) with fuzzy suggestions
Pattern search (“G” option) available for large lookup tables
Non-breaking: Old code works but gets enhanced behavior automatically
Complete subplot features import system
Plot import now handles ALL subplot feature types, not just people features
New .extract_and_process_subplot_features() dynamically queries subplot_list() to identify all subplot features
Automatically separates into two categories:
People features (valuetype == "table_colnam"): Linked to table_colnam via .link_colnam()
Other features (numeric, character, etc.): Direct value insertion
No hardcoded feature lists - fully dynamic based on database schema
Identifies subplot features by excluding flat table columns (plot_name, ddlat, ddlon, elevation, etc.)
Both types inserted as subplot features in Step 6 of import workflow
Row-Level Security (RLS) safe plot import for non-admin users
Uses PostgreSQL INSERT ... RETURNING clause to retrieve plot IDs during insertion
Bypasses RLS SELECT restrictions that would prevent non-admin users from reading their own inserted plots
Enables subplot features to be linked even when user doesn’t have SELECT permission yet
More secure than alternative approaches (no exposure of other users’ plot IDs)
Critical fix: Previously, non-admin imports would fail at Step 6 (subplot features) with empty plot_id_data
Bug Fixes
Fixed Shiny apps crashing RStudio when browser is closed
Restored missing helper functions accidentally commented out
.rename_data() (R/helpers.R:307) - Renames columns in datasets
.add_modif_field() (R/helpers.R:283) - Adds modification date fields (date_modif_d/m/y)
Both functions now properly exported and available
Fixes errors: “impossible de trouver la fonction .rename_data” and “.add_modif_field”
Fixed transaction connection management throughout import workflow
try_open_postgres_table() now properly handles errors and maintains connection scope
.link_table() now uses passed db_connection parameter instead of creating new connection
.link_colnam() now uses passed db_connection parameter instead of creating new connection
add_subplot_features() added con parameter to accept transaction connection
All functions now respect transaction boundaries (no more “Invalid connection” errors)
Prevents connection invalidation during multi-step import process
Fixed invalid cli package parameter
Removed unsupported line = 2 parameter from cli::cli_rule() calls in import success messages
Fixes error: “argument inutilisé (line = 2)”
Code Refactoring
Renamed and expanded subplot features processing
.extract_and_link_people() → .extract_and_process_subplot_features()
Function now handles all subplot feature types, not just people features
Enhanced documentation reflects expanded scope and hierarchical processing logic
Breaking Changes
query_plots() now returns a list by default instead of a flat data frame
Output is automatically structured based on inventory method using the new output styles system
Different styles organize data into separate tables: metadata, individuals, censuses, height-diameter, etc.
Action required : To preserve old behavior (flat data frame), use output_style = "full"
Rationale: Structured output makes it easier to work with complex plot data without overwhelming column counts
See documentation for ?query_plots for details on available output styles
New Features
Census selection strategy for multi-census plots
New census_strategy parameter in query_plots() with three options:
"last" (default): Extract data from most recent census only
"first": Extract data from earliest census only
"mean": Average across all censuses (previous default behavior)
When using “first” or “last” strategy:
Individuals recruited after first census show NA values (biologically correct)
Individuals dead before last census show NA values (biologically correct)
Single census_date column shows the date of the selected census (instead of date_census_1, date_census_2, etc.)
Census selection based on actual census dates using proper date computation
Applies to individual-level features (stem diameter, tree height, etc.)
When show_multiple_census = TRUE, all census data shown regardless of strategy
Configurable output styles system for query_plots()
6 predefined output styles: minimal, standard, permanent_plot, permanent_plot_multi_census, transect, full
Auto-detection of appropriate style based on method field (e.g., “1 ha plot” → permanent_plot)
Manual style selection via output_style parameter
Each style returns a structured list with relevant tables (e.g., $metadata, $individuals, $censuses)
Column renaming from database names to user-friendly names (e.g., ddlat → latitude, tax_sp_level → species)
New configuration files: R/output_styles_config.R, R/output_styles_helpers.R
Specialized output tables for permanent plots
$censuses table: plot_name, census_number, census_date, team_leader, principal_investigator
$height_diameter table: Paired height-diameter measurements (id_n, D, H, POM) with issue filtering
Handles multiple censuses with automatic pivoting from wide to long format
Census-specific column renaming (e.g., stem_diameter_census_1 → dbh_census_1)
Custom print method for query results
New S3 class plot_query_list with informative print method
Shows table dimensions, column names, and geometry type for sf objects
Makes it easy to understand query result structure
Preservation of spatial data
coordinates_sf table automatically included when show_all_coordinates = TRUE
Print method detects and displays sf geometry information
Code Refactoring
Modular output style configuration
Centralized style definitions in .plot_output_styles list
Method-to-style mapping in .method_to_style_map
Style auto-detection function .detect_style_from_method()
Easy to add new output styles by extending configuration
Improved metadata extraction
Uses res_meta_data table (created before individual extraction) for metadata source
Ensures all plot-level columns available even when extract_individuals = TRUE
Consistent variable naming and error handling
Bug Fixes
Fixed Shiny apps crashing RStudio when browser is closed
Fixed commented @export tag causing roxygen2 errors
Removed @export from commented-out subplot_list() function in R/subsplots_features_function.R
Prevents documentation build failures
CafriplotsR 1.4 (development version)
New Features
Traits enrichment module in taxonomic matching Shiny app
New tab “Enrich with Traits” allows enriching matched taxonomic names with trait data from the taxa database
Aggregates multiple input names that match to the same taxon into a single row
Concatenates all input names (e.g., “cola edulis | coula edrulis” → “Coula edulis”)
Configurable options for categorical trait aggregation (mode vs concatenation)
User can select which columns to include (original names, corrected names, IDs, metadata)
Downloads enriched data as Excel file
Filters out id_trait_measures columns for cleaner output
Module: mod_traits_enrichment_ui() and mod_traits_enrichment_server()
Enhanced file upload in taxonomic matching Shiny app
CSV file support added (in addition to Excel .xlsx and .xls)
Excel sheet selector allows choosing which sheet to import from multi-sheet workbooks
Sheet selector appears dynamically after Excel file upload
Default sheet selection is the first sheet
CSV files are loaded directly without sheet selection
Bug Fixes
Fixed Shiny apps crashing RStudio when browser is closed
Fixed NA input names appearing in trait enrichment
Enrichment module now filters out rows where the input taxonomic name is NA or empty
Prevents invalid NA entries from being matched to taxa or included in enriched output
Applied in both trait fetching and result aggregation steps
Fixed incorrect input names in enrichment output
Enrichment now correctly uses the user-selected taxonomic name column (not first column of dataset)
column_name parameter now passed from main app to enrichment module
Ensures input_names column shows actual taxonomic names from the selected column
Code Refactoring
Optimized taxonomic name cleaning for faster matching
Name cleaning (removing “sp.”, “cf.”, “aff.”, etc.) now happens before batch exact matching
Previously, cleaning only occurred during slow fuzzy matching phase
Names like “Coula edulis sp.” now match exactly to “Coula edulis” in fast batch step
Significantly reduces number of names sent to slower fuzzy matching
Cleaning happens once at beginning, benefiting all matching steps (species, genus, family)
Both original and cleaned names preserved in matching pipeline
Added underscore replacement in clean_taxonomic_name() (e.g., “Coula_edulis” → “Coula edulis”)
Breaking Changes
query_taxa() default behavior changed : exact_match parameter now defaults to TRUE (was FALSE)
Exact matching is now the default for family/genus/order queries to prevent unexpected fuzzy matching results
For species queries, if exact match fails, the function automatically falls back to intelligent fuzzy matching
Action required : Code relying on fuzzy matching by default should explicitly set exact_match = FALSE
Rationale: Higher taxonomic ranks are standardized names where fuzzy matching rarely helps and can introduce errors
New Features
Intelligent taxonomic name matching with genus-constrained fuzzy search
Auto fuzzy fallback for species queries
query_taxa() automatically retries with fuzzy matching when exact species match fails
Transparent user feedback shows match quality (similarity score)
Handles typos and spelling variations automatically
Only applies to species queries; family/genus/order use exact matching only
Database enhancement: tax_level field added to table_taxa
New column explicitly indicates taxonomic level: “species”, “genus”, “family”, “order”, “infraspecific”, “higher”
Indexed for query performance
Eliminates ambiguity between missing data and genus/family-level taxa
Script provided: add_tax_level_field.R for database migration
All query functions updated to use new field for cleaner, more reliable filtering
Code Refactoring
Complete rewrite of query_taxa() to use new intelligent matching functions
Eliminated redundancy with helpers.R functions
8 new modular helper functions replace complex inline logic
Cleaner separation of concerns: matching, filtering, synonym resolution, formatting, trait addition
~160 lines of code removed through better abstraction
Better maintainability and extensibility
Deprecated query_fuzzy_match() and query_exact_match() in favor of match_taxonomic_names()
Simplified taxonomic level filtering using tax_level field
Replaced complex multi-column checks (e.g., is.na(tax_esp) & is.na(tax_gen)) with simple tax_level == "family"
Applied in query_taxa() for clearer intent and better performance via index usage
Bug Fixes
Fixed Shiny apps crashing RStudio when browser is closed
Fixed query_taxa() empty results with only_family = TRUE
Previously, fuzzy matching by default caused empty results when filtering for family-level taxa
Now uses exact matching by default for higher taxonomic ranks
Dependencies
Added new package dependencies to DESCRIPTION:
cli - User-friendly command line interfaces (moved from Suggests to Imports)
lifecycle - Manage function lifecycle (deprecation warnings)
data.table - High-performance data manipulation
glue - String interpolation for SQL queries
RecordLinkage - String similarity calculations
CafriplotsR 1.0
Breaking Changes
Database schema change : Renamed column ind_num_sous_plot to tag in data_individuals and followup_updates_individuals tables
All R package functions updated to use new column name
Action required : External scripts accessing ind_num_sous_plot must be updated to use tag
Updated files: R/functions_manip_db.R, R/individual_features_function.R, R/functions_divid_plot.R, R/generate_plot_summary.Rmd, structure.yml
Default parameter in approximate_isolated_xy() changed from tag = "ind_num_sous_plot" to tag = "tag"
New Features
Initial release of package structure with comprehensive database query functions
Enhanced update_ident_specimens() : Now shows summary of linked individuals before updating specimen identification
Displays which plots and how many individuals will inherit the new identification
Shows current taxonomic identification of linked individuals
Provides better context for informed decision-making before confirmation
New helper function .get_linked_individuals_summary() queries and summarizes impact
Bug Fixes
Fixed Shiny apps crashing RStudio when browser is closed
Connection error with complex home paths : Fixed create_db_config() function that failed when home directory path contained spaces or special characters (e.g., OneDrive paths like C:/Users/NOBUS CAPITAL/OneDrive/Documents/)
Added proper error handling with tryCatch() for file creation
Creates parent directories if they don’t exist
Falls back to in-memory configuration if file cannot be written
Users now get informative warnings instead of connection failures
Documentation
Added comprehensive README.md with package overview, quick start guide, and function reference
README includes prominent link to NEWS.md for tracking updates
Infrastructure
Added NEWS.md to track package changes and updates
Established git branching workflow for all code modifications
Code Refactoring
Major refactoring : Reorganized R/functions_manip_db.R (previously 10,528 lines) into modular, domain-specific files
Created R/growth_census_functions.R (556 lines) - Growth computation and census analysis functions
Created R/specimen_linking_functions.R (406 lines) - Herbarium specimen linking and querying functions
Created R/taxonomic_query_functions.R (944 lines) - Taxonomic query functions with synonym resolution
Created R/taxonomic_update_functions.R (838 lines) - Taxonomic data update and entry functions
Expanded R/connections_db.R with database query utilities (func_try_fetch, try_open_postgres_table)
Removed ~6,800 lines from R/functions_manip_db.R through extraction to specialized modules
All functions verified as moved (not duplicated) to new locations
Improved code maintainability and discoverability