1
votes

Say we have this toy data:

temp <- data.frame(A=1:6, gr=c("A","A","A","B","B","B"))

I can easily create a plot as

lev <- c("A", "B")
ggplot()+geom_point(data=temp,aes(x=A, y=gr))+ylim(lev)

I get this enter image description here

But I would like to convert it to a function in order to easily change the input parameters

myplot <- function(lev=lev) {ggplot()+geom_point(data=temp,aes(x=A, y=gr))+ylim(lev)}

But when I run

lev <- c("B","A")
myplot()

I get this error:

Error in limits(c(...), "y") : promise already under evaluation: recursive default argument reference or earlier problems?

I've tried converting ylim to a factor, and using eval, but it doesn't work either.

I've tried parametrizing other things such as the input dataset and they work well, but I don't understand why ylim doesn't.

There is a question that speaks about a related problem with aes parameters
Pass function argument to ggplot label

but its solution uses aes_string and doesn't apply here.

3

3 Answers

3
votes

Change how you define your function:

myplot <- function(lev) { #I think setting lev in the definition is causing problems
  ggplot(data=temp, aes(x=A, y=gr))+
  geom_point()+
  ylim(lev)
}

Then set up a new variable for the set of levels:

args=c("B", "A") #can reorder these however you want
myplot(lev=args)
2
votes

you're not calling your function with the argument!

myplot() 

throws the error because you're not giving it its argument. If you call it like you're supposed to call it (as defined by your own definition), it works.

myplot(lev) 

edit: You probably wanted to set the defaults of argument lev with lev? As far as I understand you get the error because of the way R evaluates function arguments. I didn't find any further info on that (in this short time), so I'd be happy to see answers going more in depth on that. You can directly set the defaults like that

myplot <- function(lev = c("A", "B)) {...}

Then you can also call your function without the argument, i.e. myplot() will work.

0
votes

I've found that strangely just calling the function's parameter with a different name than the input data works.

temp <- data.frame(A=1:6, gr=c("A","A","A","B","B","B"))
mylev <- c("A", "B")

myplot <- function(lev=mylev) {ggplot()+geom_point(data=temp,aes(x=A, y=gr))+ylim(lev)}

myplot() works

That way I can have the default parameter pointing to a given definition.

PD: Still doesn't work well. It's strange. THe first time you run it works. But If I run the it again I get this error:

Error: length(lims) == 2 is not TRUE