There's a lot of questions about how to combine two scale_
type calls in ggplot2. However, most of them involve something like this:
ggplot(iris, aes(Sepal.Length, Sepal.Width)) +
geom_point() +
scale_x_log10() +
scale_x_continuous("some new label")
#> Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.
Here the solution is easy enough, one just has to use the trans
param in scale_x_continuous
.
My situation is that I have a number of ggplot2 helper functions for quickly doing plots. These functions call scale_x
inside the function, so one cannot just edit it so easily. Example:
#helper function
table2 = function(x, prop = F, include_NA = T, sort_descending = T) {
#NA param
if (include_NA) {
NA_param = "always"
} else {
NA_param = "no"
}
#get regular table
tbl = table(x, useNA = NA_param)
#as data frame
d = tibble::data_frame("Group" = names(tbl),
"Count" = as.numeric(tbl)
)
#percent/prob
if (!prop) d$Percent = d$Count / sum(d$Count) * 100 else d$Proportion = d$Count / sum(d$Count)
#sort?
if (!is.null(sort_descending)) {
if (sort_descending) {
d %<>% dplyr::arrange(-Count)
} else {
d %<>% dplyr::arrange(Count)
}
}
d
}
GG_boxplot = function(df, y, x) {
#determine sample sizes
sample_n = df[c(x, y)] %>%
na.omit() %>%
{table2(.[[x]], include_NA = F, sort_descending = NULL)}
#plot
ggplot(df, aes_string(x = x, y = y)) +
geom_boxplot() +
scale_x_discrete(labels = function(x) {str_c(x, "\nn = ", sample_n$Count)})
}
Use case:
GG_boxplot(iris, "Sepal.Length", "Species")
So, it's a nice way to easily add the class level sample sizes to the labels. However, if we wanted to change something else with the axis, these labels would get overwritten except in special cases where we can use e.g. xlab
.
GG_boxplot(iris, "Sepal.Length", "Species") + xlab("no problem")
But if one wants to do something more fancy, the issue occurs:
#> GG_boxplot(iris, "Sepal.Length", "Species") + scale_x_discrete(position = "top")
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.
Is there a good way to solve these kinds of overwriting issues?
I tried two ways to attempt to tell ggplot2 not to overwrite the previous setting but no luck:
> GG_boxplot(iris, "Sepal.Length", "Species") + scale_x_discrete(position = "top", labels = NULL)
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.
> GG_boxplot(iris, "Sepal.Length", "Species") + scale_x_discrete(position = "top", labels = waiver())
Scale for 'x' is already present. Adding another scale for 'x', which will replace the existing scale.