2017-07-21 6 views
2

複数の許可された引数の値のうちの最初のもの以外を、デフォルト値として宣言するにはどうすればよいですか(値が渡されなかった場合)。match.argのenum-alike引数:最初の要素以外の要素をデフォルト値として選択するにはどうすればよいですか?

library(stats) 

center <- function(x, type = c("mean", "median", "trimmed")) { 
    type <- match.arg(type) 
    switch(type, 
     mean = mean(x), 
     median = median(x), 
     trimmed = mean(x, trim = .1)) 
} 

values <- c(100, 120, 200) 

center(values, "median") 
# [1] 120 

center(values, "mean") 
# [1] 140 

# uses the first value "mean" as the default! 
center(values) 
# [1] 140 

可能であれば、デフォルト値を明示的(表示可能)にするために、関数シグネチャのデフォルト値を見たいと思います。 g。 (非動作擬似コード!)を使用して、2番目の要素をデフォルト値にします。

center <- function(x, type = c("mean", "median", "trimmed")[2]) {... 

他の提案も歓迎です!

PS:私は最初の位置に常にデフォルト値を入れることができますが、リスト内の論理的な順序がある場合、私は例えばpayment.frequency = c("monthly", "quarterly", "semi-annually", "annually")(それを維持することを好む

+0

@RichScriven:center(値)をコールしたいが、関数declのデフォルト値として2番目の値を指定したいaration(呼び出しではない)。 –

答えて

2

あなたは二argを取るためにmatch.argを修正することができます最初の値が代わりに。これは、関数本体でその行を検索と置換の問題だ。

matchArg <- base::match.arg 
body(matchArg)[[c(4, 3, 2, 3)]] <- quote(return(arg[2L])) 

今、私たちはcenterの内側に私たちの新しいmatchArg機能をmatch.argを交換し、私たちは今、第二を取得しますデフォルト(中央値)。

center <- function(x, type = c("mean", "median", "trimmed")) { 
    type <- matchArg(type) 
    switch(type, 
     mean = mean(x), 
     median = median(x), 
     trimmed = mean(x, trim = .1)) 
} 

values <- c(100, 120, 200) 

center(values) 
# [1] 120 
center(values, "mean") 
# [1] 140 

もちろん、これは可視性の要件を満たしていません。しかしそれは考えです。私も(私の質問では、オプションの願いだった)関数シグネチャにデフォルト値に注釈を付けるための方法を発見したmatch.argを変更する方法を示しました@RichScrivenの受け入れ答えに

+0

可視性はオプションです。私のトップ1のお気に入りは、 'match.arg'を修正し、デフォルト値を指定するためのパラメータを追加することでした。そのような洗練されたプログラミング方法を示すためのTHX –

+1

@ALL:関数本体のASTを表示するには、 'pryr :: call_tree(body(matchArg))'を使用することができます –

+1

@rich -scriven。これはカッコいい。軽いコーディングポイントとして、 'body(matchArg)[[4]] [[3]] [[2]] [[3]]'をbody(matchArg)に置き換えて、 [[c(4、3、2、3)]] '。もちろん味の問題ですが、文字数は少なくなります。 – lmo

1

感謝。

トリックベクトル要素の名前を使用して、デフォルト値を「注釈」することである。

> values <- c(100, 120, 200) 
> center(values, "median") 
[1] 120 
> center(values, "mean") 
[1] 140 
> center(values) 
[1] 120 

PS:ここでデフォルト値は(注釈付き)は、第2のものである

matchArg <- base::match.arg 
body(matchArg)[[c(4, 3, 2, 3)]] <- quote(
    return(
    if ("default" %in% names(arg)) { 
     arg[["default"]] } 
    else { 
     arg[[1L]] 
    }) 
) 

center <- function(x, type = c("mean", default = "median", "trimmed")) { 
    type <- matchArg(type) 
    switch(type, 
     mean = mean(x), 
     median = median(x), 
     trimmed = mean(x, trim = .1)) 
} 

。このソリューションは、十分なユーザーがこの機能が必要と思われる場合は、ベースRのパッチに値するでしょう。

関連する問題