迭代行問題你好,
我非常感謝之前的所有回复,並且每天都在了解越來越多的關於 JSL 的知識。 至此,我已經掌握了基礎知識,並且了解了為了循環,對於每一行和使用公式功能。 這非常有幫助。 正如我在上一篇文章中提到的,我正在處理一個數據集,並且有 4 個關鍵列:
1) PATIENTID:患者編號的唯一值列表
2) VALUE:特定時間點患者評分的值
3) 時間:收集患者評分的時間點
4) PARAM:患者評分由 4 個單獨項目和總分組成(ITEM1、ITEM2、ITEM3、ITEM4 和 TOTAL)。 總分就是ITEM1+ITEM2+ITEM3+ITEM4的總和。
由此,我想創建第五列(稱為“測試”)。 TEST 的值基於以下邏輯:
對於個別患者來說,如果基線值為:
- 總計 > 9 或
- ITEM1、ITEM2、ITEM3 或 ITEM4 中的 1 個 > 3 或
- ITEM1、ITEM2、ITEM3 或 ITEM4 中的 3 個 > 2
那麼“TEST”中的相應行應被評估為“YES”。 非基線值和其他值應評估為“NO”。 該邏輯應該迭代到每個患者和數據表中的每一行。
我在迭代數據集中的行時遇到問題。 原因是每個患者填寫量表的時間點數量不同。 有些患者很早就退出了。 由於每個患者的行數不同,我很難弄清楚如何迭代行來編寫腳本。
我嘗試組合一些 IF 語句,但陷入需要迭代到下一個患者 ID 的位置。 我附上了我寫的腳本,但卡住了。 任何幫助是極大的讚賞。
Names Default To Here( 1 );
dt = current data table ();
dt << New Column ("TEST", Character, Formula(
If(:TIME == "BASELINE",
theRow = Row();
thePatient = :PATIENTID;
If(:PARAM == "TOTAL",
If(N Rows(dt << Get Rows Where(
Row()>=theRow &
thePatient == :PATIENTID &
:VALUE > 9
)
) > 0
,"YES"
,"NO"
)))
));這是數據表的示例(出於隱私考慮,對真實患者信息進行了編輯)

回复:迭代行問題謝謝,現在完全有道理了。 感謝您花時間解釋,非常有幫助!
回复:迭代行問題@SrihariGopal ,
您的第一篇文章介紹了公式和 Set Each Value() 如何迭代行。因此,請記住以下幾條信息:
- 邏輯語句被評估為 True 或 False。 True 相當於 1,False 相當於 0
- 假設 x 是一個數值。 JSL 函數 If( x, "YES", "NO" ) 查看 x 的值。 如果 x > 0,則結果為 True(1)=>YES,否則為 False(0)=>NO。
- :TIME == "BASELINE" 是一個返回 1 或 0 的邏輯語句,因此乘法函數將起作用,而不是使用“AND”(&)。 換句話說,TIME 必須等於 BASELINE,並且其中一條規則必須為真,即 1*1 = 1。 如果其中一個為假,則結果為零或為假。
- 外部 Maximum() 函數有 3 個參數,即 3 個規則。 該最大值函數取代了“OR”(|)。 如果 3 個規則全部為 false,則外部最大值返回 0。 如果 3 個規則中的任何一個返回 1 (True),則最大值返回 1。 但請記住,此結果具有邏輯乘數,因此這只適用於 BASELINE 值。
- 關於規則:規則 #1 ( :TOTAL > 9 ) 返回 1 或 0。規則 #2 查找 4 項中的最大值,如果大於 3,則至少有一項大於 3。 規則 #3 是 4 個邏輯結果的總和(項目 1 >2 等)。如果該總和大於 2,則其中 3 或 4 個項目大於 2。
對邏輯語句使用算術可以更輕鬆、更快速地找到滿足“k of n”規則的案例。 還有其他方法,例如連接 4 個 ITEM 並檢查它們是否在 {“0111”、“1011”、“1101”、“1110”} 中,或者將它們設為數字並查找這些值。但總和只需要一張支票(>2)。由於我對規則 #3 使用算術,所以我使用數學函數 Maximum() 而不是 OR,並用乘法而不是 AND 來處理剩餘的邏輯。請注意,您可以使用將邏輯函數與數學函數混合的語句。
希望有幫助。
回复:迭代行問題太感謝了! 這非常有效。
我正在閱讀劇本,我想知道你是否可以再解釋一下。 MAXIMUM 函數在這種情況下如何工作? 我了解您最多正在尋找 3 條規則。 但是我看到 * 運算符,我認為它意味著乘法。 我對乘法與 MAXIMUM 函數如何在 IF 語句中一起工作感到困惑。
非常感謝!回复:迭代行問題@SrihariGopal ,
你說過你的目標是
對於個別患者來說,如果基線值為:
- 總計 > 9 或
- ITEM1、ITEM2、ITEM3 或 ITEM4 中的 1 個 > 3 或
- ITEM1、ITEM2、ITEM3 或 ITEM4 中的 3 個 > 2
那麼“TEST”中的相應行應被評估為“YES”。 非基線值和其他值應評估為“NO”。 該邏輯應該迭代到每個患者和數據表中的每一行。
可以在堆疊表中完成複雜的規則,但它們會變得混亂。 如果表按照 PATIENTID 和 TIME 進行堆疊,其中規則由 PARAM 應用,則管理起來會容易得多。 如果表非常大,此方法可能效率不高。
附件是您的示例表,其中包含兩個附加 PATIENTID,用於測試這 3 條規則。在使用附加腳本之前,您應該檢查公式是否充分捕獲了您的 3 條規則。 我添加了評論欄和顏色以方便檢查。

拆分後,以下是三個規則 TEST 列的公式。 該腳本還包括用於取消堆疊和重新組織表的 JSL 代碼。
dt_split:TEST << Set Each Value(
If(
(:TIME == "BASELINE") *
Maximum(
:TOTAL > 9, //rule 1
Maximum( :ITEM1, :ITEM2, :ITEM3, :ITEM4 ) > 3, //rule 2
(:ITEM1 > 2) + (:ITEM2 > 2) + (:ITEM3 > 2) + (:ITEM4 > 2) >= 3 //rule 3
),
"YES",
"NO"
));
。