1

I have a function that I use to build bar charts in R-markdown. I wonder if there is a better way to do the aes-part of my ggplot2 function. At the moment I use "eval(parse(text=" but that is kinda hard to read/understand.

I would like something that is more direct/readable. I tried aes_string but I think the "fill = factor()" part didn't work since while I did get a chart, I got an erroneous one (I got one big, fat bar). Were did I go wrong? Or is this the best way I can do my chart.

Reproducible example:

library("data.table")
library("ggplot2")

dt <- data.table(year.var = c(2014, 2014, 2014, 2015, 2015, 2015),
                 grp.var  = c("Grp1", "Grp2", "Grp3", "Grp1", "Grp2", "Grp3"),
                 val.var  = c(100, 200, 230, 105, 260, 23))

test <- function (dts,
                  x.var,
                  y.var,
                  fill.var,
                  order.var)  {

setorderv(dts, order.var)

ggplot(dts, 
       aes(x = eval(parse(text = x.var)), 
           y = eval(parse(text = y.var)), 
           fill = eval(parse(text = fill.var))
           )
       ) +
       geom_bar(stat="identity", position="dodge")+
       scale_fill_manual(values =  c("#9badcd", "#5a6c9c"),
                         name = "Year")+
       scale_y_continuous(labels = function(val.var) { 
                                     format(val.var, big.mark = " ", 
                                     scientific = FALSE)
                                   }
                          )+
       xlab("x.label") + 
       ylab("y.label")+
       ggtitle("str.title")
}

test(dt, "grp.var", "val.var", "factor(year.var)", c("year.var"))
2
  • 2
    I would use aes_string, first manipulate the dts so it has a column called fill.var which is a factor. (would give code but don't know how to do this with a data.table) Commented Aug 12, 2016 at 12:14
  • @RichardTelford Thanks!! I think I got to caught up in my old tracks, that did the trick. If you want to post it as an answer you do it like this: dt <- dt[, f.var := as.factor(year.var)] Commented Aug 12, 2016 at 12:22

1 Answer 1

2

I think the solution is to try to keep the mapping in aes simple, and to do the data manipulation directly in the data.table. Here I have made a new column in the data.table which is a factor of the column wanted as the fill. Then aes_string can be used

test <- function (dts,
                  x.var,
                  y.var,
                  fill.var,
                  order.var)  {

  dts <- dts[, f.var := as.factor(dts[, get(fill.var)])] 
   #NB this will modify your original table
  setorderv(dts, order.var)

  ggplot(dts, 
         aes_string(x = x.var, y = y.var, fill = "f.var")) +
    geom_bar(stat="identity", position="dodge")+
    scale_fill_manual(values =  c("#9badcd", "#5a6c9c"), name = "Year")+
    scale_y_continuous(labels = function(val.var) { 
      format(val.var, big.mark = " ", scientific = FALSE)
    })+
    labs(x = "x.label", y = "y.label", title = "str.title")
}

test(dt, "grp.var", "val.var", "year.var", "year.var")
Sign up to request clarification or add additional context in comments.

2 Comments

My handling of the data.table might not be elegant. Not a package I use.
Thanks, and a good point about data manipulation outside the aes. I think your handling is fine, you could write that statement a bit shorter though, dts <- dts[, f.var := as.factor(get(fill.var))]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.