2

私は、次のような囲み関数を作成しようとしています:

  • 一部のデータを処理し、
  • cat()そのデータの結果、
  • readline()その結果に基づいて (つまり、 経由で)cat()ユーザー入力を要求します。
  • 次に、返された関数の引数のデフォルトの 1 つが によって入力された値である関数を返しますreadline()

さらに、返された関数の引数の残りのデフォルト値をユーザーが解釈できるようにしたいと考えています。つまり、デフォルトを親環境に隠されている変数の名前にしたくありません (この規定により、単純な引数の受け渡しが妨げられます)。arg()具体的には、実際に評価した数値などを返し たいです。

以下にこのソリューションを作成しましたが、扱いにくく、ぎこちなく感じます。これにアプローチするよりエレガントな方法はありますか?

top <- function(year=1990, n.times=NULL){

if(is.null(n.times)){
    ###in the real function, data would be processed here
    ###results would be returned via cat and
    ###the user is prompted return values that reflect a decision
    ###made from the processed data
    n.times <- as.numeric(readline("how many times?"))
}


out <- function(year, n.times){
    ###in the real function, this is where most of the work would happen
    rep(year, n.times)
}

###this entire section below is clunky.
if( !identical( names(formals()), names(formals(out)) ) ){
     stop("internal error: mismatching formals")

}

pass.formals <- setdiff( names(formals()), "n.times")

formals(out)[pass.formals] <- formals()[pass.formals]
formals(out)$n.times <- n.times
out

}

x <- top()
x
4

1 に答える 1

2

私には一般的に問題ないように見えます。私が別の方法で行うことはほんのわずかです。

と のパラメータが何らかの形で対応しているように見えるtop()理由はありますか? out()つまり、identical小切手が必要ですか?よくわからないので、取り出しました。これはあなたが望むことをしているようで、少し短いです:

top <- function(year=1990, n.times=NULL){
    if (is.null(n.times)) {
        n.times <- as.numeric(readline("how many times?"))
    }

    out <- function(year, n.times) {
        rep(year, n.times)
    }

    out.formals = formals(out)
    out.formals['n.times'] = n.times
    formals(out) = out.formals

    out
}

編集:そして、スーパーRマジックを使いたい場合は、次のように書くことができます

top <- function(year=1990, n.times=NULL){
    if (is.null(n.times)) {
        n.times <- as.numeric(readline("how many times?"))
    }

    `formals<-`(
        function() {
            rep(year, n.times)
        },
        value=list(year=alist(x=)$x, n.times=n.times)
    )
}

編集:DWinが提案したようなものを使用することもできます(ただし、それを使用することはできませんでしたsubstitute):

    out = function(year, n.times) {
        rep(year, n.times)
    }
    `formals<-`(out, v=`[[<-`(formals(out), 'n.times', n.times))

または使用bquote

    eval(bquote(
        function(year, n.times=.(n.times)) {
            rep(year, n.times)
        }
    )[-4L])

非常に多くのオプションがあります。

于 2012-06-08T23:08:21.930 に答える