大家好,
我有一個數據表,其中包含有日期的條目,其中最近的條目位於表的頂部,最舊的條目位於底部。
我要做的是遍歷行以查找兩行之間的日期差異。 我已經用下面的代碼完成了這個,從一個帖子中得到它@txnelson前段時間回答(對不起,我面前沒有OP)。
dt = Data Table( "My Data" );
For( i=N Rows(dt), i >= 2, i--,
:ct[i] = Abs(DateDifference(:date[i-1], :date[i], "Day"));
);
這很好用,我可以找到所有感興趣的日期差異。
但是,我真正想做的是用字母(A、B、C、D 等)標記日期範圍。
例如,如果我的第一個條目(數據表中的最後一行)從 01/01/2017 (dd/mm/yyyy) 開始,我想將該行標記為“A”,並希望繼續標記該列向上的行直到它達到日期差異 >=n 的點(在這種情況下 n=2,但可以是大於 1 的任何數字)。
請記住,隨著我們從表格底部開始,日期正在增加。 因此,上面的下一行將是 02/01/2017。 假設這一直持續到 1 月底,所以從 01/01/2017 到 31/01/2017 有 31 行。
在 2017 年 1 月 31 日上方的下一行,我們有 2017 年 5 月 2 日。 所以日期差是5。 然後我想讓我的標籤跟踪器開始將其標記為“B”,直到下一個日期更改,其中差異> = 2,然後開始標記為“C”,依此類推,直到數據表完成。
與此相近的東西也被@txnelson在這個線程中: https://community.jmp.com/t5/Discussions/Labeling-rows-as-greater-less-than-a-date-with-JSL/td-p/36376 ,但它需要一個指定的開始日期來比較其他日期。 我不想有一個指定的開始日期,而是讓它根據填充表格的任何日期自動完成。
非常感謝任何建議/支持。
謝謝!
@txnelson非常感謝您的代碼。 我非常清楚地遵循它,它有據可查並且很有意義。 在您製作的示例數據表上對其進行了測試,效果很好。
我確實必須針對我的特定數據格式稍微修改它,因為它是一個連接的大型數據表,有時日期範圍會循環回來,因此日期差異非常大(> 100 天)。 儘管如此,它很容易修改,因為您的評論幫助很大。
實際上,我開始做一些與您的解決方案非常相似的事情,但是到達那裡的速度比您做的要慢得多! 我認為這就是為什麼您的代碼邏輯如此有意義的原因。
非常感謝您的幫助,謝謝!
這是一個應該做你想做的腳本......確保你研究它,以便你了解不同的功能是如何工作的,以及代碼的邏輯是如何工作的。換句話說,不要在不了解它的情況下就剪切和粘貼它。
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>