こんにちは、
現在の行を入力として使用するロジックに一致する値を持つ別の行がテーブル内に存在するかどうかに基づいて、各行に特定の値 (「良好」、「不良」、または「N/A」) を設定する数式またはスクリプトを作成しようとしています。
完全なデータテーブルの小さなサブセットを使用するときに、ネストされた For ループを使用してこれを実行するスクリプトがあります。ただし、約 100 万行ある完全なデータテーブルを使用しようとしているため、スクリプトによって JMP がクラッシュしてしまいます。
JMP でこれを実行できるようにするためのより効率的な方法はありますか? (または、SQL で実行できる場合は、JMP に取り込む前に実行できます)。
私が話していることを実行するスクリプトについては、添付を参照してください。
通常、データ テーブルを操作する場合、for ループをネストする必要はありません。
データの小さなサブセットを提供し、必要な結果を含む列を含めることができますか?
わかりました、プライバシー上の理由から、データをモックアップします。
| コーラ | colB | コルC | 日付 | コール | 論理 |
| A0001 | 16 | 100 | 2022/04/01 9:15:01 午前 | アクション1 | なし |
| A0001 | 100 | 182 | 2022/04/01 9:15:31 午前 | アクション2 | 良い |
| A0001 | 100 | 100 | 2022/04/01 9:15:36 午前 | アクション1 | なし |
| A0002 | 212 | 200 | 2022/04/02 3:15:21 午前 | アクション1 | なし |
| A0002 | 211 | 282 | 2022/04/02 3:15:11 午前 | アクション2 | 悪い |
| A0002 | 212 | 200 | 2022/04/02 3:15:16 午前 | アクション1 | なし |
| A0003 | 441 | 382 | 2022/05/01 1:15:31 午前 | アクション2 | 悪い |
| A0004 | 441 | 382 | 2022/05/01 5:16:31 午前 | アクション2 | 悪い |
| A0004 | 441 | 300 | 2022/05/01 5:15:31 午前 | アクション1 | なし |
元のスクリプトのロジックが明確でない場合:
現在の行の colE が「アクション 1」の場合: 次に「N/A」を割り当てます。
それ以外の場合、現在の行の colE が「アクション 2」の場合は、次の段落のロジックに従います。
列 colA および colB の現在の行と同じ値を持つ別の行がテーブルに存在する場合。現在の行の colC 値は、この他の行よりも正確に 82 大きくなります。 colDate 値は互いに 18 秒以内です。現在の行の colE は「アクション 2」で、この別の行の colE は「アクション 1」です。次に、「Good」を割り当てます。それ以外の場合は、「悪い」を割り当てます。
どんな助けにも感謝します! 現時点では、ネストされたループのない方法は見当たりません。
しかし、少なくとも、元のスクリプトの 25 行目の後に Break() を配置する必要があることに気付きました。 少なくとも 1 つ存在することが既にわかっている場合、基準に一致する別の行を探し続ける理由はありません。
このスクリプトのロジックは非常に複雑です。データの制限をすべて把握しているわけではなく (たとえば、複数の一致が存在する可能性がある)、最適化もしていません。
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(9),
Compress File When Saved(1),
New Column("colA", Character, "Nominal", Set Values({"A0001", "A0001", "A0001", "A0002", "A0002", "A0002", "A0003", "A0004", "A0004"})),
New Column("colB", Numeric, "Continuous", Format("Best", 9), Set Values([16, 100, 100, 212, 211, 212, 441, 441, 441])),
New Column("colC", Numeric, "Continuous", Format("Best", 9), Set Values([100, 182, 100, 200, 282, 200, 382, 382, 300])),
New Column("colDate",
Character(22),
"Nominal",
Set Values(
{" 2022/04/01 9:15:01 AM", " 2022/04/01 9:15:31 AM", " 2022/04/01 9:15:36 AM", " 2022/04/02 3:15:21 AM", " 2022/04/02 3:15:11 AM",
" 2022/04/02 3:15:16 AM", " 2022/05/01 1:15:31 AM", " 2022/05/01 5:16:31 AM", " 2022/05/01 5:15:31 AM"}
)
),
New Column("colE",
Character(16),
"Nominal",
Set Values({"Action1", "Action2", "Action1", "Action1", "Action2", "Action1", "Action2", "Action2", "Action1"})
),
New Column(" Logic", Character(16), "Nominal", Set Values({" N/A", " Good", " N/A", " N/A", " Bad", " N/A", " Bad", " Bad", " N/A"}))
);
dt << New Column("Group", Character, Nominal, << Set Each Value(char(:colA)||char(:colB)));
//fix date
Column(dt, "colDate") << Set Each Value(Substitute(:colDate, " AM", "")) << Data Type(Numeric);
dt << New Column("Logic", Character, Nominal, << Set Each Value(
As Constant(
m_group = :Group << get values;
m_c = :colC << get values;
m_date = :colDate << get values;
);
If(:colE == "Action1",
"N/A";
, :colE == "Action2",
cur_group_idx = Loc(m_group, :Group);
If(N Items(cur_group_idx) == 0,
"Bad"
,
plus_idx = cur_group_idx[Loc(:colC - 82 == m_c[cur_group_idx])];
If(N Items(plus_idx) == 0,
"Bad"
,
timediff_idx = Loc(Abs(m_date[plus_idx] - :colDate) <= 18);
If(N Items(timediff_idx) > 0,
If(:colE == "Action2" & :colE[timediff_idx[1]] == "Action1",
"Good"
,
"Bad"
)
,
"Bad"
);
)
);
,
"Bad";
);
));
dt << Delete Column("Group");
