0

我正在对一些树木数据进行多元回归。

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% 的时间里有效,为三个删除的观察返回三个预测值。但偶尔我会收到警告:

Warning message:
'newdata' had 3 rows but variable(s) found have 2 rows 

我不知道这是从哪里来的,因为代码大部分时间都在工作,而且我没有任何有 2 行的对象。我有 3 个像这样的单独计算,每个都使用树数据。我试图在没有公共变量的情况下将它们分开,但它们是否会相互干扰?警告是否来自 g 的采样?有没有更好的方法来删除观察或进行多变量预测?谢谢。

PS - 另外,当我附加树时,尽管我可以自己打电话,Merch.Vol但我仍然不能直接打电话。没什么大不了的,但如果有一个明显的解释(我敢肯定)我想听听。trees$Merch.VolDBHHeight

4

1 回答 1

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。最后有一个额外的点。美元 ($) 运算符使用列匹配,即使您的数据中没有名为 D 的列,trees$D 也会返回 DBH 列中的值。这就是为什么 trees$Merch.Vol 也可以工作的原因,即使列名的输入不完全正确。

于 2013-05-07T05:49:54.650 回答