1

I've been trying to write an R code which reads data from an excel file and plot different graph charts (like: bar, line, point or pie) based on the user input, using the ggplot package.

For this, I am using a 3-4 different functions:

1) function for Bar plotting:

bar <- function() {
  plot <- ggplot (data= df, aes(x= Dates, y= Values))
  barPlot <- plot + geom_bar(stat="identity", fill="red", width=1)
  print(barPlot)
}

2)Similarly, for line plot :

line <- function() {
plot <- ggplot (data= df, aes(x= Dates, y= Values))
linePlot <- plot + geom_line(aes(group=1), colour="blue", size=0.5)
print(linePlot)
}

3) The main function, which declares all the libraries and reading the excel workbook as a data frame.

In the main function I am trying to call the different plot functions using "if else" as follows:

    main <- function() { 
library(XLConnect)
library(ggplot2)

wk <- loadWorkbook("D:\\....xlsx")
dataFrame = readWorksheet (wk, sheet="sheet1", header=TRUE)
df <- data.frame(Dates = dataFrame[,1],
                 Values =dataFrame[,2])

    name <- scan(what = " ")
    if (name == "bar")
    { bar() }

    else if (name == "line")
        { line() }
}

But it throws back the error: " ggplot2 doesn't know how to deal with data of class function".

Simplified Version of the Data:

Dates Values
Jan   46
Feb   54
Mar   32

How can I modify my code to accommodate this requirement of being able to plot different graphs as per user input?

Code007
  • 13
  • 5
  • 1
    Check out these: http://stackoverflow.com/help/how-to-ask and http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example . Also jnote that your code is using `barPlot` in one spot and `barplot` in another. – G. Grothendieck May 14 '15 at 15:41
  • 2
    Did you define `data` in the `bar()` function? `data` happens to be a base R function. Please create a complete, minimal [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) to fully illustrate your point. – MrFlick May 14 '15 at 15:42
  • I think the problem may be a typo in your code- you define the variable `barPlot` but attempt to print `barplot` (lower case p). Additionally, as @MrFlick pointed out, you shouldn't be using variable names like `data`, `plot` and `barplot`, as they will conflict with base r functions. Make those changes and I think this should work fine. – Joe May 14 '15 at 15:50
  • @MrFlick : Yes I have given the definitions. I have made the necessary edits. Hope that illustrates my point. – Code007 May 14 '15 at 16:06
  • @Joe : Sorry. I made a typo here. Otherwise, it is correct in my code. – Code007 May 14 '15 at 16:08
  • @G.Grothendieck : It was a mistake here. That is not the issue with my code though. – Code007 May 14 '15 at 16:17
  • The revised code is still not reproducible. Reproducible means that anyone can just copy and paste it into their session and see the same problem you do. The input must be provided as part of the code and reduced to a small portion sufficient only to demonstrate the problem. – G. Grothendieck May 14 '15 at 16:19
  • 1
    I can't reproduce your error. That indicates to me that the problem is likely with your data, which you still haven't provided. Please edit with a *simplified* version of your data (eg the output of `dput(head(data))` that still causes the problem. – Joe May 14 '15 at 16:20
  • Aha- I hadn't been keeping up with your edits, see my answer below. And Kudos for improving your question with additional details as requested- if you add all of this from the beginning next time, you'll probably get an answer much faster. – Joe May 14 '15 at 16:48
  • @G.Grothendieck : Sorry, for the inconvenience.You can check with my latest edit. That is reproducible. – Code007 May 14 '15 at 16:54
  • @Joe : Yes. I am new to the forum. Shall keep this in mind hence. – Code007 May 14 '15 at 16:56
  • 1
    Please make your example **minimal** . Start with the input data frame and get rid of the `scan`, Excel, packages not being used, files and directories specific to your system, etc. If `DF` is your input data frame then you can show it reproducibly using `dput(DF)` – G. Grothendieck May 14 '15 at 16:59
  • @G.Grothendieck : Got rid of the unwanted packages. – Code007 May 14 '15 at 17:19

2 Answers2

0

Your problem is related to variable scope: a dataframe defined within main() is only available within main(). It won't be visible to other functions such as bar() or line(), even if they are called from within main().

The preferred solution is to pass all the data that a function needs explicitly. So, define your functions as eg:

bar <- function(df) {
  plot <- ggplot (data= df, aes(x= Dates, y= Values))
  barPlot <- plot + geom_bar(stat="identity", fill="red", width=1)
  print(barPlot)
}

and call it from main() like so:

main <- function() {
  library(ggplot2)
  df <- data.frame(Dates = c("Jan", "Feb", "Mar"),
                   Values =c(46, 54, 52))
  name <- scan(what = " ")
  if (name == "bar")
  { bar(df) }
}

There are other ways to deal with this problem, which I'll mention for completeness, though they aren't as nice as the one above. First, you could nest your function definitions, eg:

main <- function(){
    bar <- function(){
        ...
    }
    ...
    bar()
}

This works because functions defined inside of other functions have access to all variables defined within that function.

Finally, all functions have access to global varaibles, so you can either define your variables outside of main() or define them as globals using the <<- operator.

Community
  • 1
  • 1
Joe
  • 3,831
  • 4
  • 28
  • 44
  • I tried out the solution you mentioned first. But on calling bar(df) from main, it just reads the item. It doesn't plot any graph!? – Code007 May 14 '15 at 17:15
  • @Code007- did you also redefine the `bar` function so that it takes `df` as an argument? This code works perfectly for me with your `main` function- the only change I've made is defining `df` directly at the beginning of the function based on your simplified data – Joe May 14 '15 at 17:21
  • Yes, I re-defined the `bar` function. But it only displays: `Read 1 item` on the console. There is no graph output. – Code007 May 14 '15 at 17:28
  • Can you pls share your graph plots, for both bar and line? – Code007 May 14 '15 at 17:33
  • @Code007 I've added the complete code that worked for me. If that works for you, then the problem lies somewhere in the steps used to simplify or read in your data. If it doesn't, then I have no idea what the problem could be. Either way, we've moved well beyond the Q&A format we're supposed to be following here... – Joe May 14 '15 at 17:43
  • Thanks for your inputs, but that doesn't work for me. It reads the data but no Graph output. I am importing the data from an excel file. – Code007 May 15 '15 at 15:35
0

It seems ggplot2 package cannot handle data of type functions. Instead of calling the function name in main() , you can pass the entire function body.

main <- function() {

...
...

name <- scan(what = " ")

    if (name == "bar")
    {  plot <- ggplot (data= df, aes(x= Dates, y= Values))
  barPlot <- plot + geom_bar(stat="identity", fill="red", width=1)
  print(barPlot)
    }
}

This displays the graph when main() is called on giving bar as input.

Code007
  • 13
  • 5