standard deviation for certain cells in a range

ThomasOES

Board Regular
Joined
Aug 29, 2017
Messages
174
This works for the average. Yet I need the standard deviation

VBA Code:
Set namcol = Range("A2",Range("A2").End(xlDown))
Set fitcol = Range("D2",Range("D2").End(xlDown))
monav = WorksheetFunction.AverageIf(namcol, "Mon", fitcol)
 

Excel Facts

Do you hate GETPIVOTDATA?
Prevent GETPIVOTDATA. Select inside a PivotTable. In the Analyze tab of the ribbon, open the dropown next to Options and turn it off
This works but I cant use a formula. The ranges need to be dynamic
VBA Code:
Selection.FormulaArray = "=STDEV(IF(A1:A17=""Mon"",I1:I17))"
 
Upvote 0
Choose your poison.

Method 1:
sd = Evaluate("stdev(if(" & namcol.Address & "= ""Mon"", " & fitcol.Address & "))")

Method 2:
Excel Formula:
monsum = 0: n = 0
For i = 1 To namcol.Count
   If LCase(namcol(i)) = "mon" Then monsum = monsum + fitcol(i) ^ 2: n = n + 1
Next
sd = Sqr((monsum - n * monav ^ 2) / (n - 1))

Method 1 really does its work in the Excel thread. It is not a "pure" VBA solution.

Aside.... Consider whether to use STDEVP (exact std dev). STDEV is an estimated std dev, assuming that fitcol is sample of a larger "population".

If you decide to use STDEVP, the calculation for Method 2 is:

sd = Sqr(monsum/n - monav ^ 2)
 
Upvote 0
Solution
Notes (too late to edit)....

sd = Evaluate("stdev(if(" & namcol.Address & "= ""Mon"", " & fitcol.Address & "))")
[....]
sd = Sqr((monsum - n * monav ^ 2) / (n - 1))

There can be an infinitesimal difference between the two calculations, due to binary arithmetic anomalies.

Although "infinitesimal", the difference might be visible when displaying 15 significant digits.

-----

If LCase(namcol(i)) = "mon" Then

In Excel, A2="Mon" and A2="mon" are both true, no matter how "mon" is capitalized in A2 (even "mOn").

But VBA requires an exact match. It is equivalent to EXACT(A2, "Mon") in Excel.

The use of LCase causes the VBA comparison to be compatible with the Excel comparison. But it might not be necessary for your data.
 
Upvote 0
VBA Code:
=STDEV(I2,I3,I4,I14)
When I manually enter the cells to get standard deviation my result is 0.000275
cell values are 0.0216, 0.0211, 0.0217, 0.0213
Your code value is 0.00149
 
Upvote 0
When I manually enter the cells to get standard deviation my result is 0.000275 [....] Your code value is 0.00149

I cannot comment on any mistakes you might have made, due to insufficient information.

After reviewing the following, if you are still unable to make the code work, post the Excel formulas and data and the VBA code and result in the same manner as below, and I will see if I can spot the problem

-----

The following is the Excel data and formulas that I used to validate my suggestions.

vba stdevif.xlsm
ADEFGH
1formulacheck
2Fri70.5529.0578226300596STDEVP29.0578226300596
3Mon12.1832.4876333394725STDEV32.4876333394725
4Wed94.14
5Fri92.04
6mon59.32
7Wed37.06
8Fri37.21
9Mon62.50
10Wed45.64
11Fri39.54
12Mon79.26
13Wed31.13
14Fri78.11
15Mon99.90
16Wed44.60
Sheet1
Formulas:
F2: { STDEVP(IF($A$2:$A$16="mon",$D$2:$D$16)) }
F3: { STDEV(IF($A$2:$A$16="mon",$D$2:$D$16)) }
H2: =STDEVP($D$3,$D$6,$D$9,$D$12,$D$15)
H3: =STDEV($D$3,$D$6,$D$9,$D$12,$D$15)
Caveat: We must manually array-enter formulas in F2 and F3 (sigh). Do not type the curly braces. Press ctrl+shift+Enter instead of just Enter.
[/CODE]

The following is the VBA code.

VBA Code:
' it is prudent to declare all variables.
' I omit declarations for simplicity
Sub doit()
Set namcol = Range("A2", Range("A2").End(xlDown))
Set fitcol = Range("D2", Range("D2").End(xlDown))
monav = WorksheetFunction.AverageIf(namcol, "Mon", fitcol)
monsum = 0: n = 0
For i = 1 To namcol.Count
    If LCase(namcol(i)) = "mon" Then monsum = monsum + fitcol(i) ^ 2: n = n + 1
Next
sdP = Sqr(monsum / n - monav ^ 2)               ' compare with STDEVP
sdS = Sqr((monsum - n * monav ^ 2) / (n - 1))   ' compare with STDEV
xlsdS = Evaluate("stdev(if(" & namcol.Address & "= ""Mon"", " & fitcol.Address & "))")
MsgBox "STDEVP" & vbNewLine & _
    sdP & vbNewLine & Range("f2") & vbNewLine & sdP - Range("f2") & _
    vbNewLine & vbNewLine & "STDEV" & _
    vbNewLine & sdS & vbNewLine & Range("f3") & vbNewLine & sdS - Range("f3") & _
    vbNewLine & vbNewLine & "STDEV (EVALUATE)" & _
    vbNewLine & xlsdS & vbNewLine & Range("f3") & vbNewLine & xlsdS - Range("f3")
End Sub

The following is the result.

vba stdevif.jpg
 
Last edited:
Upvote 0
PTP TEST GDS.xlsm
ABCDEFGHI
1SamplePosAlD-1D-2D-3D-4AvgFit
2Mon-1-30.02250.02250.02250.02250.02250.0216
3Mon-1-30.02190.02190.02190.02190.02190.0211
4Mon-1-30.02260.02260.02260.02260.02260.0217
51Q21L111-20.02030.02030.02050.02030.02040.0196
61Q21L212-20.03640.03640.03660.03640.03650.0352
7E 195-1D10-0.0240.020.02010.01980.02010.020.0192
812X 615001(0.0066)0.00420.00370.00420.00410.00410.0038
9CKD 165I90.010.00950.00960.00950.00950.00950.0091
10BSP 202280.0120.0130.01320.01310.01290.01310.0125
11BS 8620A50.0160.01660.01660.01650.0170.01670.016
12BS 195120.020.02210.02210.02210.02260.02220.0213
13BS 8620B60.0220.02390.02390.02370.02350.02380.0229
14Mon-10.02230.02220.02220.02220.02220.02220.0213
15BS 61D30.0230.02410.02410.0240.02410.02410.0232
16BS 67B40.0240.02430.02440.02440.02420.02430.0234
17BS 874070.0370.0380.0380.0380.03770.03790.0365
Al





VBA Code:
Set taborg = Range("A2")
brtt = taborg.End(xlDown).Count
reps = Range("reps").Value
Set fitcol = taborg.Offset(, 4 + reps).Resize(brtt)
Set namcol = taborg.Offset(-1).Resize(brtt + 1)
monsum = 0: n = 0
For i = 1 To namcol.Count
    If namcol(i) = "Mon" Then monsum = monsum + (fitcol(i) - monav) ^ 2: n = n + 1
Next
slorg.Offset(5, 12).Value = Sqr(monsum / n)
 
Last edited:
Upvote 0
Mon is an abbreviation of monitor. After the data is fitted I need some info of the monitor performance. Avg, StDev, ect. Needs to be dynamic. Sometimes theres many more or less samples.
 
Upvote 0
slorg.Offset(5, 12).Value = Sqr(monsum / n)

I wrote previously: Sqr(monsum / n - monav ^ 2)

I should have explained that this is an mathematically-equivalent alternative to the typical std dev expression.

However, that expression calculates STDEVP, not STDEV.

As I wrote previously, the expression for STDEV is: Sqr((monsum - n * monav ^ 2) / (n - 1))

I expect you to copy-and-paste from the text of my postings, then edit as needed (to change variable names). That minimizes your mistakes.

-----

Minor typo....
F2: { STDEVP(IF($A$2:$A$16="mon",$D$2:$D$16)) }
F3: { STDEV(IF($A$2:$A$16="mon",$D$2:$D$16)) }

Of course, there is an "=" before "STDEV" in each formula, which you can see by selecting or hovering the cursor over each cell in the XL2BB snippet. So:

F2: { =STDEVP(IF($A$2:$A$16="mon",$D$2:$D$16)) }
F3: { =STDEV(IF($A$2:$A$16="mon",$D$2:$D$16)) }
 
Upvote 0

Forum statistics

Threads
1,223,375
Messages
6,171,738
Members
452,419
Latest member
mapa

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top