在Spotfire中对同一列中的分组(表达式)进行匹配

10
关于我之前发布的问题: 如何在Spotfire中为特定行计算同一列的差异
我有一个新的问题,以下是示例:

enter image description here

我想要实现的新功能是:
  • 查找 TYPE=1 的下一个最近的 TYPE=0
  • 如果 TYPE=1 有最近的 TYPE=0,则在一个新计算列中将其标记为“T”,否则标记为 NULL
数据规则如下:
  • Status 列包含 {1,2},默认情况下,空格的值与上面最近的 Status 值相同。
  • Type 列仅包含 0 和 1。
输出应该像这样:

enter image description here

我尝试过的解决方案:
    If(([type]=1) and (first([type]) OVER (intersect(previous([type]),AllNext([status])))=0),"T",Null)

看起来没问题,但问题在于每个状态组中,例如第一个status=1组中的最后一个TYPE=1(第5行),它没有下一个最近的TYPE=0,所以判断结果会是空值。但根据代码,它应该是T! :(

有什么建议和想法吗? 非常感谢! PS:一些细节:

  • 状态的第一个Type值为NULL
  • 状态列中的其他空格可以填充如下,如果对表达式有帮助:)

enter image description here


这个有点棘手。状态和类型中的空值是 null 吗? - S3S
是的,但实际上,我们可以用最新状态来填充空值。 :) - ZAWD
@scsimon,我在问题中添加了一些细节,欢迎进一步提问 :) - ZAWD
以下是对下面答案的任何反馈吗? - S3S
2个回答

1

好的,这个真的考验了我的极限,我很好奇它是否能扩展。鉴于你在哪里有NULL,它适用于你的数据。我花了几个小时才弄清楚。

  1. 插入一个计算列RowId()并将其命名为RowNum
  2. 插入一个计算列RankReal([status],"ties.method=first")并将其命名为Rank
  3. 插入一个计算列If((first([status]) over (Previous([RowNum])) - First([status]) over ([RowNum]))=0,[Rank] - Max([RowNum]) OVER (Intersect([status],AllPrevious([RowNum]))))并将其命名为GroupOfTypes
  4. 插入一个计算列If([type]>Min([type]) over (Intersect([GroupOfTypes],AllNext([RowNum]))),"T")并将其命名为Marking。这是你真正关心的行。

结果

enter image description here

EXPLANATION

RankReal([status],"ties.method=first")

这样做实际上是为了基于状态段创建一个伪行号。您会看到它根据状态进行排序,顺序排列。这是分组数据的方法的第一步。
这个公式的第一部分 (first([status]) over (Previous([RowNum])) - First([status]) over ([RowNum]))=0 是评估前一行的[status]列是否与当前行相同。如果是,则返回布尔值TRUE。如果与其前一行相同,我们知道它属于同一块/分组,因此执行一些数学运算,使该列在整个块中标记为相同的值。即[Rank] - Max([RowNum]) OVER (Intersect([status],AllPrevious([RowNum])))。因此,我们分组内的每一行都将等于相同的值。 If([type]>Min([type]) over (Intersect([GroupOfTypes],AllNext([RowNum]))),"T")
最后,我们评估是否所有下一行中[type]的最小值都比当前[type]大。这样可以限制我们关注的数据仅为[type] = 1的行,而不实际过滤行,同时只向数据集前进查看。如果成立,我们用T标记它。

非常抱歉耽搁了!!! 最近遇到了一些没有网络的问题。 - ZAWD
没关系 @ZAWD,这种情况很常见。正如你所看到的那样,它已经成为了一个流行的问题 :) - S3S
我也感到非常惊讶 :) - ZAWD

1

@ZAWD - 另一种解决方法。

步骤1:使用表达式RowId()创建一个行ID。

步骤2:使用以下表达式创建一个计算列'Mark0'。此步骤是为了找到当前类型不为0且其连续类型为0。

注意:此列在后台运行。不需要包含在表中。另外,100是某些虚拟值,仅用于确保满足条件

If((Sum([type]) over ([RowID])!=0) and (Sum([type]) over (Next([RowID]))=0),100)

步骤三:使用以下表达式创建了一个计算列'Mark1'。此步骤是为了找到当前类型不为0且连续类型也不为0且Mark0已填。

注意:此列在后台运行,无需包含在表格中。

If((Sum([type]) over ([RowID])!=0) and (Sum([type]) over (Next([RowID])) Is Not Null) and (first([Mark0]) over (allNext([RowID]))=100),100)

第四步: 最后,使用以下表达式创建“最终成绩”列,将Mark0和Mark1列中的100分标记为“T”

If(([Mark0]=100) or ([Mark1]=100),"T",null)

最终表格:

nearest 我已经使用您的数据以及不同的场景进行了测试,例如'type'列中连续三个1而不是两个,并且看起来运行良好。请测试并让我知道是否稳定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接