Аргументы функции по умолчанию и именованные значения - PullRequest
48 голосов
/ 13 января 2011

Допустим, у меня есть функция R, в которой аргументы могут быть одним из нескольких предварительно заданных именованных значений (одно из которых является значением по умолчанию) или вектором пользовательских символов. Как мне реализовать это, не полагаясь на имена магических значений или другой флаг?

#allow use of predefined subsets or pass their own list
bratPack<-function(members='CORE',...){
  if (members=='CORE')
    members<-c('Emilio Estevez','Anthony Michael Hall','Rob Lowe','Andrew McCarthy','Demi Moore','Judd Nelson','Molly Ringwald','Ally Sheedy')
  else if (members=='ALL')
    members<-c('Emilio Estevez','Anthony Michael Hall','Rob Lowe','Andrew McCarthy','Demi Moore','Judd Nelson','Molly Ringwald','Ally Sheedy','James Spader','Robert Downey, Jr.','Jon Cryer', 'John Cusack', 'Kevin Bacon', 'Jami Gertz', 'Mary Stuart Masterson', 'Matthew Broderick', 'Sean Penn', 'Kiefer Sutherland')
  ...
}

Ответы [ 2 ]

59 голосов
/ 13 января 2011

Из вашего примера у нас есть выбор "CORE" и "ALL". Если это две опции, мы указываем их в определении функции для аргумента 'members'. E.g.:

foo <- function(x, members = c("CORE", "ALL")) {
    ## do something
}

Это определение функции устанавливает допустимые значения для аргумента 'members' со значением по умолчанию "CORE", поскольку это первая именованная опция.

Код, который используется внутри тела функции, - match.arg(), как уже упоминал @Joris, но поскольку мы настроили функцию, как указано выше, мы можем просто использовать значение match.arg(members).

Таким образом, мы можем написать foo как:

foo <- function(x, members = c("CORE", "ALL")) {
    ## evaluate choices
    members <- match.arg(members)
    ## do something
    print(members)
}

Который мы используем так:

> foo()
[1] "CORE"
> foo(members = "CORE")
[1] "CORE"
> foo(members = "ALL")
[1] "ALL"
> foo(members = "3rdRate")
Error in match.arg(members) : 'arg' should be one of “CORE”, “ALL”

Обратите внимание на поведение, когда мы предоставляем строку, не входящую в набор опций. Мы получаем интуитивное сообщение об ошибке, все потому, что мы установили параметры в аргументах функции.

9 голосов
/ 13 января 2011

Я бы использовал какой-нибудь постоянный фрейм данных где-нибудь в пакете:

.mdata <- data.frame(
    CORE= c(TRUE,FALSE,TRUE),
    OLD = c(TRUE,TRUE,FALSE),
    ALL = c(TRUE,TRUE,TRUE),
    row.names=c("John Doe", "Jan Janssen", "Piet Peters")
)

bratPack<-function(members='CORE',...){
  m.tmp <- try(
         match.arg(members,names(.mdata),several.ok=T),
         silent=T) 

  if(!is(m.tmp,"try-error"))
    members <- rownames(.mdata)[.mdata[[members]]]

  print(members)
}

> bratPack('CORE')
[1] "John Doe"    "Piet Peters"

> bratPack('Jan Janssen')
[1] "Jan Janssen"

> bratPack(c("John Doe","Dick Dickers"))
[1] "John Doe"     "Dick Dickers"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...