使用Excel频率函数的直方图

使用Excel频率函数的直方图,excel,histogram,frequency,Excel,Histogram,Frequency,在Excel 2010中,我在列a中有一个值列表,并且在B1中指定了一个箱子大小。这允许我使用以下公式创建包含N个箱子的直方图: {=频率(A:A,(行(间接(“1:”&上限((最大(A:A)-MIN(A:A))/B1,1))-1)*B1+MIN(A:A))} 唯一的问题是,我需要选择N个单元格并应用此公式来获得N个箱子,作为条形图的数据源。是否可以跳过此步骤?例如,是否可以在单个单元格中使用此公式(稍作修改),以便在用作数据源时,将其解释为N个单元格,生成一个具有N个值的漂亮直方图 谢谢 我能

在Excel 2010中,我在列
a
中有一个值列表,并且在
B1
中指定了一个箱子大小。这允许我使用以下公式创建包含N个箱子的直方图:

{=频率(A:A,(行(间接(“1:”&上限((最大(A:A)-MIN(A:A))/B1,1))-1)*B1+MIN(A:A))}

唯一的问题是,我需要选择N个单元格并应用此公式来获得N个箱子,作为条形图的数据源。是否可以跳过此步骤?例如,是否可以在单个单元格中使用此公式(稍作修改),以便在用作数据源时,将其解释为N个单元格,生成一个具有N个值的漂亮直方图

谢谢


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

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

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
去年我写了一篇文章——更具容错性,二维输出,等等

编辑:但是。。。您使用的公式不适用于这种方法:它依赖于输入时已知的输出范围大小。这里有一个可以自动调整大小的替代建议:

我们可以创建一组可用的垃圾箱,如下所示:

={(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()
(目标不重要,因为我们没有使用它的值)创建一个范围。然后我们取范围内每个单元格的
行()
(减去1得到一组从零开始的值),然后乘以我们的仓位大小。您可能希望移动值的范围(例如,通过添加
MIN(A:A)

最大的区别在于,
Evaluate()

要获得直方图,请将bin公式的输出插入
FREQUENCY()
,或插入整个公式。自动调整大小应该以任何一种方式工作

如果您特别反对运行宏(我可以通过自定义功能区按钮和热键组合使用宏),那么您可以使用
工作表\u Change
事件来观察应用宏的机会。我不能肯定这是否会有任何令人不快的副作用。

(这与宏驱动的动态范围大小调整方法完全不同,因此我使用单独的答案…)

动态直方图可以通过记住“命名范围”实际上是命名公式来构建,因此它们的值可能是动态的,在某些情况下尤其如此

让我们先假设A列中有一组任意的值,从第1行开始,另外还有一个单元格,其中包含我们想要在直方图中显示的箱子数量。在我的工作簿中,这恰好是E2。因此,我们启动名称管理器(在“公式”选项卡上)并创建

num_bins             =Sheet1!$E$2
我倾向于定义大量的箱子,而不是箱子大小(我们将在后面定义),因为后者使我们很难准确地知道如何设置箱子边界:例如,第一个箱子和最后一个箱子可能会覆盖值范围中不同大小的部分,我们对此满意吗*

我们还可以建立动态公式来描述我们的数据:

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)
科学来了:这些公式构成了动态数组:

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\u-bins的行号减去一个
-size范围来生成
bin\u-size的倍数。它不会在
min\u val
处启动数组,因为
FREQUENCY()
函数将项目计数到每个箱子值。它比所需的存储箱数小一个,因为函数生成的数组比所需的存储箱数大一个,其中最终条目的点高于最高的存储箱数。因此,我们制作了一个单独的
bin_标签
数组,用于演示

现在我们可以做一张图表了。插入(比如)二维柱状图并打开“选择数据”对话框(从功能区或右键单击图表)。添加新系列,将系列值设置为
=Sheet1!频率数组
。必须包含工作表名称或工作簿名称才能使其正常工作。如果愿意,请添加一个系列名称,然后单击“确定”。现在单击“水平(类别)轴标签”的“编辑”,并将范围设置为
=Sheet1!垃圾箱标签

这里有2000个单元格,其中包含
=RAND()*5个
和5个存储箱(我列出了名称及其公式,其中的值不生成数组)

=RAND()*5
将结果放入5个箱子“>

将num_bins更改为10后,将显示相同的工作表。(重新计算
RAND()
公式,因此这些bins的合计值可能不完全相同)

  • (如果必须有用户定义的箱子尺寸,则需要将
    bin_尺寸
    作为图纸参考,并使用命名公式计算
    num_箱子

我想创建一个动态直方图,通过改变单个常量(箱子大小)可以轻松更改。我甚至可以禁用UI交互(我使用Excel自动化创建直方图)。通过“直方图”,所需的输出是工作表上的图表还是数组?如果是一张图表,整个过程都可以用命名公式来完成。否则,您将需要一个如上所述的范围大小调整功能,或者为范围设置最大大小,并使数组变大。只要在更改存储箱大小时更新图表,图表就可以了。我尝试过使用命名公式,但不断出现错误。。。以前从未做过这件事:PNow,这是一个很好的答案。谢谢!:)不过有点小的修正:第二个
数据\u vals
应该重命名,以避免名称冲突。