2

long-time reader, first-time question-writer...I have a function that puts takes in data and spits out a ggplot2 histogram with some specific formatting. I'm trying to edit this function so that one of the function parameters can specify whether I want the histogram to show the frequency or the density of the data. I know I can specify this manually inside the geom_histogram() function with aes(y=..count..) or aes(y=..density..), respectively. But I'm having issues figuring out how to access these variables if they aren't inputted directly.

Here is a simplified version of what I'm trying to do:

library(ggplot2)

histplot <- function(data,density=FALSE) {

  if (density) {
    type <- "..density.."
  } else {
    type <- "..count.."
  }

  theplot <- ggplot(data, aes(x=data[,1])) +
    geom_histogram(position="identity",binwidth = 2, 
               aes(y=eval(parse(text=type))))

  g <- ggplot_gtable(ggplot_build(theplot))
  grid.draw(g)

}

xy <- data.frame(X=rnorm(100,0,10),Y=rnorm(100))
histplot(xy)

When I execute this function, the error I get is:

Error in eval(expr, envir, enclos) : object '..count..' not found

I can't figure out why this won't work, because if I do something like the following:

x <- 1:5
y <- "x"
eval(parse(text=y))

Then the output will be

[1] 1 2 3 4 5

My guess is it has something to do with the environments.

  • @Elin If you have a variable named `string`, then `eval(parse(text="string"))` takes the character string `"string"` and executes the variable with that same name – Lindsay Lee Mar 11 '17 at 14:59

1 Answers1

2

I believe you can use aes_string in this case so something like this should work

type="..count.."
ggplot(xy, aes_string(x=xy[,1], y=type)) +
  geom_histogram(position="identity",binwidth = 2)
jyr
  • 690
  • 6
  • 20
  • That seems to do it, thank you! Can you explain why what I was trying wasn't working, and why this does? – Lindsay Lee Mar 11 '17 at 15:05
  • 1
    @LindsayLee It's to do with standard and non-standard evaluation. Using `aes_string()` means you can pass arguments as quoted strings, while `aes()` expects unquoted objects. Have a look at http://adv-r.had.co.nz/Computing-on-the-language.html As a general rule of thumb if you find yourself using `eval(parse())` there's a better way! – Phil Mar 11 '17 at 17:08