使用predict()函数时出错

时间:2014-04-24 14:29:42

标签: r predict

我应该将ar.ols的输出转换为predict可以接受的某种类型吗?

y=rnorm(100, 0,1)
z=rnorm(100, 0,1)
yz=cbind(y,z)
> output = ar.ols(yz, aic = F, order.max = 2, demean = F, intercept = T)    
> predict(output, n.ahead = 2, se.fit = F)

x=as.data.frame(yz) # x is a data frame, and otherwise same as yz. 
> output = ar.ols(x, aic = F, order.max = 2, demean = F, intercept = T)    
> predict(output, n.ahead = 2, se.fit = F)
Error in array(STATS, dims[perm]) : 'dims' cannot be of length 0

谢谢!

1 个答案:

答案 0 :(得分:12)

所以错误来自predict.ar。如果您将运行?predict,您将看到它是一个通用函数," 调用依赖于第一个参数的类的特定方法"

所以

class(output)
[1] "ar"

methods(predict)
#  [1] predict.ar*                predict.Arima*             predict.arima0*            predict.glm                predict.HoltWinters*      
#  [6] predict.lm                 predict.loess*             predict.mlm*               predict.nls*               predict.poly*             
# [11] predict.ppr*               predict.prcomp*            predict.princomp*          predict.smooth.spline*     predict.smooth.spline.fit*
# [16] predict.StructTS*

#    Non-visible functions are asterisked       

告诉你我们正在寻找第一种方法

下一次尝试是在该方法中查找错误消息。之前的操作通知我们predict.ar是不可见的函数,因此我们需要结合getAnywherecapture.output以及一些正则表达式函数来查找错误消息,但不幸的是,赢了&# 39;工作

grep("array", capture.output(getAnywhere("predict.ar")))
## integer(0)

这意味着该错误来自于predict.ar内运行的其他一些函数。

(正如@hadley所提到的)我们需要使用traceback()来识别导致它的内部函数

predict(output, n.ahead = 2, se.fit = F)
# Error in array(STATS, dims[perm]) : 'dims' cannot be of length 0
traceback()
# 6: array(STATS, dims[perm])
# 5: aperm(array(STATS, dims[perm]), order(perm))
# 4: sweep(newdata, 2L, object$x.mean, check.margin = FALSE)
# 3: rbind(sweep(newdata, 2L, object$x.mean, check.margin = FALSE), 
#          matrix(rep.int(0, nser), n.ahead, nser, byrow = TRUE))
# 2: predict.ar(output, n.ahead = 2, se.fit = F)
# 1: predict(output, n.ahead = 2, se.fit = F)

这很好地展示了我们函数调用的工作流程: 致电predict - >识别对象的类并调用相应的方法predict.ar - > rbind预先分配的矩阵(大小为ncol(x) * n.ahead),使用sweep - >的平均中心数据在对数据进行中心处理时(使用sweep),转置一些array并创建一个新的array,而最后一个操作返回错误。

所以基本上所有sweep函数都会从yz中减去yz的平均值(均值中心 - 这可以通过运行scale(yz, scale = FALSE)来完成,所以不确定为什么他们首先使用sweep。也许是dmean = FALSE特例?)。在您的情况下,您指定了dmean = FALSE,因此它从两列中删除了零(这是非常不必要的操作,在这种情况下可能应该避免)。比较

all.equal(t(t(yz) - colMeans(yz)), sweep(yz, 2L, colMeans(yz)))
## [1] TRUE

唯一的问题是sweep对数组进行操作,因此它会尝试将数据转换为数组,同时通过从dim传递yz属性来指定正确的维度并创建array用于进一步操作,即

dims <- dim(yz)
perm <- c(2L, seq_along(dims)[-2L])
array(colMeans(yz), dims[perm])

这适用于精细矩阵,因为根据定义,所有矩阵都具有dim属性。

虽然data.frame没有dim属性,但dim(x)功能仍然足够聪明,可以计算昏暗本身,所以这样做完全正常

dim(x)
## [1] 100   2

唯一的问题是predict.ar函数在class到达x之前的某个地方从sweep剥离了matrix属性,所以这就是data.frameclass(x) <- NULL dim(x) ## NULL class(x) ## [1] "list" 对此非常重要

class(yz) <- NULL
dim(yz)
## [1] 100   2
class(yz)
## [1] "matrix"

虽然

x

请注意,list只是变成了matrix,其中包含了向量和属性等不同元素,而dim由于其class属性而保留了原始结构,因此x函数仍然可以识别它是一个矩阵,而class完全变形,class无法再处理它。

如果您想了解STATS <- colMeans(yz) class(yz) <- NULL dims <- dim(yz) perm <- c(2L, seq_along(dims)[-2L]) array(STATS, dims[perm]) 的工作原理以及实际发生的情况,请参阅我的回答here

无论如何,虽然这仍然有效

x <- as.data.frame(yz)
STATS <- colMeans(x)
class(x) <- NULL
dims <- dim(x)
perm <- c(2L, seq_along(dims)[-2L])
array(STATS, dims[perm])
# Error in array(STATS, dims[perm]) : 'dims' cannot be of length 0

现在返回

之前看到的错误
dim

我希望您能够进一步挖掘in the rabbit hole,以便更好地了解?ar.ols的工作原理。

因此,为了得出结论(如@joran的评论中所述) - 请始终阅读文档。如果您仔细查看xx应该是单变量或多变量时间序列。在示例中,ts 总是data.frame的对象,而从不一个demean = FALSE

因此,虽然我同意对于您已指定{{1}}的特定情况,但首先不应发生此错误,了解您的情况仍然是更好的做法这样做。换句话说,这是问题的经典XY problem类型。