| Title: | Behavioral Insight Design: A Toolkit for Integrating Behavioral Science in UI/UX Design |
| Version: | 0.4.0 |
| Description: | Provides a framework and toolkit to guide R dashboard developers in implementing the Behavioral Insight Design (BID) framework. The package offers functions for documenting each of the five stages (Interpret, Notice, Anticipate, Structure, and Validate), along with a comprehensive concept dictionary. Works with both 'shiny' applications and 'Quarto' dashboards. |
| License: | MIT + file LICENSE |
| Encoding: | UTF-8 |
| Depends: | R (≥ 4.1.0) |
| RoxygenNote: | 7.3.3 |
| Imports: | cli, DBI, dplyr, glue, janitor, jsonlite, memoise, readr (≥ 2.1.5), rlang, RSQLite, stats, stringdist (≥ 0.9.15), tibble (≥ 3.2.1), tools, utils |
| Suggests: | DiagrammeR, knitr, otel, otelsdk, rmarkdown, spelling, testthat (≥ 3.0.0), withr |
| VignetteBuilder: | knitr |
| Config/testthat/edition: | 3 |
| Language: | en-US |
| URL: | https://jrwinget.github.io/bidux/ |
| BugReports: | https://github.com/jrwinget/bidux/issues |
| NeedsCompilation: | no |
| Packaged: | 2026-02-27 21:39:12 UTC; user |
| Author: | Jeremy Winget |
| Maintainer: | Jeremy Winget <contact@jrwinget.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-02-27 22:02:06 UTC |
bidux: Behavioral Insight Design: A Toolkit for Integrating Behavioral Science in UI/UX Design
Description
Provides a framework and toolkit to guide R dashboard developers in implementing the Behavioral Insight Design (BID) framework. The package offers functions for documenting each of the five stages (Interpret, Notice, Anticipate, Structure, and Validate), along with a comprehensive concept dictionary. Works with both 'shiny' applications and 'Quarto' dashboards.
Author(s)
Maintainer: Jeremy Winget contact@jrwinget.com (ORCID)
See Also
Useful links:
Calculate severity metrics for an issue
Description
Calculate severity metrics for an issue
Usage
.calculate_severity_metrics(issue_key, notice, events, total_sessions)
Arguments
issue_key |
String identifier for the issue |
notice |
Bid_stage notice object containing problem description |
events |
Raw events data frame |
total_sessions |
Total number of sessions |
Value
List with severity, affected_sessions, and impact_rate
Classify issue type from issue key
Description
Classify issue type from issue key
Usage
.classify_issue_type(issue_key)
Arguments
issue_key |
String identifier for the issue |
Value
Classified issue type
Create tidy issues tibble from notice issues list
Description
Create tidy issues tibble from notice issues list
Usage
.create_issues_tibble(notice_issues, total_sessions, events)
Arguments
notice_issues |
List of bid_stage objects from telemetry analysis |
total_sessions |
Total number of sessions analyzed |
events |
Raw events data frame |
Value
Tibble with structured issue metadata
Extract global telemetry flags from issues and events
Description
Extract global telemetry flags from issues and events
Usage
.flags_from_issues(issues_tbl, events, thresholds)
Arguments
issues_tbl |
Tidy issues tibble |
events |
Raw events data frame |
thresholds |
Threshold parameters used in analysis |
Value
Named list of boolean flags
Suggest theory from text with confidence scoring and messaging
Description
Internal helper that wraps suggest_theory_from_mappings with additional confidence scoring and user messaging. Factored out for reuse across different BID functions.
Usage
.suggest_theory_from_text(
problem_text,
evidence_text = NULL,
mappings = NULL,
show_message = TRUE
)
Arguments
problem_text |
Clean problem description text |
evidence_text |
Clean evidence description text |
mappings |
Optional custom theory mappings |
show_message |
Whether to display auto-suggestion message (default TRUE) |
Value
List with theory, confidence, and auto_suggested flag
Apply context-based scoring adjustments
Description
Apply context-based scoring adjustments
Usage
adjust_suggestion_score(suggestion, previous_stage, concept)
Apply suggestion rules to context data
Description
Evaluates suggestion rules against provided context data and returns applicable suggestions. Used by generate_stage_suggestions() for consistent suggestion generation.
Usage
apply_suggestion_rules(stage_name, context_data, rules_list = NULL)
Arguments
stage_name |
Name of the BID stage |
context_data |
Named list with stage-specific context |
rules_list |
Optional custom rules list (defaults to consolidated rules) |
Value
Character vector of applicable suggestions
Convert bid_issues object to tibble
Description
Extracts the tidy issues tibble from a bid_issues object for analysis and visualization. This provides a structured view of all telemetry issues with metadata for prioritization and reporting.
Usage
## S3 method for class 'bid_issues'
as_tibble(x, ...)
Arguments
x |
A bid_issues object from bid_ingest_telemetry() |
... |
Additional arguments (unused) |
Value
A tibble with issue metadata including severity, impact, and descriptions
Convert bid_stage to tibble
Description
Convert bid_stage to tibble
Usage
## S3 method for class 'bid_stage'
as_tibble(x, ...)
Arguments
x |
A bid_stage object |
... |
Additional arguments (unused) |
Value
A tibble
Assign category based on suggestion content and concept
Description
Categorizes suggestions into high-level groupings based on their focus area.
Usage
assign_category(suggestion, concept)
Arguments
suggestion |
Suggestion object with title and details |
concept |
The behavioral science concept this suggestion relates to |
Value
Character string representing the category
Assign difficulty rating based on components and suggestion complexity
Description
Analyzes suggestion details and component count to assign a difficulty rating. Considers complexity patterns in the suggestion text and number of components.
Usage
assign_difficulty(suggestion)
Arguments
suggestion |
Suggestion object with title, details, and components |
Value
Character string: "Easy", "Medium", or "Hard"
Create Notice stage from single telemetry issue (sugar)
Description
Convenience function that combines issue selection and Notice creation in one step. Useful for quick workflows where you want to address a specific issue immediately.
Usage
bid_address(issue, previous_stage, ...)
Arguments
issue |
A single row from bid_telemetry() output |
previous_stage |
Previous BID stage (typically from bid_interpret) |
... |
Additional arguments passed to bid_notice_issue() |
Value
A bid_stage object in the Notice stage
Examples
## Not run:
issues <- bid_telemetry("data.sqlite")
interpret <- bid_interpret("How can we improve user experience?")
# Address the highest impact issue
top_issue <- issues[which.max(issues$impact_rate), ]
notice <- bid_address(top_issue, interpret)
## End(Not run)
Document User Behavior Anticipation Stage in BID Framework
Description
This function documents the anticipated user behavior by listing bias mitigation strategies related to anchoring, framing, confirmation bias, etc. It also supports adding interaction hints and visual feedback elements.
Usage
bid_anticipate(
previous_stage,
bias_mitigations = NULL,
include_accessibility = TRUE,
quiet = NULL,
...
)
Arguments
previous_stage |
A tibble or list output from an earlier BID stage function. |
bias_mitigations |
A named list of bias mitigation strategies. If NULL, the function will suggest bias mitigations based on information from previous stages. |
include_accessibility |
Logical indicating whether to include accessibility mitigations. Default is TRUE. |
quiet |
Logical indicating whether to suppress informational messages. If NULL, uses getOption("bidux.quiet", FALSE). |
... |
Additional parameters. If 'interaction_principles' is provided, it will be ignored with a warning. |
Value
A tibble containing the documented information for the "Anticipate" stage.
Examples
interpret_stage <- bid_interpret(
central_question = "How can we improve selection efficiency?",
data_story = new_data_story(
hook = "Too many options",
context = "Excessive choices",
tension = "User frustration",
resolution = "Simplify menu"
)
)
notice_stage <- bid_notice(
previous_stage = interpret_stage,
problem = "Issue with dropdown menus",
evidence = "User testing indicated delays"
)
structure_info <- bid_structure(previous_stage = notice_stage)
# Let the function suggest bias mitigations based on previous stages
bid_anticipate(previous_stage = structure_info)
# with accessibility included (default) and custom bias mitigations
anticipate_result <- bid_anticipate(
previous_stage = structure_info,
bias_mitigations = list(
anchoring = "Use context-aware references",
framing = "Toggle between positive and negative framing"
),
include_accessibility = TRUE
)
summary(anticipate_result)
Get detailed information about a specific concept
Description
Returns detailed information about a specific BID framework concept, including implementation recommendations based on the concept's stage.
Usage
bid_concept(concept_name, add_recommendations = TRUE)
Arguments
concept_name |
A character string with the exact or partial concept name |
add_recommendations |
Logical indicating whether to add stage-specific recommendations |
Value
A tibble with detailed concept information
Search BID Framework Concepts
Description
Search for behavioral science and UX concepts used in the BID framework. Returns concepts matching the search term along with their descriptions, categories, and implementation guidance.
Usage
bid_concepts(search = NULL, fuzzy_match = TRUE, max_distance = 2)
Arguments
search |
A character string to search for. If NULL or empty, returns all concepts. |
fuzzy_match |
Logical indicating whether to use fuzzy string matching (default: TRUE) |
max_distance |
Maximum string distance for fuzzy matching (default: 2) |
Value
A tibble containing matching concepts with their details
Extract telemetry flags from bid_issues object
Description
Extracts global telemetry flags and metadata from a bid_issues object. These flags provide boolean indicators for different types of issues and can be used for conditional logic in downstream BID stages.
Usage
bid_flags(x)
## S3 method for class 'bid_issues'
bid_flags(x)
## Default S3 method:
bid_flags(x)
Arguments
x |
A bid_issues object from bid_ingest_telemetry() or any object with a flags attribute |
Value
A named list of boolean flags and metadata
Get current quiet mode setting
Description
Check whether bidux is currently in quiet mode.
Usage
bid_get_quiet()
Value
Logical indicating whether quiet mode is enabled
Examples
# Check current quiet setting
bid_get_quiet()
Ingest telemetry data and identify UX friction points
Description
This function ingests telemetry data from multiple sources and automatically identifies potential UX issues, translating them into BID framework Notice stages. It returns a hybrid object that is backward-compatible as a list of Notice stages while also providing enhanced functionality with tidy tibble access and flags extraction.
Supported telemetry sources:
shiny.telemetry (SQLite or JSON)
Shiny native OpenTelemetry (Shiny >= 1.12.0, OTLP JSON or SQLite)
DBI database connections
Format is automatically detected based on file structure and content.
OpenTelemetry Support: For Shiny >= 1.12.0 applications using native
OpenTelemetry, pass the path to OTLP JSON exports or OTEL-formatted
SQLite databases. Spans are automatically converted to events for analysis.
See vignette("otel-integration") for complete setup guide.
Note: For Quarto dashboards, shiny.telemetry only works when using
server: shiny in the Quarto YAML. Static Quarto dashboards and OJS-based
dashboards do not support shiny.telemetry. Consider alternative analytics
solutions (e.g., Plausible) for static dashboard usage tracking.
Usage
bid_ingest_telemetry(
source,
format = NULL,
events_table = NULL,
table_name = NULL,
thresholds = list()
)
Arguments
source |
Either a file path to telemetry data or a DBI connection object. Supports:
|
format |
Optional format specification ("sqlite", "json", "otlp_json", "otel_sqlite"). If NULL (default), auto-detected from file extension and structure. OTLP formats are automatically detected when file contains OpenTelemetry span data. |
events_table |
Optional data.frame specifying custom events table when
reading from SQLite. Must have columns: event_id, timestamp,
event_type, user_id. If NULL, auto-detects standard table names
(event_data, events). Cannot be used with |
table_name |
Optional character string specifying the table name to read
from the database. If NULL (default), auto-detects standard table names
(event_data, events). Cannot be used with |
thresholds |
Optional list of threshold parameters: - unused_input_threshold: percentage of sessions below which input is considered unused (default: 0.05) - delay_threshold_secs: seconds of delay considered problematic (default: 30) - error_rate_threshold: percentage of sessions with errors considered problematic (default: 0.1) - navigation_threshold: percentage of sessions visiting a page below which it's considered underused (default: 0.2) - rapid_change_window: seconds within which multiple changes indicate confusion (default: 10) - rapid_change_count: number of changes within window to flag as confusion (default: 5) |
Value
A hybrid object of class c("bid_issues", "list") containing bid_stage objects for each identified issue in the "Notice" stage. The object includes:
Legacy list |
Named list of bid_stage objects (e.g., "unused_input_region", "delayed_interaction") |
issues_tbl |
Attached tidy tibble with issue metadata |
flags |
Global telemetry flags as named list |
created_at |
Timestamp when object was created |
Use as_tibble() to access the tidy issues data, bid_flags() to extract flags,
and legacy list access for backward compatibility.
Examples
## Not run:
# Works with shiny.telemetry SQLite
issues <- bid_ingest_telemetry("telemetry.sqlite")
# Works with Shiny OpenTelemetry (1.12+)
issues <- bid_ingest_telemetry("otel_spans.json")
# Use sensitivity presets for easier configuration
strict_issues <- bid_ingest_telemetry(
"telemetry.sqlite",
thresholds = bid_telemetry_presets("strict")
)
# Analyze JSON log with custom thresholds
issues <- bid_ingest_telemetry(
"telemetry.log",
format = "json",
thresholds = list(
unused_input_threshold = 0.1,
delay_threshold_secs = 60
)
)
# Use a DBI connection object directly
con <- DBI::dbConnect(RSQLite::SQLite(), "telemetry.sqlite")
issues <- bid_ingest_telemetry(con)
# Connection remains open for further use
DBI::dbDisconnect(con)
# Specify custom table name
issues <- bid_ingest_telemetry(
"telemetry.sqlite",
table_name = "my_custom_events"
)
# Same analysis workflow for both shiny.telemetry and OTEL
if (length(issues) > 0) {
# Take first issue and continue with BID process
interpret_result <- bid_interpret(
previous_stage = issues[[1]],
central_question = "How can we improve user engagement?"
)
}
## End(Not run)
Document User Interpretation Stage in BID Framework
Description
This function documents the interpretation of user needs, capturing the central question and the data storytelling narrative. It represents stage 1 in the BID framework.
Usage
bid_interpret(
previous_stage = NULL,
central_question,
data_story = NULL,
user_personas = NULL,
quiet = NULL
)
Arguments
previous_stage |
Optional tibble or list output from an earlier BID stage function. Since Interpret is the first stage in the BID framework, this is typically NULL but can accept previous stage output in some iteration scenarios. |
central_question |
Required. A character string representing the main question to be answered. If NULL, will be suggested based on previous stage information. |
data_story |
A list containing elements such as |
user_personas |
Optional list of user personas to consider in the design. |
quiet |
Logical indicating whether to suppress informational messages. If NULL, uses getOption("bidux.quiet", FALSE). |
Value
A tibble containing the documented information for the "Interpret" stage.
Examples
# Recommended: use new_data_story() with flat API
interpret_result <- bid_interpret(
central_question = "What drives the decline in user engagement?",
data_story = new_data_story(
hook = "Declining trend in engagement",
context = "Previous high engagement levels",
tension = "Unexpected drop",
resolution = "Investigate new UI changes"
)
)
# With user personas (using data.frame)
interpret_personas <- bid_interpret(
central_question = "How can we improve data discovery?",
data_story = new_data_story(
hook = "Users are missing key insights",
context = "Critical data is available but overlooked",
tension = "Time-sensitive decisions are delayed",
resolution = "Highlight key metrics more effectively",
audience = "Data analysts and executives"
),
user_personas = data.frame(
name = c("Sara, Data Analyst", "Marcus, Executive"),
goals = c(
"Needs to quickly find patterns in data",
"Wants high-level insights at a glance"
),
pain_points = c(
"Gets overwhelmed by too many visualizations",
"Limited time to analyze detailed reports"
),
technical_level = c("advanced", "beginner"),
stringsAsFactors = FALSE
)
)
summary(interpret_personas)
Document User Notice Stage in BID Framework
Description
This function documents the observation and problem identification stage. It represents stage 2 in the BID framework and now returns a structured bid_stage object with enhanced metadata and external mapping support.
Usage
bid_notice(
previous_stage,
problem,
theory = NULL,
evidence = NULL,
quiet = NULL,
...
)
Arguments
previous_stage |
A tibble or list output from the previous BID stage function (typically bid_interpret). |
problem |
A character string describing the observed user problem. |
theory |
A character string describing the behavioral theory that might explain the problem. If NULL, will be auto-suggested using external theory mappings. |
evidence |
A character string describing evidence supporting the problem. |
quiet |
Logical indicating whether to suppress informational messages. If NULL, uses getOption("bidux.quiet", FALSE). |
... |
Additional parameters. Deprecated parameters (e.g., 'target_audience') will generate warnings if provided. |
Value
A bid_stage object containing the documented information for the "Notice" stage with enhanced metadata and validation.
Examples
interpret_result <- bid_interpret(
central_question = "How can we improve user task completion?",
data_story = new_data_story(
hook = "Users are struggling with complex interfaces",
context = "Complex interfaces reducing completion",
resolution = "Simplify key interactions"
)
)
# Auto-suggested theory
bid_notice(
previous_stage = interpret_result,
problem = "Users struggling with complex dropdowns and too many options",
evidence = "User testing shows 65% abandonment rate on filter selection"
)
# With explicit theory
notice_result <- bid_notice(
previous_stage = interpret_result,
problem = "Mobile interface is difficult to navigate",
theory = "Fitts's Law",
evidence = "Mobile users report frustration with small touch targets"
)
summary(notice_result)
Create Notice stage from individual telemetry issue
Description
Bridge function that converts a single telemetry issue row into a BID Notice stage. This allows seamless integration between telemetry analysis and the BID framework.
Usage
bid_notice_issue(issue, previous_stage = NULL, override = list())
Arguments
issue |
A single row from bid_telemetry() output or issues tibble |
previous_stage |
Optional previous BID stage (typically from bid_interpret) |
override |
List of values to override from the issue (problem, evidence, theory) |
Value
A bid_stage object in the Notice stage
Examples
## Not run:
issues <- bid_telemetry("data.sqlite")
interpret <- bid_interpret("How can we reduce user friction?")
# Convert first issue to Notice stage
notice <- bid_notice_issue(issues[1, ], previous_stage = interpret)
# Override problem description
notice <- bid_notice_issue(
issues[1, ],
previous_stage = interpret,
override = list(problem = "Custom problem description")
)
## End(Not run)
Create multiple Notice stages from telemetry issues
Description
Bridge function that converts multiple telemetry issues into Notice stages. Provides filtering and limiting options for managing large issue sets.
Usage
bid_notices(issues, filter = NULL, previous_stage = NULL, max_issues = 5, ...)
Arguments
issues |
A tibble from bid_telemetry() output |
filter |
Optional filter expression for subsetting issues (e.g., severity == "critical") |
previous_stage |
Optional previous BID stage (typically from bid_interpret) |
max_issues |
Maximum number of issues to convert (default: 5) |
... |
Additional arguments passed to bid_notice_issue() |
Value
A named list of bid_stage objects in the Notice stage
Examples
## Not run:
issues <- bid_telemetry("data.sqlite")
interpret <- bid_interpret("How can we reduce user friction?")
# Convert all critical issues
notices <- bid_notices(issues, filter = severity == "critical", interpret)
# Convert top 3 issues by impact
top_issues <- issues[order(-issues$impact_rate), ][1:3, ]
notices <- bid_notices(top_issues, previous_stage = interpret)
## End(Not run)
Create pipeline of Notice stages from top telemetry issues (sugar)
Description
Convenience function that creates a pipeline of Notice stages from the highest priority telemetry issues. Useful for systematic issue resolution workflows.
Usage
bid_pipeline(issues, previous_stage, max = 3, ...)
Arguments
issues |
A tibble from bid_telemetry() output |
previous_stage |
Previous BID stage (typically from bid_interpret) |
max |
Maximum number of issues to include in pipeline (default: 3) |
... |
Additional arguments passed to bid_notices() |
Value
A named list of bid_stage objects in the Notice stage
Examples
## Not run:
issues <- bid_telemetry("data.sqlite")
interpret <- bid_interpret("How can we systematically improve UX?")
# Create pipeline for top 3 issues
notice_pipeline <- bid_pipeline(issues, interpret, max = 3)
# Continue with first issue in pipeline
anticipate <- bid_anticipate(previous_stage = notice_pipeline[[1]])
## End(Not run)
Quick UX Suggestions for R Dashboard Developers
Description
Provides a streamlined, single-step workflow for R dashboard developers who need quick UX suggestions without going through the full 5-stage BID framework. This function internally leverages the BID framework stages but presents results in a simple, actionable format. Works with both Shiny applications and Quarto dashboards.
Unlike the full BID workflow (Interpret -> Notice -> Anticipate -> Structure -> Validate), this function provides immediate suggestions based on a problem description. Use this for rapid prototyping or when you need quick guidance. For comprehensive UX redesign projects, use the full BID workflow.
Usage
bid_quick_suggest(
problem,
context = NULL,
package = NULL,
limit = 10,
min_score = 0.7,
quiet = NULL
)
Arguments
problem |
Required. A character string describing the UX problem. Examples: "Users can't find the download button", "Information overload on dashboard", "Mobile interface is hard to navigate". |
context |
Optional. Additional context about the application or users. This helps refine suggestions to your specific situation. |
package |
Optional. Filter suggestions to specific package ("bslib", "shiny", "reactable", "DT", "plotly", "leaflet", etc.). If NULL, returns suggestions for all relevant packages. Note: bslib, plotly, DT, reactable, and leaflet components work in both Shiny apps and Quarto dashboards. |
limit |
Optional. Maximum number of suggestions to return (default: 10). Set to Inf to return all suggestions. |
min_score |
Optional. Minimum relevance score 0-1 (default: 0.7). Higher values return only the most relevant suggestions. |
quiet |
Optional. Logical indicating whether to suppress informational messages. If NULL, uses getOption("bidux.quiet", FALSE). |
Details
How it works:
The function analyzes your problem description using keyword matching and semantic analysis to:
Identify relevant UX concepts (cognitive load, navigation, visual hierarchy, etc.)
Detect appropriate layout patterns (grid, card, breathable, etc.)
Generate ranked suggestions with specific component recommendations
Filter and sort by relevance score
Problem Analysis Keywords:
"overload", "overwhelm", "too many" -> Cognitive Load Theory
"find", "search", "navigate" -> Information Scent
"cluttered", "messy", "disorganized" -> Visual Hierarchy
"mobile", "touch", "responsive" -> Fitts's Law
"confusing", "unclear", "complex" -> Progressive Disclosure
When to use this vs full BID workflow:
Use
bid_quick_suggest(): Quick fixes, prototyping, single issuesUse full workflow: Comprehensive redesigns, complex projects, team collaboration
Quarto Dashboard Compatibility:
Component suggestions include both Shiny-specific (shiny::) and framework-agnostic
components. For static Quarto dashboards or OJS-based interactivity, focus on
bslib, DT, plotly, reactable, and leaflet suggestions. Shiny-prefixed components
require server: shiny in Quarto dashboards or a traditional Shiny app.
Value
A tibble with columns:
title |
Brief actionable description of the suggestion |
details |
Specific implementation guidance |
components |
R dashboard component recommendations (character vector). Components prefixed with 'shiny::' require Shiny runtime; bslib, DT, plotly, reactable, and leaflet components work in both Shiny and Quarto dashboards. |
concept |
UX concept the suggestion is based on |
score |
Relevance score (0-1, higher is more relevant) |
difficulty |
Implementation difficulty (easy/moderate/advanced) |
rationale |
1-2 sentence explanation of why this helps |
Examples
# Basic usage
suggestions <- bid_quick_suggest(
problem = "Users can't find the download button"
)
print(suggestions)
# With additional context
suggestions <- bid_quick_suggest(
problem = "Dashboard has too many charts and metrics",
context = "Financial analysts need quick insights but get overwhelmed",
limit = 5
)
# Filter to specific package
bslib_suggestions <- bid_quick_suggest(
problem = "Mobile interface is hard to use",
package = "bslib",
min_score = 0.8
)
# Navigation issues
nav_suggestions <- bid_quick_suggest(
problem = "Users get lost in multi-tab interface",
context = "Application has 10+ tabs with nested content"
)
# Information overload
overload_suggestions <- bid_quick_suggest(
problem = "Too many filters and options on the sidebar",
context = "Beginners find the interface overwhelming"
)
Generate BID Framework Report
Description
Creates a comprehensive report from a completed BID framework process. This
report summarizes all stages and provides recommendations for implementation.
Reports include component suggestions that work with both Shiny applications
and Quarto dashboards (shiny-prefixed components (i.e., shiny::) require
Shiny runtime).
Usage
bid_report(
validate_stage,
format = c("text", "html", "markdown"),
include_diagrams = TRUE
)
Arguments
validate_stage |
A tibble output from |
format |
Output format: "text", "html", or "markdown" |
include_diagrams |
Logical, whether to include ASCII diagrams in the report (default: TRUE) |
Value
A formatted report summarizing the entire BID process
Examples
if (interactive()) {
# After completing all 5 stages
validation_result <- bid_validate(...)
# Generate a text report
bid_report(validation_result)
# Generate an HTML report
bid_report(validation_result, format = "html")
# Generate a markdown report without diagrams
bid_report(
validation_result,
format = "markdown",
include_diagrams = FALSE
)
}
Constructor for BID result collection objects
Description
Constructor for BID result collection objects
Usage
bid_result(stages)
Arguments
stages |
List of bid_stage objects |
Value
Object of class 'bid_result'
Set global quiet mode for bidux functions
Description
Convenience function to set the global quiet option for all bidux functions. When quiet mode is enabled, most informational messages are suppressed.
Usage
bid_set_quiet(quiet = TRUE)
Arguments
quiet |
Logical indicating whether to enable quiet mode. When TRUE, most bidux messages are suppressed. |
Value
The previous value of the quiet option (invisibly)
Examples
# Enable quiet mode
bid_set_quiet(TRUE)
# Disable quiet mode
bid_set_quiet(FALSE)
Constructor for BID stage objects
Description
Constructor for BID stage objects
Usage
bid_stage(stage, data, metadata = list())
Arguments
stage |
Character string indicating the stage name |
data |
Tibble containing the stage data |
metadata |
List containing additional metadata |
Value
Object of class 'bid_stage'
Document Dashboard Structure Stage in BID Framework
Description
This function documents the structure of the dashboard and generates ranked, concept-grouped actionable UI/UX suggestions. Returns structured recommendations with specific component pointers and implementation rationales.
Usage
bid_structure(
previous_stage,
concepts = NULL,
telemetry_flags = NULL,
quiet = NULL,
...
)
Arguments
previous_stage |
A tibble or list output from an earlier BID stage function. |
concepts |
A character vector of additional BID concepts to include. Concepts can be provided in natural language (e.g., "Principle of Proximity") or with underscores (e.g., "principle_of_proximity"). The function uses fuzzy matching to identify the concepts. If NULL, will detect relevant concepts from previous stages automatically. |
telemetry_flags |
Optional named list of telemetry flags from bid_flags(). Used to adjust suggestion scoring based on observed user behavior patterns. |
quiet |
Logical indicating whether to suppress informational messages. If NULL, uses getOption("bidux.quiet", FALSE). |
... |
Additional parameters (reserved for future use). |
Details
Suggestion Engine: Generates ranked, actionable recommendations grouped
by UX concepts. Each suggestion includes specific R dashboard components
(Shiny, bslib, DT, plotly, etc.), implementation details, and rationale.
Suggestions are scored based on relevance and contextual factors. Component
suggestions work with both Shiny applications and Quarto dashboards, with
shiny-prefixed components (i.e., shiny::) requiring Shiny runtime.
Value
A bid_stage object containing:
stage |
"Structure" |
suggestions |
List of concept groups with ranked suggestions (nested format) |
suggestions_tbl |
Flattened tibble with all suggestions, includes columns: concept, title, details, components, rationale, score, difficulty, category |
concepts |
Comma-separated string of all concepts used |
Examples
notice_result <- bid_interpret(
central_question = "How can we simplify data presentation?",
data_story = new_data_story(
hook = "Data is too complex",
context = "Overloaded with charts",
tension = "Confusing layout",
resolution = "Introduce clear grouping"
)
) |>
bid_notice(
problem = "Users struggle with information overload",
evidence = "Survey results indicate delays"
)
# Generate concept-grouped suggestions
structure_result <- bid_structure(previous_stage = notice_result)
print(structure_result$suggestions) # Ranked suggestions by concept (nested)
# Access flattened tibble format for easier manipulation
suggestions_flat <- structure_result$suggestions_tbl[[1]]
print(suggestions_flat)
# Filter by difficulty
easy_suggestions <- suggestions_flat[suggestions_flat$difficulty == "Easy", ]
# Filter by category
layout_suggestions <- suggestions_flat[suggestions_flat$category == "Layout", ]
summary(structure_result)
Suggest alternative analytics solutions for static dashboards
Description
Provides recommendations for analytics and telemetry solutions suitable for static Quarto dashboards, where Shiny-based telemetry (shiny.telemetry or OpenTelemetry) is not available. This function helps you choose the right analytics tool based on your needs and constraints.
Important: shiny.telemetry and Shiny OpenTelemetry only work with
server: shiny in Quarto YAML. For static Quarto dashboards (including
OJS-based dashboards), you need alternative web analytics solutions.
Usage
bid_suggest_analytics(
dashboard_type = c("static", "ojs", "python"),
privacy_preference = c("gdpr_compliant", "privacy_focused", "standard"),
budget = c("flexible", "free", "low"),
self_hosted = FALSE
)
Arguments
dashboard_type |
Character string specifying the type of dashboard:
|
privacy_preference |
Character string indicating privacy requirements:
|
budget |
Character string indicating budget constraints:
|
self_hosted |
Logical indicating whether self-hosted solutions are preferred (default: FALSE) |
Value
A data frame with recommended analytics solutions, including:
solution |
Name of the analytics platform |
type |
Type of solution (privacy-focused, traditional, open-source) |
cost |
Cost tier (free, paid, freemium) |
self_hosted |
Whether self-hosting is available |
gdpr_compliant |
Whether the solution is GDPR compliant |
integration_method |
How to integrate (script tag, API, etc.) |
key_features |
Main features for UX analysis |
bidux_compatibility |
How well it works with BID framework |
docs_url |
Link to integration documentation |
Integration Patterns
For Static Quarto Dashboards:
-
Event Tracking - Track user interactions with custom events:
Button clicks, filter changes, tab switches
Use JavaScript event listeners in Quarto
Send events to analytics platform via API
-
Session Analysis - Monitor user sessions:
Page views, time on page, bounce rate
User flow through dashboard sections
Identify drop-off points
-
Custom Dimensions - Track dashboard-specific metrics:
Selected filters, date ranges, visualization types
User cohorts, roles, or departments
Dashboard version or configuration
Example Integration (Plausible Analytics):
Add to your Quarto dashboard header:
<script defer data-domain="yourdomain.com" src="https://plausible.io/js/script.tagged-events.js"></script>
Track custom events in your dashboard JavaScript:
// Track filter change
document.getElementById('regionFilter').addEventListener('change', function(e) {
plausible('Filter Changed', {props: {filter: 'region', value: e.target.value}});
});
// Track visualization interaction
plotElement.on('plotly_click', function(data) {
plausible('Chart Interaction', {props: {chart: 'sales_plot', action: 'click'}});
});
Analyzing Results with BID Framework:
While these analytics tools won't automatically integrate with bid_ingest_telemetry(),
you can still apply BID framework principles:
-
Notice - Export analytics data, identify friction points manually
-
Interpret - Use
bid_interpret()with insights from analytics -
Anticipate - Apply
bid_anticipate()to plan improvements -
Structure - Design improvements with
bid_structure() -
Validate - Measure impact with before/after analytics comparison
Examples
# Get recommendations for static Quarto dashboard with GDPR compliance
suggestions <- bid_suggest_analytics(
dashboard_type = "static",
privacy_preference = "gdpr_compliant"
)
print(suggestions)
# Find free, privacy-focused solutions for OJS dashboard
privacy_options <- bid_suggest_analytics(
dashboard_type = "ojs",
privacy_preference = "privacy_focused",
budget = "free"
)
# Get self-hosted options
self_hosted <- bid_suggest_analytics(
dashboard_type = "static",
self_hosted = TRUE
)
# View top recommendation
top_choice <- suggestions[1, ]
cat(sprintf("Recommended: %s\n", top_choice$solution))
cat(sprintf("Integration: %s\n", top_choice$integration_method))
cat(sprintf("Docs: %s\n", top_choice$docs_url))
Suggest UI Components Based on BID Framework Analysis
Description
This function analyzes the results from BID framework stages and suggests appropriate UI components from popular R dashboard packages like shiny, bslib, DT, plotly, reactable, and htmlwidgets. The suggestions are based on the design principles and user needs identified in the BID process. Components work with both Shiny applications and Quarto dashboards (shiny-prefixed components require Shiny runtime).
Usage
bid_suggest_components(bid_stage, package = NULL)
Arguments
bid_stage |
A tibble output from any BID framework stage function |
package |
Optional character string specifying which package to focus suggestions on. Options include "shiny", "bslib", "DT", "plotly", "reactable", "htmlwidgets". If NULL, suggestions from all packages are provided. |
Value
A tibble containing component suggestions with relevance scores
Examples
if (interactive()) {
# After completing BID stages
notice_result <- bid_notice(
problem = "Users struggle with complex data",
theory = "Cognitive Load Theory"
)
# Get all component suggestions
bid_suggest_components(notice_result)
# Get only bslib suggestions
bid_suggest_components(notice_result, package = "bslib")
# Get shiny-specific suggestions
bid_suggest_components(notice_result, package = "shiny")
}
Concise telemetry analysis with tidy output
Description
Preferred modern interface for telemetry analysis. Returns a clean tibble of identified issues without the legacy list structure. Use this function for new workflows that don't need backward compatibility.
OpenTelemetry Support: For Shiny >= 1.12.0 applications using native
OpenTelemetry, pass the path to OTLP JSON exports or OTEL-formatted
SQLite databases. Format is auto-detected. See
vignette("otel-integration") for complete setup guide.
Usage
bid_telemetry(
source,
format = NULL,
events_table = NULL,
table_name = NULL,
thresholds = list()
)
Arguments
source |
Either a file path to telemetry data or a DBI connection object. Supports:
|
format |
Optional format specification ("sqlite", "json", "otlp_json", "otel_sqlite"). If NULL (default), auto-detected from file extension and structure. OTLP formats are automatically detected when file contains OpenTelemetry span data. |
events_table |
Optional data.frame specifying custom events table when
reading from SQLite. Must have columns: event_id, timestamp,
event_type, user_id. If NULL, auto-detects standard table names
(event_data, events). Cannot be used with |
table_name |
Optional character string specifying the table name to read
from the database. If NULL (default), auto-detects standard table names
(event_data, events). Cannot be used with |
thresholds |
Optional list of threshold parameters: - unused_input_threshold: percentage of sessions below which input is considered unused (default: 0.05) - delay_threshold_secs: seconds of delay considered problematic (default: 30) - error_rate_threshold: percentage of sessions with errors considered problematic (default: 0.1) - navigation_threshold: percentage of sessions visiting a page below which it's considered underused (default: 0.2) - rapid_change_window: seconds within which multiple changes indicate confusion (default: 10) - rapid_change_count: number of changes within window to flag as confusion (default: 5) |
Value
A tibble of class "bid_issues_tbl" with structured issue metadata
Examples
## Not run:
# Works with shiny.telemetry
issues <- bid_telemetry("telemetry.sqlite")
# Works with Shiny OpenTelemetry (1.12+)
issues <- bid_telemetry("otel_spans.json")
# Same analysis workflow for both
high_priority <- issues[issues$severity %in% c("critical", "high"), ]
# Use DBI connection directly
con <- DBI::dbConnect(RSQLite::SQLite(), "telemetry.sqlite")
issues <- bid_telemetry(con, table_name = "my_events")
DBI::dbDisconnect(con)
# Use with bridges for BID workflow
top_issue <- issues[1, ]
notice <- bid_notice_issue(top_issue, previous_stage = interpret_stage)
## End(Not run)
Get predefined telemetry sensitivity presets
Description
Returns predefined threshold configurations for telemetry analysis with different
sensitivity levels. Use these presets with bid_ingest_telemetry() or
bid_telemetry() to easily adjust how aggressively the analysis identifies
UX friction points.
OpenTelemetry Compatibility: These presets work with both shiny.telemetry event data and Shiny 1.12+ OpenTelemetry span data. When using OTEL data, spans are automatically converted to events for analysis.
Usage
bid_telemetry_presets(preset = c("moderate", "strict", "relaxed"))
Arguments
preset |
Character string specifying the sensitivity level:
|
Value
Named list of threshold parameters suitable for passing to
bid_ingest_telemetry() or bid_telemetry() thresholds parameter.
Examples
# Get strict sensitivity thresholds
strict_thresholds <- bid_telemetry_presets("strict")
# Use with telemetry analysis (works with both shiny.telemetry and OTEL)
## Not run:
# Works with shiny.telemetry
issues <- bid_telemetry(
"telemetry.sqlite",
thresholds = bid_telemetry_presets("strict")
)
# Works with Shiny OpenTelemetry (1.12+)
issues <- bid_telemetry(
"otel_spans.json",
thresholds = bid_telemetry_presets("strict")
)
## End(Not run)
# Compare different presets
moderate <- bid_telemetry_presets("moderate")
relaxed <- bid_telemetry_presets("relaxed")
Document User Validation Stage in BID Framework
Description
This function documents the validation stage, where the user tests and refines the dashboard. It represents stage 5 in the BID framework.
Usage
bid_validate(
previous_stage,
summary_panel = NULL,
collaboration = NULL,
next_steps = NULL,
include_exp_design = TRUE,
include_telemetry = TRUE,
telemetry_refs = NULL,
include_empower_tools = TRUE,
quiet = NULL
)
Arguments
previous_stage |
A tibble or list output from an earlier BID stage function. |
summary_panel |
A character string describing the final summary panel or key insight presentation. |
collaboration |
A character string describing how the dashboard enables collaboration and sharing. |
next_steps |
A character vector or string describing recommended next steps for implementation and iteration. |
include_exp_design |
Logical indicating whether to include experiment design suggestions. Default is TRUE. |
include_telemetry |
Logical indicating whether to include telemetry tracking and monitoring suggestions. Default is TRUE. |
telemetry_refs |
Optional character vector or named list specifying specific telemetry reference points to include in validation steps. If provided, these will be integrated into the telemetry tracking recommendations with provenance information. |
include_empower_tools |
Logical indicating whether to include context-aware empowerment tool suggestions. Default is TRUE. |
quiet |
Logical indicating whether to suppress informational messages. If NULL, uses getOption("bidux.quiet", FALSE). |
Value
A tibble containing the documented information for the "Validate" stage.
Examples
validate_result <- bid_interpret(
central_question = "How can we improve delivery efficiency?",
data_story = new_data_story(
hook = "Too many delays",
context = "Excessive shipments",
tension = "User frustration",
resolution = "Increase delivery channels"
)
) |>
bid_notice(
problem = "Issue with dropdown menus",
evidence = "User testing indicated delays"
) |>
bid_anticipate(
bias_mitigations = list(
anchoring = "Provide reference points",
framing = "Use gain-framed messaging"
)
) |>
bid_structure() |>
bid_validate(
include_exp_design = FALSE,
include_telemetry = TRUE,
include_empower_tools = TRUE
)
summary(validate_result)
Temporarily suppress bidux messages
Description
Execute code with bidux messages temporarily suppressed.
Usage
bid_with_quiet(code)
Arguments
code |
Code to execute with messages suppressed |
Value
The result of evaluating code
Examples
# Run analysis quietly without changing global setting
result <- bid_with_quiet({
bid_interpret(
central_question = "How can we improve user engagement?",
data_story = new_data_story(
hook = "Users are leaving",
context = "User engagement declining",
resolution = "Fix issues"
)
)
})
Build suggestions for a specific concept
Description
Build suggestions for a specific concept
Usage
build_concept_group(concept, previous_stage)
Arguments
concept |
Name of the concept to generate suggestions for |
previous_stage |
Previous stage data |
Value
List with concept name and suggestions
Build suggestion groups organized by concept
Description
Build suggestion groups organized by concept
Usage
build_groups_with_suggestions(concepts_final, previous_stage)
Arguments
concepts_final |
Final list of concepts to generate suggestions for |
previous_stage |
Previous stage data for context |
Value
List of concept groups with suggestions
Calculate span duration in milliseconds
Description
Computes the duration between span start and end times in milliseconds.
Usage
calculate_span_duration_ms(start_time, end_time)
Arguments
start_time |
POSIXct start timestamp |
end_time |
POSIXct end timestamp |
Value
Numeric duration in milliseconds, or NA if either time is missing
Examples
## Not run:
start <- as.POSIXct("2024-01-01 12:00:00", tz = "UTC")
end <- as.POSIXct("2024-01-01 12:00:01.5", tz = "UTC")
calculate_span_duration_ms(start, end) # returns 1500
## End(Not run)
Check JSON nesting depth recursively
Description
Validates that JSON data does not exceed a maximum nesting depth to prevent stack overflow and resource exhaustion attacks.
Usage
check_json_depth(obj, max_depth = 50, current_depth = 1)
Arguments
obj |
JSON object (list or other R object from |
max_depth |
Maximum allowed nesting depth (default: 50) |
current_depth |
Current recursion depth (internal use) |
Value
Logical TRUE if depth is acceptable, aborts with error if exceeded
Check if OpenTelemetry packages are available
Description
Internal function to check if the required OpenTelemetry packages (otel, otelsdk) are installed. Provides helpful error message if not available.
Usage
check_otel_available()
Value
NULL invisibly if packages are available, otherwise throws error
classify audience type from description text
Description
classify audience type from description text
Usage
classify_audience(audience_text)
Arguments
audience_text |
character string describing the audience |
Value
character string: one of "executive", "analyst", "marketing", "operations", "general"
Convert OTLP spans to bidux event schema
Description
Converts OpenTelemetry Protocol (OTLP) span data to the bidux telemetry event schema.
This enables transparent compatibility with existing friction detection algorithms.
This function is called automatically by bid_telemetry() and bid_ingest_telemetry()
when OTLP data is detected - you rarely need to call it directly.
Automatic Format Detection: When you pass OTLP JSON or SQLite to bid_telemetry(),
this conversion happens automatically. The same UX friction detection algorithms work
seamlessly on both shiny.telemetry events and OpenTelemetry spans.
Span to Event Mapping:
session_start -> login
output -> output
reactive, observe -> input
reactive_update -> synthetic timing events
Error span events -> error
Usage
convert_otel_spans_to_events(spans_df)
Arguments
spans_df |
Data frame of OTLP spans with columns:
|
Value
Tibble with bidux event schema columns:
timestamp: POSIXct event timestamp
session_id: character session identifier
event_type: character event type (login, input, output, error)
input_id: character input identifier (NA for non-input events)
value: character/numeric value (NA for most otel spans)
error_message: character error message (NA for non-error events)
output_id: character output identifier (NA for non-output events)
navigation_id: character navigation identifier (NA for otel spans)
See Also
-
bid_telemetry()for high-level telemetry analysis (automatic format detection) -
bid_ingest_telemetry()for legacy telemetry workflows -
vignette("otel-integration")for complete OTEL setup guide
Examples
## Not run:
# Typically you don't need to call this directly - use bid_telemetry() instead:
issues <- bid_telemetry("otel_spans.json")
# Manual conversion (advanced use case):
# After reading otlp json file
spans <- read_otel_json("spans.json")
events <- convert_otel_spans_to_events(spans)
# Verify schema compatibility
names(events)
# [1] "timestamp" "session_id" "event_type" "input_id" "value" "error_message"
# [7] "output_id" "navigation_id"
# Now use standard friction detection
issues <- detect_telemetry_issues(events)
## End(Not run)
Create notice stage for confusion patterns
Description
Create notice stage for confusion patterns
Usage
create_confusion_notice(confusion_info, total_sessions, events = NULL)
Arguments
confusion_info |
List with confusion pattern information |
total_sessions |
Total number of sessions |
events |
Optional full events data frame for performance context |
Value
bid_stage object
Create notice stage for delayed interactions
Description
Create notice stage for delayed interactions
Usage
create_delay_notice(delay_info, total_sessions, threshold, events = NULL)
Arguments
delay_info |
List with delay statistics |
total_sessions |
Total number of sessions |
threshold |
Threshold used for analysis |
events |
Optional full events data frame for performance context |
Value
bid_stage object
Create notice stage for error patterns
Description
Create notice stage for error patterns
Usage
create_error_notice(error_info, total_sessions, events = NULL)
Arguments
error_info |
List with error pattern information |
total_sessions |
Total number of sessions |
events |
Optional full events data frame for performance context |
Value
bid_stage object
Create notice stage for navigation issues
Description
Create notice stage for navigation issues
Usage
create_navigation_notice(nav_info, total_sessions, events = NULL)
Arguments
nav_info |
List with navigation pattern information |
total_sessions |
Total number of sessions |
events |
Optional full events data frame for performance context |
Value
bid_stage object
Create a telemetry notice from problem and evidence
Description
Create a telemetry notice from problem and evidence
Usage
create_telemetry_notice(central_question, problem, evidence)
Arguments
central_question |
The central question for the interpret stage |
problem |
Problem description string |
evidence |
Evidence description string |
Value
bid_stage object in the Notice stage
Create notice stage for unused input
Description
Create notice stage for unused input
Usage
create_unused_input_notice(input_info, total_sessions, events = NULL)
Arguments
input_info |
List with input usage information |
total_sessions |
Total number of sessions |
events |
Optional full events data frame for performance context |
Value
bid_stage object
Remove duplicate warning-suggestion pairs
Description
Identifies and removes redundant warnings where the warning message duplicates information already provided in suggestions. Helps clean up verbose output by preferring actionable suggestions over warnings.
Usage
deduplicate_warnings_suggestions(
warnings,
suggestions,
similarity_threshold = 0.7
)
Arguments
warnings |
Character vector of warning messages |
suggestions |
Character vector of suggestion messages |
similarity_threshold |
Similarity threshold for detecting duplicates (0-1) |
Value
List with cleaned warnings and suggestions
Detect if JSON file contains OTLP (OpenTelemetry Protocol) data
Description
Checks if a JSON file contains OpenTelemetry Protocol span data by looking for the characteristic OTLP structure (resourceSpans, scopeSpans, spans).
Usage
detect_otel_json(source_path)
Arguments
source_path |
Path to JSON file |
Value
Logical TRUE if OTLP format detected, FALSE otherwise
Examples
## Not run:
detect_otel_json("spans.json") # returns TRUE for otlp files
detect_otel_json("telemetry.json") # returns FALSE for shiny.telemetry files
## End(Not run)
Auto-detect telemetry format from file extension
Description
Auto-detect telemetry format from file extension
Usage
detect_telemetry_format(path)
Arguments
path |
File path |
Value
Format string ("sqlite" or "json")
Extract error message from span events
Description
Extracts error messages from OTLP span events. Error events contain the error details in their attributes.
Usage
extract_error_message_from_span(span_events)
Arguments
span_events |
List or data frame of span events |
Value
Character error message, or NA if no error found
Examples
## Not run:
events <- list(
list(
name = "error",
attributes = list(
list(key = "message", value = list(stringValue = "Division by zero"))
)
)
)
extract_error_message_from_span(events) # returns "Division by zero"
## End(Not run)
Extract input ID from span name or attributes
Description
Extracts input identifier from OTLP span. Looks in span name (e.g., "reactive:input$slider1") and span attributes (e.g., input_id attribute).
Usage
extract_input_id_from_span(span_name, span_attributes)
Arguments
span_name |
Character span name |
span_attributes |
List or data frame of span attributes |
Value
Character input ID, or NA if not found
Examples
## Not run:
# extract from span name
extract_input_id_from_span("reactive:input$slider1", NULL) # returns "slider1"
# extract from attributes
attrs <- list(list(key = "input_id", value = list(stringValue = "text1")))
extract_input_id_from_span("reactive", attrs) # returns "text1"
## End(Not run)
Extract navigation ID from span attributes
Description
Extracts navigation identifier from OTLP span attributes.
Usage
extract_navigation_id_from_span(span_attributes)
Arguments
span_attributes |
List or data frame of span attributes |
Value
Character navigation ID, or NA if not found
Extract output ID from span name or attributes
Description
Extracts output identifier from OTLP span. Looks in span name (e.g., "output:plot1") and span attributes (e.g., output_id attribute).
Usage
extract_output_id_from_span(span_name, span_attributes)
Arguments
span_name |
Character span name |
span_attributes |
List or data frame of span attributes |
Value
Character output ID, or NA if not found
Examples
## Not run:
# extract from span name
extract_output_id_from_span("output:plot1", NULL) # returns "plot1"
# extract from attributes
attrs <- list(list(key = "output_id", value = list(stringValue = "table1")))
extract_output_id_from_span("output", attrs) # returns "table1"
## End(Not run)
Extract session ID from span attributes
Description
Extracts the session.id attribute from OTLP span attributes list. Handles both nested list and data frame formats.
Usage
extract_session_id_from_span(span_attributes)
Arguments
span_attributes |
List or data frame of span attributes |
Value
Character session ID, or NA if not found
Examples
## Not run:
# from list format
attrs <- list(
list(key = "session.id", value = list(stringValue = "abc123"))
)
extract_session_id_from_span(attrs) # returns "abc123"
## End(Not run)
Extract an attribute value from span attributes by key names
Description
Extract an attribute value from span attributes by key names
Usage
extract_span_attribute(span_attributes, key_names)
Arguments
span_attributes |
The attributes object (data.frame, named list, or list-of-objects) |
key_names |
Character vector of possible key names to look for |
Value
The extracted value as character, or NA_character_ if not found
Extract specific stage from bid_result
Description
Extract specific stage from bid_result
Usage
extract_stage(workflow, stage)
Arguments
workflow |
A bid_result object |
stage |
Character string with stage name |
Value
A bid_stage object or NULL if not found
Extract theory concepts from Stage 1 (Notice)
Description
Extract theory concepts from Stage 1 (Notice)
Usage
extract_stage1_theory(previous_stage)
Arguments
previous_stage |
Previous stage data |
Value
Character vector of theory-based concepts
Find confusion patterns (rapid repeated changes)
Description
Find confusion patterns (rapid repeated changes)
Usage
find_confusion_patterns(
events,
window_seconds = confusion_window_secs,
min_changes = confusion_min_changes
)
Arguments
events |
Telemetry events data frame |
window_seconds |
Time window in seconds |
min_changes |
Minimum changes to flag as confusion |
Value
List of confusion patterns
Find sessions with delayed first interaction
Description
Find sessions with delayed first interaction
Usage
find_delayed_sessions(events, threshold_seconds = delay_threshold_secs)
Arguments
events |
Telemetry events data frame |
threshold_seconds |
Delay threshold in seconds |
Value
List with delay statistics
Find error patterns in telemetry
Description
Find error patterns in telemetry
Usage
find_error_patterns(events, threshold_rate = error_rate_threshold)
Arguments
events |
Telemetry events data frame |
threshold_rate |
Error rate threshold |
Value
List of error patterns
Find navigation drop-offs or underused pages
Description
Find navigation drop-offs or underused pages
Usage
find_navigation_dropoffs(events, threshold = nav_dropoff_threshold)
Arguments
events |
Telemetry events data frame |
threshold |
Minimum visit rate threshold |
Value
List of navigation issues
Find unused or under-used inputs
Description
Find unused or under-used inputs
Usage
find_unused_inputs(events, threshold = unused_input_threshold)
Arguments
events |
Telemetry events data frame |
threshold |
Percentage threshold for considering input unused |
Value
List of unused input information
Convert nested suggestion groups to flat tibble
Description
Transforms the nested list structure of suggestions (grouped by concept) into a flat tibble with one row per suggestion. Maintains backward compatibility by keeping the nested structure available.
Usage
flatten_suggestions_to_tibble(suggestion_groups)
Arguments
suggestion_groups |
List of concept groups with suggestions |
Value
Tibble with columns: concept, title, details, components, rationale, score, difficulty, category
Format field label based on output format
Description
Format field label based on output format
Usage
format_label(label, format, type = "field")
Arguments
label |
Base label text |
format |
Output format ("markdown" or "text") |
type |
Label type ("header", "field", or "section") |
Value
Formatted label string
Get accessibility recommendations for a given context
Description
Get accessibility recommendations for a given context
Usage
get_accessibility_recommendations(context = "", guidelines = NULL)
Arguments
context |
Character string describing the interface context |
guidelines |
Optional custom accessibility guidelines |
Value
Character vector of relevant accessibility recommendations
Generate Cognitive Load Theory suggestions
Description
Generate Cognitive Load Theory suggestions
Usage
get_cognitive_load_suggestions(previous_stage)
Get bias mitigation strategies for concepts
Description
Get bias mitigation strategies for concepts
Usage
get_concept_bias_mappings(concepts, mappings = NULL)
Arguments
concepts |
Character vector of concept names |
mappings |
Optional custom concept-bias mappings |
Value
Data frame with relevant bias mappings
Get the canonical concept keyword map for text-based concept detection
Description
Returns the single authoritative mapping of behavioral science concept names
to keyword vectors. This is the merged union of all keyword sets previously
scattered across infer_concepts_from_story() and
detect_concepts_from_text().
Usage
get_concept_keywords()
Value
Named list mapping concept names to keyword vectors
Internal function to get concepts data from external files
Description
Internal function to get concepts data from external files
Usage
get_concepts_data()
Value
A tibble with all BID framework concepts
Get consolidated suggestion rules for all BID stages
Description
Returns a structured list of suggestion rules for each BID stage. These rules help generate consistent, context-aware suggestions based on user input patterns and common issues.
Usage
get_consolidated_suggestion_rules()
Value
Named list of suggestion rules by stage
Get default concepts data with lazy loading
Description
Internal function to retrieve default BID framework concepts data using lazy loading from external CSV file. This includes behavioral science concepts, cognitive principles, and implementation guidance for each stage of the BID framework.
Usage
get_default_concepts_data()
Value
A tibble with default BID framework concepts
Get default layout mappings (fallback)
Description
Get default layout mappings (fallback)
Usage
get_default_layout_mappings()
Value
Data frame with default layout mappings
Get default theory mappings (fallback)
Description
Get default theory mappings (fallback)
Usage
get_default_theory_mappings()
Value
Data frame with default theory mappings
Generate Dual-Processing Theory suggestions
Description
Generate Dual-Processing Theory suggestions
Usage
get_dual_processing_suggestions(previous_stage)
Fallback concepts data for emergency use
Description
Provides minimal fallback data if external file cannot be loaded. Only used as last resort to prevent package failure.
Usage
get_fallback_concepts_data()
Value
A tibble with minimal concepts data
Generate fallback suggestions for stages without specific rules
Description
Provides generic but helpful suggestions for BID stages that don't have specific rules defined or when no rules match the context.
Usage
get_fallback_suggestion(stage_name)
Arguments
stage_name |
Name of the BID stage |
Value
Character string with fallback suggestion
Generate generic suggestions for unrecognized concepts
Description
Generate generic suggestions for unrecognized concepts
Usage
get_generic_suggestions(concept, previous_stage)
Generate Information Scent suggestions
Description
Generate Information Scent suggestions
Usage
get_information_scent_suggestions(previous_stage)
Get concepts recommended for a layout
Description
Get concepts recommended for a layout
Usage
get_layout_concepts(layout, mappings = NULL)
Arguments
layout |
Character string indicating layout type |
mappings |
Optional custom layout mappings |
Value
Character vector of recommended concepts
Get metadata from bid_stage object
Description
Get metadata from bid_stage object
Usage
get_metadata(x)
Arguments
x |
A bid_stage object |
Value
List with metadata
Generate User Onboarding suggestions
Description
Generate User Onboarding suggestions
Usage
get_onboarding_suggestions(previous_stage)
Generate Progressive Disclosure suggestions
Description
Generate Progressive Disclosure suggestions
Usage
get_progressive_disclosure_suggestions(previous_stage)
Generate Principle of Proximity suggestions
Description
Generate Principle of Proximity suggestions
Usage
get_proximity_suggestions(previous_stage)
Get stage name from bid_stage object
Description
Get stage name from bid_stage object
Usage
get_stage(x)
Arguments
x |
A bid_stage object |
Value
Character string with stage name
Generate Visual Hierarchy suggestions
Description
Generate Visual Hierarchy suggestions
Usage
get_visual_hierarchy_suggestions(previous_stage)
Infer concepts from Stage 2 (Interpret) story elements
Description
Infer concepts from Stage 2 (Interpret) story elements
Usage
infer_concepts_from_story(previous_stage)
Arguments
previous_stage |
Previous stage data |
Value
Character vector of story-inferred concepts
Check if object is a bid_stage
Description
Check if object is a bid_stage
Usage
is_bid_stage(x)
Arguments
x |
Object to test |
Value
Logical indicating if object is bid_stage
Check if workflow is complete (has all 5 stages)
Description
Check if workflow is complete (has all 5 stages)
Usage
is_complete(x)
Arguments
x |
A bid_result object |
Value
Logical indicating if workflow is complete
Load accessibility guidelines
Description
Load accessibility guidelines
Usage
load_accessibility_guidelines(custom_guidelines = NULL)
Arguments
custom_guidelines |
Optional custom guidelines data frame |
Value
Data frame with accessibility guidelines
Load concept-bias mappings
Description
Load concept-bias mappings
Usage
load_concept_bias_mappings(custom_mappings = NULL)
Arguments
custom_mappings |
Optional custom mappings data frame |
Value
Data frame with concept-bias mappings
Load concepts data from external file with caching
Description
Loads concepts data from CSV file with caching for performance. Uses memoise to ensure data is only loaded once per session.
Usage
load_concepts_data()
Value
A tibble with concepts data
Load layout-concept mappings
Description
Load layout-concept mappings
Usage
load_layout_mappings(custom_mappings = NULL)
Arguments
custom_mappings |
Optional custom mappings data frame |
Value
Data frame with layout-concept mappings
Load theory mappings from external file or use defaults
Description
Load theory mappings from external file or use defaults
Usage
load_theory_mappings(custom_mappings = NULL)
Arguments
custom_mappings |
Optional custom mappings data frame |
Value
Data frame with theory mappings
Create bias mitigations tibble
Description
Creates a structured bias mitigations tibble for use in bidux functions. Replaces nested list structures with a validated data.frame structure.
Usage
new_bias_mitigations(mitigations_df)
Arguments
mitigations_df |
Data.frame with required columns: bias_type, mitigation_strategy, confidence_level |
Value
A bid_bias_mitigations S3 object (inherits from data.frame)
Examples
mitigations <- new_bias_mitigations(data.frame(
bias_type = c("confirmation_bias", "selection_bias"),
mitigation_strategy = c("seek_disconfirming_evidence", "randomize_sample"),
confidence_level = c(0.8, 0.7)
))
Create a BID result collection object (internal constructor)
Description
Create a BID result collection object (internal constructor)
Usage
new_bid_result(stages)
Arguments
stages |
List of bid_stage objects |
Value
Object of class 'bid_result'
Create a BID stage result object (internal constructor)
Description
Create a BID stage result object (internal constructor)
Usage
new_bid_stage(stage, data, metadata = list())
Arguments
stage |
Character string indicating the stage name |
data |
Tibble containing the stage data |
metadata |
List containing additional metadata |
Value
Object of class 'bid_stage'
Create a data story object
Description
Creates a structured data story object for use in bid_interpret() and other bidux functions. Uses a flat API with hook, context, tension, and resolution fields to structure your data narrative.
Usage
new_data_story(
hook = NULL,
context = NULL,
tension = NULL,
resolution = NULL,
...
)
Arguments
hook |
Character string for the story hook (attention-grabbing opening) |
context |
Character string describing the data context |
tension |
Character string describing the problem or tension |
resolution |
Character string describing the resolution or next steps |
... |
Optional additional fields (audience, metrics, visual_approach, etc.) |
Value
A bid_data_story S3 object
Examples
# Basic usage
story <- new_data_story(
hook = "User engagement is declining",
context = "Our dashboard usage has dropped 30% this quarter",
tension = "We don't know if it's UX issues or changing user needs",
resolution = "Analyze telemetry to identify friction points"
)
# With optional fields
story_detailed <- new_data_story(
hook = "Revenue dashboards are underutilized",
context = "Only 40% of sales team uses the new revenue dashboard",
tension = "Critical metrics are being missed",
resolution = "Redesign with behavioral science principles",
audience = "Sales team",
metrics = "adoption_rate, time_to_insight"
)
Create user personas tibble
Description
Creates a structured user personas tibble for use in bidux functions. Replaces nested list structures with a validated data.frame structure.
Usage
new_user_personas(personas_df)
Arguments
personas_df |
Data.frame with required columns: name, goals, pain_points, technical_level |
Value
A bid_user_personas S3 object (inherits from data.frame)
Examples
personas <- new_user_personas(data.frame(
name = c("data analyst", "product manager"),
goals = c("quick insights", "strategic overview"),
pain_points = c("complex tools", "data delays"),
technical_level = c("intermediate", "beginner")
))
Normalize telemetry column names
Description
Normalize telemetry column names
Usage
normalize_telemetry_columns(events)
Arguments
events |
Raw events data frame |
Value
Normalized data frame
Parse Unix nanosecond timestamp to POSIXct
Description
Converts OTLP Unix nanosecond timestamps to R POSIXct objects.
Usage
parse_span_timestamp(span_time_unix_nano)
Arguments
span_time_unix_nano |
Character string or numeric Unix timestamp in nanoseconds |
Value
POSIXct timestamp in UTC timezone, or NA if parsing fails
Examples
## Not run:
# parse otlp timestamp
parse_span_timestamp("1234567890123456789")
## End(Not run)
Print method for bias mitigations objects
Description
Print method for bias mitigations objects
Usage
## S3 method for class 'bid_bias_mitigations'
print(x, ...)
Arguments
x |
A bid_bias_mitigations object |
... |
Additional arguments passed to print.data.frame |
Print method for data story objects
Description
Print method for data story objects
Usage
## S3 method for class 'bid_data_story'
print(x, ...)
Arguments
x |
A bid_data_story object |
... |
Additional arguments (unused) |
Print method for bid_issues objects
Description
Displays a triage view of telemetry issues with severity-based prioritization and provides a reminder about legacy list access for backward compatibility.
Usage
## S3 method for class 'bid_issues'
print(x, ...)
Arguments
x |
A bid_issues object from bid_ingest_telemetry() |
... |
Additional arguments (unused) |
Value
Invisible x (for chaining)
Print method for BID result objects
Description
Print method for BID result objects
Usage
## S3 method for class 'bid_result'
print(x, ...)
Arguments
x |
A bid_result object |
... |
Additional arguments |
Value
Returns the input bid_result object invisibly (class:
c("bid_result", "list")). The method is called for its side
effects: printing a workflow overview to the console showing
completion status, stage progression, and key information from each
completed BID stage. The invisible return supports method chaining
while emphasizing the console summary output.
Print method for BID stage objects
Description
Print method for BID stage objects
Usage
## S3 method for class 'bid_stage'
print(x, ...)
Arguments
x |
A bid_stage object |
... |
Additional arguments |
Value
Returns the input bid_stage object invisibly (class:
c("bid_stage", "tbl_df", "tbl", "data.frame")). The method is
called for its side effects: printing a formatted summary of the BID
stage to the console, including stage progress, key stage-specific
information, and usage suggestions. The invisible return allows for
method chaining while maintaining the primary purpose of console
output.
Print method for user personas objects
Description
Print method for user personas objects
Usage
## S3 method for class 'bid_user_personas'
print(x, ...)
Arguments
x |
A bid_user_personas object |
... |
Additional arguments passed to print.data.frame |
Rank and sort suggestions within each group
Description
Rank and sort suggestions within each group
Usage
rank_and_sort_suggestions(groups, previous_stage)
Arguments
groups |
List of concept groups with suggestions |
previous_stage |
Previous stage data for scoring adjustments |
Value
List of groups with ranked suggestions
Read OpenTelemetry JSON (OTLP) file
Description
Reads OpenTelemetry Protocol (OTLP) JSON files containing span data from Shiny 1.12+ applications. Extracts spans from the nested OTLP structure and converts them to bidux event schema.
Usage
read_otel_json(path)
Arguments
path |
Path to OTLP JSON file |
Value
Data frame with bidux event schema (converted from spans)
Examples
## Not run:
events <- read_otel_json("otel_spans.json")
names(events)
# [1] "timestamp" "session_id" "event_type" "input_id" "value" "error_message"
# [7] "output_id" "navigation_id"
## End(Not run)
Read OpenTelemetry SQLite database
Description
Reads OpenTelemetry span data from SQLite databases that store OTEL traces. Looks for standard OTEL table names (spans, span_events, span_attributes) and joins them to reconstruct the span structure before converting to bidux events.
Usage
read_otel_sqlite(source)
Arguments
source |
SQLite database path or DBI connection object |
Value
Data frame with bidux event schema (converted from spans)
Examples
## Not run:
events <- read_otel_sqlite("otel_traces.db")
names(events)
# [1] "timestamp" "session_id" "event_type" "input_id" "value" "error_message"
# [7] "output_id" "navigation_id"
## End(Not run)
Read telemetry data from file or connection
Description
Read telemetry data from file or connection
Usage
read_telemetry_data(source, format, events_table = NULL, table_name = NULL)
Arguments
source |
File path or DBI connection object |
format |
Format ("sqlite" or "json") |
events_table |
Optional custom events table for SQLite |
table_name |
Optional table name for SQLite |
Value
Data frame of events
Read telemetry from JSON log file
Description
Read telemetry from JSON log file
Usage
read_telemetry_json(path)
Arguments
path |
JSON log file path |
Value
Data frame of events
Read telemetry from SQLite database
Description
Read telemetry from SQLite database
Usage
read_telemetry_sqlite(source, events_table = NULL, table_name = NULL)
Arguments
source |
SQLite database path or DBI connection object |
events_table |
Optional custom events table data.frame |
table_name |
Optional character string specifying table name to read |
Value
Data frame of events
Safely convert text to lowercase with null handling
Description
Helper function that safely converts text to lowercase while handling NULL, NA, and non-character values gracefully.
Usage
safe_lower(x)
Arguments
x |
Input value to convert to lowercase string |
Value
Character string in lowercase, or empty string if input is NULL/NA
Safe access to data_story elements from previous stage
Description
Safe access to data_story elements from previous stage
Usage
safe_stage_data_story_access(previous_stage, element)
Arguments
previous_stage |
Previous stage data |
element |
Name of data_story element to access |
Value
Character string or empty string if not found
Generate ranked, concept-grouped, actionable UI/UX suggestions
Description
Creates structured suggestions organized by UX concepts with specific component recommendations and rationales. Suggestions are ranked by relevance and grouped by concept for systematic implementation.
Usage
structure_suggestions(previous_stage, concepts = NULL, quiet = NULL)
Arguments
previous_stage |
A tibble or list output from an earlier BID stage |
concepts |
Optional character vector of additional concepts to include |
Details
The function combines concepts from multiple sources:
Stage 1 theory (from Notice)
Stage 2 inferred concepts (from keywords in story)
Optional user-provided concepts
Each suggestion includes:
title: Brief actionable description
details: Specific implementation guidance
components: R dashboard component recommendations (shiny::, bslib::, etc.)
rationale: 1-2 sentence explanation
score: Relevance ranking (0-1)
Framework Compatibility:
Components prefixed with 'shiny::' require Shiny runtime (either a Shiny app
or Quarto dashboard with server: shiny). Components from bslib, DT, plotly,
reactable, and leaflet work in both Shiny apps and static/OJS Quarto
dashboards.
Value
List of concept groups with ranked suggestions
Suggest theory based on problem and evidence using mappings
Description
Suggest theory based on problem and evidence using mappings
Usage
suggest_theory_from_mappings(problem, evidence = NULL, mappings = NULL)
Arguments
problem |
Character string describing the problem |
evidence |
Optional character string with supporting evidence |
mappings |
Optional custom theory mappings |
Value
Character string with suggested theory
Summary method for BID result objects
Description
Summary method for BID result objects
Usage
## S3 method for class 'bid_result'
summary(object, ...)
Arguments
object |
A bid_result object |
... |
Additional arguments |
Value
Returns the input bid_result object invisibly (class:
c("bid_result", "list")). The method is called for its side
effects: printing a detailed workflow analysis to the console
including completion statistics, duration metrics, and comprehensive
stage-by-stage breakdowns with key data from each BID framework
stage. The invisible return facilitates method chaining while
focusing on comprehensive console reporting.
Summary method for BID stage objects
Description
Summary method for BID stage objects
Usage
## S3 method for class 'bid_stage'
summary(object, ...)
Arguments
object |
A bid_stage object |
... |
Additional arguments |
Value
Returns the input bid_stage object invisibly (class:
c("bid_stage", "tbl_df", "tbl", "data.frame")). The method is
called for its side effects: printing a comprehensive summary to the
console including stage metadata, all non-empty data columns, and
timestamp information. The invisible return enables method chaining
while prioritizing the detailed console output display.
Validate BID result object
Description
Validate BID result object
Usage
validate_bid_result(x)
Arguments
x |
Object to validate |
Value
TRUE if valid, throws error otherwise
Validate BID stage object
Description
Validate BID stage object
Usage
validate_bid_stage(x)
Arguments
x |
Object to validate |
Value
TRUE if valid, throws error otherwise
Validate loaded concepts data structure
Description
Validate loaded concepts data structure
Usage
validate_concepts_data_structure(concepts_data)
Arguments
concepts_data |
Raw concepts data from CSV |
Value
Invisible NULL if valid, throws error otherwise
Common validation utility for bidux functions (DRY principle)
Description
Centralized parameter validation to reduce code duplication
Usage
validate_param(
value,
arg_name,
type = "character",
min_length = 1,
max_length = Inf,
allow_na = FALSE,
choices = NULL
)
Arguments
value |
The value to validate |
arg_name |
The argument name for error messages |
type |
Expected type: "character", "logical", "numeric" |
min_length |
Minimum length for vectors |
max_length |
Maximum length for vectors |
allow_na |
Whether NA values are allowed |
choices |
Valid choices for character parameters |