[R] Simple programming problem with 'with' or 'data ='

Duncan Murdoch murdoch at stats.uwo.ca
Wed Aug 27 19:35:40 CEST 2008


On 8/27/2008 1:15 PM, Peter Flom wrote:
> Hello
> 
> I wrote a simple program to modify a boxplot:
> 
> <<<
> 
> gdsbox <- function(indvar){
> boxplot(indvar~gds3lev, 
>    main = paste('Boxplot of', substitute(indvar), "for GDS groups"),
>    names = c('1', '3', '4, 5, 6'))
> }
> 
>>>>
> 
> If I attach the dataframe gdsgraph, this works fine. However, I've been warned against attach.  When I tried to run this program using 'with', it did not work.
> 
> e.g. 
> 
>            with(gdsgraph, gdsbox(BReT3T5T))
> 
> produced an error that gds3level was not found
> 
> but if I try
> 
>           with(gdsgraph, boxplot(BReT3T5T~gds3lev))
> 
> it works fine.
> 
> Similar problems occurred when I tried to use data =
> 
> What am I missing?

You defined your gdsbox function in the global environment, which means 
it will go looking for non-local variables there.  It doesn't matter 
where you call it from, R uses lexical scoping.

To get what you want, you could define your function within the with, i.e.

with(gdsgraph, {

  gdsbox <- function(indvar){
  boxplot(indvar~gds3lev,
     main = paste('Boxplot of', substitute(indvar), "for GDS groups"),
     names = c('1', '3', '4, 5, 6'))
  }

  gdsbox(BReT3T5T)
})

but this misses the point of defining gdsbox once, and using it in many 
places.  So I'd say the best thing to do is to change the definition of 
it to use the data argument, i.e.

gdsbox <- function(indvar, data) {
     boxplot(indvar~gds3lev,
     main = paste('Boxplot of', substitute(indvar), "for GDS groups"),
     names = c('1', '3', '4, 5, 6'), data=data)
  }

and call it as

gdsbox(BReT3T5T, gdsgraph)

There are ways to make your function act as though it doesn't use 
lexical scoping (parent.env, etc.), but they are ugly, and I don't think 
they're necessary here.

Duncan Murdoch



More information about the R-help mailing list