[R] Returning the name of an object passed directly or from a list by lapply

andrewH ahoerner at rprogress.org
Sat Sep 17 01:27:06 CEST 2011


Dear Bill--
Wow. This is very clever and I learned a lot from it. I've never seen the
...() trick before, and on a Google code search, I could not find anyone
else who had used it. And I've never used the "..." feature, which, BTW,
though mentioned in every intro to R text, has no help page I can find.
<grrr>

Your function is still not doing what I am trying to do, doubtless because I
was not clear enough in the question I pose  At the bottom of this message I
have posted a copy of my testing function, and a few objects to test it on.
Its details are unimportant and not very interesting, but note that all of
its important outputs are in the form of side effects.   What I would like
to be able to do is this:

f(fun, <n variable names>)
and get back this:
fun(variable#1)
fun(variable#2)
...
fun(variable#n)

Attempting to copy some of your techniques, I came up with this: 
evaluate <- function(fun, ...){   
unevaluatedArgs <- substitute(...)
for (i in 1:length(deparse(unevaluatedArgs)))
fun(deparse(unevaluatedArgs)[i])
invisible(TRUE)
}
As applied to my test data, it works on the first variable (but gets the
variable name wrong) and ignores the remainder of the list, e.g.:

> evaluate(testX, H.char, H.vec, H.df,  H.mat)
###################
testX( deparse(unevaluatedArgs)[i] ):  Class= character  Type= character 
Mode= character 
Summary:
   Length     Class      Mode 
        1 character character 
Structure:
 chr "H.char"

On the other hand, this almost works:
evaluate <- function(fun, ...){   
evaluatedArgs <- list(...)
for (i in 1:length(evaluatedArgs))  fun(evaluatedArgs[i])
invisible(TRUE)
}

The only thing it does not do is get the name of the passed object right.
That seems like it ought to be a small problem, but as you pointed out, the
names are not in the list.  (BTW, I don't understand dropping the names as a
design choice for the list() function. If you use list() to make a list out
of four symbols for objects, wouldn't it be better to make the text of the
symbols the default names for those objects? That would solve this problem
nicely.) [s]ubstitute seems to drop all but the first variable passed by
"...".

Thanks so much for your thoughtful help.

andrewH



testX <- function(objectX, bar=TRUE) {    # A useful diagnostic function
    object.name <- deparse(substitute(objectX))
    if(bar) cat("##################################\n");
    cat("testX(", object.name, "): ");  cat(" Class=", class(objectX));
cat("  Type=", typeof(objectX)); cat("  Mode=", mode(objectX), "\n");
    cat("Summary:\n"); print(summary(objectX))
    cat("Structure:\n");  str(objectX);
    if (is.factor(objectX)) {cat("Levels: ", levels(objectX), "\n");
cat("Length: ", length(objectX), "\n")}
    invisible(object.name)
}

## Define 4 test variables: H.char, H.vec, H.df, H.mat
H.char  <- letters[1:10]
H.vec   <- c(1:10)
H.df      <- {  # Makes a test data set A.df with 2-, 3-, & 4-factor sorting
variables, making 24 
# combinations,  & a 4th variable with a  unique data value for each
combination.
# No random component. 
   year.2     <- factor( rep(1:2, each=12) )
   cohort.3 <- factor( rep(rep(1:3,each=4),2) )
   race.4     <- factor( rep(1:4, 6) )
   D1          <- as.numeric(as.character(year.2))*1.1 +
as.numeric(as.character(cohort.3))*1.01+
as.numeric(as.character(race.4))*1.001
   data.frame(year.2,cohort.3,race.4,D1)
}
H.mat <-matrix(1:16, 4, 4)
## End of test variables

--
View this message in context: http://r.789695.n4.nabble.com/Returning-the-name-of-an-object-passed-directly-or-from-a-list-by-lapply-tp3816798p3819378.html
Sent from the R help mailing list archive at Nabble.com.



More information about the R-help mailing list