大家好,
我有一个数据表,其中包含有日期的条目,其中最近的条目位于表的顶部,最旧的条目位于底部。
我要做的是遍历行以查找两行之间的日期差异。 我已经用下面的代码完成了这个,从一个帖子中得到它@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>