Sign in to follow this  
Followers 0
Mat

Spearmans Rank Correlation Coefficient Calculator

5 posts in this topic

#1 ·  Posted (edited)

"Correlation Coefficient Calculator", now that sounds awesome!

Anyhow, Spearmans rank is a method of testing whether 2 sets of data show any correlation. It returns a result between -1 and +1, -1 being perfect negative correlation, 0 being no correlation, and +1 being perfect positive correlation.

This is a simple GUI where you enter the values, and it does the maths, and creates you a table in excel. Its very simple, but helps a lot!

http://AutoMatIc.fileave.com/AutoMatIc/Spearmans Rank.zip

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=..\..\..\..\Documents and Settings\Diesel Home\My Documents\My documents\Dowloads\Fast Launcher\Icons\019.ico
#AutoIt3Wrapper_outfile=Spearmans Rank.exe
#AutoIt3Wrapper_Compression=4
#AutoIt3Wrapper_Res_Description=Spearmans rank calculator!
#AutoIt3Wrapper_Res_Fileversion=1.0.0.2
#AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y
#AutoIt3Wrapper_Res_LegalCopyright=Matt Diesel 2009
#AutoIt3Wrapper_Run_AU3Check=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
; Spearmans rank!!

#include<excel.au3>

Local $alist[2], $aInp[2], $hTab, $aLbl[2]

$hGUI = GUICreate("Spearmans Rank", 300, 580, -1, -1, BitOR(0x00040000, 0x00080000, 0x00020000, 0x00010000, 0x00C00000))
   GUICtrlCreateLabel("Spearans Rank is a famous test for finding a correlation between 2 data sets. " & _
        "Start by entering your sets of data to compare. The computer do the maths for you.", 2, 2, 296, 40)
      GUICtrlSetResizing(-1, 0x0002 + 0x0020 + 0x0200)
   GUICtrlCreateLabel("Dataset name:", 4, 72, 70, 20)
      GUICtrlSetResizing(-1, 0x0002 + 0x0020 + 0x0200 + 0x0100)
   $hTab = GUICtrlCreateTab(2, 44, 296, 514)
      GUICtrlSetResizing(-1, 0x0020 + 0x0002 + 0x0040 + 0x0004)
      GUICtrlCreateTabItem("Set 1 Data")
         $aInp[0] = GUICtrlCreateInput("Set 1 Data", 74, 70, 220, 20)
            GUICtrlSetResizing(-1, 0x0020 + 0x0002 + 0x0200 + 0x0004)
         $alist[0] = GUICtrlCreateListView("Data:", 2, 90, 230, 466, 0x8000 + 0x0008, 0x00000020 + 0x00000001 + 0x00010000)
            GUICtrlSetResizing(-1, 0x0020 + 0x0002 + 0x0040 + 0x0004)
            GUICtrlSendMsg($alist[0], 0x1000 + 30, 0, -2)
         $aLbl[0] = GUICtrlCreateLabel("0 Item(s).", 234, 534, 80, 20)
            GUICtrlSetResizing(-1, 0x0040 + 0x0004 + 0x0100 + 0x0200)
      GUICtrlCreateTabItem("Set 2 Data")
         $aInp[1] = GUICtrlCreateInput("Set 2 Data", 74, 70, 220, 20)
            GUICtrlSetResizing(-1, 0x0020 + 0x0002 + 0x0200 + 0x0004)
         $alist[1] = GUICtrlCreateListView("Data:", 2, 90, 230, 466, 0x8000 + 0x0008, 0x00000020 + 0x00000001 + 0x00010000)
            GUICtrlSetResizing(-1, 0x0020 + 0x0002 + 0x0040 + 0x0004)
            GUICtrlSendMsg($alist[1], 0x1000 + 30, 0, -2)
         $aLbl[1] = GUICtrlCreateLabel("0 Item(s).", 234, 534, 80, 20)
            GUICtrlSetResizing(-1, 0x0040 + 0x0004 + 0x0100)
   GUICtrlCreateTabItem("")
   $hAdd = GUICtrlCreateButton("Add", 234, 90, 60, 20)
      GUICtrlSetResizing(-1, 0x0020 + 0x0004 + 0x0100 + 0x0200)
   $hEdt = GUICtrlCreateButton("Edit", 234, 112, 60, 20)
      GUICtrlSetResizing(-1, 0x0020 + 0x0004 + 0x0100 + 0x0200)
   $hRem = GUICtrlCreateButton("Remove", 234, 134, 60, 20)
      GUICtrlSetResizing(-1, 0x0020 + 0x0004 + 0x0100 + 0x0200)
   $hAll = GUICtrlCreateButton("Remove All", 234, 156, 60, 20)
      GUICtrlSetResizing(-1, 0x0020 + 0x0004 + 0x0100 + 0x0200)

   GUICtrlCreateLabel("By Matt Diesel 2009", 2, 560, 128, 20)
   GUICtrlSetResizing(-1, 0x0240)
   $hCnc = GUICtrlCreateButton("Cancel", 132, 558, 80, 20)
   GUICtrlSetResizing(-1, 0x0240)
   $hFin = GUICtrlCreateButton("Finished", 214, 558, 80, 20)
   GUICtrlSetResizing(-1, 0x0240)
   GUICtrlSetState($hFin, 128)

GUISetState()

Local $aCur[2] = ["Set 1 Data", "Set 2 Data"]

While 1
    Switch GUIGetMsg()
        Case - 3, $hCnc
            Exit
        Case $hAdd
            $nCur = GUICtrlRead($hTab)
            $temp = InputBox("Enter new value...", "Please enter the new value to be added to data set " & $nCur + 1 & ".", _
                    "", "", 200, 130)
            If @Error Then ContinueLoop
            _CheckInput($temp + 0)
            If @Error Then ContinueLoop
            GUICtrlCreateListViewItem($temp, $alist[$nCur])
            GUICtrlSetData($aLbl[$nCur], StringRegExpReplace(GUICtrlRead($aLbl[$nCur]), "([0-9]*)(.*)", "\1") + 1 & " Item(s).")
            If(GUICtrlSendMsg($alist[0], 0x1000 + 4, 0, 0) = GUICtrlSendMsg($alist[1], 0x1000 + 4, 0, 0)) AND(GUICtrlSendMsg($alist[1], 0x1000 + 4, 0, 0) <> 0) Then
                GUICtrlSetState($hFin, 64)
            Else
                GUICtrlSetState($hFin, 128)
            EndIf
        Case $hEdt
            $nCur = GUICtrlRead($hTab)
            $nItm = GUICtrlRead($alist[$nCur])
            If $nItm = 0 Then ContinueLoop
            $temp = InputBox("Edit Current Value...", "Please enter the new value for the current data in set " & $nCur + 1 & ".", _
                    StringTrimRight(GUICtrlRead($nItm), 1), "", 200, 130)
            If @Error Then ContinueLoop
            If $temp = "" Then
                GUICtrlDelete($nItm)
                GUICtrlSetData($aLbl[$nCur], StringRegExpReplace(GUICtrlRead($aLbl[$nCur]), "([0-9]*)(.*)", "\1") - 1 & " Item(s).")
                If(GUICtrlSendMsg($alist[0], 0x1000 + 4, 0, 0) = GUICtrlSendMsg($alist[1], 0x1000 + 4, 0, 0)) AND(GUICtrlSendMsg($alist[1], 0x1000 + 4, 0, 0) <> 0) Then
                    GUICtrlSetState($hFin, 64)
                Else
                    GUICtrlSetState($hFin, 128)
                EndIf
                continueLoop
            EndIf
            _CheckInput($temp + 0)
            If @Error Then ContinueLoop
            GUICtrlSetData($nItm, $temp)
        Case $hRem
            GUICtrlDelete(GUICtrlRead($alist[GUICtrlRead($hTab)]))
            GUICtrlSetData($aLbl[$nCur], StringRegExpReplace(GUICtrlRead($aLbl[$nCur]), "([0-9]*)(.*)", "\1") - 1 & " Item(s).")
            If(GUICtrlSendMsg($alist[0], 0x1000 + 4, 0, 0) = GUICtrlSendMsg($alist[1], 0x1000 + 4, 0, 0)) AND(GUICtrlSendMsg($alist[1], 0x1000 + 4, 0, 0) <> 0) Then
                GUICtrlSetState($hFin, 64)
            Else
                GUICtrlSetState($hFin, 128)
            EndIf
        Case $hAll
            GUICtrlSendMsg($alist[GUICtrlRead($hTab)], 0x1000 + 9, 0, 0)
            GUICtrlSetData($aLbl[$nCur], "0 Item(s).")
            GUICtrlSetState($hFin, 128)
        Case $hFin
            Local $nCnt[2] = [GUICtrlSendMsg($alist[0], 0x1000 + 4, 0, 0), GUICtrlSendMsg($alist[1], 0x1000 + 4, 0, 0)]
            If $nCnt[0] <> $nCnt[1] Then ContinueLoop 1 + 0 * MsgBox(16, "Error", _
                    "Number of items in each data set do not match! You have " & $nCnt[0] & " bits of data in set 1, and " & _
                    $nCnt[1] & " bits i set 2." & @CRLF & @CRLF & "Please check your data sets and then continue.")
            Local $aItem0[$nCnt[0] + 1]
            Local $aItem1[$nCnt[0] + 1]
            For $i = 1 to $nCnt[0]
                $aItem0[$i] = ControlListView($hGUI, "", $alist[0], "GetText", $i - 1, 0) + 0
                $aItem1[$i] = ControlListView($hGUI, "", $alist[1], "GetText", $i - 1, 0) + 0
            Next
            $temp0 = _ArrayGetOrder($aItem0, 1, 0, 1)
            $temp1 = _ArrayGetOrder($aItem1, 1, 0, 1)
            $temp = 0
            For $i = 0 to $nCnt[0] - 1
                $temp += ($temp0[$i] - $temp1[$i]) ^ 2
            Next
            $oExcel = _ExcelBookNew(0)
            _ExcelSheetNameSet($oExcel, "Results")
            ; Headings
            _ExcelWriteCell($oExcel, "Spearmans rank Results", 1, 1)
            _ExcelWriteCell($oExcel, GUICtrlRead($aInp[0]), 3, 1)
            _ExcelWriteCell($oExcel, "Rank", 3, 2)
            _ExcelWriteCell($oExcel, GUICtrlRead($aInp[1]), 3, 3)
            _ExcelWriteCell($oExcel, "Rank", 3, 4)
            _ExcelWriteCell($oExcel, "Difference", 3, 5)
            _ExcelWriteCell($oExcel, "d^2", 3, 6)
            ; Data
            For $i = 1 to $nCnt[0]
                _ExcelWriteCell($oExcel, $aItem0[$i], $i + 3, 1)
                _ExcelWriteCell($oExcel, $temp0[$i - 1], $i + 3, 2)
                _ExcelWriteCell($oExcel, $aItem1[$i], $i + 3, 3)
                _ExcelWriteCell($oExcel, $temp1[$i - 1], $i + 3, 4)
                _ExcelWriteCell($oExcel, $temp0[$i - 1] - $temp1[$i - 1], $i + 3, 5)
                _ExcelWriteCell($oExcel, ($temp0[$i - 1] - $temp1[$i - 1]) ^ 2, $i + 3, 6)
            Next
            _ExcelWriteCell($oExcel, $temp, $i + 4, 6)
            _ExcelWriteCell($oExcel, 1 - ((6 * $temp) / (($nCnt[0] ^ 3) - $nCnt[0])), $i + 7, 6)
            $oExcel.Columns.AutoFit
            $sFile = FileSaveDialog("Save spearmans rank analysis...", @WorkingDir, "Excel spreadsheet (*.xls)|All Files (*.*)")
            If @Error Then _ExcelBookClose($oExcel, 0)
            _ExcelBookSaveAs($oExcel, $sFile)
    EndSwitch
    $cur = GUICtrlRead($hTab)
    If GUICtrlRead($aInp[$cur]) = $aCur[$cur] Then ContinueLoop
    $aCur[$cur] = GUICtrlRead($aInp[$cur])
    GUICtrlSetData(GUICtrlRead($hTab, 1), $aCur[$cur])
WEnd

Func _ArrayGetOrder($aArray, $iStart = 0, $iEnd = 0, $nRetType = 0)
    If Not IsArray($aArray) Then Return SetError(1, 0, -1)
    If UBound($aArray, 0) <> 1 Then Return SetError(3, 0, -1)

    Local $iUBound = UBound($aArray) - 1

    ; Bounds checking
    If $iEnd < 1 Or $iEnd > $iUBound Then $iEnd = $iUBound
    If $iStart < 0 Then $iStart = 0
    If $iStart > $iEnd Then Return SetError(2, 0, -1)

    Local $temp = ""

    For $i = $iStart to $iEnd
        $iMaxIndex = 0
        If Not IsNumber($aArray[$i]) Then Return SetError(4, $i, -1)
        For $x = $iStart To $iEnd
            If $aArray[$iMaxIndex] < $aArray[$x] Then $iMaxIndex = $x
        Next
        $temp = $iMaxIndex & "," & $temp
        $aArray[$iMaxIndex] = 0
    Next
    $temp = StringTrimRight($temp, 1)
    If $nRetType = 0 then return $temp
    Return StringSplit($temp, ",", 2)
EndFunc   ;==>_ArrayGetOrder

Func _CheckInput($sInput)
    If $sInput = "" Then Return SetError(1, 0 * MsgBox(16, "Error", "Input cannot be blank"), 0)
    If Not IsNumber($sInput) Then SetError(2, 0 * MsgBox(16, "Error", "Input must be a number"), 0)
    Return 1
EndFunc   ;==>_CheckInput

Mat

Edited by Mat

Share this post


Link to post
Share on other sites



It returns a result between -0.1 and +0.1, -0.1 being perfect negative correlation, 0 being no correlation, and +0.1 being perfect positive correlation.

Shouldn't rho be between -1 and +1?

Nice work.


- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!

Share this post


Link to post
Share on other sites

Shouldn't rho be between -1 and +1?

Nice work.

hmm... Wikipedai doesn't mention it... But my geography teacher said it should be between -0.1 and +0.1.

I did a test with 2 similar sets of data and got:"0.942857142857143", which is what i'd expect.

Thanks.

Mat

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

But my geography teacher said it should be between -0.1 and +0.1.

If you get a result of 0.9428... then you can assume either of two things:

1) your code gives the wrong answer

2) your teacher is wrong

Guess which it is!

Never assume that everything everyone tells you is correct...even teachers.

Edited by andybiochem

- Table UDF - create simple data tables - Line Graph UDF GDI+ - quickly create simple line graphs with x and y axes (uses GDI+ with double buffer) - Line Graph UDF - quickly create simple line graphs with x and y axes (uses AI native graphic control) - Barcode Generator Code 128 B C - Create the 1/0 code for barcodes. - WebCam as BarCode Reader - use your webcam to read barcodes - Stereograms!!! - make your own stereograms in AutoIT - Ziggurat Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Box-Muller Gaussian Distribution RNG - generate random numbers based on normal/gaussian distribution - Elastic Radio Buttons - faux-gravity effects in AutoIT (from javascript)- Morse Code Generator - Generate morse code by tapping your spacebar!

Share this post


Link to post
Share on other sites

LOL!!!! I only just realized how I had contradicted myself in the same post. Geez thats a real low.

You're right... Luckily my code is too. Unfortunately I have another GCSE added to my "Probably fail" list, alongside french.

Mat

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0