For median, how to pick higher of two values, Access

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

Does anyone know the Visual Basic for: if the median is a tie, then pick
the higher of two values? Example: we do two-fold dilutions to test
antibiotics: .5, 1, 2, 4, 8, 16, 32, etc. If the median is evenly split
between 8 and 16, how can I program the results so it will pick the higher
value? Any help would be much appreciated. Thanks.
 
Does anyone know the Visual Basic for: if the median is a tie, then pick
the higher of two values? Example: we do two-fold dilutions to test
antibiotics: .5, 1, 2, 4, 8, 16, 32, etc. If the median is evenly split
between 8 and 16, how can I program the results so it will pick the higher
value? Any help would be much appreciated. Thanks.

Here's a Median function that emerged from a thread here the other day.
I think that all you'll need to do to convert it to your
not-quite-median function is

1) Replace every occurrence of Median870 with another name.
2) Add a comment to make it clear that it handles "ties" in a non-
standard way and taking responsibility for the changed code
3) Change this line
Answer = (Answer + rst.Fields("Val").Value) / 2
to
Answer = rst.Fields("Val").Value
4) Test it.

Public Function Median870(ByVal SQL As String) As Variant
'SQL must be a Jet SQL SELECT statement query that returns
'fields Qty and Val ordered by Val ASC
'based on code posted by Tim Ferguson
'elaborated by John Nurick and
'refined with testing and input from Tom Wickerath

Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim rstSums As DAO.Recordset
Dim MinVal As Long
Dim QtyTotal As Long
Dim QtySoFar As Long
Dim Answer As Variant ' or currency if you prefer

Set db = CurrentDb()
If Right(SQL, 1) = ";" Then
SQL = Left(SQL, Len(SQL) - 1)
End If

Set rst = db.OpenRecordset(SQL, dbOpenSnapshot, dbForwardOnly)
If rst.EOF Then
MsgBox "Empty recordset", vbExclamation + vbOKOnly
Median870 = Null
Exit Function
End If

Set rstSums = db.OpenRecordset("SELECT MIN(Val), SUM(QTY) FROM (" _
& SQL & ")", dbOpenSnapshot, dbForwardOnly)
MinVal = rstSums.Fields(0).Value
QtyTotal = rstSums.Fields(1).Value
Answer = Null
rstSums.Close


Do While IsNull(Answer)
' we should never see the end of the recordset
If rst.EOF Then Err.Raise 9999, , "Someone has blundered!"

QtySoFar = QtySoFar + rst.Fields("Qty").Value

If QtySoFar * 2 > QtyTotal + 1 Then
' if we've gone past, we don't need to worry about interpolating
Answer = rst.Fields("Val").Value 'wrap in CDbl()
'or CCur() if desired

ElseIf QtySoFar * 2 = QtyTotal + 1 Then
' okay, it's exactly the middle one out of an odd
' number so we've got the answer
Answer = rst.Fields("Val").Value

ElseIf QtySoFar * 2 = QtyTotal Then
' this is the first of the middle pair; we need to
' average this Val and the next one
Answer = rst.Fields("Val").Value
rst.MoveNext
If rst.EOF Then
'The middle item is in the last record, so the
'median Val is also the maximum Val
'and Answer is already set to the right value
Else
Answer = (Answer + rst.Fields("Val").Value) / 2
End If

Else
' no joy yet, just get the next record and move on
rst.MoveNext

End If
Loop
rst.Close

' return Answer (use CDbl() or CCur() if desired)
Median870 = Answer
End Function
 
Hi

I can give you this but please confirm how you define median as your scale
increases to the power of 2.

So do you consider the median between, say, 8 and 16 to be 12, or 11.31 (2
to power 3.5)?

BW
 
I see nothing in John's code that increases to the power of 2. He's
multiplying numbers by 2, not squaring them.
 
True - a slip of the tongue but my question is still valid.

I should have said that his progression incresases at the rate of 2 to the
power n (where n is an integer).

My question is still relevant.

e.g. with the 8 to 16 range, is he looking to match against the mid-point of
the numbers (12) or the mid-point of the progression (2 to power 3.5 =
11.31..). My guesse is, is that its the later.

Regards.

BW
 
If the median is evenly split
between 8 and 16, how can I program the results so it will pick the
higher value?

If (numberOfValues And 1) Then ' odd
' assuming a one-based list, also assuming it's ordered in
' increasing value
medianValue = valueAt((numberOfValues + 1) / 2)

Else ' even
medianValue = valueAt(numberOfValues / 2 + 1)

End If


Hope that helps


Tim F
 
I still don't see how he's progressing exponentially in any way.

My suggestion would be to copy his code into a module, make the suggested
changes, then see what value it returns.

For another take on Median, see my October, 2005 "Access Answers" column in
Pinnacle Publication's "Smart Access". You can download the column (and
sample database) for free at
http://www.accessmvp.com/DJSteele/SmartAccess.html
 
Here's a Median function that emerged from a thread here the other day.
I think that all you'll need to do to convert it to your
not-quite-median function is

This was a rather specialised version, for the situation where the
records are in (Value, Count) i.e.

345.34, 2
348.65, 6
390.02, 12
412.33, 8
450.99, 1


so there is a total of 29 values to search for the median in. From the OP
it sounds as though it's a much simpler situation of a single list.

Of course, if it really is just finding the middle of a geometric
progression, then it's something along the lines of

0.5 * 2^Int(n/2)

where 0.5 is the starting point and n is the number of values. I have not
tested this, though!

Hope that helps


Tim F
 
Hi Tim,

This was a rather specialised version, for the situation where the
records are in (Value, Count) i.e.

345.34, 2
348.65, 6
390.02, 12
412.33, 8
450.99, 1

Yes, I should have mentioned this. But for the simple case one can just
feed it a list of Values and hold the Count at 1:
345.34, 1
348.65, 1
...
 
I've not even doing that. Where the median falls between two items on
the list, the function as posted returns the mean of the two values.

But the OP said "if the median is a tie, then pick
the higher of two values? ... the higher value". So this is how I read
it:

Values: 1,2,3,4,5
Median: 3

Values: 1,2,3,4
Median conventionally calculated: (2+3)/2 = 2.5
"Median" for OP: MAX(2,3) = 3
 
Yes, I should have mentioned this. But for the simple case one can just
feed it a list of Values and hold the Count at 1:
345.34, 1
348.65, 1
...

But it's still a really bad solution for such a situation. Far easier just
to work out the total number of values and go straight to the int((n+1)/2)
value.

Since the OP mentioned something about serial dilutions, and provided data
that looked an awful lot like a geometric progression, the actual answer is
a one-line expression anyway.

B Wishes

Tim F
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top