Use of ggplot() within another function in R

2019-01-02 18:09发布

I'm trying to write a simple plot function, using the ggplot2 library. But the call to ggplot doesn't find the function argument.

Consider a data.frame called means that stores two conditions and two mean values that I want to plot (condition will appear on the X axis, means on the Y).

library(ggplot2)
m <- c(13.8, 14.8)
cond <- c(1, 2)
means <- data.frame(means=m, condition=cond)
means
# The output should be:
#     means    condition
#   1 13.8     1
#   2 14.8     2

testplot <- function(meansdf)
{
  p <- ggplot(meansdf, aes(fill=meansdf$condition, y=meansdf$means, x = meansdf$condition))
  p + geom_bar(position="dodge", stat="identity")
}

testplot(means)
# This will output the following error:
# Error in eval(expr, envir, enclos) : object 'meansdf' not found

So it seems that ggplot is calling eval, which can't find the argument meansdf. Does anyone know how I can successfully pass the function argument to ggplot?

(Note: Yes I could just call the ggplot function directly, but in the end I hope to make my plot function do more complicated stuff! :) )

标签: r ggplot2
10条回答
查无此人
2楼-- · 2019-01-02 18:40

Here is a simple trick I use a lot to define my variables in my functions environment (second line):

FUN <- function(fun.data, fun.y) {
    fun.data$fun.y <- fun.data[, fun.y]
    ggplot(fun.data, aes(x, fun.y)) + 
        geom_point() + 
        scale_y_continuous(fun.y)    
}

datas <- data.frame(x = rnorm(100, 0, 1),
                    y = x + rnorm(100, 2, 2),
                    z = x + rnorm(100, 5, 10))
FUN(datas, "y")
FUN(datas, "z")

Note how the y-axis label also changes when different variables or data-sets are used.

查看更多
弹指情弦暗扣
3楼-- · 2019-01-02 18:41

This frustrated me for some time. I wanted to send different data frames with different variable names and I wanted the ability to plot different columns from the data frame. I finally got a work around by creating some dummy (global) variables to handle plotting and forcing assignment inside the function

plotgraph function(df,df.x,df.y) {

dummy.df <<- df
dummy.x <<- df.x
dummy.y <<- df.y

p = ggplot(dummy.df,aes(x=dummy.x,y=dummy.y,.....)
print(p)

}

then in the main code I can just call the function

plotgraph(data,data$time,data$Y1)
plotgraph(data,data$time,data$Y2)
查看更多
低头抚发
4楼-- · 2019-01-02 18:41

Short answer: Use qplot

Long answer: In essence you want something like this:

my.barplot <- function(x=this.is.a.data.frame.typically) {
   # R code doing the magic comes here
   ...
}

But that lacks flexibility because you must stick to consistent column naming to avoid the annoying R scope idiosyncrasies. Of course the next logic step is:

my.barplot <- function(data=data.frame(), x=..., y....) {
   # R code doing something really really magical here
   ...
}

But then that starts looking suspiciously like a call to qplot(), right?

qplot(data=my.data.frame, x=some.column, y=some.other column,
      geom="bar", stat="identity",...)

Of course now you'd like to change things like scale titles but for that a function comes handy... the good news is that scoping issues are mostly gone.

my.plot <- qplot(data=my.data.frame, x=some.column, y=some.other column,...)
set.scales(p, xscale=scale_X_continuous, xtitle=NULL,
           yscale=scale_y_continuous(), title=NULL) {
  return(p + xscale(title=xtitle) + yscale(title=ytitle))
}
my.plot.prettier <- set.scale(my.plot, scale_x_discrete, 'Days',
                              scale_y_discrete, 'Count')
查看更多
琉璃瓶的回忆
5楼-- · 2019-01-02 18:42

You don't need anything fancy. Not even dummy variables. You only need to add a print() inside your function, is like using cat() when you want something to show in the console.

myplot <- ggplot(......) + Whatever you want here print(myplot)

It worked for me more than one time inside the same function

查看更多
登录 后发表回答