robwschlegel / heatwaveR

This GitHub repo contains all of the code for the heatwaveR package.

Home Page:https://robwschlegel.github.io/heatwaveR/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Pass variable name to `exceedance` function from a wrapper

Fred-Wu opened this issue · comments

I tried to wrap up exceedance function in a function so that I can pass difference temperature variable names to exceedance. However, since exceedance has already implemented non-standard evaluation for input variable, how can I make it work for the wrapper?

Here is the function I tried to write

hw.fun <- function(dat, temp_var, duration, pctl) {

  temp_name <- deparse(substitute(temp_var))
  thres <- quantile(dat[, get(temp_name)], pctl)
  exceed <- exceedance(dat, x = arrival_date, y = temp_var,
                       threshold = thres, minDuration = duration,
                       maxGap = 0)$threshold
  return(1*exceed[, "exceedance"]$exceedance)
}

Found a solution, so I will close this.

Hello Fred,
Would you mind posting the solution here in case anyone else finds this page via a web search?
Thank you,
-Robert

No problem, Robert.

Here is what I have done, which uses substitute function to wrap exceedance. The parameters in the function arguments are automatically substituted. It, then, can be called in data.table by including parent.frame() when evaluating the expression.

That would be great if you could double check it.

hw.fun <- function(dat, date_var, temp_var, duration, pctl) {

  temp_name <- substitute(temp_var)
  thres <- quantile(dat[, eval(temp_name)], pctl)
  exceed_exprs <- substitute(exceedance(dat,
                                        x = date_var,
                                        y = temp_name,
                                        threshold = thres,
                                        minDuration = duration,
                                        maxGap = 0)$threshold)
  exceed <- eval(exceed_exprs, parent.frame())
  hw <- 1*exceed[c("thresh", "exceedance", "exceedance_no")]
  return(hw)
}

DATA[, c("thresh", "hw", "hw_no") := hw.fun(.SD, arrival_date, tmax, 3, 0.9), by = .(climate_zone, grp_name)]

Hello Fred,
This is an interesting application of the function. The use of parent.frame() within eval() is not something I've seen before. I'm sure there is another way to do this, but if this works for you then that is great.
All the best,
-Robert