2011-05-12 3 views
3

私の仕事の多くは、結核診断テストを中心に展開されています。ご想像のとおり、これらのテストの出力をすばやく評価して検証できることは便利です。私はちょうどそれを行う関数、hereを書きました(分かりやすくするためにまとめてあります)。一言で言えば、それはテストの数値結果を取り、製造業者指定の解釈を生成する。Rのネストされたifで一連の基準を評価すると良い方法がありますか?

この機能は私にとってうまくいきます。私は何千ものテストに対してそれを検証しました。しかし私は、それと普及のためのパッケージに同様の機能のカップルをバンドルしたい、と私は私がそうする前に、その上にいくつかのフィードバックを取得したいのですが:

  1. 機能が依存しますネストされたif-else関数を囲むループにとっては非常に大きなものです。それは特にエレガントではなく、畏敬の念を浮かべて間違いなく私の信頼性が損なわれますが、それはうまくいきます。これにはより良いアプローチがありますか?もしそうなら、コード・ザ・ワークスの書き直しを保証することは十分に良いでしょうか?

  2. 上記の機能の基準は、北米でのテストの解釈です。世界の残りの部分はわずかに異なる基準に従います。私はそれらも利用できるようにしたいと思います。私は、それぞれに別々の、エクスポートされていない機能を持つことを検討しています。上記の要点から除外されたさまざまなデータチェックはmain関数に存続し、指定されたサブ関数を呼び出すことになります。それは合理的に聞こえるか?

  3. その他のアドバイスやアドバイスはありますか?スタイル、コード構成 - 何でも。

私はおそらくちょうど巣の外に、この赤ちゃんの鳥をプッシュする必要があります実現が、私は、真空中で主に働くので、少し緊張しています。アドバイスをいただければ幸いです。

編集:要点へのリンクを逃した場合、this is the function I'm talking about


要求通り、sample test data

+0

潜在的に変化する基準8、.25などのハードコーディングされた値ですか?または、例えば、中間?または、他の何か? – geoffjentry

+0

サンプルデータと期待される結果を投稿して、変更内容をテストできますか? – Andrie

+0

実際には、グローバル基準を見てからしばらくしています。それは、北米に特有の基準の最後のセット(23〜26行目)のようです。それはオンとオフを切り替えるだけで簡単になります。しかし、私は異なるグループ(例えば、免疫無防備状態の患者)のための他の基準のセット、または研究で開発された代替基準を追加したいと思うかもしれません。 –

答えて

4

編集コメントが反映されるようにし、あなたは完全にループまたはifのいずれかのタイプを避け、単にRベクトルの添字を使用することができ、テストデータ

に対して検証する:

qft.interp <- function(nil, tb, mitogen, tbnil.cutoff = 0.35){ 

    # Set a tolerance to avoid floating point comparison troubles. 
    tol <- .Machine$double.eps^0.5 

    # Set up the results vector 
    result <- rep(NA, times = length(nil)) 
    result[nil+tol > 8.0] <- "Indeterminate" 
    result[is.na(result) & (tb-nil+tol > tbnil.cutoff) & 
      (tb-nil+tol > .25*nil)] <- "Positive" 
    result[is.na(result) & (tb-nil+tol < tbnil.cutoff | tb-nil+tol < .25*nil) & 
     !(mitogen-nil+tol < 0.5)] <- "Negative" 
    result[is.na(result) & ((tb-nil+tol < tbnil.cutoff | tb-nil+tol < .25*nil) & 
      mitogen-nil+tol < 0.5)] <- "Indeterminate" 
    result 
} 

all(with(tests, qft.interp(nil, tb, mitogen)) == tests$interp) 

[1] TRUE 
+0

サンプルデータが追加されました!提案していただきありがとうございます。 –

+3

完全にベクトル化されたソリューションを得るためには、それらのインスタンスの一部を切り取る必要があると思いますが、これが最もクリーンな方法であると私は同意します。コメントではうまくいかない、私の下の行を見てください。 –

+0

このアプローチの問題は、後の基準で以前のデータを上書きできることです。たとえば、nil = 9.41、tb = 6.73、mitogen = 10のサンプルデータにテストがあります。後で否定に変わった。オリジナルの 'if()'フローはこれを防ぎます。 –

1

forループを使用しない場合は、applyを使用して解釈を返します。

+0

これだけで私はこれを投稿してうれしいです。私はいつもいつも忘れています... –

+2

'apply'は' for'のちょっとした形ですが、通常はそれほど高速ではありません。 – Henry

+0

そう、私はそれを忘れる傾向があります。とにかくスピードはここではあまり意味がありません。すでに十分速いです。しかし、かなり良いです。 –

4
result[ nil + (tol > 8.0)] <- "Indeterminate" 
result[(tb - nil + (tol > tbnil.cutoff)) & (tb - nil + (tol > .25 * nil))] <- "Positive" 
result[ (tb - nil + (tol < tbnil.cutoff))| (tb - nil + (tol < .25 * nil)) & 
         !(mitogen - nil + tol < 0.5) ] <- "Negative" 
result[ (tb - nil + (tol < tbnil.cutoff)) | (tb - nil + (tol < .25 * nil)) & 
          (mitogen - nil + (tol < 0.5)) ] <- "Indeterminate" 
+0

あなたのコメントをありがとう。 Matt ParkerのコメントはMECEではないので、あなたのテストに '!is.na(result)'を追加するべきだというコメントに注目してください。私の更新された答えを見てください。 – Andrie

+0

@Andrie:それを確認して良かったです。彼らが本当に互いに排他的かどうかは疑問でした。私はコードを強化すると思います(あなたがそれを維持し、デバッグするのをより簡単にするでしょうから)。 –

関連する問題