Thanks again to the s-news group this problem has been solved. The
following did the trick:
all.dates <- function(id){
frame.name <- paste("station", id, sep="")
temp.frame <- get(frame.name, where=1)
temp.frame$weather.date <- clean.dates(temp.frame$weather.date)
assign(frame.name, temp.frame, where=1)
}
Answers to my questions over the past few days have made me clearer on the
logic of S, but I know that I still have a long way to go. The responses I
received to this particular query are found below:
_____________________________________________________________________
Hi,
There are two (that I know of) general tricks that will help in your
situation: I'll call them get/assign, and eval/parse. eval/parse you almost
seem to have below.
Let's say you have the name of the frame as a string, like you have in your
example.
frame.name <- paste("station", id, sep="")
Then
get(frame.name)
will return the data frame with the name specified in "frame.name".
There are additional arguments to "get", "where" and "frame", that specify
where to look for "frame.name". These are useful when the object referenced
by "frame.name" is not in one of the "default" places. See the help page
for "get" for an explanation of this.
"assign" works like "get":
assign(frame.name, x)
will assign the value "x" to "frame.name". Again there are "where" and
"frame" arguments to specify where "frame.name" lives.
The catch is that you can't use this to assign to a subelement of an object,
i.e., you can't do
assign(frame.name$foo, x)
Instead you have to do something like this:
tmpvar <- get(frame.name)
tmpvar$foo <- x
assign(frame.name, tmpvar)
Also, when using these things inside functions the where and frame arguments
become more important. The sys.nframe() function is useful in such a
context for finding out the frame number of a function.
Okay, the other strategy, eval/parse. You were basically on the right track
below. Using paste, construct a command by joining strings, then parse it
as text, then eval it.
eval(parse(text=paste("station",id,
"$weather.date <- clean.dates(station", id,
"$weather.date)", sep="")))
It's a good idea to do the paste part first, then print it out to make sure
the command looks right.
Those are the two main tricks that I know of, there are probably others out
there.
HTH,
Chris Green
/*************************************************************/
/* Christopher G. Green (cggreen@stat.washington.edu) */
/* Graduate Student * Teaching Assistant * Powerlifter */
/* Dept. of Statistics, Box 354322,Seattle, WA,98195,U.S.A. */
/* http://www.stat.washington.edu/cggreen/ */
/* */
/* "Only those who risk going too far can possibly find out */
/* how far one can go." -- T.S. Eliot */
/* "Think big." -- Anonymous */
/*************************************************************/
____________________________________________________________________
Yes by name is needed, try the following:
clean.all <-function(id)
{
obj.name<-paste("station",id,sep="")
value<-clean.dates(get(where=1,obj.name)$weather.date)
eval(substitute(X$weather.date<-VALUE,list(X=as.name(obj.name),VALUE=value))
,local=F)
id
}
Test case:
station4<-data.frame(weather.date=c(1,2,3,4),junk=1:4)
clean.dates<-function(x) x^2
Some notes:
1. You must substitute both X and VALUE, since evaluation is at the top
level.
2. Using local=F makes the evaluation performed in the top level frame (1).
This is the calling frame. In fact local=T wont work even with "<<-".
3. where=1, use position one. I assume that your data is in the working
directory.
4. I returned the id, thus if you are running this and it crashes, you could
check the list of ids (provided you save/print them), since changes are made
in the working directory at the time of the eval call.
Tom Jagger
Research Associate
FSU department of Geography
|