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.
Claus Dethlefsen <dethlef <at> math.aau.dk> writes:> > 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)Since you want to single out terms with 'tvar' in them, something like tvar.terms <- terms( your.formula.above, specials = "tvar" ) will likely be what you want. You'll want to study ?terms ?terms.object and then print( tvar.terms ) And likely 'deparse' will help, too.> example:[rest deleted]
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[1] "x:A" "z" "B" "poly(v,3)"> term.labels[1] "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[1] 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.
Okay, well you could define a tvar function as follows tvar <- function(term) term Then stick to fm1 X <- model.matrix(fm1,keep.order=TRUE) pAssign <- attr(X, "assign") tvar.terms <- terms( fm1, specials = "tvar",keep.order=TRUE ) idx <- attr(tvar.terms,"specials")$tvar if (attr(tvar.terms,"response")) idx <- idx -1 all.labels <- attr(tvar.terms, "term.labels") tvar.labels <- all.labels[idx] tvarAssign <- match(pAssign, match(tvar.labels, all.labels)) tvarAssign[is.na(tvarAssign)] <- 0 I think that the specials attributes is an index of the variables attribute, hence I have replaced if (attr(tvar.terms,"intercept")) idx <- idx -1 with if (attr(tvar.terms,"response")) idx <- idx -1 check e.g. fm1 <- Y ~ tvar(x:A) + tvar(z) + u + tvar(B) + tvar(poly(v,3)) fm1 <- ~ 1 + tvar(x:A) + tvar(z) + u + tvar(B) + tvar(poly(v,3)) Heather From: "Claus Dethlefsen" <dethlef at math.aau.dk> To: "'Heather Turner'" <Heather.Turner at warwick.ac.uk>, <r-help at stat.math.ethz.ch> Date: 12/16/04 8:33am Subject: RE: [R] Advice on parsing formulae 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 Mrs H Turner Research Assistant Dept. of Statistics University of Warwick