Hola a todos,
Estoy intentando crear una fórmula o secuencia de comandos que establezca un valor determinado ("Bueno", "Malo" o "N/A") para cada fila en función de si hay otra fila en la tabla con valores que coincidan con la lógica que utiliza la fila actual como entrada.
Tengo un script que hace precisamente esto mediante el uso de bucles For anidados cuando uso un pequeño subconjunto de la tabla de datos completa. Sin embargo, con la tabla de datos completa que estoy tratando de usar, que tiene aproximadamente 1 millón de filas, el script simplemente falla JMP.
¿Existe una forma más eficiente de permitir que JMP realice esto? (O si se puede hacer con SQL, puedo hacerlo antes de incorporarlo a JMP).
Vea adjunto el script que hace lo que estoy hablando.
Por lo general, no es necesario anidar bucles for cuando se trabaja con tablas de datos.
¿Podría proporcionar un pequeño subconjunto de sus datos e incluir una columna con los resultados que desea?
De acuerdo, me burlaré de los datos por razones de privacidad.
| reajuste salarial | colB | COLC | fechafría | col | Lógica |
| A0001 | dieciséis | 100 | 2022/04/01 9:15:01 a. m. | Acción1 | N / A |
| A0001 | 100 | 182 | 2022/04/01 9:15:31 a. m. | Acción2 | Bien |
| A0001 | 100 | 100 | 2022/04/01 9:15:36 a. m. | Acción1 | N / A |
| A0002 | 212 | 200 | 2022/04/02 3:15:21 a. m. | Acción1 | N / A |
| A0002 | 211 | 282 | 2022/04/02 3:15:11 a. m. | Acción2 | Malo |
| A0002 | 212 | 200 | 2022/04/02 3:15:16 a. m. | Acción1 | N / A |
| A0003 | 441 | 382 | 2022/05/01 1:15:31 a. m. | Acción2 | Malo |
| A0004 | 441 | 382 | 2022/05/01 5:16:31 a. m. | Acción2 | Malo |
| A0004 | 441 | 300 | 2022/05/01 5:15:31 a. m. | Acción1 | N / A |
Si la lógica del guión original no estaba clara:
Si el colE de la fila actual es "Acción 1": entonces asigne "N/A";
De lo contrario, si el colE de la fila actual es "Acción 2", siga la lógica del siguiente párrafo.
Si existe otra fila en la tabla con los mismos valores de la fila actual para las columnas colA y colB; el valor colC de la fila actual es exactamente 82 más que esta otra fila; los valores de colDate tienen una diferencia de 18 segundos entre sí; colE de la fila actual es "Acción 2" y colE de esta otra fila es "Acción 1": luego asigne "Bueno"; de lo contrario, asigne "Malo".
¡Agradezco cualquier ayuda! Simplemente no veo una manera sin bucles anidados en este momento.
Pero ahora al menos me doy cuenta de que debería poner un Break() después de la línea 25 de mi script original. No hay motivo para seguir buscando otra fila que coincida con mis criterios si ya encontré que existe al menos una.
La lógica en este script es demasiado complicada ya que no conozco todas las limitaciones de los datos (por ejemplo, puede haber múltiples coincidencias) y no la optimicé.
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");
