2016-09-14 3 views
0

J'ai un problème qui m'a rendu fou pendant les deux dernières heures.Objet non trouvé numéro

J'utilise les packages suivants dans R: forecast, fracdiff, doParallel, foreach et d'autres. J'ai aussi la fonction suivante.

doparPredictions <- function(train, test, cl){ 
    training = train 
    pred = foreach (i = 1:length(test), .combine=c) %dopar% { 
     if (i > 1) { 
      training = c(train,test[1:i-1]) 
     } 
     fit = nnetar(training, 8, P=1, 5) 
     forecast(fit, 1)$mean 
    } 
} 

... et la fonction ci-dessus FONCTIONNE!

Toutefois, si je remplace nnetar(training, 8, P=1, 5) par fracdiff(training, 3, 1, h=0.00001), la fonction commence à échouer avec l'erreur suivante.

Error in { : task 1 failed - "object 'training' not found" 

Voici où cela devient intéressant. Il n'échoue pas réellement sur la ligne éditée. Il échoue en fait sur la ligne suivante: forecast(fit, 1)$mean

En d'autres termes, ce qui suit fonctionne.

fits = foreach (i = 1:length(test)) %dopar% { 
    if (i > 1) { 
     training = c(train,test[1:i-1]) 
    } 
    fracdiff(training, p, q, h=0.00001) 
} 

mais ...

pred = foreach (i = 1:length(test), .combine=c) %dopar% { 
    forecast(fits[[i]], 1)$mean 
} 

lancers francs l'erreur a été mentionné précédemment à propos "object 'training' not found"

EDIT: Comme par exemple la demande ... un ... reproductible

require(quantmod) 
require(forecast) 
require(fracdiff) 
require(doParallel) 
require(foreach) 

cl <- makeCluster((detectCores() - 1), type="FORK") 
registerDoParallel(cl) 

predictionsThatWork <- function(train, test, cl){ 
    training = train 
    pred = foreach (i = 1:length(test), .combine=c) %dopar% { 
     if (i > 1) { 
      training = c(train,test[1:i-1]) 
     } 
     fit = nnetar(training, 8, P=1, 5) 
     forecast(fit, 1)$mean 
    } 
    return(pred) 
} 

predictionsThatDoNotWork <- function(train, test, cl){ 
    training = train 
    pred = foreach (i = 1:length(test), .combine=c) %dopar% { 
     if (i > 1) { 
      training = c(train,test[1:i-1]) 
     } 
     fit = fracdiff(training, 3, 1, h=0.00001) 
     forecast(fit, 1)$mean 
    } 
    return(pred) 
} 

ticker = 'IBM' #feel free to replace with ticker of your choice 
getSymbols(ticker, from='2010-01-01', to='2016-08-31') 
fullts = get(ticker) 
returnTS = diff(log(fullts[,4]),lag=1)[-1] 
returnTS = returnTS - mean(returnTS) 
numObs = length(returnTS) 
cutOff = ceiling(numObs*.85) 
train = returnTS[1:cutOff-1] 
test = returnTS[cutOff:numObs] 

predictionsThatWork(train, test, cl) 
predictionsThatDoNotWork(train, test, cl) 

stopCluster(cl) 

EDIT 2: Ok, ce problème n'a rien à voir avec le parallélisme. Cela a tout à voir avec l'interaction entre fracdiff et forecast. La fonction suivante ne fonctionne pas non plus

anotherBrokenFunction <- function(train, test) { 
    training = train 
    print(exists('training')) 
    predictions = test 
    for (i in 1:length(test)){ 
     print(exists('training')) 
     arf = fracdiff(x=training, nar=3, nma=1, h=0.00001) 
     print(exists('training')) 
     predictions[i] = forecast(arf, 1)$mean 
     print(exists('training')) 
     training = c(training, test[i]) 
    } 
    return(predictions) 
} 

Il évalue les éléments suivants

> anotherBrokenFunction(train, test) 
[1] TRUE 
[1] TRUE 
[1] TRUE 
Error in eval(expr, envir, enclos) : object 'training' not found 
+0

Pouvez-vous fournir un exemple reproductible minimal s'il vous plaît? –

+1

J'ai fait l'édition demandée – Constantine

+0

@WeihuangWong, j'ai fait une autre mise à jour. Voir au dessus. Merci – Constantine

Répondre

1

Ceci est une solution hacky, mais une suggestion est d'ajouter arf$x <- training à la fonction:

anotherBrokenFunction <- function(train, test) { 
    training = train 
    predictions = test 
    for (i in 1:length(test)){ 
     arf = fracdiff(x=training, nar=3, nma=1, h=0.00001) 
     arf$x <- training # add this 
     predictions[i] = forecast(arf, 1)$mean 
     training = c(training, test[i]) 
    } 
    return(predictions) 
} 

out <- anotherBrokenFunction(train, test) 
str(out) 
# An ‘xts’ object on 2015-09-02/2016-08-31 containing: 
# Data: num [1:252, 1] -0.000312 -0.000534 0.001913 0.000513 -0.000467 ... 
# - attr(*, "dimnames")=List of 2 
# ..$ : NULL 
# ..$ : chr "IBM.Close" 
# Indexed by objects of class: [Date] TZ: UTC 
# xts Attributes: 
# List of 2 
# $ src : chr "yahoo" 
# $ updated: POSIXct[1:1], format: "2016-09-15 09:56:46" 

Détails: forecast.fracdiff appelle getResponse, et la fracdiff méthode de getResponse ressemble à ceci:

getAnywhere("getResponse.fracdiff") 
# A single object matching ‘getResponse.fracdiff’ was found 
# It was found in the following places 
# registered S3 method for getResponse from namespace forecast 
# namespace:forecast 
# with value 

# function (object, ...) 
# { 
#  if (is.element("x", names(object))) 
#   x <- object$x 
#  else x <- eval.parent(parse(text = as.character(object$call)[2])) 
#  if (is.null(tsp(x))) 
#   x <- ts(x, frequency = 1, start = 1) 
#  return(x) 
# } 
# <bytecode: 0x7fd64bd8b698> 
# <environment: namespace:forecast> 

il recherche d'abord un élément nommé « x » dans l'objet fracdiff, à défaut de quoi il cherchera as.character(object$call)[2] (qui se trouve être training dans ce cas), ce qui génère l'erreur. L'idée est d'insérer training comme élément x dans l'objet fracdiff pour anticiper cette erreur.

+0

Merci, j'ai eu une solution de contournement différente, mais celui-ci est meilleur. Merci. – Constantine

+2

La dernière version de github devrait résoudre ce problème. –