From 4720709478e022a5cc539317deaac9755943ad9d Mon Sep 17 00:00:00 2001 From: etiennebacher Date: Wed, 8 Jan 2025 11:42:38 +0100 Subject: [PATCH 1/6] init --- DESCRIPTION | 1 + R/000-wrappers.R | 14 +++++++++ R/expr-meta.R | 47 ++++++++++++++++++++++++++++-- src/init.c | 12 ++++++++ src/rust/api.h | 2 ++ src/rust/src/expr/meta.rs | 8 +++++ tests/testthat/_snaps/expr-meta.md | 23 +++++++++++++++ tests/testthat/test-expr-meta.R | 19 ++++++++++++ 8 files changed, 124 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index ab550b67..1783908c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,6 +22,7 @@ Suggests: cli, clock, data.table, + DiagrammeR, hms, jsonlite, nanoarrow, diff --git a/R/000-wrappers.R b/R/000-wrappers.R index b72ae235..7f638247 100644 --- a/R/000-wrappers.R +++ b/R/000-wrappers.R @@ -2410,6 +2410,18 @@ class(`PlRDataType`) <- c("PlRDataType__bundle", "savvy_neopolars__sealed") } } +`PlRExpr_meta_tree_format` <- function(self) { + function() { + .Call(savvy_PlRExpr_meta_tree_format__impl, `self`) + } +} + +`PlRExpr_meta_show_graph` <- function(self) { + function() { + .Call(savvy_PlRExpr_meta_show_graph__impl, `self`) + } +} + `PlRExpr_name_keep` <- function(self) { function() { .savvy_wrap_PlRExpr(.Call(savvy_PlRExpr_name_keep__impl, `self`)) @@ -3177,6 +3189,8 @@ class(`PlRDataType`) <- c("PlRDataType__bundle", "savvy_neopolars__sealed") e$`_meta_as_selector` <- `PlRExpr__meta_as_selector`(ptr) e$`compute_tree_format` <- `PlRExpr_compute_tree_format`(ptr) e$`meta_is_column` <- `PlRExpr_meta_is_column`(ptr) + e$`meta_tree_format` <- `PlRExpr_meta_tree_format`(ptr) + e$`meta_show_graph` <- `PlRExpr_meta_show_graph`(ptr) e$`name_keep` <- `PlRExpr_name_keep`(ptr) e$`name_prefix` <- `PlRExpr_name_prefix`(ptr) e$`name_suffix` <- `PlRExpr_name_suffix`(ptr) diff --git a/R/expr-meta.R b/R/expr-meta.R index 7c74f01a..17a1dcf9 100644 --- a/R/expr-meta.R +++ b/R/expr-meta.R @@ -186,7 +186,6 @@ expr_meta_root_names <- function() { self$`_rexpr`$meta_root_names() } -# TODO: add equivalent of meta.show_graph of Python Polars #' Format the expression as a tree #' #' @return A character vector @@ -195,10 +194,54 @@ expr_meta_root_names <- function() { #' my_expr$meta$tree_format() |> #' cat() expr_meta_tree_format <- function() { - self$`_rexpr`$compute_tree_format(FALSE) |> + self$`_rexpr`$meta_tree_format() |> wrap() } +#' Format the expression as a Graphviz graph +#' +#' Note that Graphviz must be installed to render the visualization (if not +#' already present, you can download it here: +#' ``_). +#' +#' @inheritParams rlang::args_dots_empty +#' @param show Show the figure. +#' @param output_path Write the figure to disk. +#' @param raw_output Return dot syntax. This cannot be combined with `show` and +#' / or `output_path`. +#' +#' @return +#' If `show = TRUE`, the same output as `DiagrammeR::grViz()`. +#' If `raw_output = TRUE`, a string containing the GraphViz code for the graph. +#' +#' @examplesIf requireNamespace("DiagrammeR", quietly = TRUE) + #' my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 + #' my_expr$meta$show_graph() +expr_meta_show_graph <- function( + ..., + show = TRUE, + output_path = NULL, + raw_output = FALSE) { + wrap({ + rlang::check_dots_empty0(...) + dot <- self$`_rexpr`$meta_show_graph() |> + wrap() + if (isTRUE(raw_output)) { + return(dot) + } + rlang::check_installed("DiagrammeR") + graph <- DiagrammeR::grViz(dot) + if (!is.null(output_path)) { + rlang::check_installed(c("DiagrammeRsvg", "rsvg")) + graph |> + DiagrammeRsvg::export_svg() |> + charToRaw() |> + rsvg::rsvg_svg(output_path) + } + graph + }) +} + #' Indicate if this expression only selects columns (optionally with aliasing) #' #' This can include bare columns, column matches by regex or dtype, selectors diff --git a/src/init.c b/src/init.c index 35e8666a..a4e5e425 100644 --- a/src/init.c +++ b/src/init.c @@ -1844,6 +1844,16 @@ SEXP savvy_PlRExpr_meta_is_column__impl(SEXP self__) { return handle_result(res); } +SEXP savvy_PlRExpr_meta_tree_format__impl(SEXP self__) { + SEXP res = savvy_PlRExpr_meta_tree_format__ffi(self__); + return handle_result(res); +} + +SEXP savvy_PlRExpr_meta_show_graph__impl(SEXP self__) { + SEXP res = savvy_PlRExpr_meta_show_graph__ffi(self__); + return handle_result(res); +} + SEXP savvy_PlRExpr_name_keep__impl(SEXP self__) { SEXP res = savvy_PlRExpr_name_keep__ffi(self__); return handle_result(res); @@ -2893,6 +2903,8 @@ static const R_CallMethodDef CallEntries[] = { {"savvy_PlRExpr__meta_as_selector__impl", (DL_FUNC) &savvy_PlRExpr__meta_as_selector__impl, 1}, {"savvy_PlRExpr_compute_tree_format__impl", (DL_FUNC) &savvy_PlRExpr_compute_tree_format__impl, 2}, {"savvy_PlRExpr_meta_is_column__impl", (DL_FUNC) &savvy_PlRExpr_meta_is_column__impl, 1}, + {"savvy_PlRExpr_meta_tree_format__impl", (DL_FUNC) &savvy_PlRExpr_meta_tree_format__impl, 1}, + {"savvy_PlRExpr_meta_show_graph__impl", (DL_FUNC) &savvy_PlRExpr_meta_show_graph__impl, 1}, {"savvy_PlRExpr_name_keep__impl", (DL_FUNC) &savvy_PlRExpr_name_keep__impl, 1}, {"savvy_PlRExpr_name_prefix__impl", (DL_FUNC) &savvy_PlRExpr_name_prefix__impl, 2}, {"savvy_PlRExpr_name_suffix__impl", (DL_FUNC) &savvy_PlRExpr_name_suffix__impl, 2}, diff --git a/src/rust/api.h b/src/rust/api.h index e0fa2fc0..ba8e46ce 100644 --- a/src/rust/api.h +++ b/src/rust/api.h @@ -370,6 +370,8 @@ SEXP savvy_PlRExpr__meta_selector_sub__ffi(SEXP self__, SEXP c_arg__other); SEXP savvy_PlRExpr__meta_as_selector__ffi(SEXP self__); SEXP savvy_PlRExpr_compute_tree_format__ffi(SEXP self__, SEXP c_arg__display_as_dot); SEXP savvy_PlRExpr_meta_is_column__ffi(SEXP self__); +SEXP savvy_PlRExpr_meta_tree_format__ffi(SEXP self__); +SEXP savvy_PlRExpr_meta_show_graph__ffi(SEXP self__); SEXP savvy_PlRExpr_name_keep__ffi(SEXP self__); SEXP savvy_PlRExpr_name_prefix__ffi(SEXP self__, SEXP c_arg__prefix); SEXP savvy_PlRExpr_name_suffix__ffi(SEXP self__, SEXP c_arg__suffix); diff --git a/src/rust/src/expr/meta.rs b/src/rust/src/expr/meta.rs index e8e4729b..5ef5cc52 100644 --- a/src/rust/src/expr/meta.rs +++ b/src/rust/src/expr/meta.rs @@ -119,4 +119,12 @@ impl PlRExpr { fn meta_is_column(&self) -> Result { self.inner.clone().meta().is_column().try_into() } + + fn meta_tree_format(&self) -> Result { + self.compute_tree_format(false) + } + + fn meta_show_graph(&self) -> Result { + self.compute_tree_format(true) + } } diff --git a/tests/testthat/_snaps/expr-meta.md b/tests/testthat/_snaps/expr-meta.md index 50fa2b35..fd07a202 100644 --- a/tests/testthat/_snaps/expr-meta.md +++ b/tests/testthat/_snaps/expr-meta.md @@ -93,3 +93,26 @@ } +# meta$show_graph + + Code + cat(my_expr$meta$show_graph(raw_output = TRUE)) + Output + graph { + n00 [label="binary: /", ordering="out"] + n00 -- n11 + n00 -- n10 + n10 [label="lit(dyn float: 2.0)", ordering="out"] + n11 [label="window", ordering="out"] + n11 -- n22 + n11 -- n21 + n21 [label="col(ham)", ordering="out"] + n22 [label="sum", ordering="out"] + n22 -- n32 + n32 [label="binary: *", ordering="out"] + n32 -- n43 + n32 -- n42 + n42 [label="col(bar)", ordering="out"] + n43 [label="col(foo)", ordering="out"] + } + diff --git a/tests/testthat/test-expr-meta.R b/tests/testthat/test-expr-meta.R index 7990fd7b..70bc62da 100644 --- a/tests/testthat/test-expr-meta.R +++ b/tests/testthat/test-expr-meta.R @@ -118,3 +118,22 @@ test_that("meta$serialize", { jsonlite::prettify() ) }) + +test_that("meta$show_graph", { + skip_if_not_installed("DiagrammeR") + skip_if_not_installed("DiagrammeRsvg") + skip_if_not_installed("rsvg") + + my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 + + # default + expect_equal(class(my_expr$meta$show_graph()), c("grViz", "htmlwidget")) + + # raw_output + expect_snapshot(cat(my_expr$meta$show_graph(raw_output = TRUE))) + + # output_path + temp <- withr::local_tempfile(fileext = ".svg") + expect_silent(my_expr$meta$show_graph(output_path = temp)) + expect_true(file.exists(temp)) +}) From e0f12a045b66fb92592cd92904026d3224ebc515 Mon Sep 17 00:00:00 2001 From: etiennebacher Date: Wed, 8 Jan 2025 11:44:28 +0100 Subject: [PATCH 2/6] more suggests --- DESCRIPTION | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DESCRIPTION b/DESCRIPTION index 1783908c..9e97c837 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,10 +23,12 @@ Suggests: clock, data.table, DiagrammeR, + DiagrammeRsvg, hms, jsonlite, nanoarrow, patrick, + rsvg, testthat (>= 3.0.0), tibble, vctrs, From 7915bfc058e5ea0bb28634c34b42a8c74a93c33f Mon Sep 17 00:00:00 2001 From: etiennebacher Date: Wed, 8 Jan 2025 11:46:41 +0100 Subject: [PATCH 3/6] redoc --- R/expr-meta.R | 4 ++-- man/expr_meta_show_graph.Rd | 33 +++++++++++++++++++++++++++++++++ tests/testthat/test-expr-meta.R | 5 +++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 man/expr_meta_show_graph.Rd diff --git a/R/expr-meta.R b/R/expr-meta.R index 17a1dcf9..cab97d7d 100644 --- a/R/expr-meta.R +++ b/R/expr-meta.R @@ -215,8 +215,8 @@ expr_meta_tree_format <- function() { #' If `raw_output = TRUE`, a string containing the GraphViz code for the graph. #' #' @examplesIf requireNamespace("DiagrammeR", quietly = TRUE) - #' my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 - #' my_expr$meta$show_graph() +#' my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 +#' my_expr$meta$show_graph() expr_meta_show_graph <- function( ..., show = TRUE, diff --git a/man/expr_meta_show_graph.Rd b/man/expr_meta_show_graph.Rd new file mode 100644 index 00000000..7718dafa --- /dev/null +++ b/man/expr_meta_show_graph.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/expr-meta.R +\name{expr_meta_show_graph} +\alias{expr_meta_show_graph} +\title{Format the expression as a Graphviz graph} +\usage{ +expr_meta_show_graph(..., show = TRUE, output_path = NULL, raw_output = FALSE) +} +\arguments{ +\item{...}{These dots are for future extensions and must be empty.} + +\item{show}{Show the figure.} + +\item{output_path}{Write the figure to disk.} + +\item{raw_output}{Return dot syntax. This cannot be combined with \code{show} and +/ or \code{output_path}.} +} +\value{ +If \code{show = TRUE}, the same output as \code{DiagrammeR::grViz()}. +If \code{raw_output = TRUE}, a string containing the GraphViz code for the graph. +} +\description{ +Note that Graphviz must be installed to render the visualization (if not +already present, you can download it here: +\verb{}_). +} +\examples{ +\dontshow{if (requireNamespace("DiagrammeR", quietly = TRUE)) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 +my_expr$meta$show_graph() +\dontshow{\}) # examplesIf} +} diff --git a/tests/testthat/test-expr-meta.R b/tests/testthat/test-expr-meta.R index 70bc62da..9d168421 100644 --- a/tests/testthat/test-expr-meta.R +++ b/tests/testthat/test-expr-meta.R @@ -136,4 +136,9 @@ test_that("meta$show_graph", { temp <- withr::local_tempfile(fileext = ".svg") expect_silent(my_expr$meta$show_graph(output_path = temp)) expect_true(file.exists(temp)) + + expect_error( + my_expr$meta$show_graph(TRUE), + "Did you forget to" + ) }) From f5280f12952674809c9643e56907e12c3763597b Mon Sep 17 00:00:00 2001 From: etiennebacher Date: Wed, 8 Jan 2025 11:42:38 +0100 Subject: [PATCH 4/6] init --- DESCRIPTION | 1 + R/000-wrappers.R | 14 +++++++++ R/expr-meta.R | 47 ++++++++++++++++++++++++++++-- src/init.c | 12 ++++++++ src/rust/api.h | 2 ++ src/rust/src/expr/meta.rs | 8 +++++ tests/testthat/_snaps/expr-meta.md | 23 +++++++++++++++ tests/testthat/test-expr-meta.R | 19 ++++++++++++ 8 files changed, 124 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index ab550b67..1783908c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,6 +22,7 @@ Suggests: cli, clock, data.table, + DiagrammeR, hms, jsonlite, nanoarrow, diff --git a/R/000-wrappers.R b/R/000-wrappers.R index 3ef0d6a1..a50d2ae2 100644 --- a/R/000-wrappers.R +++ b/R/000-wrappers.R @@ -2410,6 +2410,18 @@ class(`PlRDataType`) <- c("PlRDataType__bundle", "savvy_neopolars__sealed") } } +`PlRExpr_meta_tree_format` <- function(self) { + function() { + .Call(savvy_PlRExpr_meta_tree_format__impl, `self`) + } +} + +`PlRExpr_meta_show_graph` <- function(self) { + function() { + .Call(savvy_PlRExpr_meta_show_graph__impl, `self`) + } +} + `PlRExpr_name_keep` <- function(self) { function() { .savvy_wrap_PlRExpr(.Call(savvy_PlRExpr_name_keep__impl, `self`)) @@ -3177,6 +3189,8 @@ class(`PlRDataType`) <- c("PlRDataType__bundle", "savvy_neopolars__sealed") e$`_meta_as_selector` <- `PlRExpr__meta_as_selector`(ptr) e$`compute_tree_format` <- `PlRExpr_compute_tree_format`(ptr) e$`meta_is_column` <- `PlRExpr_meta_is_column`(ptr) + e$`meta_tree_format` <- `PlRExpr_meta_tree_format`(ptr) + e$`meta_show_graph` <- `PlRExpr_meta_show_graph`(ptr) e$`name_keep` <- `PlRExpr_name_keep`(ptr) e$`name_prefix` <- `PlRExpr_name_prefix`(ptr) e$`name_suffix` <- `PlRExpr_name_suffix`(ptr) diff --git a/R/expr-meta.R b/R/expr-meta.R index 7c74f01a..17a1dcf9 100644 --- a/R/expr-meta.R +++ b/R/expr-meta.R @@ -186,7 +186,6 @@ expr_meta_root_names <- function() { self$`_rexpr`$meta_root_names() } -# TODO: add equivalent of meta.show_graph of Python Polars #' Format the expression as a tree #' #' @return A character vector @@ -195,10 +194,54 @@ expr_meta_root_names <- function() { #' my_expr$meta$tree_format() |> #' cat() expr_meta_tree_format <- function() { - self$`_rexpr`$compute_tree_format(FALSE) |> + self$`_rexpr`$meta_tree_format() |> wrap() } +#' Format the expression as a Graphviz graph +#' +#' Note that Graphviz must be installed to render the visualization (if not +#' already present, you can download it here: +#' ``_). +#' +#' @inheritParams rlang::args_dots_empty +#' @param show Show the figure. +#' @param output_path Write the figure to disk. +#' @param raw_output Return dot syntax. This cannot be combined with `show` and +#' / or `output_path`. +#' +#' @return +#' If `show = TRUE`, the same output as `DiagrammeR::grViz()`. +#' If `raw_output = TRUE`, a string containing the GraphViz code for the graph. +#' +#' @examplesIf requireNamespace("DiagrammeR", quietly = TRUE) + #' my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 + #' my_expr$meta$show_graph() +expr_meta_show_graph <- function( + ..., + show = TRUE, + output_path = NULL, + raw_output = FALSE) { + wrap({ + rlang::check_dots_empty0(...) + dot <- self$`_rexpr`$meta_show_graph() |> + wrap() + if (isTRUE(raw_output)) { + return(dot) + } + rlang::check_installed("DiagrammeR") + graph <- DiagrammeR::grViz(dot) + if (!is.null(output_path)) { + rlang::check_installed(c("DiagrammeRsvg", "rsvg")) + graph |> + DiagrammeRsvg::export_svg() |> + charToRaw() |> + rsvg::rsvg_svg(output_path) + } + graph + }) +} + #' Indicate if this expression only selects columns (optionally with aliasing) #' #' This can include bare columns, column matches by regex or dtype, selectors diff --git a/src/init.c b/src/init.c index 872bd39a..37605a26 100644 --- a/src/init.c +++ b/src/init.c @@ -1844,6 +1844,16 @@ SEXP savvy_PlRExpr_meta_is_column__impl(SEXP self__) { return handle_result(res); } +SEXP savvy_PlRExpr_meta_tree_format__impl(SEXP self__) { + SEXP res = savvy_PlRExpr_meta_tree_format__ffi(self__); + return handle_result(res); +} + +SEXP savvy_PlRExpr_meta_show_graph__impl(SEXP self__) { + SEXP res = savvy_PlRExpr_meta_show_graph__ffi(self__); + return handle_result(res); +} + SEXP savvy_PlRExpr_name_keep__impl(SEXP self__) { SEXP res = savvy_PlRExpr_name_keep__ffi(self__); return handle_result(res); @@ -2908,6 +2918,8 @@ static const R_CallMethodDef CallEntries[] = { {"savvy_PlRExpr__meta_as_selector__impl", (DL_FUNC) &savvy_PlRExpr__meta_as_selector__impl, 1}, {"savvy_PlRExpr_compute_tree_format__impl", (DL_FUNC) &savvy_PlRExpr_compute_tree_format__impl, 2}, {"savvy_PlRExpr_meta_is_column__impl", (DL_FUNC) &savvy_PlRExpr_meta_is_column__impl, 1}, + {"savvy_PlRExpr_meta_tree_format__impl", (DL_FUNC) &savvy_PlRExpr_meta_tree_format__impl, 1}, + {"savvy_PlRExpr_meta_show_graph__impl", (DL_FUNC) &savvy_PlRExpr_meta_show_graph__impl, 1}, {"savvy_PlRExpr_name_keep__impl", (DL_FUNC) &savvy_PlRExpr_name_keep__impl, 1}, {"savvy_PlRExpr_name_prefix__impl", (DL_FUNC) &savvy_PlRExpr_name_prefix__impl, 2}, {"savvy_PlRExpr_name_suffix__impl", (DL_FUNC) &savvy_PlRExpr_name_suffix__impl, 2}, diff --git a/src/rust/api.h b/src/rust/api.h index 3f59736f..56d08c61 100644 --- a/src/rust/api.h +++ b/src/rust/api.h @@ -370,6 +370,8 @@ SEXP savvy_PlRExpr__meta_selector_sub__ffi(SEXP self__, SEXP c_arg__other); SEXP savvy_PlRExpr__meta_as_selector__ffi(SEXP self__); SEXP savvy_PlRExpr_compute_tree_format__ffi(SEXP self__, SEXP c_arg__display_as_dot); SEXP savvy_PlRExpr_meta_is_column__ffi(SEXP self__); +SEXP savvy_PlRExpr_meta_tree_format__ffi(SEXP self__); +SEXP savvy_PlRExpr_meta_show_graph__ffi(SEXP self__); SEXP savvy_PlRExpr_name_keep__ffi(SEXP self__); SEXP savvy_PlRExpr_name_prefix__ffi(SEXP self__, SEXP c_arg__prefix); SEXP savvy_PlRExpr_name_suffix__ffi(SEXP self__, SEXP c_arg__suffix); diff --git a/src/rust/src/expr/meta.rs b/src/rust/src/expr/meta.rs index e8e4729b..5ef5cc52 100644 --- a/src/rust/src/expr/meta.rs +++ b/src/rust/src/expr/meta.rs @@ -119,4 +119,12 @@ impl PlRExpr { fn meta_is_column(&self) -> Result { self.inner.clone().meta().is_column().try_into() } + + fn meta_tree_format(&self) -> Result { + self.compute_tree_format(false) + } + + fn meta_show_graph(&self) -> Result { + self.compute_tree_format(true) + } } diff --git a/tests/testthat/_snaps/expr-meta.md b/tests/testthat/_snaps/expr-meta.md index 50fa2b35..fd07a202 100644 --- a/tests/testthat/_snaps/expr-meta.md +++ b/tests/testthat/_snaps/expr-meta.md @@ -93,3 +93,26 @@ } +# meta$show_graph + + Code + cat(my_expr$meta$show_graph(raw_output = TRUE)) + Output + graph { + n00 [label="binary: /", ordering="out"] + n00 -- n11 + n00 -- n10 + n10 [label="lit(dyn float: 2.0)", ordering="out"] + n11 [label="window", ordering="out"] + n11 -- n22 + n11 -- n21 + n21 [label="col(ham)", ordering="out"] + n22 [label="sum", ordering="out"] + n22 -- n32 + n32 [label="binary: *", ordering="out"] + n32 -- n43 + n32 -- n42 + n42 [label="col(bar)", ordering="out"] + n43 [label="col(foo)", ordering="out"] + } + diff --git a/tests/testthat/test-expr-meta.R b/tests/testthat/test-expr-meta.R index 7990fd7b..70bc62da 100644 --- a/tests/testthat/test-expr-meta.R +++ b/tests/testthat/test-expr-meta.R @@ -118,3 +118,22 @@ test_that("meta$serialize", { jsonlite::prettify() ) }) + +test_that("meta$show_graph", { + skip_if_not_installed("DiagrammeR") + skip_if_not_installed("DiagrammeRsvg") + skip_if_not_installed("rsvg") + + my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 + + # default + expect_equal(class(my_expr$meta$show_graph()), c("grViz", "htmlwidget")) + + # raw_output + expect_snapshot(cat(my_expr$meta$show_graph(raw_output = TRUE))) + + # output_path + temp <- withr::local_tempfile(fileext = ".svg") + expect_silent(my_expr$meta$show_graph(output_path = temp)) + expect_true(file.exists(temp)) +}) From 690ab73e489888c6ee62eb781c464b2e25107b1f Mon Sep 17 00:00:00 2001 From: etiennebacher Date: Wed, 8 Jan 2025 11:44:28 +0100 Subject: [PATCH 5/6] more suggests --- DESCRIPTION | 2 ++ 1 file changed, 2 insertions(+) diff --git a/DESCRIPTION b/DESCRIPTION index 1783908c..9e97c837 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -23,10 +23,12 @@ Suggests: clock, data.table, DiagrammeR, + DiagrammeRsvg, hms, jsonlite, nanoarrow, patrick, + rsvg, testthat (>= 3.0.0), tibble, vctrs, From ace665f4c8d67e43bb70504e4d9242ffff886e1d Mon Sep 17 00:00:00 2001 From: etiennebacher Date: Wed, 8 Jan 2025 11:46:41 +0100 Subject: [PATCH 6/6] redoc --- R/expr-meta.R | 4 ++-- man/expr_meta_show_graph.Rd | 33 +++++++++++++++++++++++++++++++++ tests/testthat/test-expr-meta.R | 5 +++++ 3 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 man/expr_meta_show_graph.Rd diff --git a/R/expr-meta.R b/R/expr-meta.R index 17a1dcf9..cab97d7d 100644 --- a/R/expr-meta.R +++ b/R/expr-meta.R @@ -215,8 +215,8 @@ expr_meta_tree_format <- function() { #' If `raw_output = TRUE`, a string containing the GraphViz code for the graph. #' #' @examplesIf requireNamespace("DiagrammeR", quietly = TRUE) - #' my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 - #' my_expr$meta$show_graph() +#' my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 +#' my_expr$meta$show_graph() expr_meta_show_graph <- function( ..., show = TRUE, diff --git a/man/expr_meta_show_graph.Rd b/man/expr_meta_show_graph.Rd new file mode 100644 index 00000000..7718dafa --- /dev/null +++ b/man/expr_meta_show_graph.Rd @@ -0,0 +1,33 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/expr-meta.R +\name{expr_meta_show_graph} +\alias{expr_meta_show_graph} +\title{Format the expression as a Graphviz graph} +\usage{ +expr_meta_show_graph(..., show = TRUE, output_path = NULL, raw_output = FALSE) +} +\arguments{ +\item{...}{These dots are for future extensions and must be empty.} + +\item{show}{Show the figure.} + +\item{output_path}{Write the figure to disk.} + +\item{raw_output}{Return dot syntax. This cannot be combined with \code{show} and +/ or \code{output_path}.} +} +\value{ +If \code{show = TRUE}, the same output as \code{DiagrammeR::grViz()}. +If \code{raw_output = TRUE}, a string containing the GraphViz code for the graph. +} +\description{ +Note that Graphviz must be installed to render the visualization (if not +already present, you can download it here: +\verb{}_). +} +\examples{ +\dontshow{if (requireNamespace("DiagrammeR", quietly = TRUE)) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf} +my_expr <- (pl$col("foo") * pl$col("bar"))$sum()$over(pl$col("ham")) / 2 +my_expr$meta$show_graph() +\dontshow{\}) # examplesIf} +} diff --git a/tests/testthat/test-expr-meta.R b/tests/testthat/test-expr-meta.R index 70bc62da..9d168421 100644 --- a/tests/testthat/test-expr-meta.R +++ b/tests/testthat/test-expr-meta.R @@ -136,4 +136,9 @@ test_that("meta$show_graph", { temp <- withr::local_tempfile(fileext = ".svg") expect_silent(my_expr$meta$show_graph(output_path = temp)) expect_true(file.exists(temp)) + + expect_error( + my_expr$meta$show_graph(TRUE), + "Did you forget to" + ) })