Pregunta sobre iteración a través de filasHola,
Estoy muy agradecido por todas las respuestas anteriores y cada día aprendo más sobre JSL. En este punto, me siento cómodo con los conceptos básicos y he aprendido sobre Para bucles, Por cada fila y uso de la Fórmula función. Esto fue muy útil. Como mencioné en mi publicación anterior, estoy trabajando en un conjunto de datos y tengo 4 columnas clave:
1) PATIENTID: lista de valores únicos para el número de paciente
2) VALOR: Valor de la calificación de un paciente en un momento determinado
3) HORA: Momento en el que se recopiló la calificación del paciente
4) PARAM: La calificación del paciente se compone de 4 elementos individuales y una puntuación total (ITEM1, ITEM2, ITEM3, ITEM4 y TOTAL). La puntuación total es simplemente una suma de ITEM1+ITEM2+ITEM3+ITEM4.
A partir de esto, me gustaría crear una quinta columna (llamada "PRUEBA"). El valor de TEST se basa en la siguiente lógica:
Para un paciente individual, si base los valores son:
- TOTAL > 9 o
- 1 de ITEM1, ITEM2, ITEM3 o ITEM4 son > 3 o
- 3 de ITEM1, ITEM2, ITEM3 o ITEM4 son > 2
Entonces la fila correspondiente en "PRUEBA" debería evaluarse como "SÍ". Los valores no iniciales y otros valores deben evaluarse como "NO". Esta lógica debe repetirse para cada paciente y cada fila de la tabla de datos.
Tengo problemas para recorrer las filas de mi conjunto de datos. La razón es que cada paciente tiene un número diferente de momentos en los que completó la escala. Algunos pacientes abandonaron temprano. Dado que cada paciente tiene un número diferente de filas, tengo dificultades para descubrir cómo recorrer las filas para escribir el guión.
Intenté combinar algunas declaraciones IF, pero me quedé atascado en el punto en el que necesito iterar hasta el siguiente ID de paciente. Adjunto un guión que escribí, pero me quedé atascado. Cualquier ayuda es muy apreciada.
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"
)))
));A continuación se muestra un ejemplo de cómo se ve la tabla de datos (información real del paciente redactada por motivos de privacidad)

Re: Pregunta sobre iteración a través de filasGracias, ahora tiene mucho sentido. Gracias por tomarte el tiempo de explicar, ¡¡muy útil!!
Re: Pregunta sobre iteración a través de filas@SrihariGopal ,
Su primera publicación le indicó cómo las fórmulas y Set Each Value() se itera a través de las filas.Así que aquí hay algunos datos a tener en cuenta:
- Las declaraciones lógicas se evalúan como Verdaderas o Falsas. Verdadero equivale a 1 y Falso equivale a cero
- Supongamos que x es un valor numérico. La función JSL If( x, "YES", "NO" ) analiza el valor de x. Si x > 0, entonces el resultado es True(1)=>YES, de lo contrario False(0)=>NO.
- :TIME == "BASELINE" es una declaración lógica que devuelve un 1 o un 0, por lo que en lugar de utilizar un "Y" (&), la función de multiplicación funcionará. En otras palabras, el TIEMPO debe ser igual a la LÍNEA BASE y una de las reglas debe ser verdadera, es decir, 1*1 = 1. Si cualquiera de ellos es falso, el resultado es cero o falso.
- La función externa Maximum() tiene 3 argumentos, las 3 reglas. Esta función máxima reemplaza "O" ( | ). Si las 3 reglas son falsas, el máximo externo devuelve un 0. Si cualquiera de las 3 reglas devuelve un 1 (Verdadero), entonces el Máximo devuelve un 1. Pero tenga en cuenta que este resultado tiene el multiplicador lógico, por lo que esto solo se aplica a los valores BASELINE.
- Con respecto a las reglas: la regla n.° 1 ( :TOTAL > 9 ) devuelve un 1 o 0. La regla n.° 2 encuentra el máximo de los 4 elementos, si es mayor que 3, entonces al menos un elemento es mayor que 3. La regla número 3 es la suma de 4 resultados lógicos (ELEMENTO 1 > 2, etc.). Si esa suma es mayor que 2, entonces 3 o 4 de los elementos son mayores que 2.
El uso de la aritmética en declaraciones lógicas hace que sea más fácil y rápido encontrar casos que satisfagan las reglas "k de n". Hay otros métodos como concatenar los 4 ITEMs y comprobar si están en { "0111", "1011", "1101", "1110"} o hacerlos numéricos y buscar esos valores.Pero la suma requiere sólo una verificación (>2).Como estaba usando aritmética para la regla número 3, usé funciones matemáticas, Máximo() en lugar de O, y multipliqué en lugar de Y para la lógica restante.Tenga en cuenta que puede tener declaraciones que combinen funciones lógicas con funciones matemáticas.
Espero que ayude.
Re: Pregunta sobre iteración a través de filas¡Muchas gracias! Esto funcionó perfectamente.
Estoy leyendo el guión y me preguntaba si podrías explicar un poco más. ¿Cómo funciona la función MÁXIMO en este contexto? Entiendo que buscas un máximo de las 3 reglas. Sin embargo, veo el operador *, que supongo que significa multiplicación. Estaba confundido sobre cómo la multiplicación junto con la función MÁXIMO funcionan juntas en la declaración IF.
¡Muchas gracias!Re: Pregunta sobre iteración a través de filas@SrihariGopal ,
Dijiste que tu objetivo era
Para un paciente individual, si base los valores son:
- TOTAL > 9 o
- 1 de ITEM1, ITEM2, ITEM3 o ITEM4 son > 3 o
- 3 de ITEM1, ITEM2, ITEM3 o ITEM4 son > 2
Entonces la fila correspondiente en "PRUEBA" debería evaluarse como "SÍ". Los valores no iniciales y otros valores deben evaluarse como "NO". Esta lógica debe repetirse para cada paciente y cada fila de la tabla de datos.
Se pueden hacer reglas complejas en una tabla apilada, pero se vuelven confusas. Es mucho más fácil de administrar si la tabla se desapila mediante PATIENTID y TIME, donde las reglas se aplican mediante PARAM. Si la tabla es extremadamente grande, es posible que este método no sea eficaz.
Se adjunta una tabla de ejemplo con dos PATIENTID adicionales para probar estas 3 reglas.Antes de utilizar el script adjunto, debes comprobar si la fórmula captura adecuadamente tus 3 reglas. Agregué una columna de comentarios y colores para que sea más fácil de verificar.

Una vez dividida, aquí está la fórmula para la columna PRUEBA de tres reglas. El script también incluye el código JSL para desapilar y reorganizar la tabla.
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"
));
.