在函数周围包装ggplot

时间:2014-04-14 13:51:56

标签: r ggplot2

我有以下代码,如果我只是按照下面的说法,它似乎运行良好

      p<-ggplot(data=x.all.ER, aes(x=Year, y=value, fill = (factor(x.all.ER$Strategy))))+ 
      geom_bar(stat = 'identity',position = 'dodge', colour = "black") +
      scale_fill_manual(values = mycols) +
      scale_y_continuous(breaks=  seq(-0.3,0.3,by=0.025), labels = percent) +
      ylab("ERET") + theme(axis.title.y = element_text(size=15, face = "bold"))+
      xlab("YEAR") + theme(axis.title.x = element_text(size=15, face = "bold"))
      print(p)

但是当我尝试将其包装在另一个函数周围时,它会给我带来错误。任何帮助是极大的赞赏。谢谢!

      mybar<-function(DS, x, y, fillby, labels, mycols, xlabel, xbreaks, 
                                                            ylabel, title)
          {
     #my.cols =c("#F7FBFF", "#DEEBF7", "#C6DBEF", "#9ECAE1", "#6BAED6", 
             # "#000000","#2171B5")

      p<-ggplot(data=DS, aes(x=x, y=y, fill = fillby)+ 
              geom_bar(stat = 'identity',position = 'dodge', colour = "black") + 
              scale_fill_manual(values = mycols) +
              scale_y_continuous(breaks=  xbreaks, labels = percent) +
              ylab(ylabel) + 
              theme(axis.title.y = element_text(size=15, face = "bold"))+   
              xlab(xlabel) + 
              theme(axis.title.x = element_text(size=15, face = "bold"))
              print(p)
        }

2 个答案:

答案 0 :(得分:3)

您可以在ggplot2中键入x=x而不是x="x",因为DS data.frame基本上附加在该函数中(请参阅?with以了解正在发生的事情上)。您对ggplot的调用是在fillby数据框中查找名为DS的变量,但没有一个。正如评论中所建议的那样,解决这个问题的方法是使用aes_string函数。

library(ggplot2)
df = data.frame( xx=1:10, yy=1:10+rnorm(10) )

# Regular use of ggplot
ggplot(df,aes(x=xx,y=yy)) + geom_point()

# wrapping ggplot in another function
myggplot = function( DF, x, y) {
  ggplot(df,aes(x=x,y=y)) + geom_point()
}
myggplot(df,x,y)
## Error in eval(expr, envir, enclos) : object 'x' not found

问题是ggplot正在寻找data.frame中的x列,因为ggplot(df,aes(x=x,y=y))中的myggplot。请注意,这样可以正常工作。

names(df) = c("x","y")
myggplot(df,x,y)

但这也是如此。

names(df) = c("x","y")
myggplot(df,NULL,NA)

修复:

df = data.frame( xx=1:10, yy=1:10+rnorm(10) )
myggplot2 = function( DF, x, y) {
  ggplot(df,aes_string(x=x,y=y)) + geom_point()
}
myggplot2(df,"xx","yy")

如果您想避免编写引号,请执行

myggplot3 = function( DF, x, y) {
  ggplot(df,aes_string(x=deparse(substitute(x)),
                       y=deparse(substitute(y)))) + geom_point()

}
myggplot3(df,xx,yy)

答案 1 :(得分:1)

使用aes_string(...)而不是aes(...),就像在另一个答案中一样,这是执行此操作的惯用方法。我实际上更喜欢略有不同的方法:

mybar<-function(DS, x, y, fillby, label, mycols, xlabel, xbreaks, 
                ylabel, title) {
  require(ggplot2)
  gg <- data.frame(x=DS[,x],y=DS[,y],fill=DS[,fillby])
  p<-ggplot(gg, aes(x=x, y=y, fill = fill))+ 
    geom_bar(stat = 'identity',position = 'dodge', colour = "black") + 
    scale_fill_manual(values = mycols) +
    scale_y_continuous(breaks=  xbreaks, labels = percent) +
    ylab(ylabel) + 
    theme(axis.title.y = element_text(size=15, face = "bold"))+   
    xlab(xlabel) + 
    theme(axis.title.x = element_text(size=15, face = "bold"))
  print(p)         
}

除了在函数中创建新的df之外,这与您的相同。这稍微慢一点,但有一个优点是您可以将列名或列号作为xyfillby传递。

另请注意,您传递了参数label,但似乎没有对其进行任何操作。