首页 文章

范围问题; R无法在函数环境中找到对象

提问于
浏览
2

我的目标是每次改变y和x变量时拟合模型并产生预测 . 这将使我的代码更简洁 .

当我尝试预测测试时间序列时,R会抛出一个错误:eval中的错误(expr,envir,enclos):找不到对象'train'但是在函数的本地环境中生成了火车如果我将火车移动到全局环境,没有错误

我需要做什么才能将所有语句都包含在函数中?

library(fpp)
y <- (1:60)
z <- y + rnorm(60)
my.df <- data.frame(y,z)
NFcst <- 30

my.fcast <- fcast('y','z',my.df,NFcst) 

fcast <- function(a,b,df,h) {
  model <- paste(a,'~',b)
  x <- ts(data=df)  
  train.end <- time(x)[nrow(x)-h]
  test.start <- time(x)[nrow(x)-h+1]
  train <- window(x,end=train.end)
  test <- window(x,start=test.start)
  fit <- lm(model, data=train)
  my.fcast <- forecast(fit,test)   #error object 'train' not found
}

#If I move train to the global environment, there is no error
x <- ts(data=my.df)  
train.end <- time(x)[nrow(x)-NFcst]
train <- window(x,end=train.end)

my.fcast <- fcast2('y','z',my.df,NFcst)

fcast2 <- function(a,b,df,h) {
  model <- paste(a,'~',b)
  test.start <- time(x)[nrow(x)-h+1]
  test <- window(x,start=test.start)
  fit <- lm(model, data=train)
  my.fcast <- forecast(fit,test)   #no error
}

2 回答

  • 4

    它看起来像 forecast.lm 中的一个错误来自这个表达式:

    if (!is.null(object$data)) 
        origdata <- object$data
    else if (!is.null(object$call$data)) 
        origdata <- object$data <- eval(object$call$data)
    else origdata <- as.data.frame(fitted(object) + residuals(object))
    

    ?sys.parent 中所述, eval 呼叫似乎做了一些奇怪的事情:

    严格地说,sys.parent和parent.frame引用父解释函数的上下文 . 因此,内部函数(可能会或可能不会设置上下文,因此可能会或可能不会出现在调用堆栈中)可能不会被计算,并且S3方法也可以做出令人惊讶的事情 .

    快速修复函数是将数据设置为lm对象以避免 eval 调用:

    fcast <- function(a,b,df,h) {
      model <- paste(a,'~',b)
      x <- ts(data=df)  
      train.end <- time(x)[nrow(x)-h]
      test.start <- time(x)[nrow(x)-h+1]
      train <- window(x,end=train.end)
      test <- window(x,start=test.start)
      fit <- lm(model, data=train)
      fit$data <- train
      my.fcast <- forecast(fit,test)
    }
    
  • 3

    除了@James的回答 . 您的模型未正确定义 . 参数 model <- paste(a,'~',b) 在数据集中的所有数字之间放置 ~ .

    简单地将 model 定义为函数中的争论可能更好 . 如:

    fcast <- function(model,df,h) { #define model outside of the function
      #model <- paste(a,'~',b) #commented out
      x <- ts(data=df)  
      train.end <- time(x)[nrow(x)-h]
      test.start <- time(x)[nrow(x)-h+1]
      train <- window(x,end=train.end)
      test <- window(x,start=test.start)
      fit <- lm(model, data=train)
      my.fcast <- forecast(fit,test)   #error object 'train' not found -> see @James' answer
    }
    

    这意味着您的功能如下所示:

    fcast(a~b,df,h)
    

相关问题