我创建了一个执行统计技术引导的VBA脚本。我的原始样本是通过在excel中使用数据分析工具从泊松分布中提取的(因为在泊松分布的excel函数中没有反向构建,我想不出任何其他模拟泊松分布值的方法)。但是,当我运行我的VBA脚本时,我从第一次迭代中得到了这个通知:
"随机数生成 - 输出范围将覆盖现有数据。按OK键覆盖范围内的数据:' [TestCoverage(Poisson,ss50).xlsm] ParametricBootstrap'!$ B $ 2:$ B $ 51"
我知道"覆盖"在使用数据分析工具时需求,因此在运行VBA脚本之前,我总是检查单元格是否为空。但除了检查自己是否清楚之外,我已经在模型中加入了一个特定部分,用于清除问题所指示的单元格内容,就在第一次使用工具之前(第16行),但仍然是VBA脚本的行为就像显示此通知的单元格不为空。当VBA脚本到达第22行(数据分析工具的操作)时,它会抛出上一条消息。
奇特的部分是我创建了一个相同的VBA脚本(因为我必须为分布池评估bootstrapping),它使用数据分析工具再次从Normal分布中绘制原始样本,但是那种情况它运作正常。
这是代码:
Sub parametricbootstrappoisson50()
Dim iterations As Integer
iterations = InputBox("Please insert the number of times you want the bootstrapping process to be performed")
Application.ScreenUpdating = False
'These statements clear the results in the Coverage Results sheet existing from previous operations of the macro
Sheets("Coverage Results").Activate
Range("A3").Select
Range(Selection, Selection.End(xlToRight)).Select
Range(Selection, Selection.End(xlDown)).Select
Selection.ClearContents
Sheets("Parametric Bootstrap").Activate
Range("B2:C51").Select
Selection.ClearContents
For n = 1 To iterations
'Creates an original sample from a Poisson distribution with parameter lambda P2 (mean)
Application.Run "ATPVBAEN.XLAM!Random", ActiveSheet.Range("$B$2"), 1, 50, _
5, , Range("P2").Value
'1000 bootstrap samples and bootstrap means are produced and stored in the respective cells
For i = 1 To 1000
'Creates a bootstrap sample from a Poisson distribution with estimated parameter lambda Q2 (mean)
Application.Run "ATPVBAEN.XLAM!Random", ActiveSheet.Range("$B$2"), 1, 50, _
5, , Range("Q2").Value
Sheets("Parametric Bootstrap").Range("E2").Offset(i, 0).Value = Sheets("Parametric Bootstrap").Range("R2").Value
'Delete the bootstrap sample produced so that it will not need confirmation to overwrite the data when the next bootstrap sample will be drawn
Range("C2:C51").Select
Selection.ClearContents
Next i
'This is the process of transferring the results of the bootstrapping process to the Coverage Results sheet
Sheets("Coverage Results").Range("A1:F1").Offset(n, 0).Value = Sheets("Parametric Bootstrap").Range("I2:N2").Value
'Indication on whether the population mean is covered from the bootstrap confidence intervals of the nth iteration or not
If Sheets("Parametric Bootstrap").Range("P2").Value >= Sheets("Coverage Results").Range("C1").Offset(n, 0).Value And Sheets("Parametric Bootstrap").Range("P2").Value <= Sheets("Coverage Results").Range("D1").Offset(n, 0).Value Then
Sheets("Coverage Results").Range("G1").Offset(n, 0).Value = "Yes"
Else
Sheets("Coverage Results").Range("G1").Offset(n, 0).Value = "No"
End If
Sheets("Parametric Bootstrap").Activate
'Delete the original sample produced so that it will not need confirmation to overwrite the data when the next original sample will be drawn
Range("B2:B51").Select
Selection.ClearContents
Next n
Application.ScreenUpdating = True
Sheets("Coverage Results").Activate
Range("I2").Select
End Sub
答案 0 :(得分:0)
这并不是你问题的答案,但我有机会进行模拟,需要模拟泊松随机变量,并为此编写了我自己的用户定义函数。它的工作原理是模拟泊松过程并计算1个单位时间内的到达次数。如果您希望评论标记的行为类似于工作表函数Application.Volatile
,请从Rand()
移除评论标记,并在电子表格发生任何更改时重新计算。
Function RandPoisson(lambda As Double) As Long
'Application.Volatile
Dim count As Long
Dim x As Double, sum As Double
Do While True
x = -Log(Rnd()) / lambda
If sum + x > 1 Then
RandPoisson = count
Exit Function
Else
sum = sum + x
count = count + 1
End If
Loop
End Function
为了测试这个,我编写了以下子,并将输出与内置函数Poisson.Dist
进行了比较:
Sub test()
Dim i As Long, p As Long
Dim counts As Variant
ReDim counts(0 To 9)
Randomize
For i = 1 To 1000000
p = RandPoisson(3)
If p < 10 Then counts(p) = counts(p) + 1
Next i
For i = 0 To 9
Range("B2").Offset(i).Value = counts(i) / 1000000
Next i
End Sub
输出:
即使涉及一百万次模拟,计算也只需要1秒钟。