频率()与数组:添加一个元素返回数组
我使用以下公式作为命名公式(通过名称pipe理器)。 然后它被用在一个更大的sumproduct()中。 我们的目标是确保在使用数组计算的情况下,对于某些特定的行只计算一次(例如,对于A类,您有相同的数据在多行中重复。我只需要知道A类中有多less人)。
=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个项目在数组中,正如所料。
这是搞乱了我的计算,因为从这个函数的返回数组乘以其他所有有6项(或无论是我有数据行数)的数组。
这是什么第七项,我怎么能得到它或防止它返回错误?
我曾尝试将一些公式包装到iferror()或ifna()中,但是它并不干净。 我觉得这可能会适得其反,并不是一个强有力的办法。 我宁愿把它在源头….
编辑:例如用于其他数组:
{=SUMPRODUCT(--IFERROR(((tdata[_isVisible]=1)*(f_uniqueUUIDfactor),0))}
其中f_uniqueUUIDfactor是来自初始文章的公式。 tdata [_isVisible] = 1用于过滤仪表板上的数据(例如通过下拉菜单,用户可以设置date范围,使用VBA将原始数据中的行隐藏在范围内)。
重点是sumproduct()最终将每个原始数据行thothheter乘以0和1秒,以便只有满足所有标准的人才能返回。 上面的IFERROR()是frequency()引入的额外数组元素的解决方法。 它的工作原理,但如果一个更清洁的方式存在,我更喜欢这一点。 我也会热衷于理解为什么这些元素被添加。
这是一个很好的例子,为什么当根据多个条件计算数组时,最好使用多个recursionIF
语句,而不是形成这些数组的产物。
首先,在说明理由之前,我应该指出一些小的技术上的不准确/缺陷。
1)通过在作为FREQUENCY
的data_array和bins_arrayparameter passing的构造中包含一个value_if_false子句,可能会导致错误的结果,因为零是FREQUENCY
考虑的有效数字,而布尔FALSE
(这将是等效条目在结果数组中,你完全省略了value_if_false子句)被这个函数忽略。
2) MATCH
一个精确的(即0或者FALSE
) MATCH
参数是一个相对资源较重的结构,特别是如果要考虑的范围相当大。 因此,由于没有必要将这种结构用于FREQUENCY
的bins_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
总是返回一个数组,其条目数大于传递的bins_array数 。
正如我在对你的post的评论中所提到的那样,你所面临的问题的解决在很大程度上取决于你对最终arrays的进一步操纵。
但是,为了说明起见,我们假设您只是希望将您的FREQUENCY
构造所产生的数组与您表中的某个其他列相乘, 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
子句,在这里是至关重要的。
事实上,前者总是会返回一个错误,而后者通常不会。
原因是前者会解决(假设你的表有例如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])
而我给予的第二个build设将解决:
=SUM(IF({TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE},tdata[Column2]))
两者可能看起来完全相同,但前者使用乘法来parsing数组,而后者不是这样的事实是关键的区别。
尽pipe在这两种情况下由FREQUENCY
构造产生的arrays,即:
{TRUE;TRUE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;TRUE;TRUE;FALSE}
包含11个条目(即,比第二个数组中的条目数目多1个),不同之处在于,当您试图将11元素数组与10元素数组(即tdata [Column2] ) 相乘时 , Excel不是完全禁止这样的操作,而是人为地重新调整两个arrays中较小的一个,使其与较大的尺寸匹配。
但是,在此过程中,任何附加条目都会自动设置为#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元素的arrays被重新调整到11个元素之一,以试graphics成合法的操作。 而且还提到,第11个因素是#N/A
,这意味着整个build设也将导致这个价值。
然而,在非乘法版本中,即:
=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
'覆盖'与第二个arrays相同位置的误差值,因为上面解决了:
=SUM({38;FALSE;49;FALSE;10;11;97;FALSE;3;FALSE;FALSE})
问候