Pass Function Arguments to Both Dplyr and Ggplot

pass function arguments to both dplyr and ggplot

Tidy evaluation is now fully supported in ggplot2 v3.0.0 so it's not necessary to use aes_ or aes_string anymore.

library(rlang)
library(tidyverse)

diamond_plot <- function (data, group, metric) {
quo_group <- sym(group)
quo_metric <- sym(metric)

data %>%
group_by(!! quo_group) %>%
summarise(price = mean(!! quo_metric)) %>%
ggplot(aes(x = !! quo_group, y = !! quo_metric)) +
geom_col()
}

diamond_plot(diamonds, "clarity", "price")

Sample Image

Created on 2018-04-16 by the reprex package (v0.2.0).

pass a list as arguments to ggplot

Use do.call:

yscale<-list(limits=c(0,40), name='A Y scale name')
p <- p +
do.call(scale_y_continuous, yscale)

How do I pass multiple arguments through an R function to ggplot, both aesthetics and scale format?

Try this

library(ggplot2)
library(scales)
library(rlang) # for sym

myfunction <- function(var1,var2){
p <- ggplot(diamonds, aes(x=cut, y= !! sym(var1)) ) +
geom_boxplot() +
scale_y_continuous(labels = get(var2))
p
return(p)
}
myfunction('price','dollar')

How to pass column name as an arguments in the function

This is basically a question related to programming in dplyr. To achieve your desired result and get rid of hardcoding the column names in your function and use x, y, z instead you could make use of the {{ curly-curly operator as you did in the ggplot code and the special assignment operator :=. Additionally instead of wrapping all your code inside ggplotly you proceed in steps. Do the data wrangling, make your ggplot and finally pass it to ggplotly:

library(plotly)
library(dplyr)
library(stringr)

ggplot_common_function <- function(data, x, y, z) {
data <- data %>%
group_by({{ x }}, {{ z }}) %>%
summarise({{ y }} := sum({{ y }})) %>%
mutate(total_sum = sum({{ y }}))

p <- ggplot(data, mapping = aes({{ x }}, {{ y }}, text = paste(total_sum))) +
geom_col(aes(fill = {{ z }})) +
theme_classic() +
theme(axis.line.y = element_blank(), axis.ticks = element_blank(), legend.position = "bottom") +
labs(x = "", y = "Agreements Values (In Lakhs)", fill = "") +
theme(axis.title.y = element_text(size = 8)) +
scale_fill_manual(values = c("#1F7A3F", "#70B821")) +
scale_y_continuous(labels = function(x) format(x, scientific = FALSE), expand = expansion(mult = c(0, .3)), breaks = integer_breaks())

ggp <- ggplotly(p, tooltip = c("text")) %>%
layout(legend = list(orientation = "h", x = 0.1, y = -0.2, font = list(family = "Arial", size = 10, color = "black")), xaxis = x_labels, yaxis = y_labels) %>%
config(displaylogo = FALSE, modeBarButtonsToRemove = list("sendDataToCloud", "autoScale2d", "resetScale2d", "toggleSpikelines", "hoverClosestCartesian", "hoverCompareCartesian", "zoom2d", "pan2d", "select2d", "lasso2d", "zoomIn2d", "zoomOut2d"))

Removestring(ggp)
}

ggplot_common_function(data, m_year, Applications, status)
#> `summarise()` has grouped output by 'm_year'. You can override using the
#> `.groups` argument.

Sample Image

How can I pass a column name as a function argument using dplyr and ggplot2?

This code seems to fix it. As the commenters above mention, variables passed in to the function must be wrapped in the "enquo" function and then unwrapped with the !!. Note the aes() function becomes aes_() when working with strings.

library(tidyverse)

to_plot <- function(df, model, response_variable, indep_variable) {
response_variable <- enquo(response_variable)
indep_variable <- enquo(indep_variable)

resp_plot <-
df %>%
mutate(model_resp = predict.glm(model, df, type = 'response')) %>%
group_by(!!indep_variable) %>%
summarize(actual_response = mean(!!response_variable),
predicted_response = mean(model_resp)) %>%
ggplot(aes_(indep_variable)) +
geom_line(aes_(x = indep_variable, y = quote(actual_response)), colour = "blue") +
geom_line(aes_(x = indep_variable, y = quote(predicted_response)), colour = "red") +
ylab(label = 'Response')

return(resp_plot)
}

fit <- glm(data = mtcars, mpg ~ wt + qsec + am, family = gaussian(link = 'identity'))
to_plot(mtcars, fit, mpg, wt)

variable use in dplyr and ggplot

aes_string has been deprecated and the preferred way now is to use .data pronoun which can also be used in filter.

library(dplyr)
library(ggplot2)

remove_col <- "carb"
remove_val <- 4

x_value <- "mpg"
y_value <- "hp"

data %>%
filter(.data[[remove_col]] != remove_val ) %>%
ggplot() + geom_point(aes(x = .data[[x_value]], y = .data[[y_value]],
color = .data[[remove_col]])) +
ggtitle("Variables for `geom_point with aes` and for value to remove from `carb`")

You can also use sym with !! :

data %>% 
filter(!!sym(remove_col) != remove_val ) %>%
ggplot() + geom_point(aes(x = !!sym(x_value), y = !!sym(y_value), color = !!sym(remove_col))) +
ggtitle("Variables for `geom_point with aes` and for value to remove from `carb`")

How to pass a filter statement as a function parameter in dplyr using quosure

You can use parse_expr from rlang

library(dplyr)

myfunc <- function(df, filter_statement) {
df %>% filter(eval(rlang::parse_expr(filter_statement)))
}

identical(myfunc(PlantGrowth, "group %in% c('trt1', 'trt2')"),
PlantGrowth %>% filter(group %in% c('trt1', 'trt2')))

#[1] TRUE

The same can be done using infamous eval and parse.

myfunc <- function(df, filter_statement) {
df %>% filter(eval(parse(text = filter_statement)))
}

passing arguments to function with a view to plotting with ggplot stat_function

If I understand, Having a multi parameters functions , you want to induce a partial function where you vary one parameter and fix others. Try this for example:

F <- function(a,b,...) {a^b+b/a}
L <- list("a" = 5, "b" = 2, "c" = 0)

f.partial <- function( var = "a",params=L){
params[[var]]=as.name("x")
function(x)do.call(F,params)
}

We can test this for example:

## vary a
f.partial("a")(1)
[1] 3
> F(1,b=L$b)
[1] 3
## vary b
> f.partial("b")(1)
[1] 5.2
> F(1,a=L$a)
[1] 5.2

Testing with ggplot2:

library("ggplot2")
df <- data.frame(x = seq(0,1,0.1))
ggplot(df, aes(x)) +
stat_function(fun = f.partial("a"),col='blue') +
stat_function(fun = f.partial("b"),col='red')

Sample Image

How to pass / evaluate function arguments within another function for use with ggplot?

you can use aes_string for this purpose. So test should be like this:

test <- function(x,n){
graph <- ggplot(x, aes_string(x = names(x)[n]))
graph + geom_bar()
}


Related Topics



Leave a reply



Submit