Hola a todos,
Tengo una tabla de datos que consta de entradas con fecha donde la entrada más reciente está en la parte superior de la tabla y la entrada más antigua está en la parte inferior.
Lo que estoy tratando de hacer es recorrer las filas para encontrar la diferencia de fecha entre dos filas. He hecho esto con el siguiente código, lo obtuve de una publicación que @txnelson contestó hace algún tiempo (lo siento, no tengo el OP en frente de mí).
dt = Data Table( "My Data" );
For( i=N Rows(dt), i >= 2, i--,
:ct[i] = Abs(DateDifference(:date[i-1], :date[i], "Day"));
);
Esto funciona muy bien, y puedo encontrar todas las diferencias de fechas de interés.
Sin embargo, lo que realmente quiero hacer es etiquetar los intervalos de fechas con letras del alfabeto (A, B, C, D, etc.).
Por ejemplo, si mi primera entrada (última fila en la tabla de datos) comienza el 01/01/2017 (dd / mm / aaaa), quiero etiquetar esa fila "A", y quiero continuar etiquetando las filas que suben por la columna hasta que llegue a un punto donde la diferencia de fechas es> = n (en este caso n = 2, pero podría ser cualquier número mayor que 1).
Tenga en cuenta que las fechas aumentan a medida que avanzamos desde la parte inferior de la tabla. Por lo tanto, la siguiente fila de arriba sería 02/01/2017. Digamos que esto continúa hasta finales de enero, por lo que hay 31 filas que van del 01/01/2017 al 31/01/2017.
En la siguiente fila por encima del 31/01/2017, tenemos 05/02/2017. Así que la diferencia de fecha es 5. Me gustaría que mi rastreador de etiquetas comience a etiquetarlo como "B" hasta que la próxima fecha cambie donde la diferencia es> = 2 y luego comience a etiquetar como "C", y así sucesivamente hasta que la tabla de datos haya terminado.
Algo cercano a esto también fue publicado por @txnelson en este hilo: https://community.jmp.com/t5/Discussions/Labeling-rows-as-greater-less-than-a-date-with-JSL/td-p/36376 , pero requiere una fecha de inicio especificada para comparar otras fechas. No quiero tener una fecha de inicio especificada, sino hacerlo automáticamente en función de las fechas en las que se haya completado la tabla.
Cualquier sugerencia / apoyo es muy apreciado.
¡Gracias!
@txnelson Muchas gracias por su código. Lo seguí muy claramente, estaba bien documentado y tenía sentido. Lo probé en la tabla de datos de muestra que hizo y funcionó muy bien.
Tuve que modificarlo ligeramente para mi formato de datos específico, ya que es una tabla de datos grande que está concatenada y, a veces, el intervalo de fechas vuelve atrás, por lo que la diferencia de fechas es muy grande (> 100 días). No obstante, fue fácil de modificar ya que sus comentarios ayudaron mucho.
En realidad, estaba empezando a hacer algo muy similar a lo que es tu solución, ¡pero estaba llegando mucho más lento que tú! Creo que es por eso que la lógica de tu código tiene tanto sentido.
Realmente aprecio la ayuda, gracias!
Aquí hay un script que debe hacer lo que usted desea ...... asegúrese de estudiarlo para que pueda comprender cómo funcionan las diferentes funciones y cómo funciona la lógica del código. En otras palabras, no solo córtelo y péguelo sin entenderlo.
Names Default To Here( 1 );
// Create a sample data table
dt = New Table( "Example",
Add Rows( 100 ),
New Column( "Date",
Numeric,
"Continuous",
Format( "ddMonyyyy", 12 ),
Input Format( "ddMonyyyy" ),
Set Values(
[3640106008.56964, 3639892909.24216, 3639816069.76636, 3639711971.2654,
3639614050.02423, 3639594631.39805, 3639581856.84272, 3639499697.65438,
3639405448.76553, 3639293346.42584, 3639022373.8664, 3638682552.62729,
3638662956.28802, 3638644514.74731, 3638510978.46425, 3638508355.329,
3638447240.64829, 3638280760.96257, 3638253465.01226, 3638182573.0004,
3638135159.78165, 3638031154.80142, 3638019646.52908, 3637888422.23898,
3637821622.60523, 3637761224.6898, 3637708154.53698, 3637655683.55496,
3637523013.28917, 3637336766.86203, 3637273948.44657, 3637146868.92602,
3637139130.85435, 3637041997.93449, 3636718392.96078, 3636702006.57404,
3636684337.39444, 3636645617.3044, 3636621923.04457, 3636576772.74921,
3636548097.39841, 3636524282.13857, 3636202501.07711, 3636082870.01646,
3636015305.10949, 3635986264.04419, 3635954006.90437, 3635864908.69012,
3635855262.80858, 3635593939.60592, 3635374128.02522, 3635336114.35042,
3635271204.82971, 3635136811.26229, 3635062537.71875, 3635022035.10663,
3634999736.12185, 3634972464.2373, 3634849211.45924, 3634794399.03536,
3634785984.37775, 3634667869.53241, 3634645627.14123, 3634606120.34103,
3634483420.7033, 3634469476.65781, 3634457506.03348, 3634300180.05399,
3634161262.31866, 3634024215.74686, 3633993153.4734, 3633957176.13649,
3633780205.72602, 3633775930.38711, 3633762315.48745, 3633671471.68225,
3633623618.86685, 3633564003.73824, 3633498484.02555, 3633488261.49554,
3633127296.72145, 3633091315.52892, 3632836504.4496, 3632759089.11,
3632695080.2713, 3632564084.614, 3632496376.27829, 3632409035.04661,
3632213416.86148, 3632155851.6491, 3632136908.29403, 3632061846.54667,
3632011684.6858, 3631978413.53537, 3631925136.87974, 3631865971.06053,
3631774901.06017, 3631755982.44004, 3631706805.99126, 3631667141.16235]
),
Set Display Width( 68 )
)
);
// Create the new column
dt<<NEW column="">= 1, i--,
If( i == N Rows( dt ),
// Last row in the table gets the letter "A"
dt:Label[i] = alphaList[letter],
// Otherwise
// If the date on this row is >= the date on the last row,
// change the letter number
If( Abs( Date Difference( :date[i + 1], :date[i], "Day" ) ) >= 2,
letter = letter + 1
);
// Since there could be more than 26 groups, groups AA, BB etc.
// may have to be added, so calculate the number of letters
howmanyLetters = Floor( Letter / 26 ) + 1;
// Now calculate which letter to use
whichLetter = Modulo( letter, 26 );
If( whichLetter == 0,
whichLetter = 26
);
// Create the new value for the column Label
For( k = 1, k <= howmanyLetters, k++,
dt:Label[i] = dt:Label[i] || alphaList[whichLetter]
);
)
);</NEW>