MYaseen208
MYaseen208

Reputation: 23938

Unconstrained Design matrix for factorial experiment in R

I want to create an unconstrained design matrix for factorial experiment in R and the following code gives me the desired matrix. But the code requires separate model.matrix command for each factor as well as for intercept term. I'm curious whether the same result can be obtained by a single liner. Thanks

y <- c(55, 56, 57, 53, 54, 55, 51, 52, 53, 61, 62, 63)
N <- gl(n = 2, k = 6, length = 2 * 6
        , labels = c("Low", "High")
        , ordered = FALSE)
P <- gl(n = 2, k = 3, length = 2 * 6
        , labels = c("Low", "High")
        , ordered = FALSE)
Data <- data.frame(y, N, P)

X <-
  cbind(
      model.matrix(object = y ~ 1,        data = Data)
    , model.matrix(object = y ~ -1 + N,   data = Data)
    , model.matrix(object = y ~ -1 + P,   data = Data)
    , model.matrix(object = y ~ -1 + N:P, data = Data)
    )

print(x = X)

Upvotes: 9

Views: 337

Answers (2)

SchaunW
SchaunW

Reputation: 3601

I think the key is to set all contrasts to FALSE. I guess technically this could be a one-liner...it would just be a really long line.

model.matrix(y ~ N +P + N:P, data=Data, 
      contrasts.arg = lapply(Data[,sapply(Data, is.factor)], 
                             contrasts, contrasts=FALSE))


   (Intercept) NLow NHigh PLow PHigh NLow:PLow NHigh:PLow NLow:PHigh NHigh:PHigh
1            1    1     0    1     0         1          0          0           0
2            1    1     0    1     0         1          0          0           0
3            1    1     0    1     0         1          0          0           0
4            1    1     0    0     1         0          0          1           0
5            1    1     0    0     1         0          0          1           0
6            1    1     0    0     1         0          0          1           0
7            1    0     1    1     0         0          1          0           0
8            1    0     1    1     0         0          1          0           0
9            1    0     1    1     0         0          1          0           0
10           1    0     1    0     1         0          0          0           1
11           1    0     1    0     1         0          0          0           1
12           1    0     1    0     1         0          0          0           1
attr(,"assign")
[1] 0 1 1 2 2 3 3 3 3
attr(,"contrasts")
attr(,"contrasts")$N
     Low High
Low    1    0
High   0    1

attr(,"contrasts")$P
     Low High
Low    1    0
High   0    1

Upvotes: 4

Jan van der Laan
Jan van der Laan

Reputation: 8105

Not a one liner, but perhaps somewhat simpler:

contrasts(N, nlevels(N)) <- diag(nlevels(N))
contrasts(P, nlevels(P)) <- diag(nlevels(P))
Data2 <- data.frame(y, N, P)
X2 <- model.matrix(y ~ 1 + N + P + N:P, data=Data2)

Upvotes: 3

Related Questions