[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