Reputation: 23938
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
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
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