大家好,
我正在嘗試創建一個公式或腳本,該公式或腳本將根據表中是否有另一行具有與使用的值匹配的邏輯來為每行設置特定值(“好”、“壞”或“不適用”)當前行作為輸入。
我有一個腳本,在使用完整資料表的一小部分時,透過使用巢狀的 For 循環來完成此操作。然而,對於我嘗試使用的完整資料表(大約 100 萬行),該腳本只會使 JMP 崩潰。
是否有更有效的方法讓 JMP 執行此操作? (或者,如果可以使用 SQL 完成,我可以在將其引入 JMP 之前完成)。
請參閱附件中執行我正在討論的腳本。
在處理數據表時,通常不需要嵌套 for 循環。
您能否提供一小部分數據並在其中包含一個包含您想要的結果的列?
好吧,出於隱私原因,我會模擬數據。
| 可樂 | colB | colC | 日期 | 油菜 | 邏輯 |
| 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 上午 | 動作一 | 不適用 |
| A0002 | 211 | 282 | 2022/04/02 3:15:11 上午 | 動作2 | 壞的 |
| A0002 | 212 | 200 | 2022/04/02 凌晨 3:15:16 | 動作一 | 不適用 |
| 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 是“Action 1”:則分配“N/A”;
否則,如果當前行的 colE 是“Action 2”,則遵循下一段中的邏輯。
如果表中存在另一行,其列 colA 和 colB 的值與當前行的值相同;當前行的 colC 值正好比另一行多 82; colDate 值彼此相差 18 秒以內;當前行的 colE 是“Action 2”,而另一行的 colE 是“Action 1”:然後分配“Good”;否則分配“壞”。
感謝任何幫助! 我現在只是沒有看到沒有嵌套循環的方法。
但我現在至少意識到我應該在原始腳本的第 25 行之後放置一個 Break()。 如果我已經找到至少一個存在,就沒有理由繼續尋找符合我的標準的另一行。
這個腳本中的邏輯過於復雜,因為我不知道數據的所有限制(例如可以有多個匹配項)並且我沒有優化它
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");
