Frequency() with arrays: 添加一个元素到 return 数组

Frequency() with arrays: adds an element to return arrays

我使用以下公式作为命名公式(通过名称管理器)。然后在更大的 sumproduct() 中使用它。目标是确保通过数组计算,只对某些行组进行一次计算(例如,对于 A 类,您在多行中重复了相同的数据。我只需要知道有多少人属于 A 类一次).

=IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],
 tdata[reportUUID],0),0),IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],
 tdata[reportUUID],0),0))>0,TRUE)

让我们用Excel中的求值公式逐一分析结果。抱歉截屏,但是 Excel 不允许使用真实数据复制实际步骤....

步骤顺序:

在最后一张图片中,我的数组中现在有第 7 个项目。我只有 6 行数据,因此为什么在前面的步骤中我在数组中只有 6 项,正如预期的那样。

这打乱了我的计算,因为这个函数的 return 数组乘以其他数组,这些数组都有 6 个项目(或者我拥有的数据行数)。

第 7 项是什么,我怎样才能使用它或防止它出现 return 错误?

我确实尝试将一些公式包装到 iferror() 或 ifna() 中,但感觉不干净。我觉得这可能会适得其反,并且不是处理这个问题的有效方法。我宁愿从源头上看它....

编辑:例如与其他数组一起使用:

{=SUMPRODUCT(--IFERROR(((tdata[_isVisible]=1)*(f_uniqueUUIDfactor),0))}

其中 f_uniqueUUIDfactor 是来自初始 post 的公式。 tdata[_isVisible]=1 用作在仪表板上过滤数据的一种方式(例如,通过下拉菜单,用户可以设置日期范围,并且使用 VBA 我隐藏原始数据中不在范围内的行) .

关键是 sumproduct() 最终将每个原始数据行的数字相乘为 0 和 1 s,因此只有满足所有条件的才会得到 returned。上面的 IFERROR() 是 frequency() 引入的额外数组元素的解决方法。它按原样工作,但如果存在更简洁的方法,我会更喜欢它。我也很想了解为什么要添加这些元素。

这是一个很好的例子,说明为什么在根据多个条件评估数组时最好使用多个递归 IF 语句,而不是形成这些数组的乘积。

不过,首先,在说明该声明的原因之前,我还应该指出一些与您的构造有关的小技术 inaccuracies/flaws。

1) 通过在您的构造中包含一个 value_if_false 子句作为 FREQUENCYdata_arraybins_array 参数,您冒着不正确结果的风险,因为零是 FREQUENCY 考虑的有效数字,而布尔值 FALSE(如果您完全省略了 value_if_false 子句,则结果数组中的等效条目)将被此函数忽略。

2) MATCH 具有精确的(即 0 或 FALSEmatch_type 参数是一个相对资源密集型结构,特别是如果要考虑的范围很大。因此,由于没有必要对 FREQUENCYbins_array 参数使用此构造,因此最好使用更有效的:

ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1

此外,请注意,在第二个参数中也不需要重复 IF(LEN 构造。

总计,那么:

IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,TRUE)

比您提供的版本更加严格和高效。

为了回答你的主要问题,有据可查的是 FREQUENCY 总是 returns 数组的条目数比 bins_array通过了。

正如我在对您的 post 的评论中提到的,您面临的问题的解决很大程度上取决于您打算对结果数组进行何种进一步操作。

但是,为了便于解释,我们假设您只是希望将 FREQUENCY 构造产生的数组乘以 table、tdata 中的其他列[Column2]说,然后求和结果。

两者的区别:

=SUM(IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,TRUE)*tdata[Column2])

即使用两个数组的乘法,并且:

=SUM(IF(FREQUENCY(IF(LEN(tdata[reportUUID])>0,MATCH(tdata[reportUUID],tdata[reportUUID],0)),ROW(tdata[reportUUID])-MIN(ROW(tdata[reportUUID]))+1)>0,tdata[Column2]))

即使用直截了当的 IF 子句在这里至关重要。

事实上,前者总是return错误,而后者通常不会。

原因是前者将解析为(假设您的 table 具有例如 10 行的数据,并假设 FREQUENCY 构造的一些随机布尔结果):

=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},TRUE)*tdata[Column2])

也就是说,因为 value_if_true 子句在这里是多余的:

=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*tdata[Column2])

而我给出的第二个结构将解析为:

=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},tdata[Column2]))

两者可能看起来相同,但关键区别在于前者使用乘法来解析数组,而后者不是。

尽管在这两种情况下都是 FREQUENCY 构造产生的数组,即:

{TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}

包含 11 个条目(即比所考虑的第二个数组中的条目数多 1),不同之处在于,当您随后尝试将 11 元素数组与 10 元素数组相乘时(即 tdata[Column2]), Excel, 而不是完全禁止这样的操作,人为地重新调整两个数组中较小的数组,使其与较大的数组的维度相匹配。

但是,这样做时,任何其他条目都会自动设置为 #N/A 错误值。

有效,那么:

=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*tdata[Column2])

解析为:

=SUM({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}*{38;67;49;3;10;11;97;20;3;57;#N/A})

即,如前所述,第二个 10 元素数组被重新定义为 11 个元素之一,以尝试形成合法操作。并且,如前所述,第 11 个元素是 #N/A,这当然意味着整个构造也将产生该值。

然而,在非乘法版本中,即:

=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},tdata[Column2]))

虽然同样的重新计算也发生了,但我们通过使用 IF 子句代替乘法来保存,因为上面解析为:

=SUM(IF({TRUE;FALSE;TRUE;FALSE;TRUE;TRUE;TRUE;FALSE;TRUE;FALSE;FALSE},{38;67;49;3;10;11;97;20;3;57;#N/A}))

和第 11 个位置的布尔值 FALSE 'overrides' 来自第二个数组的等效位置的错误值,因为上面解析为:

=SUM({38;FALSE;49;FALSE;10;11;97;FALSE;3;FALSE;FALSE})

此致