Я столкнулся с подобной проблемой неправильной передачи аргумента с map
в совершенно ином контексте (не в функции и не с использованием многоточия, для справки см. Функцию recode_df
в конце этого ответа ).
Тогда было решено создать именованную функцию, которая принимает только один аргумент и передает его map
, так что единственным аргументом является вектор / список, по которому вы перебираете цикл. * Применительно к вашей проблеме решение будет выглядеть следующим образом:
# function with forwarding
read_all <- function(path, ...) {
# function within function that sets the arguments path and ellipsis as given and only leaves sheet to be determined
read_xl <- function(sheet) {
readxl::read_excel(path = path, sheet, ...)
}
path %>%
readxl::excel_sheets() %>%
rlang::set_names() %>%
purrr::map_df(read_xl)
}
# this allows you to pass along arguments in the ellipsis correctly
read_all(path)
read_all(path, col_names = FALSE)
Кажется, эта проблема возникает из-за неправильной обработки окружения функцией purrr::as_mapper
. Чтобы обойти это, я предложил использовать анонимную функцию в комментариях. Очевидно, что приведенный ниже подход также работает.
read_all <- function(path, ...) {
path %>%
readxl::excel_sheets() %>%
rlang::set_names() %>%
purrr::map_df(function(x) {
readxl::read_excel(path = path, sheet = x, ...)
})
}
Чтобы убедиться, что это действительно функция as_mapper
, которая вызывает проблему, мы можем переписать названную функцию в функции сверху, используя as_mapper
. Это снова приводит к ошибкам с и без дополнительных аргументов в многоточии.
# function with forwarding
read_all <- function(path, ...) {
# named mapper function
read_xl <- purrr::as_mapper(~ readxl::read_excel(path = path, sheet = .x, ...))
path %>%
readxl::excel_sheets() %>%
rlang::set_names() %>%
purrr::map_df(read_xl)
}
Обновление Знание того, что as_mapper
вызывает проблему, позволяет нам углубиться в проблему. Теперь мы можем проверить в отладчике RStudio, что происходит под капотом при работе с простой версией маппера read_excel
:
read_xl <- purrr::as_mapper(~ readxl::read_excel(path = .x, sheet = .y, ...))
debugonce(read_xl)
read_xl(path, 1)
Кажется, что когда многоточие включено в функцию маппера, as_mapper
отображает первый аргумент не только на .x
, но также автоматически на многоточие ...
. Мы можем убедиться в этом, создав простую функцию отображения paster
с двумя аргументами .x
и ...
.
paster <- purrr::as_mapper(~ paste0(.x, ...))
paster(1)
> [1] "11"
paster(2)
> [1] "22"
Теперь возникает вопрос: есть ли другой способ, которым мы должны использовать многоточие в функциях картографирования, или это ошибка.