Skip to content

loops with assign() and get()

4 messages · Laura Villegas Ortiz, William Dunlap, PO SU

#
The first step to making things easier to do is to put those data.frames
into a list.  I'll call it DFS and your data.frames will now be DFs[[1]],
DFs[[2]], ..., DFs[[length(DFs)]].
    DFs <- lapply(paste0("DFs", 1:102), get)
In the future, I think it would be easier if you skipped the 'assign()'
and just put the data into a list from the start.

Now use lapply to process that list, creating a new list called 'df', where
df[[i]] is the result of processing DFs[[i]]:

df <- lapply(DFs, FUN=function(DFsi) {
                      # your code from the for loop you supplied
                      dfi=DFsi[1,]
                      dfi=dfi[,1:3]
                      names(dfi)=names(DFsi[c(1,4,5)])
                      dfi=rbind(dfi,DFsi[c(1,4,5)])
                      names(dfi)=c("UID","Date","Location")
                      dfi # return this to put in list that lapply is making
                  })

(You didn't supply sample data so I did not run this - there may be typos.)

Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Sat, Aug 9, 2014 at 1:39 PM, Laura Villegas Ortiz <lvilleg at ncsu.edu> wrote:
1 day later
#
That code will not work.  get() and assign() are troublesome for a
variety of reasons.  E.g.,

* adding made-up names to the current environment is dangerous.  They
may clobber fixed names in the environment.  You may be confused about
what the current environment is (especially when refactoring code).
You can avoid this by using dataEnv <- new.env() to make an
environment for your related objects and using the envir=dataEnv
argument to get() and assign() to put the objects in there.  However,
once you go this route, you may as well use the syntax dataEnv[[name]]
to refer to your objects instead of get(name, envir=dataEnv) and
assign(name, value, envir=dataEnv).

* replacement syntax like
    names(get(someName)) <- c("One", "Two")
will not work.  You have to use kludgy code like
    tmp <- get(someName)
    names(tmp) <- c("One", "Two")
    assign(someName, tmp)
If you use the dataEnv[[name]] syntax then you can use the more normal looking
    names(dataEnv[[name]]) <- c("One", "Two")

By the way, I do not think your suggested code will work - you call
assign() before making a bunch of changes to dfi instead of after
making the changes.
I have not measured the memory implications of your method vs. using
lapply on lists, but I don't think there is much of a difference in
this case.  (There can be a big difference when you are replacing the
inputs by the outputs.)

Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Sun, Aug 10, 2014 at 8:22 PM, PO SU <rhelpmaillist at 163.com> wrote: