0

i have a variable v containing a data.frame column name.

I now want to plot it against its index.

Normally, plotting a column against its index is easy:

df <- data.frame(a = c(.4, .5, .2))
ggplot(df, aes(seq_along(a), a)) + geom_point()

But in my case, I can’t figure out what incantations to do:

plot_vs <- function(df, count = 2) {
    vs <- paste0('V', seq_len(count)) # 'V1', 'V2', ...
    for (v in vs) {
        # this won’t work because “v” is a string
        print(ggplot(df, aes(seq_along(v), v)) + geom_point())
        # maybe this? but it also doesn’t work (“object ‘v.s’ not found”)
        v.s <- as.symbol(v)
        print(ggplot(df, aes(seq_along(v.s), v.s)) + geom_point())
        # this doesn’t work because i use seq_along, and seq_along('V1') is 1:
        print(ggplot(df, aes_string(seq_along(v), v)) + geom_point())
    }
}
plot_vs(data.frame(V1 = 4:6, V2 = 7:9, V3 = 10:12))
flying sheep
  • 8,475
  • 5
  • 56
  • 73
  • 1
    http://stackoverflow.com/questions/15458526/r-pass-variable-column-names-to-ggplot2 – Anthony Damico Jun 03 '15 at 09:12
  • The "get" function returns the value of an object given its name as a string. ggplot(df, aes(seq_along(get(v)), get(v))) + geom_point() – JohannesNE Jun 03 '15 at 09:13
  • @AnthonyDamico wrong, please read the code again – flying sheep Jun 03 '15 at 09:18
  • @JohannesNE sadly it doesn’t work, just like my second idea (“Error in function ‘get’: object ‘v’ not found”) – flying sheep Jun 03 '15 at 09:19
  • @flyingsheep could you edit your question and clarify why `aes_string` does not solve your problem? – Anthony Damico Jun 03 '15 at 09:44
  • @AnthonyDamico i already did that, read the last comment and the line below. – flying sheep Jun 03 '15 at 10:24
  • Would this work: `print(ggplot(df, aes(seq_along(df[v]), df[v])) + geom_point())` – cory Jun 03 '15 at 12:28
  • @cory: this would not evaluate in the correct environment. See [here](http://stackoverflow.com/a/15323561/2591234). On the other hand `print(ggplot(df, aes(seq_along(df[[v]]), df[[v]]), environment = environment()) + geom_point())` would work. But it is [not generally advisable to pass vectors to `aes`](http://stackoverflow.com/a/30618800/2591234). – shadow Jun 03 '15 at 12:39
  • Some of the answers [here](http://stackoverflow.com/questions/5106782/use-of-ggplot-within-another-function-in-r) may be relevant. – aosmith Jun 03 '15 at 17:21

3 Answers3

1

Your question title explicitly states that you want to do this without aes_string. Here's how you do it with aes_string: use paste.

plot_vs <- function(df, count = 2) {
  vs <- paste0('V', seq_len(count)) # 'V1', 'V2', ...
  for (v in vs) {
    print(ggplot(df, aes_string(paste("seq_along(", v, ")"), v)) + geom_point())
  }
}

plot_vs(data.frame(V1 = 4:6, V2 =7:9, V3 = 10:12))
shadow
  • 21,823
  • 4
  • 63
  • 77
0
library(ggplot2)
df <- data.frame(a = c(.4, .5, .2))
v <- "a"
df$num<-seq(nrow(df))
ggplot(df, aes_string("num", v)) + geom_point()
Anthony Damico
  • 5,779
  • 7
  • 46
  • 77
  • sure, this works if the `data.frame` is small enough and if i want to mutate it. – flying sheep Jun 03 '15 at 11:51
  • you have it inside your function, so any changes to `df` will be discarded at the end of the call. yes, it only works if you have enough ram to read the data.frame and also add a column of indices. – Anthony Damico Jun 03 '15 at 11:57
0

@shadow’s comment gave the hint to find the solution, namely aes_q:

plot_vs <- function(df, count = 2) {
    vs <- paste0('V', seq_len(count)) # 'V1', 'V2', ...
    for (v in vs) {
        v = as.name(v)
        print(ggplot(df, aes_q(substitute(seq_along(v)), v)) + geom_point())
    }
}
plot_vs(data.frame(V1 = 4:6, V2 = 7:9, V3 = 10:12))
flying sheep
  • 8,475
  • 5
  • 56
  • 73