# [R] Advice on parsing formulae

Claus Dethlefsen dethlef at math.aau.dk
Thu Dec 16 09:33:46 CET 2004

```Thank you for the advice. I have now boiled my problem down to the
following:

How do I create fm2 from fm1 ?

fm1 <-  Y ~ 1 + tvar(x:A) + tvar(z) + u + tvar(B) + tvar(poly(v,3))
fm2 <-  Y ~ 1 + x:A + z + u + B + poly(v, 3)

Thus, how do I simply remove tvar( * ) from a formula? Do I have to write a
function to parse the string and then re-create the formula? Is there an
easy way of doing this?

When my above problem is solved, I can (with the help from Heather Turner
and Chuck Berry) do the following

## define som data
x <- z <- u <- v <- rnorm(5)
A <- B <- factor( rep( c(1,2), c(3,2) ) )

## define my formula fm1 and manually create fm2.
fm1 <-  Y ~ 1 + tvar(x:A) + tvar(z) + u + tvar(B) + tvar(poly(v,3))
fm2 <-  Y ~ 1 + x:A + z + u + B + poly(v, 3)

## extract the term.labels from fm2, make the design matrix and extract
'assign'
term.labels <- unname(sapply(attr(terms(fm2), "term.labels"),
removeSpace))
X <- model.matrix(fm2,keep.order=TRUE)
pAssign <- attr(X, "assign")

## Now, extract the tvar-terms from fm1
tvar.terms <- terms( fm1, specials = "tvar",keep.order=TRUE )
idx <- attr(tvar.terms,"specials")\$tvar
if (attr(tvar.terms,"intercept")) idx <- idx -1
tvar <- attr(terms(fm2,keep.order=TRUE),"term.labels")[idx]
tvar <- unname( sapply( tvar, removeSpace) )

## Finally, combine the information to get the vector I asked for
tvarAssign <- match(pAssign, sort(match(tvar, term.labels)))
tvarAssign[is.na(tvarAssign)] <- 0

> -----Original Message-----
> From: Heather Turner [mailto:Heather.Turner at warwick.ac.uk]
> Sent: 15. december 2004 11:41
> To: r-help at stat.math.ethz.ch
> Subject: Re: [R] Advice on parsing formulae
>
>
> I think this will do what you want:
>
> # Need this function to remove spaces from term labels later on
> > removeSpace <-  function(string) gsub("[[:space:]]", "", string)
>
> # Specify which terms are in a "tvar" group
> # (could remove spaces separately)
> > tvar <- unname(sapply(c("x:A", "z", "B", "poly(v,3)"), removeSpace))
>
> # Use terms to get term labels from formula
> > formula <- Y ~ 1 + x:A + z + u + B + poly(v,3)
> > term.labels <- unname(sapply(attr(terms(formula),
> "term.labels"), removeSpace))
> > tvar
>  "x:A"       "z"         "B"         "poly(v,3)"
> > term.labels
>  "z"         "u"         "B"         "poly(v,3)" "x:A"
>
> # Get assign variable for parameters
> # (You would use first two lines, but I don't have data so
> defined assign variable myself)
> > #X <- model.matrix(formula)
> > #pAssign <- attr(X, "assign")
> > pAssign <- c(0,1,2,3,4,4,4,5,5)
>
> # Define "tvarAssign"
> > tvarAssign <- match(pAssign, sort(match(tvar, term.labels)))
> > tvarAssign[is.na(tvarAssign)] <- 0
> > tvarAssign
>  0 1 0 2 3 3 3 4 4
>
> HTH
>
> Heather
>
> Mrs H Turner
> Research Assistant
> Dept. of Statistics
> University of Warwick
>
> >>> "Claus Dethlefsen" <dethlef at math.aau.dk> 12/13/04 04:10pm >>>
> Dear list
>
> I would like to be able to group terms in a formula using a
> function that I
> will call tvar(), eg. the formula
>
> Y ~ 1 + tvar(x:A) + tvar(z) + u + tvar(B) + tvar(poly(v,3))
>
> where x,u and v are numeric and A and B are factors - binary, say.
>
> As output, I want the model.matrix as if tvar had not been
> there at all. In
> addition, I would like to have information on the grouping,
> as a vector as
> long as ncol( model.matrix ) with zeros corresponding to
> terms outside tvar
> and with an index grouping the terms inside each tvar(). In the (sick)
> example:
>
>
> > model.matrix(Y ~ 1 + tvar(x:A) + tvar(z) + u + tvar(B) +
> tvar(poly(v,3)))
>    (Intercept)     z     u B2 poly(v, 3)1 poly(v, 3)2 poly(v,
> 3)3  x:A1
> x:A2
> 1            1 -1.55 -1.03  0       0.160      -0.350
> -0.281  0.66
> 0.00
> 2            1 -1.08  0.55  0      -0.164      -0.211
> 0.340  0.91
> 0.00
> 3            1  0.29 -0.26  0      -0.236      -0.073
> 0.311 -1.93
> 0.00
> 4            1 -1.11  0.96  0       0.222      -0.285
> -0.385 -0.23
> 0.00
> 5            1  0.43 -0.76  1      -0.434       0.515
> -0.532  0.22
> 0.00
>
> I would like the vector
>
> c(0,1,0,2,3,3,3,4,4)
>
> pointing to the tvar-grouped terms.
>
> Thus what I would like, looks a bit like the 'assign' attribute of the
> model.matrix() output. I have not figured out a way of doing
> this in a nice
> way and would like some help, please.
>
> I hope somebody can help me (or point the manual-pages I should read),
>
> Best,
>
> Claus Dethlefsen
> --------------------------------------------------------------
> Assistant Professor, Claus Dethlefsen, Ph.D.
> mailto:dethlef at math.auc.dk, http://www.math.auc.dk/~dethlef
> Dpt. of Mathematical Sciences, Aalborg University
> Fr. Bajers Vej 7G, 9220 Aalborg East
> Denmark
>

--
No virus found in this outgoing message.
Checked by AVG Anti-Virus.

```