StanLe
StanLe

Reputation: 5157

Interesting R error related to calling functions

I have a function that I made and it goes as follows:

plot_colorByDensity = function(x,y,
                               ylim=c(min(y),max(y)),
                               xlim=c(min(x),max(x)),
                               xlab="",ylab="",main="") {
    #print(xlim)
    x1 = x
    x2 = y
    df <- data.frame(x1,x2)
    x <- densCols(x1,x2, colramp=colorRampPalette(c("black", "white")))
    df$dens <- col2rgb(x)[1,] + 1L
    cols <-  colorRampPalette(c("#000099", "#00FEFF", "#45FE4F","#FCFF00", "#FF9400", "#FF3100"))(256)
    df$col <- cols[df$dens]
    plot(x2~x1, data=df[order(df$dens),], 
         ylim=ylim,xlim=xlim,pch=20,col=col,
         cex=2,xlab=xlab,ylab=ylab,
         main=main)
}

It produces a plot where color represents density of points. Take a look at this output, and the error that the function above produces, leading to no plot being drawn:

> x
 [1]  0.4855447 -0.7463454 -0.3623149  0.4508110 -0.6204866 -0.8302512  1.7498530
 [8]  0.9920785  0.5215649  1.0366535
> y
 [1]  0.4855447 -0.7463454 -0.3623149  0.4508110 -0.6204866 -0.8302512  1.7498530
 [8]  0.9920785  0.5215649  1.0366535
> plot_colorByDensity(x,y)
Error in plot.window(...) : invalid 'xlim' value

Here's the interesting part: When I uncomment that print(xlim) line in the function, I don't get this error and it plots fine.

What's up with that?

Upvotes: 1

Views: 263

Answers (1)

Peyton
Peyton

Reputation: 7396

When you call a function, R doesn't immediately evaluate the arguments, so, in your case, when evaluation of your function starts, xlim does not actually contain a vector with the minimum and maximum values in x because the expression to generate those values hasn't been evaluated yet. Without the call to print, the expression isn't evaluated until you get to plot. But by that time, x has taken on a new value:

x <- densCols(x1,x2, colramp=colorRampPalette(c("black", "white")))

The best way to see this is to move your call to print to the line after the assignment of x:

x <- densCols(x1,x2, colramp=colorRampPalette(c("black", "white")))
print(xlim)

You'll see this:

[1] "#000000" "#FFFFFF"

which is clearly an invalid xlim.

The easiest way to fix this is simply to pick a new name for x. (You could also force evaluation of xlim at the beginning of the function by calling force(xlim).)

Upvotes: 2

Related Questions