-3

Why my code is not working, correctly. How can I pass, properly, the argument hist.args = NULL, plot.args = NULL to the function plot and hist inside the plot.gevp function?

    plot.gevp=function (vector, type = c("predictive", "retlevel"), t, hist.args = NULL, plot.args = NULL){
      if (type=="predictive"){
      dat=vector$data
      linf = max(min(dat) - 1, 0)
      lsup = 11 * max(dat)/10
      x = seq(linf, lsup, (lsup - linf)/70)
      n = length(x)
      int = length(vector$posterior[, 1])
      res = array(0, c(n))
      for (i in 1:n) {
          for (j in 1:int) {
              if ((vector$posterior[j, 3] > 0) && (x[i] > (vector$posterior[j, 1] - 
                  vector$posterior[j, 2]/vector$posterior[j, 3]))) 
                  res[i] = res[i] + (1/int) * dgev(x[i], vector$posterior[j, 
                    3], vector$posterior[j, 1], vector$posterior[j, 2])
              if ((vector$posterior[j, 3] < 0) && (x[i] < (vector$posterior[j, 1] - 
                  vector$posterior[j, 2]/vector$posterior[j, 3]))) 
                  res[i] = res[i] + (1/int) * dgev(x[i], vector$posterior[j, 
                    3], vector$posterior[j, 1], vector$posterior[j, 2])
          }
      }
      hist.args.all <- c(list(data, freq = F, ylim = c(min(res), max(res)), 
      main = NULL, xlab = "data", ylab = "density"), hist.args)
      do.call("hist", hist.args.all)

      lines(x, res)
      out<-list(pred=res)
      return(out)
      }

      if(type=="retlevel"){
      amostra = qgev(1 - 1/t, vector$posterior[, 3], vector$posterior[, 1], vector$posterior[, 2])
      res = quantile(amostra, 0.5)

      t = seq(1, 100, 1)
      n = length(t)
      li = array(0, c(n))
      ls = array(0, c(n))
      pred = array(0, c(n))
      for (s in 1:n) {
          amostra = qgev(1 - 1/s, vector$posterior[, 3], vector$posterior[, 1], vector$posterior[, 
              2])
          li[s] = quantile(amostra, 0.025)
          ls[s] = quantile(amostra, 0.975)
          pred[s] = quantile(amostra, 0.5)
      }
      plot.args.all <- c(list(t, pred, type = "l", ylim = c(li[2], max(ls)), 
      ylab = "returns"), plot.args)
      do.call("plot", plot.args.all)

      lines(t, li, lty = 2)
      lines(t, ls, lty = 2)
      out<-list(retmedian=res, retpred=pred)

      return(out)
      }

  }

When I call the function like:

plot(p,"retlevel",t=10, plot.args=list(main="list")) 

I got the error:

Error in plot.gevp(p, "retlevel", t = 10, main = "list") : 
  unused argument (main = "list")

How I can fix this?

aliocha
  • 5
  • 3

1 Answers1

1

How about using the ... construct?

plot.gevp=function (vector, data, type, t, ...)
{
# rest of your code
hist(data, freq = F, ylim = c(min(res), max(res)), main = NULL, 
    xlab = "data", ylab = "density", ...)

plot(t, pred, type = "l", ylim = c(li[2], max(ls)), ylab = "returns", ...)
}

All further arguments you will pass to your function will be passed verbatim to plot and hist.

edit: To avoid passing ... to two different functions, a slightly more complex example. In this case, you should pass all further arguments inside a list.

plot.gevp=function (vector, data, type, t, hist.args = NULL, plot.args = NULL)
{
# rest of your code
hist.args.all <- c(list(data, freq = F, ylim = c(min(res), max(res)), 
    main = NULL, xlab = "data", ylab = "density"), hist.args)
do.call("hist", hist.args.all)

plot.args.all <- c(list(t, pred, type = "l", ylim = c(li[2], max(ls)), 
    ylab = "returns"), plot.args)
do.call("plot", plot.args.all)
}
Choubi
  • 640
  • 3
  • 9
  • I have to put your suggestion in the end of my code, and when I go to call my function, for example, `plot(p,nidd.annual,"predictive", hist.args=c(main="Pred"))` ? Because I have tried this and it is not working. I liked your suggestion, and I would like to use this in my code @Choubi – aliocha Jul 04 '16 at 18:50
  • I have to put like: `hist.args.all <- c(list(data, freq = F, ylim = c(min(res), max(res)), main = NULL, xlab = "data", ylab = "density"), hist.args) do.call("hist", hist.args.all) hist(dat, freq = F, ylim = c(min(res), max(res)), main = NULL, xlab = "data", ylab = "density") lines(x, res)` ? @Choubi – aliocha Jul 04 '16 at 23:52
  • You do not need the second call to `hist`. The `do.call("hist", hist.args.all)` is the call to `hist`. – Choubi Jul 05 '16 at 07:42
  • it's not working, I throw away the second call, like you said. But, when I call the function plot() to change for example the main title, using 'plot(p,"predictive", hist.args=list(main="e"))' I got error. I'm going to change my code in my main question in this post, if you could look at how it is. @Choubi – aliocha Jul 05 '16 at 15:25
  • Is your gevp a class and you are writing an S3 method for this class? If so, then when you are calling "plot" the second time around (inside `do.call`), it looks like it is running `plot.gevp` again so that this time it possesses the `main = "e"` argument as wanted, except that `plot.gevp` doesn't take such an argument, hence the error. If you want to ensure you are calling the default plot method in that case, replace `do.call("plot", plot.args.all)` by `do.call("plot.default", plot.args.all)` – Choubi Jul 05 '16 at 15:36
  • Now its working. Thanks!! But, why can not I change arguments that are in the list of plot.args.all ? When I try it, The R give me a error `Error in hist.default(c(..., : formal argument "main" matched by multiple actual arguments` In this case, I tried to change the title, and the title was on the list inside the function. And yes, the gevp is a class, and the plot.gevp is my S3 method @Choubi – aliocha Jul 05 '16 at 16:03
  • Bascially, all arguments that are already given inside your `plot.gevp` function (for `hist`: data, freq = F, ylim = c(min(res), max(res)), main = NULL, xlab = "data", ylab = "density") cannot be set in `hist.args` otherwise they'll be set twice and you'll get the same error (formal argument matched twice). If you want to let your users set one of these arguments, you either have to drop the `main = NULL` from inside your code and let the user define it inside `hist.args` or create a new argument `hist.main = NULL` in your function definition and use `main = hist.main` inside `hist.args.all` – Choubi Jul 06 '16 at 07:37
  • worked, thank you for your suggestions @Choubi – aliocha Jul 07 '16 at 03:23