我尝试将model.matrix
与contrasts.arg
参数一起使用以实现以下目标:
将带有因子的数据框转换为矩阵而不进行拦截,但将所有(!)因子编码为具有k-1
级别的假人。
由于model.matrix
的默认行为是在没有拦截的情况下用k
级别编码第一个因子,我认为明确指定contrasts.arg
参数会起作用,但它没有:
df <- data.frame(num=c(1,2,3), f1=factor(c("a", "b", "a")), f2=factor(c("c","d", "c")))
frml <- ~ num + f1 + f2 - 1
what.i.get <- model.matrix(frml, df, contrasts.arg=list(f1=contrasts(df[,"f1"]), f2=contrasts(df[,"f2"])))
df
# num f1 f2
#1 1 a c
#2 2 b d
#3 3 a c
what.i.get
# num f1a f1b f2d
#1 1 1 0 0
#2 2 0 1 1
#3 3 1 0 0
#attr(,"assign")
#[1] 1 2 2 3
#attr(,"contrasts")
#attr(,"contrasts")$f1
# b
#a 0
#b 1
#attr(,"contrasts")$f2
# d
#c 0
#d 1
正如您所看到的,model.matrix为因子f1
创建了两列,尽管contrasts.arg
参数和对比属性状态都只为级别b创建了一列。所以我期待的是:
what.i.expect <- what.i.get[,-2]
#attr(what.i.expect, "assign") <- attributes(what.i.get)[["assign"]][-2]
#attr(what.i.expect, "contrasts") <- attributes(what.i.get)[["contrasts"]]
#what.i.expect
# num f1b f2d
#1 1 0 0
#2 2 1 1
#3 3 0 0
#attr(,"assign")
#[1] 1 2 3
#attr(,"contrasts")
#attr(,"contrasts")$f1
# b
#a 0
#b 1
#attr(,"contrasts")$f2
# d
#c 0
#d 1
我知道我可以将截距添加到公式中,然后删除model.matrix
结果的第一列。但是那样我会放弃属性(我需要的)......我想理解为什么我的方法不起作用!