From b1a01e226afb5f79c6158fecff675f51a11af83c Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Sat, 15 Dec 2018 08:52:59 +0900 Subject: [PATCH 1/5] Convert formula to function in sec_axis() --- R/axis-secondary.R | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/R/axis-secondary.R b/R/axis-secondary.R index 28d5dccd0c..8d138ad056 100644 --- a/R/axis-secondary.R +++ b/R/axis-secondary.R @@ -71,7 +71,10 @@ #' #' @export sec_axis <- function(trans = NULL, name = waiver(), breaks = waiver(), labels = waiver()) { - if (!is.formula(trans)) stop("transformation for secondary axes must be a formula", call. = FALSE) + # sec_axis() historically accpeted two-sided formula, so be permissive. + if (length(trans) > 2) trans <- trans[c(1,3)] + + trans <- rlang::as_function(trans) ggproto(NULL, AxisSecondary, trans = trans, name = name, @@ -133,19 +136,14 @@ AxisSecondary <- ggproto("AxisSecondary", NULL, # Inherit settings from the primary axis/scale init = function(self, scale) { if (self$empty()) return() - if (!is.formula(self$trans)) stop("transformation for secondary axes must be a formula", call. = FALSE) + if (!is.function(self$trans)) stop("transformation for secondary axes must be a function", call. = FALSE) if (is.derived(self$name) && !is.waive(scale$name)) self$name <- scale$name if (is.derived(self$breaks)) self$breaks <- scale$breaks if (is.derived(self$labels)) self$labels <- scale$labels }, transform_range = function(self, range) { - range <- new_data_frame(list(. = range)) - rlang::eval_tidy( - rlang::f_rhs(self$trans), - data = range, - env = rlang::f_env(self$trans) - ) + self$trans(range) }, break_info = function(self, range, scale) { From 37681d33c6568f9d11ffbfa4294b0912e002e39a Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Sat, 13 Apr 2019 09:44:02 +0900 Subject: [PATCH 2/5] Add a NEWS item --- NEWS.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS.md b/NEWS.md index 0438d614b2..a9a9724922 100644 --- a/NEWS.md +++ b/NEWS.md @@ -119,6 +119,8 @@ core developer team. * `stat_bin()` now handles data with only one unique value (@yutannihilation #3047). +* `sec_axis()` now accepts functions as well as purrr-style lamnda notations. + # ggplot2 3.1.0 ## Breaking changes From 62d384742b5201d2ea04753ade68d3dca2a2286f Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Sat, 13 Apr 2019 10:11:02 +0900 Subject: [PATCH 3/5] Update description about trans argument --- R/axis-secondary.R | 2 +- man/sec_axis.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/axis-secondary.R b/R/axis-secondary.R index 11a5879ab1..5263dc6343 100644 --- a/R/axis-secondary.R +++ b/R/axis-secondary.R @@ -4,7 +4,7 @@ #' secondary axis, positioned opposite of the primary axis. All secondary #' axes must be based on a one-to-one transformation of the primary axes. #' -#' @param trans A transformation formula +#' @param trans A formula or function of transformation #' #' @param name The name of the secondary axis #' diff --git a/man/sec_axis.Rd b/man/sec_axis.Rd index ad7a9fd737..e12228fab9 100644 --- a/man/sec_axis.Rd +++ b/man/sec_axis.Rd @@ -15,7 +15,7 @@ dup_axis(trans = ~., name = derive(), breaks = derive(), derive() } \arguments{ -\item{trans}{A transformation formula} +\item{trans}{A formula or function of transformation} \item{name}{The name of the secondary axis} From 4f8beada20235d96728df3b8beb89493a6508388 Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Sat, 13 Apr 2019 10:11:56 +0900 Subject: [PATCH 4/5] Follow the tidyverse style guide about spacing --- R/axis-secondary.R | 12 ++++++------ man/sec_axis.Rd | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/R/axis-secondary.R b/R/axis-secondary.R index 5263dc6343..5ab8e1c4c2 100644 --- a/R/axis-secondary.R +++ b/R/axis-secondary.R @@ -33,8 +33,8 @@ #' Unlike other continuous scales, secondary axis transformations for date and datetime scales #' must respect their primary POSIX data structure. #' This means they may only be transformed via addition or subtraction, e.g. -#' `~. + hms::hms(days = 8)`, or -#' `~.- 8*60*60`. Nonlinear transformations will return an error. +#' `~ . + hms::hms(days = 8)`, or +#' `~ . - 8*60*60`. Nonlinear transformations will return an error. #' To produce a time-since-event secondary axis in this context, users #' may consider adapting secondary axis labels. #' @@ -43,16 +43,16 @@ #' geom_point() #' #' # Create a simple secondary axis -#' p + scale_y_continuous(sec.axis = sec_axis(~.+10)) +#' p + scale_y_continuous(sec.axis = sec_axis(~ . + 10)) #' #' # Inherit the name from the primary axis -#' p + scale_y_continuous("Miles/gallon", sec.axis = sec_axis(~.+10, name = derive())) +#' p + scale_y_continuous("Miles/gallon", sec.axis = sec_axis(~ . + 10, name = derive())) #' #' # Duplicate the primary axis #' p + scale_y_continuous(sec.axis = dup_axis()) #' #' # You can pass in a formula as a shorthand -#' p + scale_y_continuous(sec.axis = ~.^2) +#' p + scale_y_continuous(sec.axis = ~ .^2) #' #' # Secondary axes work for date and datetime scales too: #' df <- data.frame( @@ -75,7 +75,7 @@ #' # or to transform axes for different timezones #' ggplot(df, aes(x = dx, y = price)) + geom_line() + #' scale_x_datetime("GMT", date_labels = "%b %d %I %p", -#' sec.axis = sec_axis(~. + 8*3600, name = "GMT+8", +#' sec.axis = sec_axis(~ . + 8 * 3600, name = "GMT+8", #' labels = scales::time_format("%b %d %I %p"))) #' #' @export diff --git a/man/sec_axis.Rd b/man/sec_axis.Rd index e12228fab9..f89a90c216 100644 --- a/man/sec_axis.Rd +++ b/man/sec_axis.Rd @@ -53,8 +53,8 @@ As of v3.1, date and datetime scales have limited secondary axis capabilities. Unlike other continuous scales, secondary axis transformations for date and datetime scales must respect their primary POSIX data structure. This means they may only be transformed via addition or subtraction, e.g. -\code{~. + hms::hms(days = 8)}, or -\code{~.- 8*60*60}. Nonlinear transformations will return an error. +\code{~ . + hms::hms(days = 8)}, or +\code{~ . - 8*60*60}. Nonlinear transformations will return an error. To produce a time-since-event secondary axis in this context, users may consider adapting secondary axis labels. } @@ -63,16 +63,16 @@ p <- ggplot(mtcars, aes(cyl, mpg)) + geom_point() # Create a simple secondary axis -p + scale_y_continuous(sec.axis = sec_axis(~.+10)) +p + scale_y_continuous(sec.axis = sec_axis(~ . + 10)) # Inherit the name from the primary axis -p + scale_y_continuous("Miles/gallon", sec.axis = sec_axis(~.+10, name = derive())) +p + scale_y_continuous("Miles/gallon", sec.axis = sec_axis(~ . + 10, name = derive())) # Duplicate the primary axis p + scale_y_continuous(sec.axis = dup_axis()) # You can pass in a formula as a shorthand -p + scale_y_continuous(sec.axis = ~.^2) +p + scale_y_continuous(sec.axis = ~ .^2) # Secondary axes work for date and datetime scales too: df <- data.frame( @@ -95,7 +95,7 @@ ggplot(df, aes(x = dx, y = price)) + geom_line() + # or to transform axes for different timezones ggplot(df, aes(x = dx, y = price)) + geom_line() + scale_x_datetime("GMT", date_labels = "\%b \%d \%I \%p", - sec.axis = sec_axis(~. + 8*3600, name = "GMT+8", + sec.axis = sec_axis(~ . + 8 * 3600, name = "GMT+8", labels = scales::time_format("\%b \%d \%I \%p"))) } From 9aaeb4727cf5744ef39302184a462f690c74c77d Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Sat, 13 Apr 2019 10:12:49 +0900 Subject: [PATCH 5/5] Fix NEWS item --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index a9a9724922..3abb02c650 100644 --- a/NEWS.md +++ b/NEWS.md @@ -119,7 +119,7 @@ core developer team. * `stat_bin()` now handles data with only one unique value (@yutannihilation #3047). -* `sec_axis()` now accepts functions as well as purrr-style lamnda notations. +* `sec_axis()` now accepts functions as well as formulas (@yutannihilation, #3031). # ggplot2 3.1.0