Hello, still I have difficulties with variable names in functions. I know the famous example form help for deparse/substitute but I will give a simpler one to explain my problem. I know from Reid Huntsinger (Tue, 8 Feb 2005 12:39:32 -0500) that: "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." The output of several functions does not make much sense, if these names do not appear (e.g. parameter estimates in Cox-regression, ...) Only to give a trivial example I show my problem with the table function. As you know, if I call table as follows, the output is labelled properly.> charly<-c(rep(1,3),rep(2,7));delta<-c(rep(1:2,5)) > table(charly, delta)delta charly 1 2 1 2 1 2 3 4 If I define a trivial function to call table, the output is less satisfying. (Of course, I know that this function is useless.)> mytable1<-function(x,y){table(x,y)} > mytable1(charly, delta)y x 1 2 1 2 1 2 3 4 If I define the function in the following way, it does what I wish, namely it returns output equivalent to the simple call "table(charly, delta)".> mytable2<-function(x,y){+ cat("table(",as.symbol((deparse(substitute(x)))), + "," , as.symbol(deparse(substitute(y))),")\n", + file="temp",sep="",append=F) + eval(parse("temp",n=-1)) + }> mytable2(charly, delta)delta charly 1 2 1 2 1 2 3 4>I assume that there is a better way to solve this problem and I would be happy about hints, where to find solutions in the documentation. Thanks, Heinz T?chler
Heinz Tuechler wrote:> Hello, > > still I have difficulties with variable names in functions. I know the > famous example form help for deparse/substitute but I will give a simpler > one to explain my problem. > I know from Reid Huntsinger (Tue, 8 Feb 2005 12:39:32 -0500) that: > "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." > > The output of several functions does not make much sense, if these names do > not appear (e.g. parameter estimates in Cox-regression, ...) > Only to give a trivial example I show my problem with the table function. > > As you know, if I call table as follows, the output is labelled properly. > >>charly<-c(rep(1,3),rep(2,7));delta<-c(rep(1:2,5)) >>table(charly, delta) > > delta > charly 1 2 > 1 2 1 > 2 3 4 > If I define a trivial function to call table, the output is less satisfying. > (Of course, I know that this function is useless.) > >>mytable1<-function(x,y){table(x,y)} >>mytable1(charly, delta) > > y > x 1 2 > 1 2 1 > 2 3 4 > If I define the function in the following way, it does what I wish, namely > it returns output equivalent to the simple call "table(charly, delta)". > >>mytable2<-function(x,y){ > > + cat("table(",as.symbol((deparse(substitute(x)))), > + "," , as.symbol(deparse(substitute(y))),")\n", > + file="temp",sep="",append=F) > + eval(parse("temp",n=-1)) > + } > >>mytable2(charly, delta)See argument "dnn" in ?table: mytable2 <- function(x,y){ table(x, y, dnn = c(deparse(substitute(x)), deparse(substitute(y)))) } Uwe Ligges> delta > charly 1 2 > 1 2 1 > 2 3 4 > > I assume that there is a better way to solve this problem and I would be > happy about hints, where to find solutions in the documentation. > > 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
Heinz Tuechler <tuechler at gmx.at> writes:> > mytable1<-function(x,y){table(x,y)} > > mytable1(charly, delta) > y > x 1 2 > 1 2 1 > 2 3 4 > If I define the function in the following way, it does what I wish, namely > it returns output equivalent to the simple call "table(charly, delta)". > > mytable2<-function(x,y){ > + cat("table(",as.symbol((deparse(substitute(x)))), > + "," , as.symbol(deparse(substitute(y))),")\n", > + file="temp",sep="",append=F) > + eval(parse("temp",n=-1)) > + } > > mytable2(charly, delta) > delta > charly 1 2 > 1 2 1 > 2 3 4 > > > I assume that there is a better way to solve this problem and I would be > happy about hints, where to find solutions in the documentation.What did Thomas L. say recently? "If the answer involves parse(), you probably asked the wrong question", I think it was. The canonical way is mytable <- function(x,y) eval.parent(substitute(table(x,y))) or, you could of course modify the names(dimnames(...)) and just pass the names along. -- O__ ---- Peter Dalgaard Blegdamsvej 3 c/ /'_ --- Dept. of Biostatistics 2200 Cph. N (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
At 11:48 17.02.2005 +0100, Uwe Ligges wrote:> >See argument "dnn" in ?table: > > > mytable2 <- function(x,y){ > table(x, y, dnn = c(deparse(substitute(x)), > deparse(substitute(y)))) > } > >Uwe Ligges > > >Thank you for your hint. This is of course a good solution for the example. Still I am looking for a more general solution, but it is not urgent. Heinz T?chler>Heinz Tuechler wrote: > >> Hello, >> >> still I have difficulties with variable names in functions. I know the >> famous example form help for deparse/substitute but I will give a simpler >> one to explain my problem. >> I know from Reid Huntsinger (Tue, 8 Feb 2005 12:39:32 -0500) that: >> "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 atleast>> in order to do "lazy evaluation". You can get them via "substitute" ; see >> the help for that." >> >> The output of several functions does not make much sense, if these names do >> not appear (e.g. parameter estimates in Cox-regression, ...) >> Only to give a trivial example I show my problem with the table function. >> >> As you know, if I call table as follows, the output is labelled properly. >> >>>charly<-c(rep(1,3),rep(2,7));delta<-c(rep(1:2,5)) >>>table(charly, delta) >> >> delta >> charly 1 2 >> 1 2 1 >> 2 3 4 >> If I define a trivial function to call table, the output is lesssatisfying.>> (Of course, I know that this function is useless.) >> >>>mytable1<-function(x,y){table(x,y)} >>>mytable1(charly, delta) >> >> y >> x 1 2 >> 1 2 1 >> 2 3 4 >> If I define the function in the following way, it does what I wish, namely >> it returns output equivalent to the simple call "table(charly, delta)". >> >>>mytable2<-function(x,y){ >> >> + cat("table(",as.symbol((deparse(substitute(x)))), >> + "," , as.symbol(deparse(substitute(y))),")\n", >> + file="temp",sep="",append=F) >> + eval(parse("temp",n=-1)) >> + } >> >>>mytable2(charly, delta) >> delta >> charly 1 2 >> 1 2 1 >> 2 3 4 >> >> I assume that there is a better way to solve this problem and I would be >> happy about hints, where to find solutions in the documentation. >> >> 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 11:51 17.02.2005 +0100, Peter Dalgaard wrote:>Heinz Tuechler <tuechler at gmx.at> writes: > >> > mytable1<-function(x,y){table(x,y)} >> > mytable1(charly, delta) >> y >> x 1 2 >> 1 2 1 >> 2 3 4 >> If I define the function in the following way, it does what I wish, namely >> it returns output equivalent to the simple call "table(charly, delta)". >> > mytable2<-function(x,y){ >> + cat("table(",as.symbol((deparse(substitute(x)))), >> + "," , as.symbol(deparse(substitute(y))),")\n", >> + file="temp",sep="",append=F) >> + eval(parse("temp",n=-1)) >> + } >> > mytable2(charly, delta) >> delta >> charly 1 2 >> 1 2 1 >> 2 3 4 >> > >> I assume that there is a better way to solve this problem and I would be >> happy about hints, where to find solutions in the documentation. > >What did Thomas L. say recently? "If the answer involves parse(), you >probably asked the wrong question", I think it was. > >The canonical way is > >mytable <- function(x,y) eval.parent(substitute(table(x,y))) > >or, you could of course modify the names(dimnames(...)) and just pass >the names along. > > >-- > O__ ---- Peter Dalgaard Blegdamsvej 3 > c/ /'_ --- Dept. of Biostatistics 2200 Cph. N > (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 >~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907 >Thank you, this method works well. One step further I am again using parse(), but maybe there is a better solution for that situation too. The example would be a function, where I pass the variable name as string instead of the name. The motivation for this is that it seems easier to handle if I want to pass several variables (i.e. a vector of variable names) to the function (as I learned recently from this help-list). In this case I have to use get(). In the case of calling table() the variable name disappeares.> alpha<-c(rep(1:5,10)) > name.alpha<-"alpha" > mytable1<-function(x){print(table(get(x)))} > mytable1(name.alpha)1 2 3 4 5 10 10 10 10 10 If I use eval(parse()) instead, it works as expected. I tried several combinations of eval() and substitute() but I did not find a solution. Is there a similar "trick"?> mytable2<-function(x){+ string<-paste("print(table(",as.symbol(x),"))") + eval(parse(text=string))}> mytable2(name.alpha)alpha 1 2 3 4 5 10 10 10 10 10 Thanks, Heinz T?chler
At 08:32 17.02.2005 -0800, Berton Gunter wrote:> >I thought Thomas L. was clear, but apparently not... > >** Do not pass character string names as arguments to functions. ** Pass the >objects (or expressions) which can consist of lists of vectors, dataframes, >etc. instead. > >If you need the names (e.g. as labels) you can use the deparse(substitute()) >construction. I strongly recommend that you study pp. 44-46 and section 3.5 >("Computing on the Language") of V&R's S PROGRAMMING. The point is that one >can, of course, do things the way you want, but it makes life unnecessarily >difficult and complex because R is set up to pass arguments by value and can >keep better track of proper evaluation environments when this is done (which >means you don't have to). > >-- Bert Gunter >Thank you for your advice. I will try to get the book as soon as possible and meanwhiles study again other publications regarding these questions. At the moment I am uncertain which way to prefer, since I am making my first steps in R. Somehow I got the impression that there is a little ambiguity concerning the use of object (variable) names in functions. My little experience with R gave me the imression that much output automatically has a sensible format (title, naming of estimates for factors, ...) when you pass the object (=variable) name. If you don't do it, you have more work to arrive at the same result. A title with the variable's name is usually more informative than one with "get(x)". So for a beginner like me it's temting to try to program functions in a way that they work as similar as possible to the simple call from the R prompt. Maybe objects like columns of data frames could have something like a name attribute equal to their (column)name which is passed automatically to functions. Again, many thanks, Heinz T?chler>> > >> >> Thank you, this method works well. One step further I am again using >> parse(), but maybe there is a better solution for that situation too. >> The example would be a function, where I pass the variable >> name as string >> instead of the name. The motivation for this is that it seems >> easier to >> handle if I want to pass several variables (i.e. a vector of variable >> names) to the function (as I learned recently from this help-list). >> In this case I have to use get(). In the case of calling table() the >> variable name disappeares. >> >> > alpha<-c(rep(1:5,10)) >> > name.alpha<-"alpha" >> > mytable1<-function(x){print(table(get(x)))} >> > mytable1(name.alpha) >> >> 1 2 3 4 5 >> 10 10 10 10 10 >> >> If I use eval(parse()) instead, it works as expected. I tried several >> combinations of eval() and substitute() but I did not find a solution. >> Is there a similar "trick"? >> >> > mytable2<-function(x){ >> + string<-paste("print(table(",as.symbol(x),"))") >> + eval(parse(text=string))} >> > mytable2(name.alpha) >> alpha >> 1 2 3 4 5 >> 10 10 10 10 10 >> >> >> 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 >> > > >