Как переписать жестко закодированный аргумент функции параметром dots (...)? - PullRequest
2 голосов
/ 30 мая 2019

Я пытаюсь создать функцию графика с набором значений по умолчанию и возможностью изменять эти значения, используя любой аргумент, который функция plot принимает внутри аргумента точек (...). Пример:

PlotIt <- function(x, y, ...) {
  plot(x, y, type = "l", asp = 1, ...)
}

x <- 1:10
y <- 10:1

PlotIt(x = x, y = y)
# Returns a plot
PlotIt(x = x, y = y, asp = NA)
# Error in plot.default(x, y, type = "l", asp = 1, ...) : 
#  formal argument "asp" matched by multiple actual arguments

Ошибка, естественно, потому что я пытаюсь дважды передать аргумент asp в plot. Пока что моя лучшая неуклюжая попытка - сделать заявление if-else, чтобы учесть это (подход изменен с здесь ):

PlotIt2 <- function(x, y, ...) {

  mc <- match.call(expand.dots = FALSE)

  if(names(mc$...) %in% "asp") {
  plot(x, y, type = "l", ...)  
  } else {
  plot(x, y, type = "l", asp = 1, ...)  
  }

}

PlotIt2(x = x, y = y, asp = NA)
# works

Чтобы сделать это для всех возможных параметров, которые можно установить с помощью аргумента ..., мне нужно написать длинную инструкцию if-else. Есть ли более элегантный способ сделать это?

Вопрос связан с этим , с той разницей, что я хочу автоматически перезаписать все параметры, установленные аргументом ....

1 Ответ

1 голос
/ 30 мая 2019

Если вы хотите использовать только базу R, вы можете поместить все в список и удалить дубликаты на основе имен аргументов (убедившись, что значения по умолчанию являются последними, чтобы они были удалены, если они присутствуют в ...):

PlotIt <- function(x, y, ...) {
  arguments <- list(
    x = x,
    y = y,
    ...,
    type = "l",
    asp = 1
  )

  arguments <- arguments[!duplicated(names(arguments))]

  do.call("plot", arguments)
}

Если вы не возражаете против зависимости от rlang, вы также можете сделать следующее, используя .homonyms, чтобы получить ту же функциональность (и проверить метки графика дляоси, это будет отличаться между версиями base R и rlang):

PlotIt <- function(x, y, ...) {
  require("rlang")
  arguments <- rlang::dots_list(
    rlang::expr(x),
    rlang::expr(y),
    ...,
    type = "l",
    asp = 1,
    .homonyms = "first"
  )

  call <- rlang::call2("plot", !!!arguments)
  eval(call)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...