ggplot call inside a function: Error in eval(e

2020-08-01 05:24发布

问题:

After defining this function:

compare <- function(list.a, list.b, selection)
{
  dev.new()
  df <- melt(as.data.frame(t(matrix(c( list.a[selection], list.b[selection]), nrow=2, byrow=TRUE))))
  xaxis <- rep(c(1:length(selection)), 2)
  ggplot(df, aes(x=xaxis, y=value, group=variable)) + geom_line()
}

[EDIT]

I just realized this code needs two requires to run:

require(ggplot2)
require(reshape)

And it can be summarized into a single line problem like this:

compare <- function(list.a, list.b, selection) ggplot() + geom_line(data=melt(as.data.frame(t(matrix(c( list.a[selection], list.b[selection]), nrow=2, byrow=TRUE)))), aes_string(x=rep(1:length(selection), 2), y="value", colour="variable"))

The expected output of this function is a linechart of two lists of values (a and b), but only plotting a certain range (selection) from those two lists; see an example function call below.

The one-line version of the function, by the way, does work, but the output is wrong: it produces a single line instead of the desired linechart. But if I unquote the value and variable variables (generated by the melt() call - that is melt.data.frame(), actually), then I get the same error as below ("object not found"), but now it does not find value: object 'value' not found.

Here is the "default", clean version of the function; same problem, though:

compare <- function(list.a, list.b, selection)
{
  df <- melt(as.data.frame(t(matrix(c( list.a[selection], list.b[selection]), nrow=2, byrow=TRUE))))
  xaxis <- rep(c(1:length(selection)), 2)
  ggplot(df, aes(x=xaxis, y=value, colour=variable)) + geom_line()
}

Calling any version of these functions with:

compare(runif(100), runif(100), 30:80)

Should have produced a linechart of two lines with random values in the [0,1] range on the y-axis, over 51 values taken from index 30 to 80 in both lists.

[/EDIT]

But I get the following error:

Error in eval(expr, envir, enclos) : object 'xaxis' not found

I have no clue why I am getting this error or how to prevent it. Anybody can solve this for me, please, and tell me what I am doing wrong?

回答1:

I had the same problem and found the answer here: Use of ggplot() within another function in R

As suggested there, adding environment parameter like below worked for me:

library(reshape2)
library(ggplot2)

compare <- function(list.a, list.b, selection)
{
  df <- melt(as.data.frame(t(matrix(c( list.a[selection], list.b[selection]), nrow=2, byrow=TRUE))))
  xaxis <- rep(c(1:length(selection)), 2)
  # ggplot(df, aes(x=xaxis, y=value, colour=variable)) + geom_line() # fails
  ggplot(df, aes(x=xaxis, y=value, colour=variable),environment=environment()) + geom_line() # works
}

compare(runif(100, 0, 1), runif(100, 0, 1), c(30:80))


回答2:

As per my previous comment, including 'xaxis' in your df dataframe seems to correct this error.

This code works for me

library(reshape2)
library(ggplot2)

compare <- function(list.a, list.b, selection)
  {
  dev.new()
  df <- melt(as.data.frame(t(matrix(c( list.a[selection], list.b[selection]), nrow=2,    byrow=TRUE))))
  df$xaxis <- rep(c(1:length(selection)), 2)
  ggplot(df, aes(x=xaxis, y=value, group=variable)) + geom_line()
}

compare(runif(100, 0, 1), runif(100, 0, 1), c(30:80))


回答3:

Change your function to this

compare <- function(list.a, list.b, selection) {
df <- melt(as.data.frame(
                          t(matrix(c(list.a[selection], list.b[selection]), 
                                  nrow = 2, byrow = TRUE))))
print(head(df)) #before adding axis to your df
df$xaxis <- rep(c(1:length(selection)), 2)
print(head(df)) #after adding the axis to your df
ggplot(df, aes(x=xaxis, y=value, colour=variable)) + geom_line()

}

the print statements can be removed, they are there to show you what ggplot sees. You can also use aes_string, but you still need to make a new data.frame with all the "columns" you're passing to ggplot



标签: r ggplot2