4

I have three functions and one function is made out of the other two by using useMethod().

logReg <- function(x, ...) UseMethod("logReg")
logRec.numeric <- function(x, y) {
  print(x)
}
logReg.formula <- function(formula, data) {
  print(formula)
}

My functions are a bit more complex but does not matter for my question. I want logReg to give me additionaly the original function call as output (not the function call of logReg.numeric oder logReg.formula). My first try was:

logReg <- function(x, ...) {
  out <- list()
  out$call <- match.call()
  out
  UseMethod("logReg")
}

But it does not work. Can someone give me a hint how to solve my problem?

jay.sf
  • 60,139
  • 8
  • 53
  • 110
  • You have arguments mismatch, method args has to match to generic args – jangorecki Mar 16 '19 at 11:30
  • 1
    Instead of `out` list use `on.exit` function combined with `returnValue` – jangorecki Mar 16 '19 at 11:32
  • Working example, I used it to catch `nrow` of returned value, but I also keep `match.call` there: https://github.com/jangorecki/dtq/blob/0fa04c30d859b885c1072a224d6c41e372743bea/R/zzz.R#L19 – jangorecki Mar 16 '19 at 11:35
  • 1
    If you want to get rid of `.numeric` suffix just modify language object with `substr` and `as.name` – jangorecki Mar 16 '19 at 11:41
  • If you manage to make it work please self answer your question as there might be others having same problem. I am not posting answer bc I am on the phone. – jangorecki Mar 16 '19 at 11:45
  • Thanks alot for you answers! I will try to manage it with substr and as.name as you suggested and post my solustion afterwards. – Schneeflocke Mar 16 '19 at 12:00
  • I figured out that your first suggestion might be the smarter way for me. Im just struggling with the usage of `on.exit` and `returnValue` to solve my problem. Can you tell me what your idea is about that? – Schneeflocke Mar 16 '19 at 12:33

2 Answers2

1

Try evaluating it explicitly. Note that this preserves the caller as the parent frame of the method.

logReg <- function(x, ...) {
  cl <- mc <- match.call()
  cl[[1]] <- as.name("logReg0")
  out <- structure(eval.parent(cl), call = mc)
  out
}

logReg0 <- function(x, ...) UseMethod("logReg0")
logReg0.numeric <- function(x, ...) print(x)
logReg0.formula <- function(x, ...) print(x)

result <- logReg(c(1,2))
## [1] 1 2

result
## [1] 1 2
## attr(,"call")
## logReg(x = c(1, 2))
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • When i run you code the result is only the vector itself. Im not sure why but the call is not stored in result. – Schneeflocke Mar 17 '19 at 13:06
  • 1
    Start up a fresh vanilla session of R and copy and paste the code from the answer into R and you should be able to reproduce the results shown. I tried it on both Windows and Linux and it worked as shown. – G. Grothendieck Mar 17 '19 at 13:25
  • I repeated it in a new session and it worked for me. Thanks for your help! – Schneeflocke Mar 17 '19 at 16:38
1

Here's another way :

logReg <- function(x, ...) {
  logReg <- function(x, ...) UseMethod("logReg")
  list(logReg(x,...), call=match.call())
}

res <- logReg(1,2)
# [1] 1

res
# [[1]]
# [1] 1
# 
# $call
# logReg(x = 1, 2)
# 

You can make it work with atttibutes too if you prefer.

moodymudskipper
  • 46,417
  • 11
  • 121
  • 167