Calcular la diferencia de columnas para otros niveles de columna donde el retraso varíaTengo una columna :EVENT (carácter nominal) con varios valores. También otra columna :datetime (numérico continuo). Tengo la columna :datetime ordenada de forma ascendente. Me interesa que otra columna calcule, para cada vez que hay un evento "CONNECT", cuál es la diferencia de tiempo entre este y el último evento "DESCONNECT". El problema es que el desfase puede variar entre un CONNECT y un DESCONNECT anterior (ver foto a continuación) y también preferiría mantener este formato de tabla alta. Se agradece una solución para el orden ascendente de fecha y hora, pero también sería beneficioso que no estuviera ordenado.

Análisis y modelado de datos básicosExploración y visualización de datosRe: Calcular la diferencia de columnas para otros niveles de columna donde el retraso varíaPor ejemplo, puede utilizar una variable en la fórmula para almacenar el valor de la última desconexión.
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(12),
Compress File When Saved(1),
New Column("E", Character, "Nominal", Set Values({"A", "B", "Disc", "Con", "A", "B", "C", "B", "Disc", "A", "B", "Con"})),
New Column("T", Numeric, "Continuous", Format("Best", 12), Set Values([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]))
);
dt << New Column("Dif", Numeric, Continuous, Formula(
If(Row() == 1,
last_disc = .;
retval = .;
);
If(:E == "Disc",
last_disc = :T;
retval = .;
, :E == "Con",
retval = :T - last_disc
,
retval = .;
);
retval;
));

Re: Calcular la diferencia de columnas para otros niveles de columna donde el retraso varía¡Este enfoque funcionó muy bien, gracias!
Re: Calcular la diferencia de columnas para otros niveles de columna donde el retraso varíaTambién puedes utilizar matrices
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(12),
Compress File When Saved(1),
New Column("E", Character, "Nominal", Set Values({"A", "B", "Disc", "Con", "A", "B", "C", "B", "Disc", "A", "B", "Con"})),
New Column("T", Numeric, "Continuous", Format("Best", 12), Set Values([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]))
);
events = :E << get values;
times = :T << get values;
discs = Loc(events, "Disc");
cons = Loc(events, "Con");
difs = J(1, N Rows(dt), .);
difs[cons] = times[cons] - times[discs];
dt << new column("difs", numeric, continuous, values(difs));
Esto tiene algunas suposiciones, pero se puede hacer más robusto para todo tipo de casos extremos (Loc Sorted puede ser útil para algo como esto, a veces incluso KDTable/VPTree).
Re: Calcular la diferencia de columnas para otros niveles de columna donde el retraso varíaPara complicar un poco las cosas, hay ocasiones en las que un evento CONNECT puede aparecer varias veces antes de que aparezca un evento DISCONNECT. En este caso, me gustaría que la diferencia solo se calcule en el primer evento CONNECT que aparece después de un evento DISCONNECT. ¿Hay alguna pequeña modificación en el script que pueda adaptarse a esto? Gracias nuevamente por tu ayuda.
Re: Calcular la diferencia de columnas para otros niveles de columna donde el retraso varíaAquí hay una modificación al código @jthi que debería manejar esto.
Names Default To Here(1);
dt = New Table("Untitled",
Add Rows(12),
Compress File When Saved(1),
New Column("E", Character, "Nominal", Set Values({"A", "B", "Disc", "Con", "A", "B", "C", "B", "Disc", "A", "B", "Con"})),
New Column("T", Numeric, "Continuous", Format("Best", 12), Set Values([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]))
);
dt << New Column("Dif", Numeric, Continuous, Formula(
If(Row() == 1,
last_disc = .;
retval = .;
);
If(:E == "Disc",
last_disc = :T;
retval = .;
firstCon = .;
, :E == "Con",
If(ismissing(firstcon), firstcon=:t);
retval = firstcon - last_disc
,
retval = .;
);
retval;
));
Le sugiero que se tome el tiempo de leer la Guía de creación de scripts, disponible en la Ayuda de JMP. También tómese el tiempo de estudiar el código proporcionado por los miembros del Foro de discusión que respondieron. Las modificaciones al script de Jarmo no requirieron ningún conocimiento nuevo sobre programación. Solo requirieron que se agregara algo de lógica adicional al flujo del script. El objetivo del usuario debería ser poder realizar sus propias mejoras en los scripts.