Упорядочить по нескольким столбцам с использованием нестандартной оценки - PullRequest
3 голосов
/ 08 ноября 2019

Допустим, я хочу заказать data.frame, используя несколько столбцов и используя нестандартную эволюцию. Возможно, у меня есть функция, которая выглядит примерно так* ПРИМЕЧАНИЕ: я не хочу использовать dplyr::arrange() для этой проблемы, так как она добавляет зависимость.

Ответы [ 2 ]

4 голосов
/ 08 ноября 2019

Один из вариантов - заключить выражение в 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

Обратите внимание, что мы используем eval.parent() вместо eval(), потому что комбинация eval / substitute не очень хорошо играетс вложенными функциями . Трюк eval.parent() был , предложенный @ MoodyMudskipper в качестве способа решения этой проблемы, и позволяет нам беспрепятственно использовать my_order() внутри других функций, включая трубы magrittr:

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
4 голосов
/ 08 ноября 2019

Вот один из способов передачи неразрешенных символов с использованием базы R

my_order <- function(data, ...) {
  dots <- substitute(...())
  with(data, do.call("order", as.list(dots)))
}
my_order(mtcars, mpg, cyl)

По сути, мы используем замену для захвата имен символов, а затем используем do.call, чтобы ввести их в вызов order.

В качестве альтернативы вы могли бы подумать о перезаписи вызова функции и изменении среды эвакуации

my_order <- function(data, ...) {
  call <-match.call()
  call[[1]] <- quote(order)
  call[2] <- NULL
  eval(call, data, parent.frame())
}
my_order(mtcars, mpg, cyl)
...