From 03f3d112a2ef8fd9f1eef29a4d822479440e80bf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 06:33:03 +0000 Subject: [PATCH 1/3] feat: support | 0 + var for row faceting in formula syntax Agent-Logs-Url: https://github.com/yihui/gglite/sessions/3a6cd822-fa4d-4ac0-b226-eee4af9726f3 Co-authored-by: yihui-bot <264330240+yihui-bot@users.noreply.github.com> --- DESCRIPTION | 2 +- NEWS.md | 3 +++ R/utils.R | 13 +++++++++---- tests/testit/test-utils.R | 9 +++++++++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a9990fc..05d3a06 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: gglite Title: Lightweight Data Visualization via the Grammar of Graphics -Version: 0.0.10 +Version: 0.0.11 Authors@R: person("Yihui", "Xie", role = c("aut", "cre"), email = "xie@yihui.name", comment = c(ORCID = "0000-0003-0645-5666")) Description: A lightweight R interface to the AntV G2 JavaScript visualization diff --git a/NEWS.md b/NEWS.md index 0624123..e1a662c 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # gglite 0.1 +- The formula syntax in `g2()` now supports `| 0 + var` for row faceting (e.g., + `y ~ x | 0 + var`), in addition to the existing `| var` for column faceting. + A lightweight R interface to the [AntV G2](https://g2.antv.antgroup.com/) JavaScript visualization library with a ggplot2-style API. Create interactive charts using the Grammar of Graphics diff --git a/R/utils.R b/R/utils.R index 14289f8..6db95e9 100644 --- a/R/utils.R +++ b/R/utils.R @@ -118,7 +118,8 @@ extract_terms = function(expr) { #' - `y ~ x` maps to `list(x = 'x', y = 'y')` #' - `~ x` maps to `list(x = 'x')` #' - `~ x1 + x2 + x3` maps to `list(position = c('x1', 'x2', 'x3'))` -#' - `y ~ x | z` adds faceting by `z` +#' - `y ~ x | z` adds faceting by `z` (columns) +#' - `y ~ x | 0 + z` adds faceting by `z` (rows) #' - `y ~ x | z1 + z2` adds faceting by `z1` (columns) and `z2` (rows) #' #' @param f A formula object. @@ -147,12 +148,16 @@ parse_formula = function(f) { aesthetics$position = rhs_terms } - # Build facet + # Build facet: | var → column; | 0 + var → row; | var1 + var2 → both facet = NULL if (length(facet_terms)) { enc = list() - if (length(facet_terms) >= 1) enc$x = facet_terms[1] - if (length(facet_terms) >= 2) enc$y = facet_terms[2] + row_only = facet_terms[1] == '0' + if (row_only) facet_terms = facet_terms[-1] + if (length(facet_terms) >= 1) { + if (row_only) enc$y = facet_terms[1] else enc$x = facet_terms[1] + } + if (!row_only && length(facet_terms) >= 2) enc$y = facet_terms[2] facet = list(type = 'facetRect', encode = enc) } diff --git a/tests/testit/test-utils.R b/tests/testit/test-utils.R index 55428e1..8987f01 100644 --- a/tests/testit/test-utils.R +++ b/tests/testit/test-utils.R @@ -68,6 +68,15 @@ assert('parse_formula: y ~ x | z1 + z2', { (res$facet$encode$y %==% 'b') }) +assert('parse_formula: y ~ x | 0 + z (row facet)', { + res = parse_formula(hp ~ mpg | 0 + cyl) + (res$aesthetics$x %==% 'mpg') + (res$aesthetics$y %==% 'hp') + (res$facet$type %==% 'facetRect') + (is.null(res$facet$encode$x)) + (res$facet$encode$y %==% 'cyl') +}) + assert('ts_to_df converts univariate ts', { res = ts_to_df(sunspot.year) (is.data.frame(res$data)) From 1af7a61caf2b2233a256593e29cdd59f7e8c21cc Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 06:34:44 +0000 Subject: [PATCH 2/3] guard against bare | 0 edge case, add test Agent-Logs-Url: https://github.com/yihui/gglite/sessions/3a6cd822-fa4d-4ac0-b226-eee4af9726f3 Co-authored-by: yihui-bot <264330240+yihui-bot@users.noreply.github.com> --- R/utils.R | 2 +- tests/testit/test-utils.R | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/R/utils.R b/R/utils.R index 6db95e9..cedfb89 100644 --- a/R/utils.R +++ b/R/utils.R @@ -158,7 +158,7 @@ parse_formula = function(f) { if (row_only) enc$y = facet_terms[1] else enc$x = facet_terms[1] } if (!row_only && length(facet_terms) >= 2) enc$y = facet_terms[2] - facet = list(type = 'facetRect', encode = enc) + if (length(enc)) facet = list(type = 'facetRect', encode = enc) } list(aesthetics = aesthetics, facet = facet) diff --git a/tests/testit/test-utils.R b/tests/testit/test-utils.R index 8987f01..22b2b69 100644 --- a/tests/testit/test-utils.R +++ b/tests/testit/test-utils.R @@ -77,6 +77,11 @@ assert('parse_formula: y ~ x | 0 + z (row facet)', { (res$facet$encode$y %==% 'cyl') }) +assert('parse_formula: y ~ x | 0 (bare 0, no facet)', { + res = parse_formula(hp ~ mpg | 0) + (is.null(res$facet)) +}) + assert('ts_to_df converts univariate ts', { res = ts_to_df(sunspot.year) (is.data.frame(res$data)) From 807ffb1376c62d192bf61f682073667de239ed3a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Apr 2026 06:57:20 +0000 Subject: [PATCH 3/3] address PR feedback: revert NEWS.md, compact facet logic, add vignette examples Agent-Logs-Url: https://github.com/yihui/gglite/sessions/a4f72763-bd38-4357-afa0-7214c0c67f75 Co-authored-by: yihui-bot <264330240+yihui-bot@users.noreply.github.com> --- NEWS.md | 3 --- R/utils.R | 11 ++++------- vignettes/gglite.Rmd | 18 ++++++++++++++++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/NEWS.md b/NEWS.md index e1a662c..0624123 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,8 +1,5 @@ # gglite 0.1 -- The formula syntax in `g2()` now supports `| 0 + var` for row faceting (e.g., - `y ~ x | 0 + var`), in addition to the existing `| var` for column faceting. - A lightweight R interface to the [AntV G2](https://g2.antv.antgroup.com/) JavaScript visualization library with a ggplot2-style API. Create interactive charts using the Grammar of Graphics diff --git a/R/utils.R b/R/utils.R index cedfb89..c43ab0a 100644 --- a/R/utils.R +++ b/R/utils.R @@ -151,13 +151,10 @@ parse_formula = function(f) { # Build facet: | var → column; | 0 + var → row; | var1 + var2 → both facet = NULL if (length(facet_terms)) { - enc = list() - row_only = facet_terms[1] == '0' - if (row_only) facet_terms = facet_terms[-1] - if (length(facet_terms) >= 1) { - if (row_only) enc$y = facet_terms[1] else enc$x = facet_terms[1] - } - if (!row_only && length(facet_terms) >= 2) enc$y = facet_terms[2] + # A leading 0 shifts terms to row (y) instead of column (x) + nms = if (facet_terms[1] == '0') 'y' else c('x', 'y') + facet_terms = facet_terms[facet_terms != '0'] + enc = setNames(as.list(facet_terms), head(nms, length(facet_terms))) if (length(enc)) facet = list(type = 'facetRect', encode = enc) } diff --git a/vignettes/gglite.Rmd b/vignettes/gglite.Rmd index 8011024..5e3802f 100644 --- a/vignettes/gglite.Rmd +++ b/vignettes/gglite.Rmd @@ -336,6 +336,24 @@ g2(iris, x = 'Sepal.Width', y = 'Sepal.Length', color = 'Species') |> facet_rect(x = 'Species') ``` +The formula interface supports faceting with `|`. Use `| var` for column facets, +`| 0 + var` for row facets, and `| var1 + var2` for both: + +```{r} +# Column facet: panels arranged in columns by species +g2(penguins, bill_len ~ bill_dep | species) +``` + +```{r} +# Row facet: panels arranged in rows by island +g2(penguins, bill_len ~ bill_dep | 0 + island) +``` + +```{r} +# Both: columns by species, rows by island +g2(penguins, bill_len ~ bill_dep | species + island) +``` + ## Themes Themes change the overall look. Built-in themes include `theme_classic()`