| Title: | Explore and Join Many Tables on a Zoomable Canvas |
|---|---|
| Description: | Lays out many data frames side by side as cards on a pan-and-zoom canvas, either as a 'shiny' gadget for 'RStudio' or as an 'htmlwidgets' widget for 'R Markdown' and 'Quarto' pages. Drawing a line between two columns writes the 'dplyr' join and checks it first: match rates, unmatched keys and the key relationship. Sorts, filters and other steps build up a readable pipeline of R code, and a column inspector exports a data dictionary. An optional large language model (LLM) assistant, using 'Ollama' or an 'OpenAI'-compatible service, suggests 'tidyverse' code from the table schema only, never the data rows. |
| Authors: | Yee How Lau [aut, cre, cph] |
| Maintainer: | Yee How Lau <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.4.0 |
| Built: | 2026-11-01 03:30:52 UTC |
| Source: | https://github.com/lauyeehow1986-hub/sideview |
Constructs a structured sideview_state object containing canvas transform,
card configurations, table join connections, and pipeline script state.
new_sideview_state( version = "0.3.0", canvas = list(zoom = 1, pan_x = 0, pan_y = 0), cards = list(), connections = list(), pipeline = list(code = "", active_tab = "pipeline") )new_sideview_state( version = "0.3.0", canvas = list(zoom = 1, pan_x = 0, pan_y = 0), cards = list(), connections = list(), pipeline = list(code = "", active_tab = "pipeline") )
version |
Character string representing state schema version (default |
canvas |
Named list containing canvas settings: |
cards |
List of card state objects (each specifying |
connections |
List of join connection objects (each specifying |
pipeline |
Named list containing |
The canvas writes this shape when you click Save in the toolbar, and
sideview(..., state = ) / sideview_widget(..., state = ) restore it.
Cards are matched to tables by name.
An object of class c("sideview_state", "list").
st <- new_sideview_state() print(st)st <- new_sideview_state() print(st)
Displays a concise summary of the canvas state including version, card count, and active connections.
## S3 method for class 'sideview_state' print(x, ...)## S3 method for class 'sideview_state' print(x, ...)
x |
A |
... |
Unused additional arguments. |
Invisibly returns x.
Shiny Render Function for Sideview Widget
renderSideview(expr, env = parent.frame(), quoted = FALSE)renderSideview(expr, env = parent.frame(), quoted = FALSE)
expr |
An expression that generates a |
env |
The environment in which to evaluate |
quoted |
Is |
An S3 object of class c("shiny.render.function", "function").
Exports a sideview htmlwidget or table objects to a self-contained HTML file
with all styles, fonts, and JavaScript embedded.
save_sideview( widget, file, selfcontained = TRUE, title = "Sideview", background = "white", max_rows = 5000, ... )save_sideview( widget, file, selfcontained = TRUE, title = "Sideview", background = "white", max_rows = 5000, ... )
widget |
A |
file |
Path to the output HTML file (e.g. |
selfcontained |
Logical; whether to produce a standalone HTML file with
all CSS and JavaScript dependencies inlined. Defaults to |
title |
HTML title for the output page. Default |
background |
Background color for the document body. Default |
max_rows |
Row cap used when |
... |
Additional arguments passed to |
The normalized path to the saved file (invisibly).
out <- tempfile(fileext = ".html") save_sideview(mtcars, file = out) unlink(out)out <- tempfile(fileext = ".html") save_sideview(mtcars, file = out) unlink(out)
Launches an interactive Shiny gadget containing an infinite 2D canvas with mouse-wheel zoom, pan, draggable table cards, interactive column mapping, discrepancy recoding, and LLM-assisted tidyverse code generation.
sideview( ..., title = "Sideview Canvas", viewer = sv_default_viewer(), theme = "auto", state = NULL, env = parent.frame(), run = interactive() )sideview( ..., title = "Sideview Canvas", viewer = sv_default_viewer(), theme = "auto", state = NULL, env = parent.frame(), run = interactive() )
... |
Arbitrary table objects ( |
title |
Title for the gadget viewer. |
viewer |
Shiny viewer gadget display mode (e.g. |
theme |
Canvas theme: |
state |
A saved workspace to restore: a |
env |
Environment where Run in R evaluates the generated code and
stores its result (as |
run |
Logical; if |
If run = TRUE, the generated code (invisibly) when you click
Done, or NULL after Cancel or closing the window.
If run = FALSE, returns a shiny.appobj with the normalized cards attached.
Arrow tables, datasets and queries and duckdb tables (dplyr::tbl()) go on
the canvas as cards that show a 50-row preview. When the duckdb, dbplyr and
DBI packages are installed, sorting, filtering, scrolling, the join check,
the column inspector and the codebook use the whole table: duckdb runs them
and only summaries and row windows come back into R. The table is never
collected. Without duckdb, or when the link to a table is lost, the card
says "First 50 of N rows" and the checks use the preview.
Generated code stays lazy and ends in one collect(). Known differences
from an in-memory card:
"Contains" on a number matches its text. The grid filter drops a
trailing .0, but in generated code duckdb writes a double as
"130.0" where R writes "130", and float noise or scientific
notation can differ. The generated filter is a literal match,
stringr::str_detect(col, "<escaped literal>").
POSIXct values at exactly midnight, and -0, can print differently.
Join keys of different types compare as text, and double keys compare exactly.
Arrow time-zone offsets are computed for 1900 to 2100; local times
outside that range may be off. duckdb TIMESTAMPTZ columns show in UTC.
Joining arrow with duckdb copies the arrow side into a duckdb
temporary table (arrow::to_duckdb() then dplyr::compute()), which
costs memory; a data frame joined into duckdb is copied as
sideview_<table>.
duckdb 1.4.3 can crash when it scans an arrow factor column that
contains NA. sideview decodes such columns itself, but generated code
that calls arrow::to_duckdb() on one may hit it: convert the factor to
character first.
If Run in R fails on a lazy pipeline, the message suggests moving
collect() above the step that needs R.
Date rules on joins (the calendar button on a join step) give the same rows in R, in the saved widget and on duckdb/arrow cards, with these exceptions:
The saved widget drops fractions of a second from date-times, so a boundary that falls inside a second can differ from R.
The generated duckdb code for a date-time window uses the session
time zone when the ICU extension is loaded. With a non-UTC TimeZone
setting, a boundary can move.
Running the code in R on a mixed arrow/data-frame and duckdb chain
may leave temporary dbplyr_* tables on your connection until it closes.
sideview writes na_matches = "never" on every rule join (dplyr's
default would match NA to NA).
Single-key shortcuts work when the canvas has the keyboard and you are not
typing: F fit all cards, 0 reset zoom, +/- zoom, M show or hide
the minimap, D the drawer, T light/dark, / the AI prompt and ? the
full list. Ctrl+K finds a card or column, Ctrl+Z/Ctrl+Y undo and
redo a pipeline step, and Esc cancels a connection or closes a popover.
Double-click a card title, a minimap rectangle or a search result to zoom
to that card.
sideview.session_graceSeconds the gadget waits after its last
browser session closes before stopping (default 5), so reloading the
page does not end the app.
sideview.llm_backend"ollama" (default, or the
SIDEVIEW_LLM_BACKEND variable) or "openai" for any
OpenAI-compatible server.
sideview.llm_modelModel name. Defaults to SIDEVIEW_OLLAMA_MODEL
or "llama3.2" for Ollama, and SIDEVIEW_OPENAI_MODEL or
"gpt-4o-mini" otherwise. sv_llm_models() lists what is available.
sideview.llm_endpointBase URL. Defaults to OLLAMA_HOST or
http://localhost:11434, and OPENAI_BASE_URL or
https://api.openai.com/v1.
sideview.llm_api_keyAPI key for OpenAI-compatible servers
(default: the OPENAI_API_KEY variable).
sideview.llm_thinkTRUE lets Ollama reasoning models "think"
before answering. Default FALSE, so they answer promptly.
Only schema summaries (column names, types and simple profiles) are sent to the model, never raw rows.
if (interactive()) { sideview(mtcars, iris) }if (interactive()) { sideview(mtcars, iris) }
Automatically discovers tabular datasets in the user's active environment and launches the Sideview interactive multi-table canvas gadget.
sideview_addin( env = .GlobalEnv, viewer = sv_default_viewer(), run = interactive() )sideview_addin( env = .GlobalEnv, viewer = sv_default_viewer(), run = interactive() )
env |
Environment to search for tables, and where Run in R stores
its result (defaults to |
viewer |
Shiny viewer gadget display mode, or character shorthand
( |
run |
Logical indicating whether to execute the gadget. Default |
Result of sideview(...), invisibly when the gadget was run.
Orchestrates bi-directional Shiny reactivity between the infinite 2D canvas
and the R session. Handles field mapping (column_mapped), column renaming
(column_renamed), discrepancy calculations (discrepancy_check), natural
language AI prompts (run_ai_prompt), RStudio script injection (inject_script),
and RStudio console execution (send_console).
sideview_server( cards = list(), ..., llm_fn = sv_call_llm, insert_fn = sv_insert_code, console_fn = sv_send_to_console, gadget = FALSE, run_env = parent.frame() )sideview_server( cards = list(), ..., llm_fn = sv_call_llm, insert_fn = sv_insert_code, console_fn = sv_send_to_console, gadget = FALSE, run_env = parent.frame() )
cards |
A |
... |
Additional arguments. |
llm_fn |
Function used to execute LLM queries (default |
insert_fn |
Function used to insert code into active RStudio document (default |
console_fn |
Function used to send code to RStudio console (default |
gadget |
If |
run_env |
Environment where Run in R evaluates the pipeline and
stores its result (as |
A Shiny server function function(input, output, session).
Builds the complete 2D infinite canvas user interface for Sideview, containing the draggable table cards, panzoom canvas, SVG connector overlay, action drawer, and natural language AI bar with all HTML dependencies attached.
sideview_ui( cards = list(), title = "Sideview Canvas", gadget = FALSE, theme = "auto", state = NULL )sideview_ui( cards = list(), title = "Sideview Canvas", gadget = FALSE, theme = "auto", state = NULL )
cards |
A |
title |
Display title for the application toolbar. Default is "Sideview Canvas". |
gadget |
If |
theme |
|
state |
Optional saved workspace to restore on load (see |
A shiny.tag.list UI definition.
Normalizes passed table objects (data.frame, tibble, table, gt,
flextable, htmlwidgets) and creates an interactive 2D infinite canvas
htmlwidget suitable for rendering in R Markdown, Quarto, Shiny, or
exporting via save_sideview().
sideview_widget( ..., width = NULL, height = NULL, elementId = NULL, options = list(), theme = "auto", state = NULL, max_rows = 5000 )sideview_widget( ..., width = NULL, height = NULL, elementId = NULL, options = list(), theme = "auto", state = NULL, max_rows = 5000 )
... |
Arbitrary table objects ( |
width |
Optional widget width (e.g. |
height |
Optional widget height (e.g. |
elementId |
Optional HTML element identifier. |
options |
Named list of canvas options (e.g. |
theme |
Canvas theme: |
state |
A saved workspace to restore (see |
max_rows |
Most rows of each data-frame table to embed in the widget
(default 5000). A longer table is cut to its first |
An S3 object of class c("sideview", "htmlwidget").
if (interactive()) { sideview_widget(mtcars, iris) }if (interactive()) { sideview_widget(mtcars, iris) }
Shiny Output Container for Sideview Widget
sideviewOutput(outputId, width = "100%", height = "600px")sideviewOutput(outputId, width = "100%", height = "600px")
outputId |
Output variable to read from. |
width, height
|
Must be a valid CSS unit (e.g. |
A shiny.tag object representing the widget container.
Returns the same proxy sideviewServer(id) returned, so a canvas started in one
module can be driven from another. Inside a nested module, id is relative to
the calling module, as for moduleServer().
sideviewProxy(id, session = shiny::getDefaultReactiveDomain())sideviewProxy(id, session = shiny::getDefaultReactiveDomain())
id |
The id given to |
session |
The Shiny session (default: the current one). |
A sideview_proxy.
if (interactive()) { # inside a server function: # sv_replace_card(sideviewProxy("review"), "labs", labs_now()) }if (interactive()) { # inside a server function: # sv_replace_card(sideviewProxy("review"), "labs", labs_now()) }
sideviewUI() and sideviewServer() put an R-backed sideview canvas into your
own Shiny app (several per page). Row sorting and filtering, lazy arrow/duckdb
cards, the join check and the column inspector all run in R, as in sideview().
Tables are added, replaced and removed from the server with the verbs
sv_add_card(), sv_replace_card() and sv_remove_card(); the user's work is
read back with the reactives of the returned proxy.
sideviewUI(id, height = "600px", title = NULL, theme = "auto") sideviewServer(id, cards = list(), state = NULL, llm_fn = NULL)sideviewUI(id, height = "600px", title = NULL, theme = "auto") sideviewServer(id, cards = list(), state = NULL, llm_fn = NULL)
id |
Module id. |
height |
CSS height of the canvas, e.g. |
title |
Text shown in the toolbar; |
theme |
|
cards |
Tables for the canvas: a (named) list as |
state |
A saved workspace applied once after the first cards arrive: a state object, or its JSON text (a string whose first non-blank character is an opening curly brace). |
llm_fn |
Function used for the AI bar and the copilot (as for |
Code execution is off in a module (Insert Script, Run & Exit, Run in R and Run
Console are not rendered, and their inputs are ignored by the server). The
composed $code() is built in the browser: treat it as untrusted text to show,
save or review, never eval() it unattended.
sideviewUI() returns a shiny.tag.list. sideviewServer() returns a
sideview_proxy: a list with the reactives code() (the composed code, ""
for none), pipeline() (the typed steps as a list), state() (a state object,
or NULL before the first change) and cards() (the card names), plus id,
ns and session. The values update after the user's changes settle (300 ms).
Calling sideviewServer() twice with the same id in one session replaces the
first canvas's entry in the proxy registry: sideviewProxy() then reaches the
second. Give each canvas its own id.
sideviewProxy(), sv_add_card()
if (interactive()) { library(shiny) ui <- fluidPage(sideviewUI("cv"), verbatimTextOutput("code")) server <- function(input, output, session) { px <- sideviewServer("cv", cards = list(cars = mtcars, flowers = iris)) output$code <- renderText(px$code()) } shinyApp(ui, server) }if (interactive()) { library(shiny) ui <- fluidPage(sideviewUI("cv"), verbatimTextOutput("code")) server <- function(input, output, session) { px <- sideviewServer("cv", cards = list(cars = mtcars, flowers = iris)) output$code <- renderText(px$code()) } shinyApp(ui, server) }
Verbs for a canvas started with sideviewServer(). Each updates the R side first
and then tells the browser, and returns the proxy invisibly so they pipe.
sv_add_card(proxy, x, name) sv_replace_card(proxy, name, x) sv_remove_card(proxy, name) sv_set_state(proxy, state) sv_highlight(proxy, name, cols)sv_add_card(proxy, x, name) sv_replace_card(proxy, name, x) sv_remove_card(proxy, name) sv_set_state(proxy, state) sv_highlight(proxy, name, cols)
proxy |
A |
x |
A table: anything |
name |
Card name (a single string). |
state |
A state object or its JSON text (e.g. |
cols |
Column names (a character vector); columns not on the card are ignored. |
sv_add_card() adds an auto-placed card; a name already on the canvas is an error.
sv_replace_card() keeps the card's place and size and swaps its data. Pipeline
steps that name a column the new table lacks are disabled, not deleted, and
one toast says so.
sv_remove_card() removes a card and disables the steps that used it.
sv_set_state() replaces layout, joins and pipeline, as the Open button does.
sv_highlight() highlights columns of a card, as a header click would.
proxy, invisibly.
if (interactive()) { # px <- sideviewProxy("review") # sv_replace_card(px, "labs", labs_now()); sv_highlight(px, "labs", "lab_date") }if (interactive()) { # px <- sideviewProxy("review") # sv_replace_card(px, "labs", labs_now()); sv_highlight(px, "labs", "lab_date") }
Inspects discrepancy detection output or pairwise column discrepancies (exact matches,
fuzzy near-matches, and missing levels), automatically synthesizing clean recoding rules
using dplyr::case_when(). Handles casing differences, leading/trailing whitespace
discrepancies, and fuzzy string distance variations (Levenshtein distance <= 2).
sv_auto_clean_rules( discrepancy_result, df_name = "df", col = "status", default = col, pipe = FALSE, lazy = FALSE, df_is_code = FALSE ) sv_code_auto_clean( discrepancy_result, df_name = "df", col = "status", default = col, pipe = FALSE, lazy = FALSE, df_is_code = FALSE )sv_auto_clean_rules( discrepancy_result, df_name = "df", col = "status", default = col, pipe = FALSE, lazy = FALSE, df_is_code = FALSE ) sv_code_auto_clean( discrepancy_result, df_name = "df", col = "status", default = col, pipe = FALSE, lazy = FALSE, df_is_code = FALSE )
discrepancy_result |
A discrepancy result list (such as returned by |
df_name |
Name of the data frame to mutate. Defaults to |
col |
Column name being recoded. Defaults to |
default |
Fallback value for unmatched records. If equal to |
pipe |
Logical; if TRUE, emits piped syntax |
lazy |
Logical; TRUE when |
df_is_code |
Logical; TRUE when |
A character string of tidyverse code, or NULL if no discrepancies require cleaning.
disc <- sv_detect_discrepancies(c("male", "Female"), c("Male", "Female")) sv_auto_clean_rules(disc, df_name = "patients", col = "gender")disc <- sv_detect_discrepancies(c("male", "Female"), c("Male", "Female")) sv_auto_clean_rules(disc, df_name = "patients", col = "gender")
Formats a multi-turn conversational prompt for the Sideview AI Copilot drawer. Preserves database/table schema context, active pipeline R code, and previous dialogue turns (user/assistant). Instructs the model to output updated executable tidyverse R code within code fences.
sv_build_chat_prompt( user_message, history = list(), current_code = NULL, schema_context = NULL )sv_build_chat_prompt( user_message, history = list(), current_code = NULL, schema_context = NULL )
user_message |
Natural language query or instruction from the user. |
history |
A list of previous conversation turns, where each turn is a list
containing |
current_code |
Optional character string containing the currently active pipeline code in the drawer. |
schema_context |
Optional privacy-safe schema string built via |
A list of class c("sideview_chat_prompt", "sideview_prompt", "list")
containing system_message, user_message, history, messages, and prompt.
Formats system instructions emphasizing pure, executable tidyverse R code
enclosed in markdown code fences (```r ... ```) and packages user task
description alongside privacy-safe table schemas.
sv_build_prompt(user_prompt, schema_context = NULL)sv_build_prompt(user_prompt, schema_context = NULL)
user_prompt |
Natural language description of desired data transformation. |
schema_context |
Optional privacy-safe schema string built via |
A list of class sideview_prompt containing system_message, user_message, and prompt.
Summarizes the metadata of sideview cards (table names, dimensions, column names, types, value ranges for numerics/dates, sample levels for factors, and unique samples for characters) without leaking full raw row data or records. Non-tabular widget cards and NULL data are handled safely.
sv_build_schema_context(cards, max_categories = 5L)sv_build_schema_context(cards, max_categories = 5L)
cards |
A |
max_categories |
Maximum sample unique categories to report for categorical columns. Default is 5. |
A character string containing the privacy-safe schema summary.
Sends prompt requests to local Ollama (http://localhost:11434) or OpenAI-compatible
endpoints via httr2. Supports model selection, customizable endpoints, API key authentication,
and clean error reporting for network or HTTP status failures.
sv_call_llm( prompt, backend = c("ollama", "openai"), model = NULL, endpoint = NULL, api_key = NULL, timeout = 60, extract_code = FALSE, resolve_model = TRUE, ... )sv_call_llm( prompt, backend = c("ollama", "openai"), model = NULL, endpoint = NULL, api_key = NULL, timeout = 60, extract_code = FALSE, resolve_model = TRUE, ... )
prompt |
A character string or |
backend |
Character string: either |
model |
Model name (e.g., |
endpoint |
Base URL or full chat endpoint for the API. |
api_key |
API key (for OpenAI or authenticated endpoints). |
timeout |
Request timeout in seconds. Default 60. |
extract_code |
Logical; if TRUE, runs |
resolve_model |
Logical; for Ollama, if an untagged model such as |
... |
Additional options added to the request body (e.g. |
Character string containing the LLM response text (or extracted code if extract_code = TRUE).
Generate tidyverse Code for Arranging (Sorting) Rows
sv_code_arrange(df_name, col, desc = FALSE, pipe = FALSE)sv_code_arrange(df_name, col, desc = FALSE, pipe = FALSE)
df_name |
Name of the data frame. |
col |
Character vector of column name(s) to sort by. |
desc |
Logical vector indicating descending order for each column.
Recycled to match the length of |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Generate tidyverse Code for Filtering Rows
sv_code_filter(df_name, condition, pipe = FALSE)sv_code_filter(df_name, condition, pipe = FALSE)
df_name |
Name of the data frame. |
condition |
Character vector of boolean filter expressions. |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Constructs syntactically valid dplyr::group_by() and dplyr::summarise()
pipelines with identifier escaping, customizable summary metrics, and reproducible
grouping behavior via .groups = 'drop'.
sv_code_group_summarize( df_name = NULL, group_cols, summary_exprs, pipe = FALSE )sv_code_group_summarize( df_name = NULL, group_cols, summary_exprs, pipe = FALSE )
df_name |
Name of the data frame (optional; can be NULL for intermediate piped pipeline segments). |
group_cols |
Character vector of grouping column name(s). |
summary_exprs |
Named character vector or named list of aggregation expressions
(e.g., |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Generate tidyverse Code for Relational Table Joins
sv_code_join(df1, df2, col1, col2 = col1, join_type = "left", pipe = FALSE)sv_code_join(df1, df2, col1, col2 = col1, join_type = "left", pipe = FALSE)
df1 |
Name of the first data frame (optional / can be NULL when constructing intermediate piped join segments). |
df2 |
Name of the second data frame. |
col1 |
Key column name(s) in df1. |
col2 |
Key column name(s) in df2 (defaults to col1). |
join_type |
Type of join: "left", "inner", "anti", "right", "full", "semi". |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Generate tidyverse Code for Column Mutation
sv_code_mutate(df_name, new_col, expr, pipe = FALSE)sv_code_mutate(df_name, new_col, expr, pipe = FALSE)
df_name |
Name of the data frame. |
new_col |
Name of the column(s) being created or transformed. |
expr |
R expression string(s) to evaluate. |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Constructs syntactically valid tidyr::pivot_longer() calls with proper
identifier escaping and support for both piped workflows and direct calls.
sv_code_pivot_longer( df_name = NULL, cols, names_to = "name", values_to = "value", pipe = FALSE )sv_code_pivot_longer( df_name = NULL, cols, names_to = "name", values_to = "value", pipe = FALSE )
df_name |
Name of the data frame (optional; can be NULL for piped workflows). |
cols |
Character vector of column name(s) to pivot into longer format. |
names_to |
Character string specifying the name of the column to create from the data stored in the column names of |
values_to |
Character string specifying the name of the column to create from the data stored in cell values. Defaults to |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Constructs syntactically valid tidyr::pivot_wider() calls with proper
identifier escaping and optional aggregation functions.
sv_code_pivot_wider( df_name = NULL, names_from, values_from, values_fn = NULL, pipe = FALSE )sv_code_pivot_wider( df_name = NULL, names_from, values_from, values_fn = NULL, pipe = FALSE )
df_name |
Name of the data frame (optional; can be NULL for piped workflows). |
names_from |
Character vector of column name(s) to get the name of the output column from. |
values_from |
Character vector of column name(s) to get the cell values from. |
values_fn |
Optional function name (character string or named vector/list) to apply to values. Defaults to |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Generate tidyverse Code for Categorical Recoding and Discrepancy Crosswalks
sv_code_recode( df_name, col, crosswalk, default = NULL, method = c("case_when", "case_match", "fct_recode"), pipe = FALSE, lazy = FALSE )sv_code_recode( df_name, col, crosswalk, default = NULL, method = c("case_when", "case_match", "fct_recode"), pipe = FALSE, lazy = FALSE )
df_name |
Name of the data frame. |
col |
Column name to recode. |
crosswalk |
Mapping between source and target values. Can be:
|
default |
Fallback value for unmatched records. If NULL, omitted.
If equal to |
method |
Recoding function: "case_when" (dplyr, the default), "case_match" (dplyr; deprecated in dplyr 1.2.0, kept for older pipelines) or "fct_recode" (forcats). |
pipe |
Logical; if TRUE, uses pipe syntax |
lazy |
Logical; TRUE for a table that lives in arrow or duckdb. |
A character string of R code.
Generate tidyverse Code for Column Renaming
sv_code_rename(df_name, old_col, new_col, pipe = FALSE)sv_code_rename(df_name, old_col, new_col, pipe = FALSE)
df_name |
Name of the data frame. |
old_col |
Existing column name(s). |
new_col |
New column name(s). |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
Generate tidyverse Code for Selecting Columns
sv_code_select(df_name, cols, pipe = FALSE)sv_code_select(df_name, cols, pipe = FALSE)
df_name |
Name of the data frame. |
cols |
Character vector of column names to select. |
pipe |
Logical; if TRUE, uses pipe syntax |
A character string of R code.
One row per column across one or more tables: type, label, missingness, distinct values, whether the column is a unique key, range and quartiles, mean and SD, the most common values and data-quality flags. Write it to CSV or Excel to document a dataset or check it before analysis.
sv_codebook(..., top_n = 5L, file = NULL, progress = NULL)sv_codebook(..., top_n = 5L, file = NULL, progress = NULL)
... |
Data frames, duckdb tables or Arrow tables, or one list of them.
Names default to the argument expressions, as in |
top_n |
Number of most common values listed in |
file |
Optional path ending in |
progress |
Optional |
A data frame with columns table, column, position, class,
label, n, rows_profiled, n_missing, pct_missing, n_distinct,
unique_key, min, q1, median, q3, max (as text, so dates fit),
mean, sd, top_values and issues. rows_profiled is the number of
rows the profile used; it equals n except for a preview of a larger table.
Each column of a duckdb or Arrow table is profiled in full by duckdb, one
column at a time, so n and rows_profiled are the table's row count, and
a very wide table takes longer rather than more memory; use progress to
report on it. In the gadget, a card that only has a preview (duckdb is not
installed, or the link to the table was lost) is profiled from its first 50
rows: n is still the true row count, rows_profiled is 50, and the other
columns describe those rows.
patients <- data.frame(id = 1:4, sex = c("M", "F", "f", NA), age = c(40, 51, 62, 999)) sv_codebook(patients) visits <- data.frame(id = c(1, 1, 2, 5), sbp = c(120, 135, 128, 141)) out <- tempfile(fileext = ".csv") sv_codebook(patients, visits, file = out) unlink(out)patients <- data.frame(id = 1:4, sex = c("M", "F", "f", NA), age = c(40, 51, 62, 999)) sv_codebook(patients) visits <- data.frame(id = c(1, 1, 2, 5), sbp = c(120, 135, 128, 141)) out <- tempfile(fileext = ".csv") sv_codebook(patients, visits, file = out) unlink(out)
Summarises one column for the column inspector: counts, missingness, distinct values, whether it could serve as a unique key, quartiles and a histogram for numbers, the most common values for text, and data-quality flags (stray spaces, values that differ only in case, numbers stored as text, empty strings, extreme values).
sv_column_profile(x, top_n = 10L, bins = 20L, column = NULL)sv_column_profile(x, top_n = 10L, bins = 20L, column = NULL)
x |
A vector (a data frame column), or a lazy table (a duckdb table or an
Arrow table / dataset) together with |
top_n |
Number of most common values to keep. |
bins |
Number of equal-width histogram bins for numeric columns. |
column |
The column to profile when |
A list with kind ("numeric", "character", "logical",
"date", "datetime" or "other"), class, label (the "label"
attribute, if any), n, n_missing, pct_missing, n_distinct
(non-missing), unique_key, stats (named list: min, q1, median,
q3, max, and mean, sd for numbers), histogram (breaks,
counts), top (data frame of value, n), n_other (distinct values
not in top) and issues (character).
For a duckdb table or an Arrow table, give the table as x and the column
name as column. The database profiles the whole table in a few queries
and only the summary comes back; the result equals the one for the same
column held in memory. Arrow tables are profiled through a private duckdb
connection that is closed afterwards. duckdb ordered-factor columns report
class "factor".
sv_column_profile(c(" Male", "male", "Female", NA)) sv_column_profile(c(54, 61, 47, 999, NA))$issuessv_column_profile(c(" Male", "male", "Female", NA)) sv_column_profile(c(54, 61, 47, 999, NA))$issues
Compares distinct values between two vectors (e.g. columns mapped across tables), computing exact matches, values only in x, values only in y, fuzzy/near-matches using Levenshtein distance (adist), and comprehensive match statistics.
sv_detect_discrepancies(x, y, max_distance = 2)sv_detect_discrepancies(x, y, max_distance = 2)
x |
Vector of values from the first column. |
y |
Vector of values from the second column. |
max_distance |
Maximum Levenshtein edit distance for fuzzy matching (default 2). |
A list with elements:
exact_matches: character vector of values present in both x and y.
fuzzy_matches: data.frame with columns x, y, distance.
only_in_x: character vector of values present only in x.
only_in_y: character vector of values present only in y.
stats: list of match statistics (counts, NA counts, match rate).
match_stats: alias to stats.
Escape R Identifiers with Backticks If Non-Syntactic
sv_escape_ident(x)sv_escape_ident(x)
x |
Character vector of identifier names. |
Character vector of identifiers, escaped with backticks if necessary.
Parses code fence blocks (```r ... ```, ```R ... ```, ``` ... ```)
out of LLM responses. If multiple fences exist, concatenates them. If no fence
is found, falls back to the trimmed raw text. Strips extraneous whitespace
and returns valid R code.
sv_extract_code(response_text)sv_extract_code(response_text)
response_text |
Character vector containing the LLM response text. |
A character string of extracted R code.
Scans an environment for tabular objects, including data.frame, tibble,
matrix, table, gt, flextable, and sideview_card objects.
sv_find_tables(env = parent.frame())sv_find_tables(env = parent.frame())
env |
Environment to scan (defaults to |
A named list of tabular objects found in the environment.
Inserts tidyverse pipelines or generated code directly into the user's active
document buffer at the current cursor location via rstudioapi::insertText().
If RStudio is unavailable, running headless, or if no document is currently open,
falls back gracefully by returning a structured status list containing the code.
sv_insert_code(code, location = NULL, ...)sv_insert_code(code, location = NULL, ...)
code |
Character vector or scalar string containing the code to insert. Multiple elements are joined by newline characters. |
location |
Optional cursor position or range for |
... |
Additional arguments passed to |
A named list with:
success |
Logical indicating whether insertion into editor succeeded. |
destination |
Character |
code |
Character string of the normalized code. |
message |
Character description of the result or error. |
res <- sv_insert_code("library(dplyr)")res <- sv_insert_code("library(dplyr)")
Safely tests whether the RStudio API is running and operational in the current session without raising errors in headless, testing, or CI environments.
sv_is_rstudio_available()sv_is_rstudio_available()
Logical scalar (TRUE if RStudio is running and accessible, FALSE otherwise).
sv_is_rstudio_available()sv_is_rstudio_available()
Checks a join before you run it: how many rows match in each direction, the
key relationship (one-to-one, one-to-many, many-to-many), how many rows each
join type returns, missing and duplicated keys, a sample of unmatched keys,
and fixes that would match more rows, each measured on its own (trimming
whitespace, ignoring case, dropping leading zeros). Keys are compared the way dplyr joins compare
them by default, so NA matches NA.
sv_join_diagnostics( x, y, by, sample_n = 5L, x_name = "x", y_name = "y", rule = NULL )sv_join_diagnostics( x, y, by, sample_n = 5L, x_name = "x", y_name = "y", rule = NULL )
x, y
|
Tables to join ( |
by |
Join columns: a character vector as in |
sample_n |
Number of unmatched keys to list for each side. |
x_name, y_name
|
Table names used in messages. |
rule |
Optional date rule for the join, a list with the fields of a join
step's rule: |
The canvas runs this whenever two columns are connected and shows the result on the join step and in the Discrepancy tab.
An object of class sv_join_diagnostics: a list with by
(data frame of x/y columns), n_x, n_y, distinct_x, distinct_y,
distinct_matched, matched_x, matched_y (rows with a partner),
match_rate_x, match_rate_y, na_x, na_y (rows with a missing key),
dup_keys_x, dup_keys_y (keys that occur more than once),
relationship, rows (named list of row counts per join type),
unmatched_x, unmatched_y (sample keys), type_issues, hints (list
of fix, label, extra_x, extra_y), strict_args, warnings and
status ("ok", "warn" or "error").
strict_args is a named list with an entry per join type (left_join,
inner_join, right_join, full_join) holding the arguments a Strict
join writes (relationship, and unmatched = "error" when every row of
the checked side has a partner); an entry is absent when Strict would write
nothing for that type (no matches; right and full joins under a nearest-match
rule). With a rule the result also has rule, rule_kind (the kind of the
rule's first x column), rule_dropped_x and rule_dropped_y (rows that have a
key partner but no pair that satisfies the rule), and rows$right_join /
rows$full_join are NA under a nearest-match rule.
When x or y is a duckdb table or an Arrow table, the check runs inside
duckdb on the whole table and only the counts come back into R; the result
equals the one for the same data held in memory. If the tables are on two
different duckdb connections the check does not run. Arrow tables are
handed to duckdb with arrow::to_duckdb(), and a data frame is registered
temporarily; both are removed afterwards. Known differences from the
in-memory check: keys of different types are compared as text, double keys
are compared exactly, and an in-memory POSIXct key is compared as text where
a database key is compared as an instant. A date rule runs in duckdb too; its
date-time columns are compared as UTC instants (taken with epoch_us(), so
the session TimeZone and the ICU extension play no part), and a date-time
window adds whole days of 24 hours, as the in-memory check does.
patients <- data.frame(id = c(1, 2, 3, 4), age = c(40, 51, 62, 33)) visits <- data.frame(id = c(1, 1, 2, 5), visit = 1:4) sv_join_diagnostics(patients, visits, by = "id")patients <- data.frame(id = c(1, 2, 3, 4), age = c(40, 51, 62, 33)) visits <- data.frame(id = c(1, 1, 2, 5), visit = 1:4) sv_join_diagnostics(patients, visits, by = "id")
Queries a local Ollama server (/api/tags) or an OpenAI-compatible server
(/models) for the installed or available model names. Useful for choosing
options(sideview.llm_model = ...).
sv_llm_models( backend = c("ollama", "openai"), endpoint = NULL, api_key = NULL, timeout = 5 )sv_llm_models( backend = c("ollama", "openai"), endpoint = NULL, api_key = NULL, timeout = 5 )
backend |
|
endpoint |
Base URL. Defaults as in |
api_key |
API key for OpenAI-compatible servers. |
timeout |
Request timeout in seconds. Default 5. |
A character vector of model names.
Deserializes a previously saved Sideview canvas workspace from a .json or .rds
file and returns a sideview_state object. Optionally launches an interactive session.
sv_load_state(file, tables = NULL, launch = FALSE, format = NULL, ...)sv_load_state(file, tables = NULL, launch = FALSE, format = NULL, ...)
file |
Path to the saved state file ( |
tables |
Optional named list of data frames or tables to associate with loaded cards.
If |
launch |
Logical; if |
format |
Optional format specification ( |
... |
Further arguments for |
A sideview_state object of class c("sideview_state", "list"), or the gadget
result if launch = TRUE in an interactive session.
st <- new_sideview_state() tf <- tempfile(fileext = ".json") sv_save_state(st, tf) loaded <- sv_load_state(tf) print(loaded) unlink(tf)st <- new_sideview_state() tf <- tempfile(fileext = ".json") sv_save_state(st, tf) loaded <- sv_load_state(tf) print(loaded) unlink(tf)
Converts various R table formats (data.frame, tibble, table, gt, flextable, htmlwidgets)
into a standardized sideview_card S3 object for rendering on the 2D infinite canvas.
sv_normalize(x, name = NULL, id = NULL, ...)sv_normalize(x, name = NULL, id = NULL, ...)
x |
An object to normalize (data.frame, tibble, table, gt, flextable, htmlwidget). |
name |
Optional display name for the card. |
id |
Optional unique identifier for the card. |
... |
Additional arguments passed to methods. |
An object of class sideview_card.
Serializes the active Sideview canvas state (cards, positions, filters, connections,
and pipeline code) to either .json or .rds format.
sv_save_state(state, file, format = NULL)sv_save_state(state, file, format = NULL)
state |
A |
file |
Path to the destination file. |
format |
Optional format specification ( |
Invisibly returns the path of the saved file.
st <- new_sideview_state() tf <- tempfile(fileext = ".json") sv_save_state(st, tf) unlink(tf)st <- new_sideview_state() tf <- tempfile(fileext = ".json") sv_save_state(st, tf) unlink(tf)
Sends R code to the RStudio console for immediate evaluation or user inspection. Falls back gracefully without crashing if RStudio is unavailable or running in a headless environment.
sv_send_to_console(code, execute = TRUE, ...)sv_send_to_console(code, execute = TRUE, ...)
code |
Character vector or scalar string containing the code to execute. Multiple elements are joined by newline characters. |
execute |
Logical indicating whether to execute the code immediately ( |
... |
Additional arguments passed to |
A named list with:
success |
Logical indicating whether console transmission succeeded. |
destination |
Character |
code |
Character string of the normalized code. |
message |
Character description of the result or error. |
res <- sv_send_to_console("1 + 1", execute = FALSE)res <- sv_send_to_console("1 + 1", execute = FALSE)
Evaluates pairwise heuristic column relationships across loaded sideview_card
objects or tabular data structures, computing a 3-part composite confidence score based
on name similarity (40%), data type compatibility (20%), and Jaccard value overlap (40%).
sv_suggest_mappings(cards, ..., min_confidence = 0.6)sv_suggest_mappings(cards, ..., min_confidence = 0.6)
cards |
A list of |
... |
Additional cards or tables passed as positional arguments. |
min_confidence |
Minimum confidence threshold (numeric between 0 and 1) for
returned suggestions (default |
A data.frame with columns:
from_tableSource table or card name.
from_colSource column name.
to_tableDestination table or card name.
to_colDestination column name.
confidenceComposite confidence score in [0, 1].
reasonHuman-readable justification describing similarity components.
df1 <- data.frame(patient_id = 1:5, age = c(20, 30, 40, 50, 60)) df2 <- data.frame(patient_id = 3:7, score = c(10, 20, 30, 40, 50)) sv_suggest_mappings(list(patients = df1, visits = df2))df1 <- data.frame(patient_id = 1:5, age = c(20, 30, 40, 50, 60)) df2 <- data.frame(patient_id = 3:7, score = c(10, 20, 30, 40, 50)) sv_suggest_mappings(list(patients = df1, visits = df2))
Builds a theme for sideview() and sideview_widget(): a light/dark mode
plus optional overrides of the canvas design tokens (the --sv-* CSS
custom properties in inst/www/sideview.css).
sv_theme( mode = c("auto", "light", "dark"), primary = NULL, font = NULL, font_mono = NULL, radius = NULL, ... )sv_theme( mode = c("auto", "light", "dark"), primary = NULL, font = NULL, font_mono = NULL, radius = NULL, ... )
mode |
|
primary |
Accent colour for buttons, selections and splines (any CSS
colour that |
font, font_mono
|
Font stacks for text and code. |
radius |
Card corner radius (CSS length, e.g. |
... |
Further token overrides by name, e.g. |
An object of class sv_theme.
sv_theme("dark") sv_theme(primary = "#0f766e", radius = "4px") if (interactive()) sideview(mtcars, theme = sv_theme("dark", primary = "#f59e0b"))sv_theme("dark") sv_theme(primary = "#0f766e", radius = "4px") if (interactive()) sideview(mtcars, theme = sv_theme("dark", primary = "#f59e0b"))