【发布时间】: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 Long和For j = 1 to Ubound(temp,2)然后将所有temp(i,1)替换为temp(i,j) -
嗯,我尝试使用您的提示在列之后循环它,但我没有设法正确地做到这一点。我更新了我的问题。我错过了什么吗?
-
mean = Application.WorksheetFunction.Average(table.Columns(j))等 -
嗯,我用计算平均值和标准差调整了我的代码,但我仍然看到#ARG!。请看我的代码