1

I am using the package robust.arima in R, which works fine when I call it in a script. However, I want to organize my files and therefore call robust arima in a function. Here all of a sudden the variable is not found. Let me give an example

# Works fine
ts_list <- rnorm(100)
arima.rob(ts_list~1)

# Breaks down
get_rob_estimate <- function(x){
    out <- arima.rob(x~1)
    return(out)

ts_list <- rnorm(100)
get_rob_estimate(ts_list)

Error in eval(formula[[2]]) : object 'x' not found

Does anyone know what's going on? I think the problem looks similar to R : Pass argument to glm inside an R function , but I still can't seem to figure it out and I am curious how R processes these functions?

Edit

Okay for the basic option I understand it now, but I don't get why it works. What if I have


check_func <- function(ind_ts){
  out <- substitute(arima.rob(ind_ts~1))
  return(eval(out))
}

analyze_ts <- function(){
  df <- mvrnorm(100, mu=c(0,0,0), Sigma=diag(c(1,1,1)))
  p <- list()
  for (i in ncol(df)){
    sel <- df[,i]
    check_func(sel)
    p <- append(p, sel)
  }
  return(p)
}

analyze_ts()

I then get the error

Error in eval(formula[[2]]) : object 'sel' not found

How does it work? What is going on here? I just want my list to go as a list in my function, shouldn't be so hard right? Does not matter how many functions it goes through?

Tom
  • 31
  • 4

1 Answers1

2

Using substitute()

get_rob_estimate <- function(x) {
  out <- substitute(robustarima::arima.rob(x ~ 1))
  return(eval(out))
}


get_rob_estimate(ts_list)
# Call:
# robustarima::arima.rob(formula = ts_list ~ 1)
# 
# Regression Coefficients:
#   (Intercept) 
#        0.1032 
# 
# Degrees of freedom: 100 total; 99 residual
# Innovations standard deviation: 0.9832 
# 
# Number of outliers detected:  1
# 
# Outlier index
# [1] 59
# 
# Outlier type
# [1] "AO"
# 
# Outlier impact
# [1] -3.0963
# 
# Outlier t-statistics
# [1] 3.1493

edit

You can write your Arima wrapper correctly like so:

analyze_ts <- function(){
  df <- MASS::mvrnorm(100, mu=c(0, 0, 0), Sigma=diag(c(1, 1, 1)))
  for (i in seq_len(ncol(df))) {
    sel <- df[,i]
    sel <- check_func(sel)
    p <- append(p, sel)
  }
  return(p)
}

Better using lapply

analyze_ts <- function() {
  df <- MASS::mvrnorm(100, mu=c(0, 0, 0), Sigma=diag(c(1,1,1)))
  return(lapply(seq_len(ncol(df)), \(i) check_func(df[,i])))
}

Usage:

set.seed(42) ## for sake of reproducibility
analyze_ts()

Data:

set.seed(42)
ts_list <- rnorm(100)
jay.sf
  • 60,139
  • 8
  • 53
  • 110
  • Thanks for your reply but this does not work for me? I copied your code and still get the same error: get_rob_estimate <- function(x) { out <- robustarima::arima.rob(reformulate('1', x)) return(out) } set.seed(42) ts_list <- rnorm(100) get_rob_estimate(ts_list) Error in reformulate("1", x) : object 'x' not found – Tom Jan 21 '23 at 18:10
  • @Tom Did you also try the `substitute` version? – jay.sf Jan 21 '23 at 18:13
  • It's `return(eval(out))` not `return(out)`, @Tom – jay.sf Jan 21 '23 at 18:21
  • @Tom Try `s <- substitute(2 + 2)`, check `print(s)`, then do `eval(s)`, and you should know what's going on. – jay.sf Jan 21 '23 at 18:24
  • I'm sorry, but I am still stuck. See my edit – Tom Jan 21 '23 at 19:45
  • @Tom there are several issues, see edit. Please don't make a [chameleon question](https://meta.stackoverflow.com/q/332820/6574038) out of it now. – jay.sf Jan 21 '23 at 20:30
  • Thanks, yea sorry I tried to make a small reproducible example. I still don't get why my first option does not work – Tom Jan 22 '23 at 08:31
  • @Tom Set `i <- 1` and run the code inside your and my `for` loops to compare. – jay.sf Jan 22 '23 at 08:36