在使用predict.lm进行预测时,出现“'newdata'有1行,但发现32行变量”的警告。

89

在使用R的predict和lm函数时,我发现一个奇怪的问题。对于相同的数据,使用数据框和向量作为输入会得到不同的结果。

数据框代码:

data(mtcars)
fitCar<-lm(mtcars$mpg~mtcars$wt)
predict(fitCar,
        data.frame(x=mean(mtcars$wt)),
        interval="confidence")

输出:

     fit       lwr      upr
1  23.282611 21.988668 24.57655
2  21.919770 20.752751 23.08679
3  24.885952 23.383008 26.38890
4  20.102650 19.003004 21.20230
5  18.900144 17.771469 20.02882
6  18.793255 17.659216 19.92729
7  18.205363 17.034274 19.37645
8  20.236262 19.136179 21.33635
9  20.450041 19.347720 21.55236
10 18.900144 17.771469 20.02882
11 18.900144 17.771469 20.02882
12 15.533127 14.064349 17.00190
13 17.350247 16.104455 18.59604
14 17.083024 15.809403 18.35664
15  9.226650  6.658271 11.79503
16  8.296712  5.547468 11.04596
17  8.718926  6.052112 11.38574
18 25.527289 23.927797 27.12678
19 28.653805 26.519252 30.78836
20 27.478021 25.554415 29.40163
21 24.111004 22.715653 25.50635
22 18.472586 17.319886 19.62529
23 18.926866 17.799465 20.05427
24 16.762355 15.452833 18.07188
25 16.735633 15.423002 18.04826
26 26.943574 25.112491 28.77466
27 25.847957 24.198041 27.49787
28 29.198941 26.963760 31.43412
29 20.343151 19.242185 21.44412
30 22.480940 21.268498 23.69338
31 18.205363 17.034274 19.37645
32 22.427495 21.219818 23.63517

警告信息:

'newdata'只有1行,但发现有32行变量

当我将两个数据分别转换为向量时,得到了不同的答案

向量代码

predict(fit,data.frame(x=mean(x)), interval="confidence")

输出:

    fit   lwr   upr
1 20.09 18.99 21.19

这种差异的原因是什么?

5个回答

127

这是一个使用不同名称的问题,您的datanewdata之间存在名称冲突,并不是向量或数据框之间的问题。

当您使用lm函数拟合模型,然后使用predict进行预测时,predict会尝试在newdata上找到相同的名称。在您的第一个案例中,名称xmtcars$wt冲突,因此会出现警告。

请看下面的示例以了解我所说的内容:

以下是您执行的操作,而且没有收到错误:

a <- mtcars$mpg
x <- mtcars$wt

#here you use x as a name
fitCar <- lm(a ~ x) 
#here you use x again as a name in newdata.
predict(fitCar, data.frame(x = mean(x)), interval = "confidence") 

       fit      lwr      upr
1 20.09062 18.99098 21.19027
在这种情况下,您需要使用名称 x 拟合模型,并在新的 newdata 中使用名称 x 进行预测。这样您就不会收到任何警告并且得到您所期望的结果。
现在让我们看看当我在拟合模型时将名称更改为其他名称时会发生什么:
a <- mtcars$mpg
#name it b this time
b <- mtcars$wt 

fitCar <- lm(a ~ b) 
#here I am using name x as previously
predict(fitCar, data.frame(x = mean(x)), interval = "confidence") 

         fit       lwr      upr
1  23.282611 21.988668 24.57655
2  21.919770 20.752751 23.08679
3  24.885952 23.383008 26.38890
4  20.102650 19.003004 21.20230
5  18.900144 17.771469 20.02882
Warning message:
'newdata' had 1 row but variables found have 32 rows 

我现在所做的唯一一件事就是在拟合模型时将名称x更改为b,然后使用名称xnewdata中进行预测。正如你所看到的,我得到了与你问题中相同的错误。

希望现在清楚了!


1
为什么在这种情况下我会得到相同的错误?`install.packages("car") library(car) data(Quartet)lmfit = lm(Quartet$y2 ~ poly(Quartet$x,2,raw=TRUE)) newdata = data.frame(x = c(3,6,15)) predict(lmfit, newdata, interval = "confidence", level = 0.95)` - agaved
@agaved,由于您使用了完整的“Quartet$x”名称,因此predict函数也会在“newdata”中查找它。但是,由于“newdata”中没有“Quartet$x”,而只有“newdata$x”,因此预测失败了。 - LyzandeR
@agaved 如果您有新的问题,请将其作为新问题提出。不要使用评论来提出不同的问题。这是一个与问题中提到的不同问题。 - LyzandeR
在这个答案描述的两种情况中,R在做什么?为什么会输出五行内容? - Ceph

15

在lm函数的公式中,不要使用datasetname$variablename模式来引用变量,而应该使用variablename + variablename ...。这样不会出现警告:“newdata”有nrow(test)行,但找到的变量有nrow(train)行。


你知道为什么吗?为什么df$varvar, data=df不同呢? - adelriosantiago

10

不使用名称的一种方法是使用以下内容:

fitCar<-lm(mpg ~ wt, mtcars) #here you use x as a name
predict(fitCar,data.frame(wt=mean(mtcars$wt)), interval="confidence") 

2

将lm的定义方式从fitCar<-lm(mtcars$mpg~mtcars$wt)更改为fitCar<-lm(mpg~wt, data = mtcars),可以修复此错误。


1

当我在使用变量名与数据名结合时,我遇到了同样的问题,这是由于使用了$符号。

因此,不要这样写:

Original Answer
fitCar<-lm(mtcars$mpg~mtcars$wt)
predict(fitCar,
        data.frame(x=mean(mtcars$wt)),
        interval="confidence")

使用以下内容:

fitCar<-lm(mpg~wt , data = mtcars)
predict(fitCar,  
wt = mean(mtcars$wt), interval = "confidence")

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