jdesilvio
jdesilvio

Reputation: 1854

Passing quoted variable to transform function within ggplot

I am trying to make a reusable chart function based off of this reproducible example:

test=data.frame(name=c('a', 'b', 'c', 'd', 'e', 'f'), amount=c(1,7,3,11,2,1))

ggplot(transform(test, name=reorder(name, -amount)), 
  aes(x=name, y=amount)) + 
  geom_bar(stat='identity')

The issue that I'm having is getting the transform function to work correctly.

This function works, but does not have the transform:

p = function(df, x, y) {
  ggplot(df, 
    aes_string(x=x, y=y)) + 
    geom_bar(stat='identity')
}

p(test, 'name', 'amount')

When I add the transform function, I get the same chart:

p_order = function(df, x, y) {
  ggplot(transform(df, x=reorder(x, -y)), 
  aes_string(x=x, y=y)) + 
  geom_bar(stat='identity')
}

p_order(test, 'name', 'amount')

But gives a warning: Warning message: In mean.default(X[[1L]], ...) : argument is not numeric or logical: returning NA

I've tried wrapping different parts of x=reorder(x, -y) in get, eval, substitute, quote. I've been trying for a couple hours now and think it's some sort of promise concept that I'm just not grasping.

Upvotes: 1

Views: 364

Answers (1)

David Robinson
David Robinson

Reputation: 78610

This will be easiest to do using assignment and [[]] rather than transform:

p_order = function(df, x, y) {
  df[[x]] <- reorder(df[[x]], -df[[y]])
  ggplot(df, aes_string(x=x, y=y)) + 
      geom_bar(stat='identity')
}
p_order(test, 'name', 'amount')

If you want to use transform, you can use it with get, but only while assigning it to a new column (otherwise you'll have to start messing with do.call:

p_order = function(df, x, y) {
  ggplot(transform(df, new_col = reorder(get(x), -get(y))),
      aes_string(x = "new_col", y=y)) + 
      geom_bar(stat='identity') +
      xlab(x) # to keep it looking the same
}
p_order(test, 'name', 'amount')

Upvotes: 2

Related Questions