title: How to write a function for plotting with ggplot which works with generic data frames and variables
body: <p>I often have to make plots which are essentially the same plot, but only for different variables and/or data frames:</p>
  
  <pre><code>p &lt;- ggplot(data = data1, aes(x = variable1, y = ..density..)) +
      geom_histogram(bins = 15, alpha = 0.2, position = "identity", aes(fill = groupvar1)) + 
      geom_density(size = 1, aes(color = groupvar1))
  
  p &lt;- ggplot(data = data1, aes(x = variable2, y = ..density..)) +
      geom_histogram(bins = 15, alpha = 0.2, position = "identity", aes(fill = group2)) + 
      geom_density(size = 1, aes(color = group2))
  
  p &lt;- ggplot(data = data2, aes(x = variable3, y = ..density..)) +
      geom_histogram(bins = 15, alpha = 0.2, position = "identity", aes(fill = group3)) + 
      geom_density(size = 1, aes(color = group3))
  
    .
    .
    .
  </code></pre>
  
  <p>and so on. Instead than duplicating nearly identical code multiple times, I would like to write a single function which I can use with different data frames, variables to be plotted and with or without a grouping variable. Something like:</p>
  
  <pre><code>my_data &lt;- data.frame(y = rnorm(100,0,1),z = runif(100,0,1), 
                        group1 = rep(c("A","B"), each =50), 
                        group2 = as.factor(rep(1:4, each =25)))
  
  variable_distribution &lt;- function(dataframe, myvar, groupvar = NULL) {
      p &lt;- ggplot(data = dataframe, aes(x = myvar, y = ..density..)) 
      if (is.null(groupvar)) {
          p &lt;- p + geom_histogram(bins = 15, alpha = 0.2, position = "identity") + 
              geom_density(size = 1)
      }
      else {
          p &lt;- p + geom_histogram(bins = 15, alpha = 0.2, position = "identity", aes(fill = groupvar)) + 
              geom_density(size = 1, aes(color = groupvar))
      }
      print(p)
  }
  </code></pre>
  
  <p>Some results:        </p>
  
  <pre><code>variable_distribution(my_data, my_data$y, my_data$group1)
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/TIge7.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/TIge7.png" alt="enter image description here"></a></p>
  
  <pre><code>variable_distribution(my_data, my_data$z, my_data$group2)
  </code></pre>
  
  <p><a href="https://i.stack.imgur.com/SHZ45.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/SHZ45.png" alt="enter image description here"></a></p>
  
  <p>There are several issues with my code:</p>
  
  <ol>
  <li>The labels are not what I would like them to be. In the first call, I would like the x-label to be <code>y</code>, instead than <code>myvar</code>, and the legend title to be <code>group1</code>, instead than <code>groupvar</code>. In the second call, the x-label should be <code>z</code> and the legend title <code>group2</code>.</li>
  <li><code>y</code> and <code>group1</code> are parts of <code>my_data</code>, it seems a bit redundant to pass them as two vectors, "separated" from <code>my_data</code>.</li>
  </ol>
  
  <p>PS I don't want to address the variables by column number, because that makes the code much less readable. I'd like an interface such as</p>
  
  <pre><code>variable_distribution(my_data,y, group1)
  </code></pre>
  
  <p>or</p>
  
  <pre><code>variable_distribution("my_data", "y", "group1")
  </code></pre>
  
  <p>Or something like that... </p>
  
  <p><strong>EDIT</strong>: the solution in the linked questions <strong>just doesn't work</strong>, as someone might have noticed if he/she had actually tried to answer the question instead than concentrating on which question this one should be a duplicate of. Look:</p>
  
  <pre><code>variable_distribution &lt;- function(dataframe, x_string, group_string = NULL) {
      p &lt;- ggplot(data = dataframe, aes_string(x = x_string, y = ..density..)) 
      if (is.null(group_string)) {
          p &lt;- p + geom_histogram(bins = 15, alpha = 0.2, position = "identity") + 
              geom_density(size = 1)
      }
      else {
          p &lt;- p + geom_histogram(bins = 15, alpha = 0.2, position = "identity", aes(fill = group_string)) + 
              geom_density(size = 1, aes(color = group_string))
      }
      print(p)
  }
  
  variable_distribution(my_data, "y", "group1")
  &gt;Error in aes_string(x = x_string, y = ..density..) : 
    object '..density..' not found
  </code></pre>