[S] How to attach a data frame from within a function without copying the data?

Terry Elrod (Terry.Elrod@UAlberta.ca)
Sat, 11 Apr 1998 19:52:20 -0600


Here's a question for the experts. A good answer would be very useful to many, I think.

It's often useful to attach a data frame at the command level--accessing its variables becomes more convenient and faster. These same benefits are also obtained from within functions.

I am writing a model-fitting function with a data argument that may name a data frame. I would like to have the function attach the data frame without passing a copy of the data to the function. This is not as easy as it might appear.

Here's a straightforward way to attach and detach a data frame from within a function, but a copy of the data is passed to the function and remains there.

********************
>func <-
function(data)
{
dsn <- deparse(substitute(data))
attach(data, name = dsn, use.names = F)
on.exit(detach(what = dsn, save = F), add = T)
sys.frame() # This line is added to show what is stored in func's frame
}
> val <- func(datafrm) # example with a small data frame
> names(val)
[1] ".Auto.print" "data" "dsn" "data"
# ... shows two components of sys.frame with name "data". which means the data copied ...
> dim(val[[2]])
[1] 481 32
# yup, the data were copied all right.
********************
The problem, of course, is that func() evaluates data in its call to attach(). It is possible to remove the data frame from the function frame by adding the call: remove("data", frame = sys.nframe()) immediately after attaching the frame. While we're at it, it's also possible to attach the data frame only if it is not already attached, and to check for whether the object exists on the search path. The (tested) result is the following:

func <-
function(data)
{
dsn <- deparse(substitute(data))
if(!exists(dsn))
stop(paste(dsn, " not found on search path.", sep = ""))
else if(match(dsn, search(), nomatch = 0))
warning(paste(dsn, " already attached", sep = ""))
else {
attach(data, name = dsn)
remove("data", frame = sys.nframe())
on.exit(detach(what = dsn, save = F))
}
#. . .
# rest of func follows here
#. . .
}

However a copy of the data frame is still passed to func. One would hope there is a way to attach a data frame from within a function without copying the entire frame to the function in the first place.

My experiments with various combinations of substitute, deparse and as.name have not proven successful. I am certain code that accomplishes what is contained in func without passing the data to func would get a lot of grateful use from readers of this list.

It would of course be most handy if a function, say attach.df(), could contain the code so that all this could be accomplished by simply inserting the line attach.df(data) into the calling function, but this is perhaps too much to hope for. I see no harm in assuming, as I have in func, that the object is attached under its own name.

Any fairy godparents out there willing and able to help with this one?

Terry Elrod
-----------------
Prof. Terry Elrod; 3-23 Faculty of Business; Univ. of Alberta; Edmonton AB; Canada T6G 2R6
Tel: (403) 492-5884. Fax: (403) 492-3325. Email: Terry.Elrod@Ualberta.ca.
Web: http://www.ualberta.ca/~telrod/.
-----------------

-----------------------------------------------------------------------
This message was distributed by s-news@wubios.wustl.edu. To unsubscribe
send e-mail to s-news-request@wubios.wustl.edu with the BODY of the
message: unsubscribe s-news