使用Excel FREQUENCYfunction的直方图

在Excel 2010中,列A有一个值列表,并且在B1指定了一个bin大小。 这使我可以使用这个公式创buildN个bin的直方图:

{=FREQUENCY(A:A,(ROW(INDIRECT("1:"&CEILING((MAX(A:A)-MIN(A:A))/B1,1)))-1)*B1+MIN(A:A))}

唯一的问题是我需要select N个单元格并应用此公式来获取N个元素作为我的条形图的数据源。 有没有可能跳过这一步? 例如,是否有可能在单个单元格中使用此公式(稍加修改),以便在用作数据源时将其解释为N个单元格,从而生成一个N值良好的直方图?

谢谢。

这是让我看到上面的公式的答案。

(这与macros观驱动的dynamic范围调整方法的方法相当不同,所以我使用单独的答案…)

可以通过记住“命名范围”实际上是命名公式来构builddynamic直方图图表,因此它们的值可能是dynamic的,在某些情况下非常重要。

让我们从假定我们在A列中有一个任意的值集合开始,并且我们有另一个单元格,它包含我们想要在我们的直方图中的分箱数量。 在我的工作手册中,碰巧是E2。 所以我们启动名称pipe理器(在“公式”选项卡上)并创build

 num_bins =Sheet1!$E$2 

我已经定义了一些箱子,而不是箱子的大小(我们将在后面定义),因为后者使得我们很难确切地知道如何设置箱子的边界:我们对这样的想法感到满意:最后一个分箱可能覆盖值范围的不同大小的部分,例如?*

我们也可以设置dynamic公式来描述我们的数据:

 data_count =COUNT(Sheet1!$A:$A) data_vals =OFFSET(Sheet1!$A$1,0,0,data_count,1) max_val =MAX(data_vals) min_val =MIN(data_vals) 

随着那些定义,我们可以看中。 每个垃圾桶应该多大? 制作另一个命名公式:

 bin_size =(max_val-min_val)/(num_bins) 

科学就是这样:这些公式构成了dynamic数组:

 bin_array =min_val+ROW(OFFSET(Sheet1!$A$1,0,0,num_bins-1,1))*bin_size bin_labels =min_val+ROW(OFFSET(Sheet1!$A$1,0,0,num_bins,1))*bin_size data_vals =FREQUENCY(data_vals,bin_array) 

第一个更复杂:它使用num_bins minus one的行号num_bins minus one -size范围来生成bin_size 。 它不会在min_val处启动数组,因为FREQUENCY()函数min_val数直到每个bin值的项目。 它比所希望的箱子数目要小,因为函数产生了一个更大的数组,其中最后一个入口具有高于最高箱子数目的点。 所以我们为演示目的制作一个单独的bin_labels数组。

现在我们可以制作一个图表。 插入一个(比如说)二维柱形图并打开“select数据”对话框(可以从function区或右键单击图表)。 添加一个新系列,将系列值设置为=Sheet1!freq_array 。 有必要包含工作表名称或工作簿名称以使其工作。 如果您喜欢,请添加系列名称,然后单击“确定”。 现在单击“编辑”为“水平(类别)轴标签”,并将范围设置为=Sheet1!bin_labels

这里是2000个单元格,其中=RAND()*5和5个分档(我列出了名称和它们的公式,其中不产生数组的值)

2000 <code> = RAND()* 5 </ code>结果分成5个分箱

并且在将num_bins更改为10后重新计算RAND()公式,因此可能不会加上完全相同的值)

在将num_bins更改为10之后

  • (如果您必须具有用户定义的bin大小,则需要使用bin_size表参考并使用指定的公式计算num_bins

我能想到的唯一答案是使用macros来调整公式的输出范围。

这里有一个简单的片段来说明这个想法。

 Dim result As Variant Dim targetCols As Long result = Evaluate(fmla) With rng targetCols = UBound(result, 1) - LBound(result, 1) + 1 .Resize(1, targetCols).FormulaArray = fmla End With 

去年我写了一个更完整的实现 – 更多的容错,二维输出等等

编辑:但是…你正在使用的公式不会使用这种方法:它依赖于input的输出范围大小。 这是一个可以自动resize的替代build议:

我们可以用这样的东西创build一组可用的垃圾箱:

 ={(ROW(OFFSET(A1,0,0,CEILING((MAX(A:A)-MIN(A:A))/B1,1)+1,1))-1)*B1} 

在此之前,这是箱的数量

 CEILING((MAX(A:A)-MIN(A:A))/B1,1)+1 

然后我们使用OFFSET()创build一个范围OFFSET()由于我们没有使用它的值,因此目标无关紧要)。 然后,我们将每个单元格的ROW() (减去1得到一组以零开始的值)并乘以我们的bin大小。 您可能想要移动值的范围(例如通过添加MIN(A:A) )。

最大的区别是,这个公式不需要在Evaluate() VBA函数的范围内input,以便能够生成范围输出。

要获得直方图,可以将bin公式中的输出插入FREQUENCY()或放入整个公式中。 自动resize应该可以工作。

如果您特别反对运行macros(我可以通过自定义function区button和热键组合),那么您可以使用Worksheet_Change事件来监视应用它的机会。 我不能肯定地说这是否会有不愉快的副作用。