Jenny Bryan
18 July, 2014
A group of us at UBC are working through Wickham's Advanced R Programming book together. We just tackled the chapter on Functions, which reminded me of this ...
In the subsection on "Default and missing arguments", we have: "Since arguments in R are evaluated lazily (more on that below), the default value can be defined in terms of other arguments:"
g <- function(a = 1, b = a * 2) {
c(a, b)
}
g()
## [1] 1 2
g(10)
## [1] 10 20
My previously foggy understanding of lazy evaluation gave me hope that the following would work:
z <- data.frame(x = 1:3, y = x^2)
## Error: object 'x' not found
But clearly it never has, which just confirmed I did not understand lazy evaluation.
Here is a nutty way to make variables derived from other variables at the time of data frame creation:
lazy_this <- function(x = 1:3, y = x^2) {
data.frame(x, y)
}
lazy_this()
## x y
## 1 1 1
## 2 2 4
## 3 3 9
So I conclude ... that lazy evaluation applies at the time of function definition, not invocation?
Is there truly no plyr::mutate()
(or within()
) for de novo data frame creation?
UPDATE
Yes, Hadley confirmed that
@JennyBryan right lazy evaluation only applies at function creation; you could do non-standard evaluation, but data.frame() doesn't
— Hadley Wickham (@hadleywickham) July 18, 2014
which settles the lazy evaluation question. As for the quest to define variables in terms of other variables, Vince Buffalo had a clever suggestion
@JennyBryan @hadleywickham There's always with(): with(list(x=1:3), data.frame(x=x, y=x^2))
— Vince Buffalo (@vsbuffalo) July 18, 2014
More back and forth lead to this, which gives hope maybe one day data_frame()
function we deserve will exist ...
@JennyBryan have thought about adding dplyr::data_frame that works how you expect (and wouldn't coerce strings to factors)
— Hadley Wickham (@hadleywickham) July 18, 2014