user3878084 user3878084 - 3 days ago 5
R Question

R macro: how to f(x) --> g("x")

How can I use defmacro (from gtools) to arrange it so that when I type

f(x)
the result is the return value of
g("x")
?

I suppose (because I am a C programmer) that defmacro is involved... but I would be happy to achieve the goal with or without defmacro.

Unfortunately
f <- defmacro(x, expr={ g(quote(x)) })
is hit and miss... it works for some functions, but fails for others, like for example

g <- function(v) {
eval(parse(text=paste0("f0 = lm(Sale_Price ~ ", v, ", data = d1)")))
r0 <- data.frame(predict(f0, d1), d1$Sale_Price)
colnames(r0) <- c(v, "Sale_Price")
ggplot() +
labs(x= v, y= "Sale_Price") +
geom_point(data = r0, aes(get(v), Sale_Price), colour="black") +
geom_smooth(data = r0, method = "lm", aes(x = get(v), y Sale_Price), colour="blue", se = FALSE)
}


I can modify the above definition so that
f <- defmacro(x, expr={ g(quote(x)) })
will succeed... but that is not my question. I want to know how in general it can be arranged so that when I type
f(x)
the result is the return value of
g("x")
for arbitrary user-defined
g
(but I would appreciate an answer which works with mild restrictions on
g
).

Answer

when I type f(x) the result is the return value of g("x") for arbitrary user-defined g

f <- function(x, g) {
  g(as.character(substitute(x)))
} 

#using paste as an example of g    
f(a, paste)
#[1] "a"

Do not use eval(parse()). Forget it exists until you are much more advanced in your knowledge of the language. You can do something like this:

form <- as.formula(sprintf("Sale_Price ~ %s", v))
f0 <- lm(form, data = d1)

Also, study help("aes_string"). You don't need get.

Comments