VBA中的简单直方图?

时间:2012-01-25 14:35:11

标签: excel vba histogram

我将数据存储在某些列中(Say,A列)。列A的长度不固定(取决于代码中的先前步骤)。

我需要列A中的值的直方图,并将其放在同一张表中。我需要获取A列中的值,并自动计算M Bins,然后给出图。

我在网上查找了一个“简单”的代码,但所有代码都非常花哨,我不需要大量细节,甚至我都无法使用它。 (我是VBA初学者。)

我发现以下代码似乎可以完成这项工作,但我甚至无法调用该函数。此外,它只进行计算,但没有制作情节。

Sub Hist(M As Long, arr() As Single)
Dim i As Long, j As Long
Dim Length As Single
ReDim breaks(M) As Single
ReDim freq(M) As Single

For i = 1 To M
    freq(i) = 0
Next i

Length = (arr(UBound(arr)) - arr(1)) / M

For i = 1 To M
    breaks(i) = arr(1) + Length * i
Next i

For i = 1 To UBound(arr)
    If (arr(i) <= breaks(1)) Then freq(1) = freq(1) + 1
    If (arr(i) >= breaks(M - 1)) Then freq(M) = freq(M) + 1
    For j = 2 To M - 1
        If (arr(i) > breaks(j - 1) And arr(i) <= breaks(j)) Then freq(j) = freq(j) + 1
    Next j
Next i

For i = 1 To M
    Cells(i, 1) = breaks(i)
    Cells(i, 2) = freq(i)
Next i
End Sub

然后我尝试简单地通过以下方式调用它:

Sub TestTrial()
Dim arr() As Variant
Dim M As Double
Dim N As Range

arr = Range("A1:A10").Value
M = 10

Hist(M, arr)    ' This does not work.  Gives me Error (= Expected)
End Sub

2 个答案:

答案 0 :(得分:0)

不能100%确定该方法的功效但是;

  • 删除parens作为你的召唤; Hist M, arr
  • M声明为double,但函数收到long;这将无效,因此在调用例程中将其声明为long
  • 您需要收到arr() As Variant
  • Range -> Array生成一个二维数组,因此元素为arr(1, 1) .. arr(n, 1)

答案 1 :(得分:0)

有点晚了,但我仍想分享我的解决方案。我创建了一个Histogram函数,可以在excel电子表格中用作array formula。注意:您必须按 CTRL+SHIFT+ENTER将公式输入您的工作簿。输入是值的范围和直方图的区间数M.输出范围必须包含M行和两列。 bin值为一列,bin频率为一列。

Option Explicit
Option Base 1

Public Function Histogram(arr As Range, M As Long) As Variant
On Error GoTo ErrHandler
    Dim val() As Variant
    val = arr.Value
    Dim i As Long, j As Integer
    Dim Length As Single
    ReDim breaks(M) As Single
    ReDim freq(M) As Integer

    Dim min As Single
    min = WorksheetFunction.min(val)
    Dim max As Single
    max = WorksheetFunction.max(val)

    Length = (max - min) / M

    For i = 1 To M
        breaks(i) = min + Length * i
        freq(i) = 0
    Next i

    For i = 1 To UBound(val)
        If IsNumeric(val(i, 1)) And Not IsEmpty(val(i, 1)) Then
            If val(i, 1) > breaks(M) Then
                freq(M) = freq(M) + 1
            Else
                j = Int((val(i, 1) - min) / Length) + 1
                freq(j) = freq(j) + 1
            End If
        End If
    Next i

    Dim res() As Variant
    ReDim res(M, 2)
    For i = 1 To M
        res(i, 1) = breaks(i)
        res(i, 2) = freq(i)
    Next i

    Histogram = res
ErrHandler:
    'Debug.Print Err.Description
End Function