2016-07-22 32 views
0

私は多くの入力を持つマスターユーザー定義関数を持っています。マスター関数は、ユーザー定義関数を呼び出す。ユーザー定義関数は、入力のより小さいサブセットを使用するたびに、別の関数を呼び出す。マスタ機能からの入力を取得し、各下位レベルの機能を備えた手動Rの呼び出し環境は計算コストがかかりますか?

  1. 、及び
  2. :私は、より低いレベルの機能への入力を通過する二つの方法を思い付きました。

解決策1)は集中的に入力していますが、私は経験豊富なプログラマーが何をするのか疑いがあります。解決策2)はきれいに見えますが、実行にはかなり時間がかかります。だから私は2つの質問がある:A)ソリューション2)はなぜ時間がかかるのですか? B)プログラマによる手作業を減らし、計算上効率的であるこれらのいずれよりも優れたソリューションがありますか?このようなプログラミングのシナリオは、私の生物学の研究と統計的方法のコーディングで私の間に浮かび上がってきたので、私はこれを他の人が解決した共通の問題とみなします。

私は以下の2つの解決策の簡単な例(5つの数字を追加)をタイミングとともに示しました。

# Solution 1) 
f0 <- function(a0,a1,a2,a3,a4){ 
    val <- a0 + f1(a1=a1,a2=a2,a3=a3,a4=a4) 
    return(val) 
} 

f1 <- function(a1,a2,a3,a4){ 
    val <- a1 + f2(a2=a2,a3=a3,a4=a4) 
    return(val) 
} 

f2 <- function(a2,a3,a4){ 
    val <- a2 + f3(a3=a3,a4=a4) 
    return(val) 
} 

f3 <- function(a3,a4){ 
    val <- a3 + f4(a4=a4) 
    return(val) 
} 

f4 <- function(a4){ 
    val <- a4 
    return(val) 
} 

# Solution 2) 

g0 <- function(a0,a1,a2,a3,a4){ 
    vars <- list('a0','a1','a2','a3','a4') 
    env <<- environment() 
    val <- a0 + g1() 
    return(val) 
} 

g1 <- function(){ 
    for (i in get('vars',env)){assign(i,get(i,env),environment())} 
    val <- a1 + g2() 
    return(val) 
} 

g2 <- function(){ 
    for (i in get('vars',env)){assign(i,get(i,env),environment())} 
    val <- a2 + g3() 
    return(val) 
} 

g3 <- function(){ 
    for (i in get('vars',env)){assign(i,get(i,env),environment())} 
    val <- a3 + g4() 
    return(val) 
} 

g4 <- function(){ 
    for (i in get('vars',env)){assign(i,get(i,env),environment())} 
    val <- a4 
    return(val) 
} 

# Timing 
t0 <- Sys.time() 
replicate(1e4, f0(1,2,3,4,5)) 
t1 <- Sys.time() 

tt0 <- Sys.time() 
replicate(1e4, g0(1,2,3,4,5)) 
tt1 <- Sys.time() 

# Time: Solution 1) 
> t1-t0 
Time difference of 0.2921922 secs 

# Time: Solution 2) 
> tt1-tt0 
Time difference of 0.953675 secs 

答えて

2

あなたはlist()という名前の周りを通過、あるいはリストに基づいて独自のクラスを作成することができます。これは、ほとんどのモデルがRでどのように動作するのか、多かれ少なかれ:lmオブジェクトは大きなリストであり、オブジェクトのどの部分でも使用する多くの関数(predictsummarycoefAICplotなど)必要。

# Solution 4) 
h0 <- function(arg_list){ 
arg_list$a0 + h1(arg_list) 
} 

h1 <- function(arg_list){ 
    arg_list$a1 + h2(arg_list) 
} 

h2 <- function(arg_list){ 
    arg_list$a2 + h3(arg_list) 
} 

h3 <- function(arg_list) { 
    arg_list$a3 + h4(arg_list) 
} 

h4 <- function(arg_list) { 
    arg_list$a4 
} 


h0(list(a0 = 1, a1 = 2, a2 = 3, a3 = 4, a4 = 5)) 
# [1] 15 

これは、正確な依存性についてあまり心配する必要がないという利点があります。 h2h3を呼び出し、h3を編集してリストの別の部分を使用すると、オブジェクト全体を渡しているので、正しい引数を渡すためにh2を編集する必要はありません。

それはあなたの代わりにsummary(my_model)の、概要と他には何によって使用されているモデルの正確に作品をsummary.lmを呼び出す必要があった場合は、半数以上summary(rank = my_model$rank, resid = my_model$residuals, df_resid = my_model$df.residuals, w = my_mod$weights, ...)と上と上の必要があると思いますでしょうか迷惑な想像モデルの要素!

0

一般的に、ソリューション1は、それぞれの機能が想定されていることを明確にしているため、維持管理が簡単です。将来あなたのコードを理解するのにかかる時間は少なくなります。

一般的な「最良の」解決策は難しい。この場合は、たったのa1 + a2 + a3 + a4 + a5ですが、実際の機能と相互作用の仕方がソリューションに大きな影響を及ぼします。

なぜソリューション2がそれほど時間がかかるのかについては、単に環境内で変数を参照するだけでなく、多くの取得と割り当てを行っています。

また、varsが環境envに保存されていないため、機能しているとは思われません。

あなたは、このようなグローバル環境の中で変数を格納考えることができます:

a1 <- 1 
a2 <- 2 
a3 <- 4 
a4 <- 8 


h1 <- function(){ 
    a1 + h2() 
} 

h2 <- function(){ 
    a2 + h3() 
} 

h3 <- function(){ 
    a3 + h4() 
} 

h4 <- function(){ 
    a4 
} 

h1() 
+0

'vars'は' g0'の実行環境に格納されていたことがわかりました。これは私が進めていたものです。 'env << - environment()'の後に 'print(ls(env))'コマンドを含めてチェックしました。私はそれが '<< - 'が 'g0'の呼び出し環境に到達し、' g0'の実行環境の名前を変更するためだと思います。あなたが示唆したように地球環境に 'vars'を置いたほうが簡単ですが、私の実際の問題(他の人には役に立たないように)では、私は異なる初期パラメータに対して並列実行しています。お互いをアップ。 – BioBroo

+0

または何か間違っていましたか?私はコマンド 'get( 'vars'、env)を使っているので' vars'が 'env'に格納されていなければ私のコードがうまくいかないことに気付きました。だから私は、あなたが 'env'に格納されていない' vars'の意味を混乱させます。 – BioBroo

2

、後続の関数にパラメータを渡すために使用...:Aについて

f0 <- function(a0, ...){ 
    val <- a0 + f1(...) 
    return(val) 
} 

f1 <- function(a1, ...){ 
    val <- a1 + f2(...) 
    return(val) 
} 

f2 <- function(a2, ...){ 
    val <- a2 + f3(...) 
    return(val) 
} 

f3 <- function(a3, ...){ 
    val <- a3 + f4(...) 
    return(val) 
} 

f4 <- function(a4){ 
    val <- a4 
    return(val) 
} 

f0(1,2,3,4,5) 
#[1] 15 

):各関数呼び出しは、時間がかかります。特にassignはあまり速くないと思います。

+0

この回答にもチェックマークを付けることができたらいいですか?これは私が最も役に立つとマークした答えと同じように役立ちました。 – BioBroo

関連する問題