Hello, applying a function to a list of variables I face the following problem: Let's say I want to compute tables for several variables. I could write a command for every single table, like bravo<-c(1,1,2,3,5,5,5,);charly<-c(7,7,4,4,2,1) table(bravo); table(charly)> table(bravo); table(charly)bravo 1 2 3 5 2 1 1 3 charly 1 2 4 7 1 1 2 2 The results are two tables with the names of the variables above each. If I want to do the same thing by a function I find no way to get the variable names above the tables. demofn<-function(varlist) {for (i in seq(along=varlist)) {cat(deparse(varlist[i])) # < - - - - how to change this? print(table(varlist[i]))}}> demofn(list(bravo, charly))list(c(1, 1, 2, 3, 5, 5, 5)) 1 2 3 5 2 1 1 3 list(c(7, 7, 4, 4, 2, 1)) 1 2 4 7 1 1 2 2>Thanks, Heinz T?chler
Semantically, R is pass-by-value, so you don't really have the names, just the values. In implementation, though, R *does* pass names, in part at least in order to do "lazy evaluation". You can get them via "substitute" ; see the help for that. Reid Huntsinger -----Original Message----- From: r-help-bounces at stat.math.ethz.ch [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Heinz Tuechler Sent: Tuesday, February 08, 2005 11:45 AM To: r-help at stat.math.ethz.ch Subject: [R] How to get variable names in a function? Hello, applying a function to a list of variables I face the following problem: Let's say I want to compute tables for several variables. I could write a command for every single table, like bravo<-c(1,1,2,3,5,5,5,);charly<-c(7,7,4,4,2,1) table(bravo); table(charly)> table(bravo); table(charly)bravo 1 2 3 5 2 1 1 3 charly 1 2 4 7 1 1 2 2 The results are two tables with the names of the variables above each. If I want to do the same thing by a function I find no way to get the variable names above the tables. demofn<-function(varlist) {for (i in seq(along=varlist)) {cat(deparse(varlist[i])) # < - - - - how to change this? print(table(varlist[i]))}}> demofn(list(bravo, charly))list(c(1, 1, 2, 3, 5, 5, 5)) 1 2 3 5 2 1 1 3 list(c(7, 7, 4, 4, 2, 1)) 1 2 4 7 1 1 2 2>Thanks, Heinz T?chler ______________________________________________ R-help at stat.math.ethz.ch mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
This might be easier for your purpose:> lapply(list(bravo=bravo, charly=charly), table)$bravo 1 2 3 5 2 1 1 3 $charly 1 2 4 7 1 1 2 2 Andy> From: Heinz Tuechler > > Hello, > > applying a function to a list of variables I face the > following problem: > Let's say I want to compute tables for several variables. I > could write a > command for every single table, like > bravo<-c(1,1,2,3,5,5,5,);charly<-c(7,7,4,4,2,1) > table(bravo); table(charly) > > table(bravo); table(charly) > bravo > 1 2 3 5 > 2 1 1 3 > charly > 1 2 4 7 > 1 1 2 2 > The results are two tables with the names of the variables above each. > If I want to do the same thing by a function I find no way to get the > variable names above the tables. > demofn<-function(varlist) > {for (i in seq(along=varlist)) > {cat(deparse(varlist[i])) # < - - - - how to change this? > print(table(varlist[i]))}} > > demofn(list(bravo, charly)) > list(c(1, 1, 2, 3, 5, 5, 5)) > 1 2 3 5 > 2 1 1 3 > list(c(7, 7, 4, 4, 2, 1)) > 1 2 4 7 > 1 1 2 2 > > > > Thanks, > Heinz T?chler > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html > >
If you pass your function a NAMED list, then the following works: demofn<-function(varlist) { nm<-names(varlist) for (i in seq(along=varlist)) {cat('\n',nm[i]) print(table(varlist[[i]])) } } demofn(list(bravo=bravo, charly=charly)) If you don't pass a named list, then you need to restrict and know the form of the expression that is the varlist argument in order to substitute() and deparse it correctly to get the identifiers you want. For example, if you knew that varlist were an expression of the form: list(var1,var2,var3,...) then you could get the ith identifier vari via: deparse((as.list(substitute(varlist))[-1])[[i]]) HOWEVER, this is probably inefficient and **clearly** clumsy, undesirable, and almost certain to fail (so don't do this!). If the number of tables is small enough that you could simply list them as arguments (as opposed to constructing the list of vectors to be tabled in some way), then the function call could be of the form function(...) and the ... arguments could be processed as discussed in section 3.1 of V&R's S PROGRAMMING. That is, your example call would be of the form: demofn(bravo,charly), and you can forgo lists in the call altogether. This strategy actually also works for long constructed lists of arguments using do.call() -- see it's help file and V&R again for details. -- Bert Gunter Genentech Non-Clinical Statistics South San Francisco, CA "The business of the statistician is to catalyze the scientific learning process." - George E. P. Box> -----Original Message----- > From: r-help-bounces at stat.math.ethz.ch > [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Heinz Tuechler > Sent: Tuesday, February 08, 2005 8:45 AM > To: r-help at stat.math.ethz.ch > Subject: [R] How to get variable names in a function? > > Hello, > > applying a function to a list of variables I face the > following problem: > Let's say I want to compute tables for several variables. I > could write a > command for every single table, like > bravo<-c(1,1,2,3,5,5,5,);charly<-c(7,7,4,4,2,1) > table(bravo); table(charly) > > table(bravo); table(charly) > bravo > 1 2 3 5 > 2 1 1 3 > charly > 1 2 4 7 > 1 1 2 2 > The results are two tables with the names of the variables above each. > If I want to do the same thing by a function I find no way to get the > variable names above the tables. > demofn<-function(varlist) > {for (i in seq(along=varlist)) > {cat(deparse(varlist[i])) # < - - - - how to change this? > print(table(varlist[i]))}} > > demofn(list(bravo, charly)) > list(c(1, 1, 2, 3, 5, 5, 5)) > 1 2 3 5 > 2 1 1 3 > list(c(7, 7, 4, 4, 2, 1)) > 1 2 4 7 > 1 1 2 2 > > > > Thanks, > Heinz T?chler > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html >
At 10:32 08.02.2005 -0800, Berton Gunter wrote:>If you pass your function a NAMED list, then the following works: > >demofn<-function(varlist) >{ > nm<-names(varlist) > for (i in seq(along=varlist)) > {cat('\n',nm[i]) > print(table(varlist[[i]])) > } >} >demofn(list(bravo=bravo, charly=charly)) > >If you don't pass a named list, then you need to restrict and know the form >of the expression that is the varlist argument in order to substitute() and >deparse it correctly to get the identifiers you want. For example, if you >knew that varlist were an expression of the form: >list(var1,var2,var3,...) >then you could get the ith identifier vari via: > >deparse((as.list(substitute(varlist))[-1])[[i]]) > >HOWEVER, this is probably inefficient and **clearly** clumsy, undesirable, >and almost certain to fail (so don't do this!). > >If the number of tables is small enough that you could simply list them as >arguments (as opposed to constructing the list of vectors to be tabled in >some way), then the function call could be of the form function(...) and the >... arguments could be processed as discussed in section 3.1 of V&R's S >PROGRAMMING. That is, your example call would be of the form: >demofn(bravo,charly), and you can forgo lists in the call altogether. This >strategy actually also works for long constructed lists of arguments using >do.call() -- see it's help file and V&R again for details. > > >-- Bert Gunter >Genentech Non-Clinical Statistics >South San Francisco, CA > >"The business of the statistician is to catalyze the scientific learning >process." - George E. P. Box >Thank you for your detailled answer. I see that it is not as easy as I expected and I will think about a convenient way to do it. I tried also the opposit approach i.e. to pass a vector of names to the function like c("bravo", "charly") but until now I did not solve it either. A third way worked, but seemed to me less generally applicable. I stored all the names of the variables of a data.frame in a vector, made the selection of the variables by match() and passed the indices of the selected variables to the function. By this method I can then access each variable by its index and also its name via the vector of the stored names. It seemed to me a crude method of a beginner like me and I still hope to find a better one. Your suggestion with the named list may be the best, if I find a practical way to produce this named list by some function from a simple list without retyping each name. Thanks again, Heinz> > >> -----Original Message----- >> From: r-help-bounces at stat.math.ethz.ch >> [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of Heinz Tuechler >> Sent: Tuesday, February 08, 2005 8:45 AM >> To: r-help at stat.math.ethz.ch >> Subject: [R] How to get variable names in a function? >> >> Hello, >> >> applying a function to a list of variables I face the >> following problem: >> Let's say I want to compute tables for several variables. I >> could write a >> command for every single table, like >> bravo<-c(1,1,2,3,5,5,5,);charly<-c(7,7,4,4,2,1) >> table(bravo); table(charly) >> > table(bravo); table(charly) >> bravo >> 1 2 3 5 >> 2 1 1 3 >> charly >> 1 2 4 7 >> 1 1 2 2 >> The results are two tables with the names of the variables above each. >> If I want to do the same thing by a function I find no way to get the >> variable names above the tables. >> demofn<-function(varlist) >> {for (i in seq(along=varlist)) >> {cat(deparse(varlist[i])) # < - - - - how to change this? >> print(table(varlist[i]))}} >> > demofn(list(bravo, charly)) >> list(c(1, 1, 2, 3, 5, 5, 5)) >> 1 2 3 5 >> 2 1 1 3 >> list(c(7, 7, 4, 4, 2, 1)) >> 1 2 4 7 >> 1 1 2 2 >> > >> >> Thanks, >> Heinz T?chler >> >> ______________________________________________ >> R-help at stat.math.ethz.ch mailing list >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide! >> http://www.R-project.org/posting-guide.html >> > > >
Here's a (rather ugly) function that takes its arguments and turn them into a list, using the names of the arguments and the names of the components: listWithName <- function(...) { aname <- sapply(as.list(substitute({...})[-1]), deparse) res <- list(...) names(res) <- aname res } Here are a couple of examples:> x <- runif(5) > y <- "abc" > listWithName(x, y)$x [1] 0.44241647 0.07540958 0.46405311 0.01684738 0.94370893 $y [1] "abc"> listWithName(x, 1:3, y)$x [1] 0.44241647 0.07540958 0.46405311 0.01684738 0.94370893 $"1:3" [1] 1 2 3 $y [1] "abc"> listWithName(abc=x, y)$x [1] 0.44241647 0.07540958 0.46405311 0.01684738 0.94370893 $y [1] "abc" You can then use lapply() on the output. lapply() will automatically attach names to the components of its output. Andy> From: Heinz Tuechler > > At 10:32 08.02.2005 -0800, Berton Gunter wrote: > >If you pass your function a NAMED list, then the following works: > > > >demofn<-function(varlist) > >{ > > nm<-names(varlist) > > for (i in seq(along=varlist)) > > {cat('\n',nm[i]) > > print(table(varlist[[i]])) > > } > >} > >demofn(list(bravo=bravo, charly=charly)) > > > >If you don't pass a named list, then you need to restrict > and know the form > >of the expression that is the varlist argument in order to > substitute() and > >deparse it correctly to get the identifiers you want. For > example, if you > >knew that varlist were an expression of the form: > >list(var1,var2,var3,...) > >then you could get the ith identifier vari via: > > > >deparse((as.list(substitute(varlist))[-1])[[i]]) > > > >HOWEVER, this is probably inefficient and **clearly** > clumsy, undesirable, > >and almost certain to fail (so don't do this!). > > > >If the number of tables is small enough that you could > simply list them as > >arguments (as opposed to constructing the list of vectors to > be tabled in > >some way), then the function call could be of the form > function(...) and the > >... arguments could be processed as discussed in section 3.1 > of V&R's S > >PROGRAMMING. That is, your example call would be of the form: > >demofn(bravo,charly), and you can forgo lists in the call > altogether. This > >strategy actually also works for long constructed lists of > arguments using > >do.call() -- see it's help file and V&R again for details. > > > > > >-- Bert Gunter > >Genentech Non-Clinical Statistics > >South San Francisco, CA > > > >"The business of the statistician is to catalyze the > scientific learning > >process." - George E. P. Box > > > Thank you for your detailled answer. I see that it is not as easy as I > expected and I will think about a convenient way to do it. > I tried also the opposit approach i.e. to pass a vector of > names to the > function like c("bravo", "charly") but until now I did not > solve it either. > A third way worked, but seemed to me less generally applicable. > I stored all the names of the variables of a data.frame in a > vector, made > the selection of the variables by match() and passed the > indices of the > selected variables to the function. By this method I can then > access each > variable by its index and also its name via the vector of the > stored names. > It seemed to me a crude method of a beginner like me and I > still hope to > find a better one. > Your suggestion with the named list may be the best, if I > find a practical > way to produce this named list by some function from a simple > list without > retyping each name. > > Thanks again, > > Heinz > > > > > >> -----Original Message----- > >> From: r-help-bounces at stat.math.ethz.ch > >> [mailto:r-help-bounces at stat.math.ethz.ch] On Behalf Of > Heinz Tuechler > >> Sent: Tuesday, February 08, 2005 8:45 AM > >> To: r-help at stat.math.ethz.ch > >> Subject: [R] How to get variable names in a function? > >> > >> Hello, > >> > >> applying a function to a list of variables I face the > >> following problem: > >> Let's say I want to compute tables for several variables. I > >> could write a > >> command for every single table, like > >> bravo<-c(1,1,2,3,5,5,5,);charly<-c(7,7,4,4,2,1) > >> table(bravo); table(charly) > >> > table(bravo); table(charly) > >> bravo > >> 1 2 3 5 > >> 2 1 1 3 > >> charly > >> 1 2 4 7 > >> 1 1 2 2 > >> The results are two tables with the names of the variables > above each. > >> If I want to do the same thing by a function I find no way > to get the > >> variable names above the tables. > >> demofn<-function(varlist) > >> {for (i in seq(along=varlist)) > >> {cat(deparse(varlist[i])) # < - - - - how to change this? > >> print(table(varlist[i]))}} > >> > demofn(list(bravo, charly)) > >> list(c(1, 1, 2, 3, 5, 5, 5)) > >> 1 2 3 5 > >> 2 1 1 3 > >> list(c(7, 7, 4, 4, 2, 1)) > >> 1 2 4 7 > >> 1 1 2 2 > >> > > >> > >> Thanks, > >> Heinz T?chler > >> > >> ______________________________________________ > >> R-help at stat.math.ethz.ch mailing list > >> https://stat.ethz.ch/mailman/listinfo/r-help > >> PLEASE do read the posting guide! > >> http://www.R-project.org/posting-guide.html > >> > > > > > > > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html > >