Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refering to a variable of the data frame passed in the 'data' parameter of ggplot function

Tags:

scope

r

ggplot2

I would like to use a variable of the dataframe passed to the data parameter of function the ggplot in another ggplot2 function in the same call.

For instance, in the following example I want to refer to the variable x in the dataframe passed to the data parameter in ggplot in another function scale_x_continuous such as in:

library(ggplot2)

set.seed(2017)

samp <- sample(x = 20, size= 1000, replace = T)

ggplot(data = data.frame(x = samp), mapping = aes(x = x)) + geom_bar() +
scale_x_continuous(breaks = seq(min(x), max(x)))

And I get the error :

Error in seq(min(x)) : object 'x' not found

which I understand. Of course I can avoid the problem by doing :

df <- data.frame(x = samp)
ggplot(data = df, mapping = aes(x = x)) + geom_bar() +
scale_x_continuous(breaks = seq(min(df$x), max(df$x)))

but I don't want to be forced to define the object df outside the call to ggplot. I want to be able to directly refer to the variables in the dataframe I passed in data.

Thanks a lot

like image 212
Etienne Kintzler Avatar asked Apr 07 '17 14:04

Etienne Kintzler


1 Answers

The scale_x_continuous function does not evaluate it's parameters in the data environment. One reason for this is that each layer can have it's own data source so by the time you got to the scales it wouldn't be clear which data environment is the "correct" one any more.

You could write a helper function to initialize the plot with your default. For example

helper <- function(df, col) { 
    ggplot(data = df, mapping = aes_string(x = col)) + 
    scale_x_continuous(breaks = seq(min(df[[col]]), max(df[[col]])))
}

and then call

helper(data.frame(x = samp), "x") + geom_bar()

Or you could write a wrapper around just the scale part. For example

scale_x_custom <- function(x) {
   scale_x_continuous(breaks = seq(min(x) , max(x)))
}

and then you can add your custom scale to your plot

ggplot(data = df, mapping = aes(x = x)) + 
  geom_bar() +
  scale_x_custom(df$x)

Or since you just want breaks at integer values, you can calculate the breaks from the default limits without needed to actually specify the data. For example

scale_x_custom <- function() {
  scale_x_continuous(expand=expansion(0, .3),
    breaks = function(x) {
    seq(ceiling(min(x)), floor(max(x)))
  })
}

ggplot(data = df, mapping = aes(x = x)) + 
  geom_bar() +
  scale_x_custom()

enter image description here

like image 176
MrFlick Avatar answered Sep 20 '22 18:09

MrFlick