2017-06-06 85 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 
相关问题