Excel 按优先规则集分组

Excel grouping by prioritized ruleset

我想知道为什么没有人问这个问题,但是我如何根据优先规则集/树对 table 中的(有序)条目进行分类? (可能是裸 excel 而不是嵌套 if 级联)

最小示例(仅显示 11 个或更多特征中的 3 个)

Name      | IsCool | IsNerdy | HasChild
Joe       | 1      | 1       | 1
Charliese | 1      | 0       | 1 
Peter     | 1      | 0       | 0
Jonas     | 0      | 0       | 0

规则

Priority  | IsCool | IsNerdy | HasChild | => Group
1.        | 1      | 1       | ignore   | A (at least cool&nerdy)
2.        | ignore | ignore  | 1        | B (not A, but has a child)
3.        | 1      | 0       | 0        | C (only cool)
4.        | ignore | ignore  | ignore   | D (everything else)

stop after first match

产量:

Name      | IsCool | IsNerdy | HasChild | Group
Joe       | 1      | 1       | 1        | A
Charliese | 1      | 0       | 1        | B
Peter     | 1      | 0       | 0        | C
Jonas     | 0      | 0       | 0        | D

您可以通过在数据中创建一个键(例如 Joe =“111”、Charliese =“101”等)来做到这一点,然后它只是对包含 的规则集的 vlookup键的所有 种可能组合。

您可以将 "ruleset" 转换为所有可能的属性组合(IsCool、IsNerdy、HasChild 等),方法是将 "Ignore" 视为 0(零)或 1(统一)。

因此,问题规则集中的第一条规则将被两条规则替换。

IsCool ¦ IsNerdy ¦ HasChild¦ Group 1 ¦ 1 ¦ 0 ¦ A 1 ¦ 1 ¦ 1 ¦ A

虽然三个属性之间只有8种可能性,但这种方法可以导致超过8条规则。例如,在问题的规则集中,当 "ignore" 在规则集中时,具有由 (1,1,1) 给出的数据元组 (IsCool, IsNerdy, HasChild) 的人将匹配 A 组和 B 组以这种方式扩展。为了消除由此引起的歧义,还需要应用优先级:与 A 组的匹配比 B 组的匹配具有更高的优先级,因此查找 table 将包括 (1,1,1,A) 作为一行但不包括 (1,1,1,B)。

随着涉及更多属性的更大规则集,从 table 规则构建所需 VLOOKUPtable 的任务将不会没有问题,特别是如果非需要手动方法,只需 Excel 而不是 Excel 与 VBA.

结合使用

不涉及 VBA 的 替代方法 将规则集视为数据如下。

将上面介绍的符号形式化,涉及n个属性的规则可以表示为

(r[1],r[2],...,r[n],G)

其中 r[i] (i=1,...,n) 可以取 01"ignore" 的值,并且 G 表示组(A、B、C 或D 在问题的例子中)。

数据实例可以类似地表示为

(d[1],d[2],...,d[n])

其中 d[i] (i=1,...,n)01 的值(但不是 "ignore"

规则匹配如果

 r[i] = "ignore" OR "d[i] = r[i]" for each i from 1 to n

在 Excel 中有一个非常明显的实现方法,如

=AND(OR(r[1]="ignore",d[1]=r[1]),OR(r[2]="ignore",d[2]=r[2]),...,OR(r[n]="ignore",d[n]=r[n]))

其中,当然,相关的单元格引用用于代替上面显示的 d[i]r[i] 占位符,并且适当数量的 OR 嵌套在AND 替换 ... shorthand.

上面的伪公式的值为 TRUEFALSE,前者表示数据实例与规则匹配,后者表示不匹配。

然而,这并不是故事的结局,因为规则仍然需要按优先顺序应用。

因此,进一步扩展符号,假设规则按优先级顺序列出(规则 1 的优先级高于规则 2,规则 2 的优先级高于规则 3,依此类推)

如果单元格 C[k] 保存将第 k 条规则应用于数据实例的结果,则修改上述伪公式,使 C[k] 现在具有公式

=IF(OR(C[1],...,C[k-1]),FALSE,AND(...))

确保只有在没有更早的(因此优先级更高的)规则匹配时才能匹配第 k 条规则。 (这里IF的第三部分是前面提到的AND公式。)

下面的屏幕截图显示了问题示例的实际方法。

蓝色单元格是公式。第二个 table 中的 TRUE/FALSE 值实现了上面讨论的伪公式。例如,cellF13 显示将规则 1 应用于数据实例 (0,0,0) 的结果,并具有以下公式

=AND(OR($C="Ignore",$C=$C13),OR($D="Ignore",$D=$D13),OR($E="Ignore",$E=$E13))

注意:此公式不需要包含 IF,因为没有规则的优先级高于规则 1。

单元格 I13 的公式显示了将规则 4 应用于同一数据实例的结果,需要根据规则 1、2 和 3 考虑更高的优先级。此单元格中的公式是

=IF(OR($F13:H13),FALSE,AND(OR($C="Ignore",$C=$C13),OR($D="Ignore",$D=$D13),OR($E="Ignore",$E=$E13)))

单元格G13H13中的公式与I13中的公式类似(留作练习)。

根据设计,每一行中最多可以有一个 TRUE 值,如果规则集合理,则应该只有一个这样的值。第二个 table 最后一列中的公式对规则集进行了假设,并简单地从第一个 table 最后一列中挑选出与显示为 TRUE 的规则相对应的相关值。

单元格J13中的公式为

=INDEX(F:F,SUMPRODUCT(1*(F13:I13),F:I))

范围 F13:J13 中的公式被简单地复制到 table 的行下到单元格 F14:J20