Domanda sull'iterazione delle righeCiao,
Sono molto grato per tutte le risposte precedenti e ogni giorno imparo sempre di più su JSL. A questo punto, mi sento a mio agio con le nozioni di base e ho imparato Per loop, Per ogni riga e l'uso del Formula funzione. Questo è stato molto utile. Come ho accennato nel mio post precedente, sto lavorando su un set di dati e ho 4 colonne chiave:
1) PAZIENTE: elenco di valori univoci per il numero del paziente
2) VALORE: valore della valutazione di un paziente in un particolare momento
3) TEMPO: punto temporale in cui è stata raccolta la valutazione del paziente
4) PARAM: la valutazione del paziente è composta da 4 elementi individuali e un punteggio totale (ITEM1, ITEM2, ITEM3, ITEM4 e TOTAL). Il punteggio totale è semplicemente la somma di ITEM1+ITEM2+ITEM3+ITEM4.
Da questo, vorrei creare una quinta colonna (chiamata "TEST"). Il valore di TEST si basa sulla seguente logica:
Per un singolo paziente, se linea di base i valori sono:
- TOTALE > 9 o
- 1 di ITEM1, ITEM2, ITEM3 o ITEM4 sono > 3 o
- 3 di ITEM1, ITEM2, ITEM3 o ITEM4 sono > 2
Quindi la riga corrispondente in "TEST" dovrebbe essere valutata come "SÌ". I valori non basali e gli altri valori devono essere valutati come "NO". Questa logica dovrebbe essere ripetuta per ogni paziente e ogni riga nella tabella dati.
Ho problemi a scorrere le righe nel mio set di dati. Il motivo è che ciascun paziente ha un numero diverso di punti temporali in cui ha compilato la scala. Alcuni pazienti hanno abbandonato presto. Poiché ogni paziente ha un numero diverso di righe, ho difficoltà a capire come scorrere le righe per scrivere lo script.
Ho provato a combinare alcune istruzioni IF, ma rimango bloccato nel punto in cui devo ripetere l'ID paziente successivo. Allego uno script che ho scritto, ma sono rimasto bloccato. Qualsiasi aiuto è molto apprezzato.
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"
)))
));Ecco un esempio di come appare la tabella dati (informazioni reali del paziente oscurate per motivi di privacy)

Re: Domanda sull'iterazione delle righeGrazie, adesso ha perfettamente senso. Grazie per aver dedicato del tempo alla spiegazione, molto utile!!
Re: Domanda sull'iterazione delle righe@SrihariGopal ,
Il tuo primo post ti spiega come le formule e Set Each Value() scorrono le righe.Ecco quindi alcune informazioni da tenere a mente:
- Le affermazioni logiche vengono valutate come Vere o False. Vero equivale a 1 e Falso equivale a zero
- Supponiamo che x sia un valore numerico. La funzione JSL If( x, "YES", "NO" ) esamina il valore di x. Se x > 0, il risultato è True(1)=>YES , altrimenti False(0)=>NO.
- :TIME == "BASELINE" è un'istruzione logica che restituisce 1 o 0, quindi invece di utilizzare un "AND" (&), la funzione di moltiplicazione funzionerà. In altre parole, TIME deve essere uguale a BASELINE e una delle regole deve essere vera, ovvero 1*1 = 1. Se uno dei due è falso, il risultato è zero o falso.
- La funzione esterna Maximum() ha 3 argomenti, le 3 regole. Questa funzione massima sostituisce "OR" ( | ). Se tutte e tre le regole sono false, il massimo esterno restituisce 0. Se una qualsiasi delle 3 regole restituisce 1 (Vero), allora il Massimo restituisce 1. Ma tieni presente che questo risultato ha il moltiplicatore logico, quindi si applica solo ai valori BASELINE.
- Per quanto riguarda le regole: la regola n. 1 ( :TOTAL > 9 ) restituisce 1 o 0. La regola n. 2 trova il massimo dei 4 elementi, se è maggiore di 3, almeno un elemento è maggiore di 3. La regola n. 3 è la somma di 4 risultati logici (ITEM 1 >2, ecc.). Se tale somma è maggiore di 2, allora 3 o 4 degli elementi sono maggiori di 2.
L'uso dell'aritmetica sulle affermazioni logiche rende più facile e veloce trovare casi che soddisfano le regole "k di n". Esistono altri metodi come concatenare i 4 ITEM e controllare se sono in { "0111", "1011", "1101", "1110"} o renderli numerici e cercare quei valori.Ma la somma richiede un solo controllo (>2).Dato che stavo usando l'aritmetica per la regola n. 3, ho usato le funzioni matematiche, Massimo() invece di OR e moltiplicato invece di AND per la logica rimanente.Nota che puoi avere istruzioni che mescolano funzioni logiche con funzioni matematiche.
Spero che aiuti.
Re: Domanda sull'iterazione delle righeGrazie mille! Ha funzionato perfettamente.
Sto leggendo la sceneggiatura e mi chiedevo se potessi spiegarmi qualcosa in più. Come funziona la funzione MASSIMO in questo contesto? Capisco che stai cercando un massimo di 3 regole. Tuttavia vedo l'operatore *, che presumo significhi moltiplicazione. Ero confuso su come la moltiplicazione insieme alla funzione MASSIMO funzionano insieme nell'istruzione IF.
Grazie molto!Re: Domanda sull'iterazione delle righe@SrihariGopal ,
Hai dichiarato che il tuo obiettivo era
Per un singolo paziente, se linea di base i valori sono:
- TOTALE > 9 o
- 1 di ITEM1, ITEM2, ITEM3 o ITEM4 sono > 3 o
- 3 di ITEM1, ITEM2, ITEM3 o ITEM4 sono > 2
Quindi la riga corrispondente in "TEST" dovrebbe essere valutata come "SÌ". I valori non basali e gli altri valori devono essere valutati come "NO". Questa logica dovrebbe essere ripetuta per ogni paziente e ogni riga nella tabella dati.
È possibile eseguire regole complesse in una tabella impilata, ma diventano confuse. È molto più semplice da gestire se la tabella viene disimpilata da PATIENTID e TIME, dove le regole vengono applicate da PARAM. Se la tabella è estremamente grande questo metodo potrebbe non essere efficiente.
In allegato c'è la tua tabella di esempio con due PATIENTID aggiuntivi per testare queste 3 regole.Prima di utilizzare lo script allegato, dovresti verificare se la formula cattura adeguatamente le tue 3 regole. Ho aggiunto una colonna di commenti e colori per semplificare il controllo.

Una volta divisa, ecco la formula per la colonna TEST delle tre regole. Lo script include anche il codice JSL per disimpilare e riorganizzare la tabella.
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"
));
.