Skip to content

Commit fefbc2c

Browse files
authored
standalone (#17)
standalone
1 parent 41c6317 commit fefbc2c

21 files changed

+461
-535
lines changed

DESCRIPTION

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
Package: ggcall
22
Type: Package
3-
Title: Extract ggplot2 Layers Created within a Function
4-
Version: 0.3.0
3+
Title: Extract 'ggplot2' Layers Created Within a Function
4+
Version: 0.3.3
55
Authors@R:
66
person(given = "Maciej",
77
family = "Nasinski",
88
role = c("aut", "cre"),
99
email = "[email protected]")
1010
Maintainer: Maciej Nasinski <[email protected]>
1111
Description:
12-
Enhance ggplot2 with the ability to extract the code used to create a ggplot object, even when it is generated within a function.
13-
This feature aids in understanding, replicating, and modifying complex ggplot2 visualizations produced in functional workflows.
12+
Enhance 'ggplot2' with the ability to extract the code used to create a 'ggplot2' object, even when it is generated within a function.
13+
This feature aids in understanding, replicating, and modifying complex 'ggplot2' visualizations produced in functional workflows.
14+
URL: https://github.com/Polkas/ggcall, https://polkas.github.io/ggcall/
15+
BugReports: https://github.com/Polkas/ggcall/issues
1416
License: Apache License (>= 2)
1517
Encoding: UTF-8
1618
LazyData: true
17-
Depends:
19+
Depends:
1820
ggplot2
21+
Imports:
22+
patchwork
1923
Suggests:
20-
backports,
21-
knitr,
22-
patchwork,
23-
rmarkdown,
24+
usethis,
2425
styler,
2526
testthat (>= 3.0.0)
2627
RoxygenNote: 7.3.2
2728
Config/testthat/edition: 3
28-
VignetteBuilder: knitr

NAMESPACE

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ export(ggcall)
1111
export(ggcall_add_assignments)
1212
export(ggcall_env)
1313
export(ggplot)
14-
importFrom(ggplot2,ggplot)
14+
import(ggplot2, except = c(ggplot))
15+
import(patchwork)

NEWS.md

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# ggcall v0.3.3
2+
3+
* Added support for usethis standalone, `usethis::use_standalone` can be used with ggcall.
4+
* Added a reference to `ggcall.example` package, an example implementation of ggcall.
5+
16
# ggcall v0.3.0
27

38
* Added support for ggplot related patchwork operators.

R/patchwork.R

-40
This file was deleted.

R/ggcall.R renamed to R/standalone-ggcall.R

+47-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
# ---
2+
# repo: polkas/ggcall
3+
# file: ggcall.R
4+
# last-updated: 2024-11-21
5+
# license: https://unlicense.org
6+
# imports: ggplot2
7+
# ---
8+
#
9+
# This file provides a minimal shim to provide a ggcall functionality on top of
10+
# ggplot2.
11+
#
12+
# ## Changelog
13+
#
14+
15+
# nocov start
16+
117
#' Enhanced `ggplot` Function with History Tracking
218
#'
319
#' Overrides the default `ggplot` function from the ggplot2 package, adding the
@@ -10,8 +26,9 @@
1026
#' attribute 'ggcall' that stores the history of plot construction.
1127
#'
1228
#' @seealso \code{\link[ggplot2]{ggplot}}
13-
#' @importFrom ggplot2 ggplot
29+
#' @rawNamespace import(ggplot2, except = c(ggplot))
1430
#' @examples
31+
#' library(ggplot2, exclude = "ggplot")
1532
#' p <- ggplot(mtcars, aes(x = wt, y = mpg))
1633
#' # the + function has to come from ggcall package
1734
#' attr(p + geom_point(), "ggcall")
@@ -38,10 +55,12 @@ ggplot <- function(...) {
3855
#' conjunction with the enhanced ggplot function provided by this package.
3956
#'
4057
#' @param e1 A ggplot object of class 'ggcall'.
41-
#' @param e2 A layer or theme to add to the ggplot object.
58+
#' @param e2 A layer, theme or ggcall to add.
4259
#'
4360
#' @return A modified ggplot object with updated plot history.
61+
#' @rdname ggcall-add-operator
4462
#' @examples
63+
#' library(ggplot2, exclude = "ggplot")
4564
#' p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
4665
#' geom_point()
4766
#' attr(p, "ggcall") # View the plot call
@@ -92,6 +111,7 @@ ggplot <- function(...) {
92111
#' a list representing the history of the ggplot object.
93112
#'
94113
#' @examples
114+
#' library(ggplot2, exclude = "ggplot")
95115
#' # Example: Create a function which combines a few ggplot layers
96116
#' # Typically, it will be a function from your R package where you implemented ggcall
97117
#' func <- function(data, x, y, bool = TRUE) {
@@ -112,8 +132,12 @@ ggplot <- function(...) {
112132
#' }
113133
#' plot_call <- ggcall(func(mtcars, "wt", "mpg"))
114134
#' # Optionally: Style the code with styler
115-
#' styler::style_text(backports:::deparse1(plot_call))
116-
#'
135+
#' # deparse1 is recommended and available in R>=4.0.0
136+
#' \dontrun{
137+
#' styler::style_text(
138+
#' paste(deparse(plot_call), collapse = "\n")
139+
#' )
140+
#' }
117141
#' @export
118142
#'
119143
ggcall <- function(plot) {
@@ -143,6 +167,7 @@ ggcall <- function(plot) {
143167
#' More complex variables are referenced to ggcall environment.
144168
#'
145169
#' @examples
170+
#' library(ggplot2, exclude = "ggplot")
146171
#' # Example: Create a function which combines a few ggplot layers
147172
#' # Typically, it will be a function from your R package where you implemented ggcall
148173
#' func <- function(data, x, y, bool = TRUE) {
@@ -164,14 +189,17 @@ ggcall <- function(plot) {
164189
#' plot_call <- ggcall(func(mtcars, "wt", "mpg"))
165190
#' # Optionally: Add assignments
166191
#' plot_call_with_assignments <- ggcall_add_assignments(plot_call)
192+
#' \dontrun{
167193
#' styler::style_text(
168194
#' paste(deparse(plot_call_with_assignments), collapse = "\n")
169195
#' )
170-
#'
196+
#' }
171197
#' eval_ggcall(plot_call_with_assignments)
172198
#'
173199
#' # Will Fail as data is needed and skipped
174-
#' # eval_ggcall(ggcall_add_assignments(plot_call, vars = c("x", "y")))
200+
#' \dontrun{
201+
#' eval_ggcall(ggcall_add_assignments(plot_call, vars = c("x", "y")))
202+
#' }
175203
#' @export
176204
ggcall_add_assignments <- function(call, vars = extract_names(call)) {
177205
stopifnot(inherits(call, "ggcall_code"))
@@ -232,9 +260,14 @@ ggcall_add_assignments <- function(call, vars = extract_names(call)) {
232260
#' @return The resulting ggplot object produced by evaluating the expression `x`.
233261
#'
234262
#' @examples
235-
#' p <- ggplot(mtcars, aes(x = wt, y = mpg)) +
236-
#' geom_point()
237-
#' plot_call <- ggcall(p)
263+
#' library(ggplot2, exclude = "ggplot")
264+
#'
265+
#' func <- function() {
266+
#' ggplot(mtcars, aes(x = wt, y = mpg)) +
267+
#' geom_point()
268+
#' }
269+
#' gplot <- func()
270+
#' plot_call <- ggcall(gplot)
238271
#' reconstructed_plot <- eval_ggcall(plot_call)
239272
#' print(reconstructed_plot)
240273
#'
@@ -259,11 +292,13 @@ eval_ggcall <- function(call, ...) {
259292
#' @param call An expression representing the ggplot construction code.
260293
#' @return The environment in which the ggplot construction code was created.
261294
#' @examples
295+
#' library(ggplot2, exclude = "ggplot")
262296
#' fun <- function(data, x, y) {
263297
#' ggplot(data, aes(x = !!as.name(x), y = !!as.name(y))) +
264298
#' geom_point()
265299
#' }
266-
#' plot_call <- ggcall(fun(mtcars, "wt", "mpg"))
300+
#' gplot <- fun(mtcars, "wt", "mpg")
301+
#' plot_call <- ggcall(gplot)
267302
#' env <- ggcall_env(plot_call)
268303
#' ls(env)
269304
#' env[["data"]]
@@ -309,3 +344,5 @@ extract_names <- function(expr) {
309344

310345
return(character())
311346
}
347+
348+
# nocov end

R/standalone-patchwork.R

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# ---
2+
# repo: polkas/ggcall
3+
# file: patchwork
4+
# last-updated: 2024-11-21
5+
# license: https://unlicense.org
6+
# dependencies: ggcall.R
7+
# imports: [ggplot2, patchwork]
8+
# ---
9+
#
10+
# This file provides a minimal shim to provide a ggcall functionality on top of
11+
# ggplot2. Additionally patchwork operators are supported.
12+
#
13+
# ## Changelog
14+
#
15+
16+
# nocov start
17+
18+
#' @title Base Function for Patchwork Operators
19+
#' @description A helper function that applies patchwork operators to `ggcall` objects.
20+
#' @param e1 The left-hand side `ggcall` object.
21+
#' @param e2 The right-hand side `ggcall` object.
22+
#' @param operator The operator as a string (e.g., "-", "/", "|", "*", "&").
23+
#' @param class The class to which the operator is applied ("ggplot" or "gg").
24+
#' @return A combined `ggcall` object resulting from the operation.
25+
#' @import patchwork
26+
#' @keywords internal
27+
patch_operator_base <- function(e1, e2, operator, class) {
28+
if (!requireNamespace("patchwork", quietly = TRUE)) {
29+
stop("patchwork package has to be installed.")
30+
}
31+
plot <- utils::getFromNamespace(sprintf("%s.%s", operator, class), "patchwork")(e1, e2)
32+
if (inherits(e1, "ggcall") && inherits(e2, "ggcall")) {
33+
lhs <- ggcall(e1)
34+
rhs <- ggcall(e2)
35+
attr(plot, "ggcall") <- as.call(list(as.name(operator), lhs, rhs))
36+
attr(plot, "ggcall_env") <- merge_env(attr(e1, "ggcall_env"), attr(e2, "ggcall_env"))
37+
class(plot) <- unique(c("ggcall", class(plot)))
38+
}
39+
plot
40+
}
41+
42+
#' @title Minus Operator for ggcall Objects
43+
#' @description Applies the minus operator to `ggcall` objects, utilizing the corresponding operator from the `patchwork` package.
44+
#' @details This function allows for the subtraction of `ggcall` objects using the `patchwork` syntax.
45+
#' @inheritParams patch_operator_base
46+
#' @return A combined `ggcall` object after applying the minus operation.
47+
#' @keywords internal
48+
#' @rdname ggcall-operators
49+
#' @export
50+
"-.ggcall" <- function(e1, e2) {
51+
patch_operator_base(e1, e2, "-", "ggplot")
52+
}
53+
54+
#' @title Division Operator for ggcall Objects
55+
#' @description Applies the division operator to `ggcall` objects, utilizing the corresponding operator from the `patchwork` package.
56+
#' @details This function allows for the division of `ggcall` objects using the `patchwork` syntax.
57+
#' @inheritParams patch_operator_base
58+
#' @return A combined `ggcall` object after applying the division operation.
59+
#' @keywords internal
60+
#' @rdname ggcall-operators
61+
#' @export
62+
"/.ggcall" <- function(e1, e2) {
63+
patch_operator_base(e1, e2, "/", "ggplot")
64+
}
65+
66+
#' @title Or Operator for ggcall Objects
67+
#' @description Applies the or operator to `ggcall` objects, utilizing the corresponding operator from the `patchwork` package.
68+
#' @details This function allows for the combination of `ggcall` objects using the `patchwork` syntax.
69+
#' @inheritParams patch_operator_base
70+
#' @return A combined `ggcall` object after applying the or operation.
71+
#' @keywords internal
72+
#' @rdname ggcall-operators
73+
#' @export
74+
"|.ggcall" <- function(e1, e2) {
75+
patch_operator_base(e1, e2, "|", "ggplot")
76+
}
77+
78+
#' @title Multiplication Operator for ggcall Objects
79+
#' @description Applies the multiplication operator to `ggcall` objects, utilizing the corresponding operator from the `patchwork` package.
80+
#' @details This function allows for the multiplication of `ggcall` objects using the `patchwork` syntax.
81+
#' @inheritParams patch_operator_base
82+
#' @return A combined `ggcall` object after applying the multiplication operation.
83+
#' @keywords internal
84+
#' @rdname ggcall-operators
85+
#' @export
86+
"*.ggcall" <- function(e1, e2) {
87+
patch_operator_base(e1, e2, "*", "gg")
88+
}
89+
90+
#' @title And Operator for ggcall Objects
91+
#' @description Applies the and operator to `ggcall` objects, utilizing the corresponding operator from the `patchwork` package.
92+
#' @details This function allows for the combination of `ggcall` objects using the `patchwork` syntax.
93+
#' @inheritParams patch_operator_base
94+
#' @return A combined `ggcall` object after applying the and operation.
95+
#' @keywords internal
96+
#' @rdname ggcall-operators
97+
#' @export
98+
"&.ggcall" <- function(e1, e2) {
99+
patch_operator_base(e1, e2, "&", "gg")
100+
}
101+
102+
103+
# nocov end

0 commit comments

Comments
 (0)