I am trying to adapt boxplot.formula (in graphics) to accept an
additional parameter, weights.
I already managed to adapt boxplot.default to do this.
boxplot.formula prepares the data for a call to boxplot.default and to
achieve that does the following: It takes a formula like
x~g*h
as the first argument, and then by using
m <- match.call(expand.dots = FALSE)
saves the call. It transforms the call
m$na.action <- na.action # force use of default for this method
m[[1]] <- as.name("model.frame")
and then evaluates the modified call
mf <- eval(m, parent.frame())
print(m)
gives
model.frame(formula = x ~ g * h)
Then it uses components of mf for the call to boxplot.default.
m has a component m$formula containing the parsed model formula.
mode(m$formula) is "call".
In our case, deparse(m$formula) gives a string representation of the
formula: "x~g*h".
I want to replace the response variable (in our case x) by the weights
variable, which in the string expression can be done easily with
strsplit and paste. Then I need to reconvert the modified string to a call.
So I create newmodelstring<-"weights~g*h" and try
m$formula<-as.call(parse(newmodelstring))
print(m)
gives
model.frame(formula = weights ~ g * h())
When I try to evaluate the modified m this does not work. When I try to
evaluate m with this modification I get
Error in model.frame(formula = weights ~ g * h()) :
attempt to apply non-function
Is there a way to get rid of the empty parentheses at the
end of the formula? I think then my code could work.
--
Erich Neuwirth, Didactic Center for Computer Science
University of Vienna
Visit our SunSITE at http://sunsite.univie.ac.at
Phone: +43-1-4277-39902 Fax: +43-1-4277-9399
On 8/22/05, Erich Neuwirth <erich.neuwirth at univie.ac.at> wrote:> I am trying to adapt boxplot.formula (in graphics) to accept an > additional parameter, weights. > I already managed to adapt boxplot.default to do this. > > boxplot.formula prepares the data for a call to boxplot.default and to > achieve that does the following: It takes a formula like > > x~g*h > > as the first argument, and then by using > > m <- match.call(expand.dots = FALSE) > > saves the call. It transforms the call > > m$na.action <- na.action # force use of default for this method > m[[1]] <- as.name("model.frame") > > and then evaluates the modified call > mf <- eval(m, parent.frame()) > > print(m) > gives > model.frame(formula = x ~ g * h) > > Then it uses components of mf for the call to boxplot.default. > > m has a component m$formula containing the parsed model formula. > mode(m$formula) is "call". > In our case, deparse(m$formula) gives a string representation of the > formula: "x~g*h". > I want to replace the response variable (in our case x) by the weights > variable, which in the string expression can be done easily with > strsplit and paste. Then I need to reconvert the modified string to a call. > > So I create newmodelstring<-"weights~g*h" and try > > m$formula<-as.call(parse(newmodelstring)) > > print(m) > gives > model.frame(formula = weights ~ g * h()) > > > When I try to evaluate the modified m this does not work. When I try to > evaluate m with this modification I get > > Error in model.frame(formula = weights ~ g * h()) : > attempt to apply non-function > > Is there a way to get rid of the empty parentheses at the > end of the formula? I think then my code could work. > > -- > Erich Neuwirth, Didactic Center for Computer Science > University of Vienna > Visit our SunSITE at http://sunsite.univie.ac.at > Phone: +43-1-4277-39902 Fax: +43-1-4277-9399 > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >I think the preferred way to do this is using substitute although formulas are a bit tricky in that you need to eval them after the substitution to make sure that the object has class "formula".> (foo <- eval(substitute(x ~ g * h, list(x = as.name("weights")))))weights ~ g * h> class(foo)[1] "formula"
> >>(foo <- eval(substitute(x ~ g * h, list(x = as.name("weights"))))) > > weights ~ g * h > >>class(foo) > > [1] "formula" > >ff<-formula("x~g*h") (foo<-eval(substitute(ff,list(x=as.name("weights"))))) gives x ~ g * h what needs to be done to ff for the substitution to work? I found a way of doing it using string substitution and applying formula (instead of as.call) to the string, but I would like to be able to do it using substitution. This is what I currently do: myexpr<-paste("weights ~",strsplit(deparse(m$formula),"~")[[1]][2]) m$formula<-formula(myexpr) -- Erich Neuwirth, Didactic Center for Computer Science University of Vienna Visit our SunSITE at http://sunsite.univie.ac.at Phone: +43-1-4277-39902 Fax: +43-1-4277-9399
On 8/22/05, Erich Neuwirth <erich.neuwirth at univie.ac.at> wrote:> > > >>(foo <- eval(substitute(x ~ g * h, list(x = as.name("weights"))))) > > > > weights ~ g * h > > > >>class(foo) > > > > [1] "formula" > > > > > > ff<-formula("x~g*h") > (foo<-eval(substitute(ff,list(x=as.name("weights"))))) > > gives > > x ~ g * h > > what needs to be done to ff for the substitution to work? > > I found a way of doing it using string substitution > and applying formula (instead of as.call) to the string, > but I would like to be able to do it using substitution. > > This is what I currently do: > > myexpr<-paste("weights ~",strsplit(deparse(m$formula),"~")[[1]][2]) > m$formula<-formula(myexpr)Try do.call like this: ff <- x ~ g*h do.call("substitute", list(ff, list(x = as.name("weight"))))
> Try do.call like this: > > ff <- x ~ g*h > do.call("substitute", list(ff, list(x = as.name("weight")))) >It is even more complicated. All I know is that ff is a formula with an expression on the left hand side. This expression needs to be replaced by "weights". According to the documentation, substitute only handles replacement of variables by something else, and that is not enough in my case. -- Erich Neuwirth, Didactic Center for Computer Science University of Vienna Visit our SunSITE at http://sunsite.univie.ac.at Phone: +43-1-4277-39902 Fax: +43-1-4277-9399