向R的预测函数输入新数据

13
R的predict函数可以接受一个newdata参数,其文档说明如下:

newdata:一个可选的数据框,在其中查找用于预测的变量。如果省略,则使用拟合值。

但我发现这并不完全正确,这取决于模型的拟合方式。例如,以下代码按预期工作:
x <- rnorm(200, sd=10)
y <- x + rnorm(200, sd=1)
data <- data.frame(x, y)
train = sample(1:length(x), size=length(x)/2, replace=F)
dataTrain <- data[train,]
dataTest <- data[-train,]
m <- lm(y ~ x, data=dataTrain)
head(predict(m,type="response"))
head(predict(m,newdata=dataTest,type="response"))

但如果模型被适当地拟合:

m2 <- lm(dataTrain$y ~ dataTrain$x)
head(predict(m2,type="response"))
head(predict(m2,newdata=dataTest,type="response"))

最后两行将产生完全相同的结果。predict函数忽略newdata参数,它实际上不能计算新数据的预测值。
罪魁祸首当然是lm(y ~ x, data=dataTrain)lm(dataTrain$y ~ dataTrain$x)之间的区别。但我没有找到任何提到这两者之间差异的文档。这是一个已知的问题吗?
我正在使用R 2.15.2。

嗨,我遇到了同样的问题,你有没有想到解决方法?先感谢了。 - jbest
1个回答

16

请查看 ?predict.lm 和下面引用的 Note 部分:

Note:

     Variables are first looked for in ‘newdata’ and then searched for
     in the usual way (which will include the environment of the
     formula used in the fit).  A warning will be given if the
     variables found are not of the same length as those in ‘newdata’
     if it was supplied.

尽管它没有在“同名”等方面说明行为,但就公式而言,您传递给它的术语是foo$var形式的,而在newdata或R将遍历以查找它们的搜索路径中都没有这样的变量名称。
在您的第二个案例中,您完全误用了模型公式符号;其想法是简洁而象征性地描述模型。简洁和反复使用数据对象会导致厌烦,这两者是不兼容的。
您注意到的行为与文档记录的行为完全一致。简单来说,您使用了术语data$xdata$y拟合了模型,然后尝试预测术语xy。就R而言,它们是不同的名称,因此也是不同的东西,它没有匹配它们是正确的。

我理解这意味着“您使用数据$x$和$y$来拟合模型,然后尝试预测$x$和$y$”。但我明白您的观点。感谢澄清。 - edwardw
@edwardw 是的,抱歉。现在已经修复了。 - Gavin Simpson
10
冒着被踩的风险:让我们面对现实,手册在这个主题上不够直观。例如,如果你按照数据框列的方式传递模型,就像 lm(mydata$y ~ mydata$x,...),当你想要将 mydata= 传递给 predict() 时,准备好迎接各种惊喜。应该将列称为 xmydata$x?还是其他什么?... :-) 我没有弄清楚,只是将列复制到独立的 xy 向量中,阅读了这篇优秀的解释后,我可以使用 predict(model,mydata=data.frame(x=whatever),...) - András Aszódi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接