您必须在任何计算之前删除额外的级别,例如:
> id <- which(!(foo.new$predictor %in% levels(foo$predictor)))
> foo.new$predictor[id] <- NA
> predict(model,newdata=foo.new)
1 2 3 4
-0.1676941 -0.6454521 0.4524391 NA
这是一种更通用的方法,它将原始数据中未出现的所有级别设置为NA。正如 Hadley 在评论中提到的,他们本可以选择将其包含在predict()
函数中,但他们没有
如果您查看计算本身,为什么必须这样做就变得显而易见了。在内部,预测计算如下:
model.matrix(~predictor,data=foo) %*% coef(model)
[,1]
1 -0.1676941
2 -0.6454521
3 0.4524391
在底部,您有两个模型矩阵。您会看到 forfoo.new
有一个额外的列,因此您不能再使用矩阵计算。如果您将使用新数据集进行建模,您还将获得一个不同的模型,即具有用于额外级别的额外虚拟变量的模型。
> model.matrix(~predictor,data=foo)
(Intercept) predictorB predictorC
1 1 0 0
2 1 1 0
3 1 0 1
attr(,"assign")
[1] 0 1 1
attr(,"contrasts")
attr(,"contrasts")$predictor
[1] "contr.treatment"
> model.matrix(~predictor,data=foo.new)
(Intercept) predictorB predictorC predictorD
1 1 0 0 0
2 1 1 0 0
3 1 0 1 0
4 1 0 0 1
attr(,"assign")
[1] 0 1 1 1
attr(,"contrasts")
attr(,"contrasts")$predictor
[1] "contr.treatment"
您也不能只从模型矩阵中删除最后一列,因为即使您这样做,其他两个级别仍然会受到影响。级别的代码A
将是 (0,0)。因为B
这是(1,0),对于C
这个(0,1)......又D
是(0,0)!因此,如果您的模型天真地丢弃最后一个虚拟变量,那么您的模型会假设A
并且D
是同一水平。
在更理论的部分:可以在没有所有级别的情况下构建模型。现在,正如我之前试图解释的那样,该模型仅对您在构建模型时使用的级别有效。如果你遇到新的关卡,你必须建立一个新的模型来包含额外的信息。如果你不这样做,你唯一能做的就是从数据集中删除额外的级别。但是,您基本上会丢失其中包含的所有信息,因此通常不认为这是一种好的做法。