我可以将输出转换为可以接受的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
Run Code Online (Sandbox Code Playgroud)
谢谢!
Dav*_*urg 12
所以错误来自于predict.ar.如果您将运行,?predict您将看到它是一个泛型函数," 调用依赖于第一个参数的类的特定方法 "
所以
class(output)
[1] "ar"
Run Code Online (Sandbox Code Playgroud)
和
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
Run Code Online (Sandbox Code Playgroud)
告诉你我们正在寻找第一种方法
下一步尝试是在该方法中查找错误消息.先前的操作告诉我们的predict.ar是看不见的功能,所以我们需要结合起来getAnywhere,并capture.output以查找错误消息和一些正则表达式的功能,但不幸的是行不通的
grep("array", capture.output(getAnywhere("predict.ar")))
## integer(0)
Run Code Online (Sandbox Code Playgroud)
这意味着错误来自于其中运行的其他一些功能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)
Run Code Online (Sandbox Code Playgroud)
这很好地展示了我们的函数调用的工作流程:call predict- >识别对象的类并调用相应的方法predict.ar- > rbind预分配的矩阵(大小为ncol(x)*n.ahead),使用sweep- >平均居中数据数据(使用sweep),转置一些array并array在最后一个操作返回错误时创建一个新的.
所以基本上所有的sweep功能不被减去的平均yz距离yz(均centering-这可能只是通过运行来完成scale(yz, scale = FALSE)所以不知道他们为什么使用sweep摆在首位.也许对于dmean = FALSE特例?).在您指定的情况下dmean = FALSE,它会从两列中删除零(这是非常不必要的操作,在这种情况下可能应该避免).相比
all.equal(t(t(yz) - colMeans(yz)), sweep(yz, 2L, colMeans(yz)))
## [1] TRUE
Run Code Online (Sandbox Code Playgroud)
唯一的问题是sweep对数组进行操作,因此它尝试将数据转换为数组,同时通过传递dim属性来指定正确的维度,yz并创建array进一步的操作,即类似
dims <- dim(yz)
perm <- c(2L, seq_along(dims)[-2L])
array(colMeans(yz), dims[perm])
Run Code Online (Sandbox Code Playgroud)
这适用于精细矩阵,因为dim根据定义,所有矩阵都具有属性.
虽然data.frames没有dim属性,但该dim(x)函数仍然足够智能来计算dim本身,所以这非常好用
dim(x)
## [1] 100 2
Run Code Online (Sandbox Code Playgroud)
唯一的问题是,predict.ar功能条的class从属性,x在它到达之前的过程中的某个地方sweep,所以这是那里的之间的差异matrix和data.frame对此事显著
class(x) <- NULL
dim(x)
## NULL
class(x)
## [1] "list"
Run Code Online (Sandbox Code Playgroud)
而
class(yz) <- NULL
dim(yz)
## [1] 100 2
class(yz)
## [1] "matrix"
Run Code Online (Sandbox Code Playgroud)
请注意,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])
Run Code Online (Sandbox Code Playgroud)
现在,这将返回您之前看到的错误
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
Run Code Online (Sandbox Code Playgroud)
我会留给你进一步挖掘兔洞的乐趣,以便更好地了解它是如何dim工作的.
因此,为了得出结论(如@joran的评论中所述) - 请始终阅读文档.如果你仔细观察?ar.ols,x应该是一个单变量或多变量的时间序列.在这些例子中,x是永远类的一个对象ts,并从来没有一个data.frame.
因此,虽然我同意在您指定的特定情况下,首先demean = FALSE不应该发生此错误,但知道您正在做什么仍然是更好的做法.换句话说,这是问题的经典XY问题类型.