2017-12-01 2 views
1

これは、前の質問へのフォローアップhereです。各条件を合格および不合格とする観測結果を集計します。

私は次のようなデータを持っている:

set.seed(1) 
dt <- data.table(ID=1:10, Status=c(rep("OUT",2),rep("IN",2),"ON",rep("OUT",2),rep("IN",2),"ON"), 
       t1=round(rnorm(10),1), t2=round(rnorm(10),1), t3=round(rnorm(10),1), 
       t4=round(rnorm(10),1), t5=round(rnorm(10),1), t6=round(rnorm(10),1), 
       t7=round(rnorm(10),1),t8=round(rnorm(10),1)) 

    ID Status t1 t2 t3 t4 t5 t6 t7 t8 
1: 1 OUT -0.6 1.5 0.9 1.4 -0.2 0.4 2.4 0.5 
2: 2 OUT 0.2 0.4 0.8 -0.1 -0.3 -0.6 0.0 -0.7 
3: 3  IN -0.8 -0.6 0.1 0.4 0.7 0.3 0.7 0.6 
4: 4  IN 1.6 -2.2 -2.0 -0.1 0.6 -1.1 0.0 -0.9 
5: 5  ON 0.3 1.1 0.6 -1.4 -0.7 1.4 -0.7 -1.3 
6: 6 OUT -0.8 0.0 -0.1 -0.4 -0.7 2.0 0.2 0.3 
7: 7 OUT 0.5 0.0 -0.2 -0.4 0.4 -0.4 -1.8 -0.4 
8: 8  IN 0.7 0.9 -1.5 -0.1 0.8 -1.0 1.5 0.0 
9: 9  IN 0.6 0.8 -0.5 1.1 -0.1 0.6 0.2 0.1 
10: 10  ON -0.3 0.6 0.4 0.8 0.9 -0.1 2.2 -0.6 

私はcsvファイルから読み込まれdtに制約が適用されます。

dt_constraints <- data.table(columns=c("t1","t3","t7","t8"), operator=c(rep(">=",2),rep("<=",2)), 
          values=c(-.6,-.5,2.4,.5)) 

    columns operator values 
1 t1  >=   -0.6 
2 t3  >=   -0.5 
3 t7  <=   2.4 
4 t8  <=   0.5 

@akrunは非常に効率的なソリューションを提供

dt[eval(parse(text=do.call(paste, c(dt_constraints, collapse= ' & '))))] 

さらに2つの情報ビットが必要です:観測数各制約に合格し、各制約に失敗する観測数が渡されます。出力は次のようになります。

columns operator values obs_pass obs_fail 
1 t1  >=   -0.6  8   2 
2 t3  >=   -0.5  8   2 
3 t7  <=   2.4  10  0 
4 t8  <=   0.5  9   1 

すべてのアイデアは大歓迎です。ありがとう。私はそれを行うためのより良い方法があると思いますけれども

dt_constraints[, onexpr := sprintf("%s%sv", columns, operator)] 

dt_constraints[, n_pass := dt[.(v = values), on=onexpr, .N, by=.EACHI]$N, by=onexpr] 
dt_constraints[, n_fail := nrow(dt) - n_pass ] 

by=.EACHIは、あなたが複数の異なるvaluesと同じonexprを使用できるようにする必要があります。

答えて

3

あなたは行ごとに参加on=表現を構築して行うことができます。 onexprが一意である場合は、...

dt_constraints[, n_pass := dt[.(v = values), on=onexpr, .N], by=onexpr] 
dt_constraints[, n_fail := nrow(dt) - n_pass ] 

は、このアプローチを使用して一度にすべての制約にフィルタリングするには代わりがあります:*

n_grp = nrow(dt_constraints) 
w = seq_len(nrow(dt)) 
dt[dt_constraints[, { 
    w <- w[dt[w][.(v = values), on=onexpr, which=TRUE]] 
    if (.GRP == n_grp) w 
}, by=onexpr]$V1] 

    ID Status t1 t2 t3 t4 t5 t6 t7 t8 
1: 1 OUT -0.6 1.5 0.9 1.4 -0.2 0.4 2.4 0.5 
2: 2 OUT 0.2 0.4 0.8 -0.1 -0.3 -0.6 0.0 -0.7 
3: 5  ON 0.3 1.1 0.6 -1.4 -0.7 1.4 -0.7 -1.3 
4: 7 OUT 0.5 0.0 -0.2 -0.4 0.4 -0.4 -1.8 -0.4 
5: 9  IN 0.6 0.8 -0.5 1.1 -0.1 0.6 0.2 0.1 
6: 10  ON -0.3 0.6 0.4 0.8 0.9 -0.1 2.2 -0.6 

これは、行のみをチェックし、ループのような繰り返し動作します(w)、それ以前の制約が保持されます。

*それは意味がありませんので、..あなたが最初<=ため>=と分間最大valuesonexprごとにフィルタリングすることができ、何の繰り返しonexprを想定していません。


OPからのフォローの質問:

がどのように実行するコードを変更するであろう以下:(1)第1の制約のためにカウントをパス/フェイルを与えます。 (2)第1の制約からパスによってサブセット化されたデータを使用して、第2の制約の合格/不合格数を与える。 (3)第2の制約からパスでサブセットのデータを使用して、コードが完全に動作失敗/等

# iteratively count pass/fail 
w = seq_len(nrow(dt)) 
dt_constraints[, { 
    w0 <- w 
    w <- w[dt[w][.(v = values), on=onexpr, which=TRUE]] 
    .(n_pass = length(w), n_fail = length(w0) - length(w)) 
}, by=onexpr] 
+0

、第三の制約のパス数をパス/フェイルを与えます。本当にありがとう。どのようにしてコードを変更して、次のことを実行しますか?(1)最初の制約の合格/不合格数を指定する。 (2)第1の制約からパスによってサブセット化されたデータを使用して、第2の制約の合格/不合格数を与える。 (3)第2の制約からのパスによってサブセット化されたデータを使用して、第3の制約などの合格/不合格数を与える。出力は、質問に示されているように見えるが、新しい方法論に従って異なる合格/ 。 – FG7

+0

@ FG7ループのいくつかの変更はうまくいくようです。私は今8 6 6 6パスを見る。チャットで投稿しましたhttps://chat.stackoverflow.com/rooms/25312/r-public不明な点がある場合は、ここにお知らせください。 – Frank

+0

フランクは、私のコメントで尋ねたことを正確に実行するこのコードを提供しました: 'dt_constraints [、onexpr:= sprintf("%s%sv "、columns、operator) dt_constraints); w = seq_len(nrow(dt)); 。(n_pass =長さ(w)、n_fail =長さ、長さ(w)、長さ(w)、長さ(w0) - 長さ(w)) }、by = onexpr] ' – FG7

関連する問題