#r #r6
#r #r6
Вопрос:
Я начинаю создавать «удобный» класс R6 и хочу, чтобы функция выполняла большую часть работы моего класса. Пока это моя структура
x <- X$new()
veggie_cubes <- veggie %>% x$cubesX(ID)
veggie_slices <- veggie %>% x$sliceX(ID)
Теперь мой вопрос в том, можно ли переписать код таким образом, чтобы:
x <- X$new()
veggie_cubes <- veggie %>% x$cutX(cubesX, ID)
veggie_slices <- veggie %>% x$cutX(sliceX, ID)
Заголовок функции должен выглядеть как: cut(.data, FUN, KEY)
До сих пор моя идея состояла в том, чтобы написать cut
, как:
cutX= function(.data, FUN, KEY)
{
.data %>%
FUN({{ KEY }}) %>%
base::return()
}
Единственным способом, которым это работает, был вызов veggie %>% x$cutX(x$cubesX, ID)
, который я бы не предпочел как «удобное для пользователя» решение, мне также не очень нравится использовать для этого строки. Есть ли способ записать его без x$
?
вот упрощенный класс R6:
X <- R6::R6Class(
classname = "X",
public = base::list(
cubesX = function(.data, KEY)
{
.data %>%
dplyr::select(!{{ KEY }}) %>%
base::return()
},
sliceX = function(.data, KEY)
{
.data %>%
dplyr::select({{ KEY }}) %>%
base::return()
},
cutX = function(.data, FUN, KEY)
{
.data %>%
FUN( {{ KEY}}) %>%
base::return()
}
)
)
примеры выполнения:
x <- X$new()
iris %>% x$sliceX(Species)
iris %>% x$cubesX(Species)
# with FUN
iris %>% x$cutX(x$sliceX, Species)
iris %>% x$cutX(x$cubesX, Species)
не выполняется:
iris %>% x$cutX(sliceX, Species)
iris %>% x$cutX(cubesX, Species)
Заранее спасибо 🙂
Комментарии:
1. Не могли бы вы опубликовать код для определения вашего класса R6, пожалуйста?
Ответ №1:
Следующая реализация позволит вам вызывать ваши функции с помощью любого из ваших трех методов. Он работает с использованием нестандартной оценки, чтобы выяснить, находится ли FUN
он в формате x$func
или просто голый func
. В любом случае он принимает голое имя функции и создает вызов для ее преобразования self$func
. Затем он просто оценивает эту функцию.
Поэтому следующий класс R6 работает, как и ожидалось, во всех ваших тестовых примерах:
X <- R6::R6Class(
classname = "X",
public = base::list(
cubesX = function(.data, KEY)
{
.data %>%
dplyr::select(!{{ KEY }}) %>%
base::return()
},
sliceX = function(.data, KEY)
{
.data %>%
dplyr::select({{ KEY }}) %>%
base::return()
},
cutX = function(.data, FUN, KEY)
{
if(is.call(substitute(FUN))) {
FUN <- substitute(FUN)
FUN[[2]] <- quote(self)
}
else
FUN <- as.call(list(quote(`$`), quote(self), substitute(FUN)))
eval(as.call(list(FUN, quote(.data), substitute(KEY))))
}
)
)
Так, например:
x <- X$new()
iris %>% x$cutX(sliceX, Species)
#> Species
#> 1 setosa
#> 2 setosa
#> 3 setosa
#> 4 setosa
#> 5 setosa
#> 6 setosa
#> 7 setosa
#> 8 setosa
#> 9 setosa
#> 10 setosa
#> 11 setosa
#> 12 setosa
#> 13 setosa
#> 14 setosa
#> 15 setosa
#> 16 setosa
#> 17 setosa
#> 18 setosa
#> 19 setosa
#> 20 setosa
#> ...etc