我正在对一些树木数据进行多元回归。
trees
Index DBH Height Merch.Vol.
1 1 8.3 70 10.3
2 2 8.6 65 10.3
3 3 8.8 63 10.2
4 4 10.5 72 16.4
5 5 10.7 81 18.8
6 6 10.8 83 19.7
7 7 11.0 66 15.6
8 8 11.0 75 18.2
9 9 11.1 80 22.6
10 10 11.2 75 19.9
11 11 11.3 79 24.2
12 12 11.4 76 21.0
13 13 11.4 76 21.4
14 14 11.7 69 21.3
15 15 12.0 75 19.1
16 16 12.9 74 22.2
17 17 12.9 85 33.8
18 18 13.3 86 27.4
19 19 13.7 71 25.7
20 20 13.8 64 24.9
21 21 14.0 78 34.5
22 22 14.2 80 31.7
23 23 14.5 74 36.3
24 24 16.0 72 38.3
25 25 16.3 77 42.6
26 26 17.3 81 55.4
27 27 17.5 82 55.7
28 28 17.9 80 58.3
29 29 18.0 80 51.5
30 30 18.0 80 51.0
31 31 20.6 87 77.0
attach(trees)
我可以轻松地运行回归,但我在预测方面遇到了麻烦。我随机删除了3个观察值并重新运行回归,然后预测这三个观察值以计算MAPE。
g = sample(2:31,3);g
mbreg = lm(trees$Merch.Vol[-g]~DBH[-g]+Height[-g])
p2 = predict(mbreg,trees[g,2:3])
MAPE[2] = MAPE[2] + sum(abs((trees$Merch.Vol[g]-p2)/trees$Merch.Vol[g]))/3
j = sample(2:31,3);j
mLR = lm(log(trees$Merch.Vol[-j])~log(DBH[-j])+log(Height[-j]))
p4 = exp(predict(mLR,trees[j,2:3]))
MAPE[4] = MAPE[4] + sum(abs((trees$Merch.Vol[j]-p4)/trees$Merch.Vol[j]))/3
这可以达到我预期的大约80%的时间,返回三个预测的vaules三个删除的观察。但偶尔我会收到警告:
Warning message:
'newdata' had 3 rows but variable(s) found have 2 rows
我不知道它来自何处,因为代码大部分时间都有效,而且我没有任何有2行的对象。我有3个单独的计算,每个都使用树数据。我试图将它们分开,没有共同的变量,但它们是否会相互干扰?警告是否来自g的抽样?有没有更好的方法来删除观察或进行多变量预测?谢谢你。
P.S。 - 此外,当我附加树木时,我仍然无法在Merch.Vol
之后直接拨打trees$Merch.Vol
但我可以自己拨打DBH
和Height
。没什么大不了的,但如果有明显的解释(我敢肯定),我想听听。
答案 0 :(得分:1)
错误可能源于在lm()命令中对公式内的数据进行子集化。这是实际抛出错误的predict()命令。我们举个例子:
# Data
trees<-structure(list(Index = 1:31, DBH = c(8.3, 8.6, 8.8, 10.5, 10.7,
10.8, 11, 11, 11.1, 11.2, 11.3, 11.4, 11.4, 11.7, 12, 12.9, 12.9,
13.3, 13.7, 13.8, 14, 14.2, 14.5, 16, 16.3, 17.3, 17.5, 17.9,
18, 18, 20.6), Height = c(70L, 65L, 63L, 72L, 81L, 83L, 66L,
75L, 80L, 75L, 79L, 76L, 76L, 69L, 75L, 74L, 85L, 86L, 71L, 64L,
78L, 80L, 74L, 72L, 77L, 81L, 82L, 80L, 80L, 80L, 87L), Merch.Vol. = c(10.3,
10.3, 10.2, 16.4, 18.8, 19.7, 15.6, 18.2, 22.6, 19.9, 24.2, 21,
21.4, 21.3, 19.1, 22.2, 33.8, 27.4, 25.7, 24.9, 34.5, 31.7, 36.3,
38.3, 42.6, 55.4, 55.7, 58.3, 51.5, 51, 77)), .Names = c("Index",
"DBH", "Height", "Merch.Vol"), class = "data.frame", row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13",
"14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24",
"25", "26", "27", "28", "29", "30", "31"))
# This gives an error
g = c(3, 19, 5)
mbreg = lm(Merch.Vol[-g]~DBH[-g]+Height[-g], data=trees)
p2 = predict(mbreg,trees[g,2:3])
# This will work
# Notice that the object trees2 will contain the new, sampled dataset
# The model is then fitted on the dataset trees2
g = c(3, 19, 5)
trees2<-trees[-g,]
mbreg = lm(Merch.Vol~DBH+Height, data=trees2)
p2 = predict(mbreg,trees[g,2:3])
在使用模型拟合模型之前将数据子集(或采样)到新对象中将删除错误。您可能希望将代码示例更改为:
g = sample(2:31,3);g
trees2<-trees[-g,]
mbreg = lm(trees$Merch.Vol~DBH+Height, data=trees2)
p2 = predict(mbreg,trees[g,2:3])
MAPE[2] = MAPE[2] + sum(abs((trees$Merch.Vol[g]-p2)/trees$Merch.Vol[g]))/3
另外,我建议不要在这里使用attach命令。另一种方法是在lm()调用中使用data参数。这个参数告诉lm()命令从命名对象中查找公式中提到的变量(参见上面的例子,以及R?lm)。
您提到在附加数据后仍无法直接调用Merch.Vol。如果仔细查看列名,您可能会注意到正确的列名实际上是Merch.Vol。最后有一个额外的点。 dollar($)运算符使用列匹配,即使您的数据中没有名为D的列,树$ D也将返回DBH列中的值。这就是为什么树$ Merch.Vol也可以工作,即使列名称输入不完全正确。