假设我有一个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')
...
}
答案 0 :(得分:59)
从您的示例中,我们可以选择"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”
请注意我们提供未包含在选项集中的字符串时的行为。我们得到一个直观的错误消息,因为我们在函数参数中设置了选项。
答案 1 :(得分:9)
我在包中的某处使用了一些常量数据框:
.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"