【问题标题】:Extend function to multivariate situation将功能扩展到多变量情况
【发布时间】:2021-04-11 16:18:09
【问题描述】:

让我们将大异常值定义为符合不平等的观察:

和小的异常值作为匹配不等式的观察:

我想编写函数replace_outliers(table, std),它将遍历所有变量(所有列)并将大异常值替换为上限,即

和具有下限的小异常值,即

我目前的工作

我所做的是为单变量情况编写函数(仅当我只有一列时才有效)。

Function replace_outliers(table As Range, std As Double)
    Dim temp() As Variant
    temp = table.Value
    
    Dim mean As Double
    mean = Application.WorksheetFunction.Average(temp)
    
    Dim stdv As Double
    stdv = Application.WorksheetFunction.StDev(temp)
    Dim upper_bound As Double
    Dim lower_bound As Double
    upper_bound = std * stdv + mean
    lower_bound = mean - stdv * std
    
    Dim i As Long
    
    For i = 1 To UBound(temp, 1)
        If (temp(i, 1) - mean) / stdv > std Then
            temp(i, 1) = upper_bound
        ElseIf (temp(i, 1) - mean) / stdv < -std Then
            temp(i, 1) = lower_bound
        End If
    Next
    replace_outliers = temp
End Function

例子:

但是我不确定我应该如何扩展它以适应多变量情况(即为提供的输入表中的每一列应用replace_outliers(table, std)。你知道如何执行它吗?

编辑

我试图跨列循环它。这是我的工作:

Function outliers_std_1(table As Range, std As Double)
    Dim temp() As Variant
    temp = table.Value
    Dim j As Long
    For j = 1 To UBound(temp, 2)
        Dim mean As Double
        mean = Application.WorksheetFunction.Average(table.Columns(j))
    
        Dim stdv As Double
        stdv = Application.WorksheetFunction.StDev(table.Columns(j))
        Dim upper_bound As Double
        Dim lower_bound As Double
        upper_bound = std * stdv + mean
        lower_bound = mean - stdv * std
    
        Dim i As Long
    
        For i = 1 To UBound(temp, j)
            If (temp(i, j) - mean) / stdv > std Then
                temp(i, j) = upper_bound
         ElseIf (temp(i, j) - mean) / stdv < -std Then
                temp(i, j) = lower_bound
         End If
         Next
    Next
    outliers_std_1 = temp
End Function

但是我得到#ARG!尝试在以下数据上运行时出错:

【问题讨论】:

  • temp 是一个二维数组,因此您可以轻松地在列上添加一个内部(或者可能是外部)循环,而不是硬编码的1。见Arrays and Ranges
  • 内部循环:Dim j as LongFor j = 1 to Ubound(temp,2) 然后将所有temp(i,1) 替换为temp(i,j)
  • 嗯,我尝试使用您的提示在列之后循环它,但我没有设法正确地做到这一点。我更新了我的问题。我错过了什么吗?
  • mean = Application.WorksheetFunction.Average(table.Columns(j))
  • 嗯,我用计算平均值和标准差调整了我的代码,但我仍然看到#ARG!。请看我的代码

标签: arrays excel vba function


【解决方案1】:

测试:

Function outliers_std_1(table As Range, std As Double)
    Dim temp As Variant, j As Long, i As Long
    Dim mean As Double, stdv As Double
    Dim upper_bound As Double
    Dim lower_bound As Double
    
    temp = table.Value
    
    For j = 1 To UBound(temp, 2)
        
        mean = Application.WorksheetFunction.Average(table.Columns(j))
        stdv = Application.WorksheetFunction.StDev(table.Columns(j))
        upper_bound = mean + (std * stdv)
        lower_bound = mean - (stdv * std)
        
        For i = 1 To UBound(temp, 1)
            If temp(i, j) < lower_bound Then
                   temp(i, j) = lower_bound
            ElseIf temp(i, j) > upper_bound Then
                   temp(i, j) = upper_bound
            End If
        Next
    Next
    outliers_std_1 = temp
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-16
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多