Hola a todos,
Actualmente tengo problemas con algunas visualizaciones de datos. Tengo una tabla enorme que contiene miles de eventos que se capturan incl. hora de inicio y finalización de diferentes eventos en diferentes ubicaciones (estos se muestran como texto) en el siguiente formato que convertí con éxito para que se reconozca como hora:
Inicio: 2022-01-28T22:26:13
Fin: 2022-01-28T23:10:56
Ahora me gustaría visualizar/contar la cantidad de eventos paralelos, es decir, superponer todos los períodos resultantes y ver la cantidad máxima de eventos paralelos en las diferentes ubicaciones. También tengo disponible la duración como la diferencia entre la hora de inicio y finalización, así que en caso de que sea necesario...
Tal vez uno me puede ayudar?
¡Salud!
JMP16
Hola @ubpk ,
tal vez si nos das una pequeña muestra en una tabla, puedo intentarlo.
Le sugiero que descargue el complemento de diagrama de Gantt.Le proporcionará una excelente manera de mostrar sus eventos.

txnelson,
Gracias por la sugerencia, descargaré el complemento ya que parece bastante útil. Pero en mi caso, el eje y estaría demasiado sobrecargado debido a la cantidad de ubicaciones que tengo.
aquí hay un conjunto de datos reducido con solo dos días, pero debería hacer el trabajo. No necesito necesariamente una vista gráfica, pero para la depuración sería genial tener algún tipo de control sobre si la cantidad de eventos paralelos es razonable.
¡¡Gracias por adelantado!!
ulfo
Si la idea es obtener solo la cantidad máxima de superposiciones para la ubicación, primero puede calcular todas las superposiciones agregando las horas de inicio y finalización a una matriz y luego ordenarla mientras realiza un seguimiento de cuál es el final y cuál es el inicio. Luego puede calcular cuántos valores caben entre cada par de inicio y fin.
Tal vez algo como esto funcione (podría tener algunos problemas con valores duplicados):
Names Default To Here(1);
dt = Current Data Table();
dt << New Column("Overlap", Numeric, Continuous);
dt << Sort(By(:"Start time (UTC)"n), Replace Table, Order(Ascending));
starts = dt[0, 1];
ends = dt[0, 2];
m = Sort Ascending(starts |/ ends);
For Each Row(dt,
start = :"Start time (UTC)"n;
end = :"End time (UTC)"n;
:Overlap = Loc(m, end)[1] - Loc(m, start)[1] - 1;
);
/*
dt << New Column("MaxOverlap", Numeric, Continuous, << Set Each Value(
Col Max(:Overlap, :Location)
));
*/
tab = dt << Tabulate(
Show Control Panel(0),
Add Table(
Column Table(Statistics(Min, Mean, Max), Analysis Columns(:Overlap)),
Row Table(Grouping Columns(:Location))
)
);

Debería poder hacer esto también de forma casi interactiva en JMP creando una nueva tabla de datos con tres columnas: Hora, Tipo de hora (inicio, fin) y número de fila original. Luego ordénelo ascendiendo y escriba una fórmula para verificar si hay superposiciones (tal vez podría usar Lag(), usé Col Min(Row(), :Row) y Col Max(Row(), :Row()) y su diferencia) . Finalmente, cree una tabla de resumen para obtener el valor máximo / vuelva a unirse a la tabla original según los números de fila.

Resumen (no agregó max aquí):

Parece haber ligeras diferencias entre los dos métodos, por lo que tal vez uno de ellos sea incorrecto. Tal vez causado por valores duplicados (también eliminé los valores faltantes del método interactivo)

Es mucho más fácil buscar posibles problemas cuando tiene una tabla de datos para ello:

Además, el método interactivo se puede programar muy fácilmente con el registro mejorado de JMP16.
Editar: lo más probable es que tenga los siguientes problemas: 1. si una hora comienza antes de la hora de inicio marcada y termina después de la hora de finalización marcada, no se calculará y 2. si la hora comienza y termina entre las horas marcadas, se calculará dos veces . El segundo debería ser bastante fácil de arreglar, pero el primero requerirá un poco más.
Ejemplo de 2. OriginalRowOrder comienza y termina dentro de OriginalRowOrder 10 y se calcula dos veces:

ejemplo de 1 OriginalRowOrder 13 comienza y termina fuera de 14:

Edit2: No me molesté en descubrir cómo se podrían solucionar de forma interactiva, así que rápidamente escribí dos fórmulas (espero que sean correctas...). Los valores faltantes deben eliminarse/recodificarse antes de usarlos. OverlapsOutside puede volverse un poco lento si se hace con fórmula sin optimizaciones adicionales.
OverlapsInside (debería resolver el problema 2):
N Items(Associative Array(:OriginalRowOrder[Index(:MinRowForRow, :MaxRowForRow)])) - 1
OverlapsOutside (debería resolver el problema 1):
If(Row() == 1,
m = :OriginalRowOrder << Get As Matrix
);
Try(
starts = Associative Array(m[Index(1, :MinRowForRow - 1)]);
ends = Associative Array(m[Index(:MaxRowForRow + 1, N Rows())]);
starts << Intersect(ends);
N Items(starts);
,
.
);
OverlapsInside puede ser suficiente, dependiendo de cómo desee calcular las superposiciones. Si necesita ambos, solo obtenga la suma de esos valores.


Noté algunos problemas con mi enfoque inicial, así que reconsideré un poco y escribí un nuevo guión, con la esperanza de que ahora sea correcto. Lo más probable es que esto se pueda hacer más rápido usando solo cálculos matriciales, pero no me molesté en hacerlo ahora. Deja bastantes tablas de datos abiertas a propósito, por lo que es más fácil verificar si los valores son correctos.
Names Default To Here(1);
dt = Current Data Table();
dt << Clear Select;
dt << Sort(By(:"Start time (UTC)"n), Replace Table, Order(Ascending));
dt << New Column("Overlap", Numeric, Continuous);
dt << New Column("OriginalRowOrder", Numeric, Continuous, <<SET each="" value=""> :MaxRowForRow);
inside + outside; // if you need only inside, then don't calculate outside overlaps and just return inside
)
);
dt_overlaps << Update(
With(dt),
Match Columns(:OriginalRowOrder = :OriginalRowOrder),
Add Columns from Update Table(
:"Start time (UTC)"n, :"End time (UTC)"n, :Location
)
);
dt_statistics = dt_overlaps << Summary(
Group(:Location),
Min(:Overlaps),
Max(:Overlaps),
Range(:Overlaps),
Mean(:Overlaps),
Median(:Overlaps),
Freq("None"),
Weight("None"),
statistics column name format("stat"),
Link to original data table(0),
output table name("Overlap statistics by location")
);
f = Function({a},
selected_rows = dt_overlaps << Get Selected Rows;
dt_stack << Select Where(Contains(dt_overlaps[selected_rows, "OriginalRowOrder"], :OriginalRowOrder))
);
rs = dt_overlaps << make row state handler(f);</SET>