Let's say I want to order a data.frame
using multiple columns and using non-standard evolution. I might have a function that looks something like this
my_order <- function(data, ...) {
with(data, order(...))
}
I get an error when I use this function because my columns are not evaluated within the context of with
.
my_order(mtcars, mpg, cyl)
# Error in order(...) : object 'mpg' not found
NOTE: I do not wish to use dplyr::arrange()
for this problem as it adds a dependency.
One option is to wrap the expression into eval.parent(substitute(...))
:
my_order <- function( data, ... ) {
eval.parent(substitute( with(data, order(...)) ))
}
my_order( mtcars, cyl, mpg )
# [1] 32 21 3 9 8 27 26 19 28 18 20 11 6 10 30 1 2 4 15 16 24 7 17 31 14
# [26] 23 22 29 12 13 5 25
Note that we use eval.parent()
instead of eval()
, because eval/substitute combo doesn't play well with nested functions. The eval.parent()
trick has been proposed by @MoodyMudskipper as a way to address this problem and allows us to seamlessly use my_order()
inside other functions, including magrittr pipes:
mtcars %>% my_order(cyl)
# [1] 3 8 9 18 19 20 21 26 27 28 32 1 2 4 6 10 11 30 5 7 12 13 14 15 16
# [26] 17 22 23 24 25 29 31