| Title: | Interactive 'dplyr' Data Transformation Blocks |
|---|---|
| Description: | Extends 'blockr.core' with interactive blocks for visual data wrangling using 'dplyr' and 'tidyr' operations. Users can build data transformation pipelines through a graphical interface without writing code directly. Includes blocks for filtering, selecting, mutating, summarizing, joining, and arranging data, with support for complex expressions, grouping operations, and real-time validation. |
| Authors: | Christoph Sax [aut, cre] (ORCID: <https://orcid.org/0000-0002-7192-7044>), Nicolas Bennett [aut], David Granjon [aut], Mike Page [aut], Bristol Myers Squibb [fnd] |
| Maintainer: | Christoph Sax <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 0.1.0.9001 |
| Built: | 2026-05-26 15:07:35 UTC |
| Source: | https://github.com/bristolmyerssquibb/blockr.dplyr |
Exported for reuse by other blockr packages that reuse the shared block-container / row / popover styles.
blockr_blocks_css_dep()blockr_blocks_css_dep()
An htmltools::htmlDependency.
Exported for reuse by other blockr packages that build on the shared JS namespace (e.g. blockr.dm).
blockr_core_js_dep()blockr_core_js_dep()
An htmltools::htmlDependency.
Exported for reuse by other blockr packages that embed the shared expression-input component.
blockr_input_dep()blockr_input_dep()
An htmltools::tagList of htmlDependency objects.
Exported for reuse by other blockr packages that embed the shared select component (e.g. blockr.dm's table pickers).
blockr_select_dep()blockr_select_dep()
An htmltools::tagList of htmlDependency objects.
Returns one entry per column: list(name, label). Skips the type
detection and anyNA() sweep that build_column_summary() does — those
are only needed by the filter block's type-aware condition UI. All other
picker blocks only need the name for the option value and the optional
label for the secondary text slot, so this helper is the lean path.
build_column_picker_meta(df)build_column_picker_meta(df)
df |
A data frame |
label is read from attr(col, "label") (e.g. ADaM datasets). It is
an empty string when the attribute is missing or not a length-1 character.
A list of list(name, label) entries, one per column.
Returns name, type, hasNA, and label for each column — no unique
values. Sent on data arrival so the filter UI can render column dropdowns
instantly. Unique values are fetched on-demand via build_column_values().
build_column_summary(df)build_column_summary(df)
df |
A data frame |
label is read from attr(col, "label") (e.g. ADaM datasets). It is
an empty string when the attribute is missing or not a length-1 character.
Exported as part of the public API so other blockr packages (e.g. blockr.dm) can reuse the same column-metadata protocol.
A list of column summary objects
Computes type, range (numeric), unique values, NA/empty presence, and label for one column. Called on-demand when the user selects a column in the filter block.
build_column_values(df, col)build_column_values(df, col)
df |
A data frame |
col |
Column name (character) |
Exported as part of the public API so other blockr packages (e.g. blockr.dm) can reuse the same column-metadata protocol.
A column info object (list)
Simple selectize-based column picker module used by downstream packages (e.g. blockr.extra).
column_picker_ui(id, label = "Columns", choices = NULL, selected = NULL) column_picker_server(id, get_choices, initial_value = NULL)column_picker_ui(id, label = "Columns", choices = NULL, selected = NULL) column_picker_server(id, get_choices, initial_value = NULL)
id |
Module namespace id |
label |
Label for the input |
choices |
Initial choices |
selected |
Initial selection |
get_choices |
Reactive returning the available column names. |
initial_value |
ReactiveVal holding the initial selection. |
column_picker_ui returns a tagList; column_picker_server
returns a reactive holding the current selection.
Exported for reuse by blockr packages that embed the filter block's JS UI (e.g. blockr.dm's dm filter block).
filter_block_dep()filter_block_dep()
An htmltools::tagList of htmlDependency objects.
Exported as part of the public API so other blockr packages (e.g. blockr.dm) can reuse the same filter-condition → expression protocol.
make_filter_expr(conditions, operator = "&", preserve_order = FALSE)make_filter_expr(conditions, operator = "&", preserve_order = FALSE)
conditions |
List of condition objects from JS. Each has a |
operator |
Global operator: "&" or "|" |
preserve_order |
Reserved; currently unused at this layer. |
A language object like dplyr::filter(.(data), ...)
Sort/arrange block with dynamic rows. Each row has a column picker and a direction toggle (ascending/descending). Auto-submits on any change.
new_arrange_block(state = list(columns = list()), ...)new_arrange_block(state = list(columns = list()), ...)
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_arrange_block( state = list( columns = list( list(column = "Sepal.Length", direction = "desc") ) ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_arrange_block( state = list( columns = list( list(column = "Sepal.Length", direction = "desc") ) ) ), data = list(data = iris) ) }
Combine multiple data frames side-by-side using dplyr::bind_cols.
Minimal UI with no user-configurable parameters.
Variadic block: accepts any number of data inputs via the ...args pattern.
new_bind_cols_block(...)new_bind_cols_block(...)
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_bind_cols_block(), data = list( a = data.frame(x = 1:3), b = data.frame(y = 4:6) ) ) }if (interactive()) { library(blockr.core) serve( new_bind_cols_block(), data = list( a = data.frame(x = 1:3), b = data.frame(y = 4:6) ) ) }
Stack multiple data frames on top of each other using dplyr::bind_rows.
Simple UI with an optional text input for .id column name.
Variadic block: accepts any number of data inputs via the ...args pattern.
new_bind_rows_block(state = list(id_name = ""), ...)new_bind_rows_block(state = list(id_name = ""), ...)
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_bind_rows_block( state = list(id_name = "source") ), data = list(a = iris[1:5, ], b = iris[6:10, ]) ) }if (interactive()) { library(blockr.core) serve( new_bind_rows_block( state = list(id_name = "source") ), data = list(a = iris[1:5, ], b = iris[6:10, ]) ) }
Unified filter block combining simple mode (column + operator + values) and expression mode (free R code) in a single JS-driven UI.
new_filter_block(state = list(conditions = list(), operator = "&"), ...)new_filter_block(state = list(conditions = list(), operator = "&"), ...)
state |
List with
|
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_filter_block( state = list( conditions = list( list(type = "values", column = "Species", values = list("setosa"), mode = "include") ), operator = "&" ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_filter_block( state = list( conditions = list( list(type = "values", column = "Species", values = list("setosa"), mode = "include") ), operator = "&" ) ), data = list(data = iris) ) }
Binary join block combining key-based joins (equi and non-equi) with expression mode (free R code for join conditions) in a single JS-driven UI. Takes two data inputs (x and y).
new_join_block( state = list(type = "left_join", keys = list(), exprs = list(), suffix_x = ".x", suffix_y = ".y"), ... )new_join_block( state = list(type = "left_join", keys = list(), exprs = list(), suffix_x = ".x", suffix_y = ".y"), ... )
state |
List with:
|
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_join_block( state = list( type = "left_join", keys = list( list(xCol = "id", op = "==", yCol = "id") ), exprs = list(), suffix_x = ".x", suffix_y = ".y" ) ), data = list(x = iris, y = iris) ) }if (interactive()) { library(blockr.core) serve( new_join_block( state = list( type = "left_join", keys = list( list(xCol = "id", op = "==", yCol = "id") ), exprs = list(), suffix_x = ".x", suffix_y = ".y" ) ), data = list(x = iris, y = iris) ) }
JS-driven mutate block with dynamic mutation rows of name + expression pairs. Each mutation defines a new or modified column using an R expression.
new_mutate_block( state = list(mutations = list(list(name = "", expr = "")), by = list()), ... )new_mutate_block( state = list(mutations = list(list(name = "", expr = "")), by = list()), ... )
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_mutate_block( state = list( mutations = list( list(name = "Sepal.Ratio", expr = "Sepal.Length / Sepal.Width") ) ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_mutate_block( state = list( mutations = list( list(name = "Sepal.Ratio", expr = "Sepal.Length / Sepal.Width") ) ) ), data = list(data = iris) ) }
Reshape data from wide to long format using tidyr::pivot_longer. Multi-select column picker with text inputs for names_to, values_to, names_prefix, and a toggle for values_drop_na. Auto-submits on any change.
new_pivot_longer_block( state = list(cols = list(), names_to = "name", values_to = "value", values_drop_na = FALSE, names_prefix = ""), ... )new_pivot_longer_block( state = list(cols = list(), names_to = "name", values_to = "value", values_drop_na = FALSE, names_prefix = ""), ... )
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_pivot_longer_block( state = list( cols = list("Sepal.Length", "Sepal.Width"), names_to = "measurement", values_to = "value", values_drop_na = FALSE, names_prefix = "" ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_pivot_longer_block( state = list( cols = list("Sepal.Length", "Sepal.Width"), names_to = "measurement", values_to = "value", values_drop_na = FALSE, names_prefix = "" ) ), data = list(data = iris) ) }
Reshape data from long to wide format using tidyr::pivot_wider. Multi-selects for names_from, values_from, and id_cols (optional). Text inputs for values_fill, names_sep, names_prefix. Auto-submits on any change.
new_pivot_wider_block( state = list(names_from = list(), values_from = list(), id_cols = list(), values_fill = NULL, names_sep = "_", names_prefix = ""), ... )new_pivot_wider_block( state = list(names_from = list(), values_from = list(), id_cols = list(), values_fill = NULL, names_sep = "_", names_prefix = ""), ... )
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_pivot_wider_block( state = list( names_from = list("Species"), values_from = list("Sepal.Length"), id_cols = list(), values_fill = NULL, names_sep = "_", names_prefix = "" ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_pivot_wider_block( state = list( names_from = list("Species"), values_from = list("Sepal.Length"), id_cols = list(), values_fill = NULL, names_sep = "_", names_prefix = "" ) ), data = list(data = iris) ) }
Column rename block with dynamic rows. Each row maps an old column name to a new name. Auto-submits on any change (300ms debounce for text input).
new_rename_block(state = list(renames = list()), ...)new_rename_block(state = list(renames = list()), ...)
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_rename_block( state = list( renames = list(sepal_len = "Sepal.Length") ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_rename_block( state = list( renames = list(sepal_len = "Sepal.Length") ) ), data = list(data = iris) ) }
Column selection block with reorderable multi-select, exclude toggle, and distinct toggle. Auto-submits on any change.
new_select_block( state = list(columns = list(), exclude = FALSE, distinct = FALSE), ... )new_select_block( state = list(columns = list(), exclude = FALSE, distinct = FALSE), ... )
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_select_block( state = list( columns = list("Sepal.Length", "Species"), exclude = FALSE, distinct = FALSE ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_select_block( state = list( columns = list("Sepal.Length", "Species"), exclude = FALSE, distinct = FALSE ) ), data = list(data = iris) ) }
Split a single column into multiple columns using tidyr::separate. Single select for source column, text input for into (comma-separated new column names), text input for sep, toggle pills for remove and convert. Auto-submits on any change.
new_separate_block( state = list(col = "", into = list(), sep = "[^[:alnum:]]+", remove = TRUE, convert = FALSE, extra = "warn", fill = "warn"), ... )new_separate_block( state = list(col = "", into = list(), sep = "[^[:alnum:]]+", remove = TRUE, convert = FALSE, extra = "warn", fill = "warn"), ... )
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) df <- data.frame(x = c("a-1", "b-2", "c-3"), stringsAsFactors = FALSE) serve( new_separate_block( state = list( col = "x", into = list("letter", "number"), sep = "-", remove = TRUE, convert = FALSE, extra = "warn", fill = "warn" ) ), data = list(data = df) ) }if (interactive()) { library(blockr.core) df <- data.frame(x = c("a-1", "b-2", "c-3"), stringsAsFactors = FALSE) serve( new_separate_block( state = list( col = "x", into = list("letter", "number"), sep = "-", remove = TRUE, convert = FALSE, extra = "warn", fill = "warn" ) ), data = list(data = df) ) }
Subset rows by position using dplyr::slice_* family of functions. Single select for type (head/tail/min/max/sample), number input for n, optional column selects for order_by and weight_by, toggle pills for with_ties and replace, multi-select for grouping (.by). Auto-submits on any change.
new_slice_block( state = list(type = "head", n = 5L, prop = NULL, order_by = "", with_ties = TRUE, weight_by = "", replace = FALSE, rows = "1:5", by = list()), ... )new_slice_block( state = list(type = "head", n = 5L, prop = NULL, order_by = "", with_ties = TRUE, weight_by = "", replace = FALSE, rows = "1:5", by = list()), ... )
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_slice_block( state = list( type = "head", n = 10L, prop = NULL, order_by = "", with_ties = TRUE, weight_by = "", replace = FALSE, by = list() ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_slice_block( state = list( type = "head", n = 10L, prop = NULL, order_by = "", with_ties = TRUE, weight_by = "", replace = FALSE, by = list() ) ), data = list(data = iris) ) }
JS-driven summarize block with two row types: simple (function + column) and expression (free R code). Includes a group-by section for grouped summaries.
new_summarize_block(state = list(summaries = list(), by = list()), ...)new_summarize_block(state = list(summaries = list(), by = list()), ...)
state |
List with
|
... |
Additional arguments forwarded to |
The list of available summary functions can be extended using the
blockr.dplyr.summary_functions option. Set this option to a named
character vector where names are display labels and values are function
calls with proper namespacing:
options(
blockr.dplyr.summary_functions = c(
"extract parentheses (paren_num)" = "blockr.topline::paren_num"
)
)
if (interactive()) { library(blockr.core) serve( new_summarize_block( state = list( summaries = list( list(type = "simple", name = "avg_sl", func = "mean", col = "Sepal.Length") ), by = list("Species") ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_summarize_block( state = list( summaries = list( list(type = "simple", name = "avg_sl", func = "mean", col = "Sepal.Length") ), by = list("Species") ) ), data = list(data = iris) ) }
Paste together multiple columns into one using tidyr::unite. Text input for new column name, multi-select for columns to unite, text input for separator, toggle pills for remove and na.rm. Auto-submits on any change.
new_unite_block( state = list(col = "united", cols = list(), sep = "_", remove = TRUE, na_rm = FALSE), ... )new_unite_block( state = list(col = "united", cols = list(), sep = "_", remove = TRUE, na_rm = FALSE), ... )
state |
List with |
... |
Additional arguments forwarded to |
if (interactive()) { library(blockr.core) serve( new_unite_block( state = list( col = "full_name", cols = list("Sepal.Length", "Sepal.Width"), sep = "_", remove = TRUE, na.rm = FALSE ) ), data = list(data = iris) ) }if (interactive()) { library(blockr.core) serve( new_unite_block( state = list( col = "full_name", cols = list("Sepal.Length", "Sepal.Width"), sep = "_", remove = TRUE, na.rm = FALSE ) ), data = list(data = iris) ) }