Reputation: 255
I have this code:
library(magrittr)
a <- function(cars) return(cars)
b <- function(x) return(list(varname = deparse(substitute(x)), content = x))
b(cars)
returns a list with the string cars
and the content of the data.frame cars
.
Any way to get a(cars) %>% b()
to also return the string cars
(the name of the variable returned by the function a()
) and the content of the data.frame?
Instead, it returns .
and the content of the data.frame.
That is, I would like the second function to return the name of the variable returned by the first function as well as the content of the variable.
What I actually want to do with b()
is something like write.csv(x, paste0(deparse(substitute(x)), ".csv"))
.
Any suggestions?
Upvotes: 3
Views: 154
Reputation: 206167
If you look at the call stack inside the %>%
operators, you get something like this
a(cars) %>% (function(x) sys.calls())
# [[1]]
# a(cars) %>% (function(x) sys.calls())
# [[2]]
# withVisible(eval(quote(`_fseq`(`_lhs`)), env, env))
# [[3]]
# eval(quote(`_fseq`(`_lhs`)), env, env)
# [[4]]
# eval(expr, envir, enclos)
# [[5]]
# `_fseq`(`_lhs`)
# [[6]]
# freduce(value, `_function_list`)
# [[7]]
# withVisible(function_list[[k]](value))
# [[8]]
# function_list[[k]](value)
# [[9]]
# (function (x) sys.calls())(.)
you can see when your function finally gets called, you're quite a few levels away form the original expression. The problem is that the parameter may have been reassigned in the chain. Consider this case
a <- 6
b <- a
f <- function(x) deparse(substitute(x))
f(b)
# [1] "b"
but there is no way for R to know that b
actually came from a
. There's not a way to walk backwards through assignments like that. substitute
will only work like that if you still have access to the promise that was passed to the function.
So the problem is by the time your function is called in the chain, it has been reassigned to .
which is why you can no longer access the original "name".
Upvotes: 6