2017-06-06 108 views
1

我是新來編碼並試圖通過VBA學習。我想要做的是按照程序計算數據集中的異常值。我的麻煩是試圖確定數據集中離平均值(離羣值)最遠且循環了k次的元素。大部分代碼非常混亂,因爲我一直在試圖找出錯誤,所以忽略MsgBox的醜陋格式。在我的代碼的最後部分,我嘗試從DataSet中取出元素,並將它們從平均值中減去並將這些值存儲在新數組中。在此之後,我會將Diff數組中的元素的絕對值並將它們存儲在新數組(Diff2)中。我知道我可以通過計算Diff的絕對值來繞過Diff2。當我運行代碼時,出現類型不匹配錯誤,經過一番調查,我意識到Diff(和Diff2)不是數組。如果有人知道我可以如何製作一個數組或更好的解決方法,這將是非常感謝!如何從另一個數組的計算創建一個數組excel vba

Sub CalculateOutliers() 
    Dim n As Integer 
    Dim mean As Double 
    Dim SD As Double 
    Dim X As Integer 
    Dim k As Integer 
    Dim DataSet As Variant 
    Dim ESDPrin As Double 

    DataSet = Selection.Value 
    'Copies highlighted data into DataSet variable 
    'Cell A1 is (1,1) Because it starts at 0 which is out of range 

    n = Selection.CountLarge 
    'Counts number of entries 
    'If n < 20 Then 
     'MsgBox "Data set too small" 
     'Exit Sub 
    'End If 
    'Ends Subroutine if data set is too small for this analysis 

    If n < 50 Then 
     k = Int(n/10) 
    Else 
     k = 5 
    End If 
    'determines k = number of possible outliers 

    mean = Application.WorksheetFunction.Average(DataSet) 
    'Calculates mean of Data Set 
    MsgBox mean & "Average" 

    SD = Application.WorksheetFunction.StDev(DataSet) 
    'Calculates Standard Deviation of Data Set 

    Dim element As Variant 
    Dim Diff As Variant 

    For Each element In DataSet 
     Diff = element - mean 
     MsgBox Diff & " Difference" 
    Next element 

    Dim P As Integer 
    Dim Outlier As Integer 
    Dim Diff2 As Variant 

    Diff2 = Abs(Diff) 

    For P = 1 To k 
     Outlier = UBound(Diff, 1) 
     MsgBox Outlier 
    Next P 
End Sub 
+0

如果你希望他們作爲一個數組,你需要定義數組的所需的大小,例如Dim Diff(1到2)作爲Variant,或使用ReDim Preserve命令擴展數組(僅在一個座標軸中),而不會丟失先前的條目。 –

回答

2

這裏如何創建DIFF與數組大小爲n

ReDim Diff(1 To n) As Double 
Dim i As Long 
For Each element In DataSet 
    i = i + 1 
    Diff(i) = element - mean 
Next element 

不過,我不認爲這是要走的正確方法。不需要Diff陣列。你應該做的是,一旦你計算了meanSD,迭代DataSet數組本身,檢查每個元素與均值的絕對差值,除以stdev,並將該比率與某個閾值(比如2或3)比較決定這個元素是否是一個離羣值,在這種情況下,你將其作爲異常值打印出來。事情是這樣的:

For Each element In DataSet 
    If abs(element - mean)/SD > 3 Then Debug.Print "outlier: " & element 
Next element 
+1

我同意替代方法,但謝謝你回答這兩個問題,所以我可以知道以供將來參考!這幫了我很多! – Nick

+0

@尼克很高興看到這一點。 –

0

我覺得代碼會是這樣的

Sub CalculateOutliers() 
    Dim n As Integer 
    Dim mean As Double 
    Dim SD As Double 
    Dim X As Integer 
    Dim k As Integer 
    Dim DataSet As Variant 
    Dim ESDPrin As Double 

    DataSet = Selection.Value 
    'Copies highlighted data into DataSet variable 
    'Cell A1 is (1,1) Because it starts at 0 which is out of range 

    n = Selection.CountLarge 
    'Counts number of entries 
    'If n < 20 Then 
     'MsgBox "Data set too small" 
     'Exit Sub 
    'End If 
    'Ends Subroutine if data set is too small for this analysis 

    If n < 50 Then 
     k = Int(n/10) 
    Else 
     k = 5 
    End If 
    'determines k = number of possible outliers 

    mean = Application.WorksheetFunction.Average(DataSet) 
    'Calculates mean of Data Set 
    MsgBox mean & "Average" 

    SD = Application.WorksheetFunction.StDev(DataSet) 
    'Calculates Standard Deviation of Data Set 

    Dim element As Variant 
    Dim Diff() As Variant, Diff2() As Variant, j As Integer 

    For Each element In DataSet 
     j = j + 1 
     ReDim Preserve Diff(1 To j): ReDim Preserve Diff2(1 To j) 
     Diff(j) = element - mean 
     Diff2(j) = Abs(Diff(j)) 
     MsgBox Diff(j) & " Difference" 
     MsgBox Diff2(j) & " Difference abs " 
    Next element 
    MsgBox UBound(Diff) 
    'Dim P As Integer 
    'Dim Outlier As Integer 
    'Dim Diff2 As Variant 

End Sub 
相關問題