GOOGLE ADS

понедельник, 25 апреля 2022 г.

is_quosure(x) ошибка при пересылке... внутри карты

Я хотел бы определить оболочку для внутренней функции. Идея состоит в том, чтобы повторить случайную выборку, которая использует одну из r*базовых функций (например runif, rnorm, и т. д.), и позволить пользователю легко изменить эту внутреннюю функцию и определить собственные.

В приведенном ниже примере показан воспроизводимый пример, который я не могу заставить работать с tidyevalшаблонами и, точнее, внутри файла purrr::map. Кажется, что оценка ...не происходит должным образом. Я что-то пропустил при оценке quosures, но не могу понять что. Ниже я также покажу обходной путь, который отлично работает со старым добрым replicate.

Хотелось бы реализовать такое поведение в более сложных случаях и, вообще, радоваться любому указателю и понимать, почему следующее не работает.

# use the tidyverse and define a dummy tibble
library(tidyverse)
df <- tibble(col1=seq(10, 50, 10), col2=col1+5)
# first random function, on top of stats::runif
random_1 <- function(x, min, max){
x %>%
rowwise() %>%
mutate(new=runif(1, min={{min}}, max={{max}})) %>%
ungroup()
}
# second random function, on top of stats::rnorm
random_2 <- function(x, mean, sd){
x %>%
rowwise() %>%
mutate(new=rnorm(1, mean={{mean}}, sd={{sd}})) %>%
ungroup()
}
# at top level, everything works fine
> df %>% random_1(min=col1, max=col2)
> df %>% random_2(mean=col1, sd=col2)
# So far so good
# we we wrap it for a single shot
random_fun <- function(x, random_fun,...){
random_fun(x,...)
}
random_fun(df, random_1, min=col1, max=col2)
# Still fine.
# Here comes the trouble:
random_fun_k <- function(df, k, random_fun,...){
map(1:k, ~random_fun(df,...))
}
random_fun_k(df, k=2, random_1, min=col1, max=col2)

Ошибка в is_quosure(x): аргумент "x" отсутствует, без значения по умолчанию

Следующий обходной путь replicateработает нормально, но я хотел бы придерживаться духа tidyeval:

random_fun_k_oldie <- function(df, k, random_fun,...){
f <- random_fun(df,...)
replicate(k, f, simplify=FALSE)
}
random_fun_k_oldie(df, k=2, random_1, min=col1, max=col2)
random_fun_k_oldie(df, k=2, random_2, mean=col1, sd=col2)


Решение проблемы

Может быть лучше использовать оригинальную лямбда-функцию, т.е.function(x)

library(purrr)
random_fun_k <- function(df, k, random_fun,...){
map(seq_len(k), function(x) random_fun(df,...))
}

-тестирование

> random_fun_k(df, k=2, random_1, min=col1, max=col2)
[[1]]
# A tibble: 5 × 3
col1 col2 new
<dbl> <dbl> <dbl>
1 10 15 12.6
2 20 25 21.4
3 30 35 34.1
4 40 45 40.7
5 50 55 53.8
[[2]]
# A tibble: 5 × 3
col1 col2 new
<dbl> <dbl> <dbl>
1 10 15 13.1
2 20 25 24.2
3 30 35 33.8
4 40 45 41.6
5 50 55 50.9

ПРИМЕЧАНИЕ. Имя функции и имя аргумента кажутся одинаковыми, rand_funи это также может вызвать некоторую путаницу (хотя это не является источником ошибки). Может быть лучше переименовать аргумент функции по-другому

random_fun <- function(x, rn_fun,...){
rn_fun(x,...)
}

Комментариев нет:

Отправить комментарий

Laravel Datatable addColumn returns ID of one record only

Я пытаюсь использовать Yajra Datatable для интеграции DataTable на свой веб-сайт. Я смог отобразить таблицу, но столкнулся с проблемой. В по...