with the following simple data frame dd = structure(list(z = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L ), .Label = c("a", "b"), class = "factor"), x = c(0.3, 0.2, 0.1, 0, 0, 0, 0.2, 0.3)), .Names = c("z", "x"), row.names = c(NA, -8L), class = "data.frame") I would like know if it's possible to use model.matrix() to construct the following design matrix in some sensible way: za zb 1 1 0 2 1 0 3 1 0 4 0 0 5 0 0 6 0 0 7 0 1 8 0 1 In other words, I want column 1 to be (z=="a" & x>0) and column 2 to be (z=="b" & x>0). I can construct this matrix using sweep(model.matrix(~z-1,dd),1,dd$x>0,"*") and then stick it into lm.fit -- but is there a more elegant way to do this in general? I haven't found a formula combining (z-1) and I(x>0) that works, although I can imagine there is one. thanks Ben Bolker -- Ben Bolker Associate professor, Biology Dep't, Univ. of Florida bolker at ufl.edu / www.zoology.ufl.edu/bolker GPG key: www.zoology.ufl.edu/bolker/benbolker-publickey.asc -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 261 bytes Desc: OpenPGP digital signature URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20091102/44e20ea0/attachment-0002.bin>
On Nov 2, 2009, at 10:40 PM, Ben Bolker wrote:> > with the following simple data frame > dd = structure(list(z = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L > ), .Label = c("a", "b"), class = "factor"), x = c(0.3, 0.2, 0.1, > 0, 0, 0, 0.2, 0.3)), .Names = c("z", "x"), row.names = c(NA, > -8L), class = "data.frame") > > I would like know if it's possible to use model.matrix() > to construct the following design matrix in some sensible way: > > za zb > 1 1 0 > 2 1 0 > 3 1 0 > 4 0 0 > 5 0 0 > 6 0 0 > 7 0 1 > 8 0 1 > > In other words, I want column 1 to be (z=="a" & x>0) and > column 2 to be (z=="b" & x>0). I can construct this matrix > using > > sweep(model.matrix(~z-1,dd),1,dd$x>0,"*") > > and then stick it into lm.fit -- but is there a more > elegant way to do this in general?Elegance? You decide. But at least more economical from a keystroke perspective: model.matrix(~z-1,dd)*(dd$x>0) #------ za zb 1 1 0 2 1 0 3 1 0 4 0 0 5 0 0 6 0 0 7 0 1 8 0 1 attr(,"assign") [1] 1 1 attr(,"contrasts") attr(,"contrasts")$z [1] "contr.treatment> I haven't found a formula combining > (z-1) and I(x>0) that works, although I can imagine there is one. > > thanks > Ben Bolker > >David Winsemius, MD Heritage Laboratories West Hartford, CT
Try this: dd$i <- with(dd,interaction(z,x>0)) contrasts(dd$i,2) <- rbind( c(0,0),c(0,0),c(1,0),c(0,1) ) model.matrix( ~i, dd )[,-1] -- Gregory (Greg) L. Snow Ph.D. Statistical Data Center Intermountain Healthcare greg.snow at imail.org 801.408.8111> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r- > project.org] On Behalf Of Ben Bolker > Sent: Monday, November 02, 2009 8:41 PM > To: r-help at r-project.org > Subject: [R] design matrix construction question > > > with the following simple data frame > dd = structure(list(z = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L > ), .Label = c("a", "b"), class = "factor"), x = c(0.3, 0.2, 0.1, > 0, 0, 0, 0.2, 0.3)), .Names = c("z", "x"), row.names = c(NA, > -8L), class = "data.frame") > > I would like know if it's possible to use model.matrix() > to construct the following design matrix in some sensible way: > > za zb > 1 1 0 > 2 1 0 > 3 1 0 > 4 0 0 > 5 0 0 > 6 0 0 > 7 0 1 > 8 0 1 > > In other words, I want column 1 to be (z=="a" & x>0) and > column 2 to be (z=="b" & x>0). I can construct this matrix > using > > sweep(model.matrix(~z-1,dd),1,dd$x>0,"*") > > and then stick it into lm.fit -- but is there a more > elegant way to do this in general? I haven't found a formula combining > (z-1) and I(x>0) that works, although I can imagine there is one. > > thanks > Ben Bolker > > > -- > Ben Bolker > Associate professor, Biology Dep't, Univ. of Florida > bolker at ufl.edu / www.zoology.ufl.edu/bolker > GPG key: www.zoology.ufl.edu/bolker/benbolker-publickey.asc