4

I need to generate a plot inside a function, relying on aes_string(), and I need labels as rownames.

The below plot works fine, but not inside a function.

library(ggplot2)
data(mtcars)
plotfun <- function(cars) {
  g <- ggplot(data = cars, aes_string(x = "mpg", y = "disp", label = "rownames(cars)"))
  g <- g + geom_point()
  g <- g + geom_text()
  g
}
plotfun(cars = mtcars)

When run as a function, that gets me:

Error: Aesthetics must either be length one, or the same length as the dataProblems:mpg, disp

I can't wrap my head around it. I am aware that there are plenty of similar questions about aes_string() inside a function –– I just wasn't able to adapt their solutions to my problem.

Ps.: obviously, the above MWE is pretty stupid; in my real use-case, I run the plot through for loops, hence the need for aes_string().

2
  • 1
    i would just use the rownames and create a new column and move on Commented Jul 17, 2015 at 21:00
  • yup, thought about that – does not work in my case, because said for loop loops over the columns of that df ... so I can't "pollute" it with other columns. Also namespace headaches there. Commented Jul 17, 2015 at 21:04

2 Answers 2

5

I think you would be better served by aes_q here rather than aes_string

library(ggplot2)
data(mtcars)
plotfun <- function(cars) {
  g <- ggplot(data = cars, aes_q(x = as.name("mpg"), y = as.name("disp"), label=rownames(cars)))
  g <- g + geom_point()
  g <- g + geom_text()
  g
}
plotfun(cars = mtcars)

The aes_q allows you to pass unevaluated symbols and calls so we just use as.name() to convert your strings into symbols that can later be evaluated in your data.

Sign up to request clarification or add additional context in comments.

2 Comments

fantastic; did not know about aes_q(). Seems to be a recent addition, right? It's not on docs.ggplot2.org/0.9.3/index.html, but is on CRAN already.
@maxheld apparently since 1.0
4

Using it inside of deparse seems to work with aes_string:

plotfun <- function(cars) {
  g <- ggplot(data = cars, aes_string(x = "mpg", y = "disp", 
              label = deparse(rownames(cars))))
  g <- g + geom_point()
  g <- g + geom_text()
  g
}

plotfun(cars = mtcars)

enter image description here

For some additional info deparse will turn unevaluated expressions i.e. (rownames(cars)) into character strings which means in case of mtcars:

> deparse(rownames(mtcars))
[1] "c(\"Mazda RX4\", \"Mazda RX4 Wag\", \"Datsun 710\", \"Hornet 4 Drive\", "         
[2] "\"Hornet Sportabout\", \"Valiant\", \"Duster 360\", \"Merc 240D\", \"Merc 230\", "
[3] "\"Merc 280\", \"Merc 280C\", \"Merc 450SE\", \"Merc 450SL\", \"Merc 450SLC\", "   
[4] "\"Cadillac Fleetwood\", \"Lincoln Continental\", \"Chrysler Imperial\", "         
[5] "\"Fiat 128\", \"Honda Civic\", \"Toyota Corolla\", \"Toyota Corona\", "           
[6] "\"Dodge Challenger\", \"AMC Javelin\", \"Camaro Z28\", \"Pontiac Firebird\", "    
[7] "\"Fiat X1-9\", \"Porsche 914-2\", \"Lotus Europa\", \"Ford Pantera L\", "         
[8] "\"Ferrari Dino\", \"Maserati Bora\", \"Volvo 142E\")"   

which as a character vector can be easily evaluated inside of aes_string.

Comments

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.