Module stikpetP.other.poho_pairwise_ps

Expand source code
import pandas as pd
from ..tests.test_sign_ps import ts_sign_ps
from ..tests.test_wilcoxon_ps import ts_wilcoxon_ps
from ..tests.test_trinomial_ps import ts_trinomial_ps

def ph_pairwise_ps(data, 
                   levels = None, 
                   test = "sign", 
                   appr = "wilcoxon", 
                   noDiff = "wilcoxon", 
                   ties = True, 
                   cc = False):
    '''
    Post-Hoc Pairwise Paired Samples Tests
    --------------------------------------
    This function simply performs pairwise paired tests: Sign, Wilcoxon and Trinomial. It then adds a Bonferroni correction.
    
    These could be used with a Friedman test, but other post-hoc tests are also available in the ph_friedman() function (a Dunn, Nemenyi and Conover test).
    
    Parameters
    ----------
    data : dataframe
        dataframe with a column for each variable
    levels : dataframe or dictionary, optional
        indication of what the levels are in order
    test : {"sign", "wilcoxon", "trinomial"}, optional
        test to use in pairwise comparisons. Default is sign.
    appr : {"exact", "appr", "wilcoxon", "imanz", "imant"}
        option for sign and wilcoxon test. Default for wilcoxon is wilcoxon, for sign is appr.
    noDiff : {"wilcoxon", "pratt", "zsplit"}, optional 
        method to deal with scores equal to mu. Default is "wilcoxon". Only applies if test="wilcoxon"
    ties : boolean, optional 
        to use a tie correction. Default is True. Only applies if test="wilcoxon"
    cc : boolean, optional 
        use a continuity correction. Default is False. Only applies if test="wilcoxon"
        
    Returns
    -------
    res : dataframe
        test results with the same columns as the test and 
        
        * *var 1*, the name of the first variable in the pair
        * *var 2*, the name of the second variable in the pair
        * *adj. p-value*, the Bonferroni adjusted p-value
    
    Notes
    -----
    This function creates each possible pair of the variables (columns) and then uses the requested paired samples test.
    
    See for the calculations:
    
    * Sign test -> ts_sign_ps()
    * Wilcoxon signed rank test -> ts_wilcoxon_ps()
    * Trinomial test -> ts_trinomial_ps()
    
    The Bonferroni adjustment is done using:
    $$sig._{adj} = \\min \\left(sig. \\times n_c, 1\\right)$$
    $$n_c = \\frac{k\\times\\left(k-1\\right)}{2}$$
    
    Where \\(n_c\\) is the number of comparisons (pairs)
    
    Author
    ------
    Made by P. Stikker
    
    Companion website: https://PeterStatistics.com  
    YouTube channel: https://www.youtube.com/stikpet  
    Donations: https://www.patreon.com/bePatron?u=19398076
    
    '''
    #Remove rows with missing values and reset index
    data = data.dropna()    
    data = data.reset_index(drop=True)   
    
    nr = len(data)
    k = len(data.columns)
    
    if levels is not None:
        data = data.replace(levels)
    
    colNames = data.columns
    
    #number of comparisons
    ncomp = k * (k - 1) / 2
    
    res = pd.DataFrame()
    useRow=0
    for i in range(0, k-1):
        for j in range(i+1, k):
            cat1 = colNames[i]
            cat2 = colNames[j]
            selDf = data[[cat1, cat2]]
            selDf = selDf.dropna()
            
            res.at[useRow,0] = cat1
            res.at[useRow,1] = cat2
            
            if test=="sign":
                testRes = ts_sign_ps(selDf[cat1], selDf[cat2], levels=levels, method=appr)
                res.at[useRow,2] = testRes.iloc[0,0]
                res.at[useRow,3] = testRes.iloc[0,1]
                res.at[useRow,4] = testRes.iloc[0,2]
                res.at[useRow,5] = testRes.iloc[0,3]
                res.at[useRow,6] = testRes.iloc[0,3]*ncomp
                if res.iloc[useRow,6] > 1:
                    res.iloc[useRow,6] = 1
                
            elif test=="wilcoxon":
                testRes = ts_wilcoxon_ps(selDf[cat1], selDf[cat2], levels=levels, appr=appr, noDiff=noDiff, ties=ties, cc=cc)
                res.at[useRow,2] = testRes.iloc[0,0]
                res.at[useRow,3] = testRes.iloc[0,1]
                res.at[useRow,4] = testRes.iloc[0,2]
                res.at[useRow,5] = testRes.iloc[0,3]
                res.at[useRow,6] = testRes.iloc[0,4]
                res.at[useRow,7] = testRes.iloc[0,5]
                res.at[useRow,8] = testRes.iloc[0,5]*ncomp
                if res.iloc[useRow,8] > 1:
                    res.iloc[useRow,8] = 1
            
            elif test=="trinomial":
                testRes = ts_trinomial_ps(selDf[cat1], selDf[cat2], levels=levels)
                res.at[useRow,2] = testRes.iloc[0,0]
                res.at[useRow,3] = testRes.iloc[0,1]
                res.at[useRow,4] = testRes.iloc[0,2]
                res.at[useRow,5] = testRes.iloc[0,3]
                res.at[useRow,6] = testRes.iloc[0,3]*ncomp
                if res.iloc[useRow,6] > 1:
                    res.iloc[useRow,6] = 1
                
            useRow=useRow+1
    
    if test=="sign":
        res.columns = ["var 1", "var 2", "n pos", "n neg", "statistic", "p-value", "adj. p-value"]
    elif test=="wilcoxon":
        res.columns = ["var 1", "var 2", "nr", "mu", "W", "statistic", "df", "p-value", "adj. p-value"]
    elif test=="trinomial":
        res.columns = ["var 1", "var 2", "n pos", "n neg", "n 0", "p-value", "adj. p-value"]
        
    return res

Functions

def ph_pairwise_ps(data, levels=None, test='sign', appr='wilcoxon', noDiff='wilcoxon', ties=True, cc=False)

Post-Hoc Pairwise Paired Samples Tests

This function simply performs pairwise paired tests: Sign, Wilcoxon and Trinomial. It then adds a Bonferroni correction.

These could be used with a Friedman test, but other post-hoc tests are also available in the ph_friedman() function (a Dunn, Nemenyi and Conover test).

Parameters

data : dataframe
dataframe with a column for each variable
levels : dataframe or dictionary, optional
indication of what the levels are in order
test : {"sign", "wilcoxon", "trinomial"}, optional
test to use in pairwise comparisons. Default is sign.
appr : {"exact", "appr", "wilcoxon", "imanz", "imant"}
option for sign and wilcoxon test. Default for wilcoxon is wilcoxon, for sign is appr.
noDiff : {"wilcoxon", "pratt", "zsplit"}, optional
method to deal with scores equal to mu. Default is "wilcoxon". Only applies if test="wilcoxon"
ties : boolean, optional
to use a tie correction. Default is True. Only applies if test="wilcoxon"
cc : boolean, optional
use a continuity correction. Default is False. Only applies if test="wilcoxon"

Returns

res : dataframe

test results with the same columns as the test and

  • var 1, the name of the first variable in the pair
  • var 2, the name of the second variable in the pair
  • adj. p-value, the Bonferroni adjusted p-value

Notes

This function creates each possible pair of the variables (columns) and then uses the requested paired samples test.

See for the calculations:

  • Sign test -> ts_sign_ps()
  • Wilcoxon signed rank test -> ts_wilcoxon_ps()
  • Trinomial test -> ts_trinomial_ps()

The Bonferroni adjustment is done using: sig._{adj} = \min \left(sig. \times n_c, 1\right) n_c = \frac{k\times\left(k-1\right)}{2}

Where n_c is the number of comparisons (pairs)

Author

Made by P. Stikker

Companion website: https://PeterStatistics.com
YouTube channel: https://www.youtube.com/stikpet
Donations: https://www.patreon.com/bePatron?u=19398076

Expand source code
def ph_pairwise_ps(data, 
                   levels = None, 
                   test = "sign", 
                   appr = "wilcoxon", 
                   noDiff = "wilcoxon", 
                   ties = True, 
                   cc = False):
    '''
    Post-Hoc Pairwise Paired Samples Tests
    --------------------------------------
    This function simply performs pairwise paired tests: Sign, Wilcoxon and Trinomial. It then adds a Bonferroni correction.
    
    These could be used with a Friedman test, but other post-hoc tests are also available in the ph_friedman() function (a Dunn, Nemenyi and Conover test).
    
    Parameters
    ----------
    data : dataframe
        dataframe with a column for each variable
    levels : dataframe or dictionary, optional
        indication of what the levels are in order
    test : {"sign", "wilcoxon", "trinomial"}, optional
        test to use in pairwise comparisons. Default is sign.
    appr : {"exact", "appr", "wilcoxon", "imanz", "imant"}
        option for sign and wilcoxon test. Default for wilcoxon is wilcoxon, for sign is appr.
    noDiff : {"wilcoxon", "pratt", "zsplit"}, optional 
        method to deal with scores equal to mu. Default is "wilcoxon". Only applies if test="wilcoxon"
    ties : boolean, optional 
        to use a tie correction. Default is True. Only applies if test="wilcoxon"
    cc : boolean, optional 
        use a continuity correction. Default is False. Only applies if test="wilcoxon"
        
    Returns
    -------
    res : dataframe
        test results with the same columns as the test and 
        
        * *var 1*, the name of the first variable in the pair
        * *var 2*, the name of the second variable in the pair
        * *adj. p-value*, the Bonferroni adjusted p-value
    
    Notes
    -----
    This function creates each possible pair of the variables (columns) and then uses the requested paired samples test.
    
    See for the calculations:
    
    * Sign test -> ts_sign_ps()
    * Wilcoxon signed rank test -> ts_wilcoxon_ps()
    * Trinomial test -> ts_trinomial_ps()
    
    The Bonferroni adjustment is done using:
    $$sig._{adj} = \\min \\left(sig. \\times n_c, 1\\right)$$
    $$n_c = \\frac{k\\times\\left(k-1\\right)}{2}$$
    
    Where \\(n_c\\) is the number of comparisons (pairs)
    
    Author
    ------
    Made by P. Stikker
    
    Companion website: https://PeterStatistics.com  
    YouTube channel: https://www.youtube.com/stikpet  
    Donations: https://www.patreon.com/bePatron?u=19398076
    
    '''
    #Remove rows with missing values and reset index
    data = data.dropna()    
    data = data.reset_index(drop=True)   
    
    nr = len(data)
    k = len(data.columns)
    
    if levels is not None:
        data = data.replace(levels)
    
    colNames = data.columns
    
    #number of comparisons
    ncomp = k * (k - 1) / 2
    
    res = pd.DataFrame()
    useRow=0
    for i in range(0, k-1):
        for j in range(i+1, k):
            cat1 = colNames[i]
            cat2 = colNames[j]
            selDf = data[[cat1, cat2]]
            selDf = selDf.dropna()
            
            res.at[useRow,0] = cat1
            res.at[useRow,1] = cat2
            
            if test=="sign":
                testRes = ts_sign_ps(selDf[cat1], selDf[cat2], levels=levels, method=appr)
                res.at[useRow,2] = testRes.iloc[0,0]
                res.at[useRow,3] = testRes.iloc[0,1]
                res.at[useRow,4] = testRes.iloc[0,2]
                res.at[useRow,5] = testRes.iloc[0,3]
                res.at[useRow,6] = testRes.iloc[0,3]*ncomp
                if res.iloc[useRow,6] > 1:
                    res.iloc[useRow,6] = 1
                
            elif test=="wilcoxon":
                testRes = ts_wilcoxon_ps(selDf[cat1], selDf[cat2], levels=levels, appr=appr, noDiff=noDiff, ties=ties, cc=cc)
                res.at[useRow,2] = testRes.iloc[0,0]
                res.at[useRow,3] = testRes.iloc[0,1]
                res.at[useRow,4] = testRes.iloc[0,2]
                res.at[useRow,5] = testRes.iloc[0,3]
                res.at[useRow,6] = testRes.iloc[0,4]
                res.at[useRow,7] = testRes.iloc[0,5]
                res.at[useRow,8] = testRes.iloc[0,5]*ncomp
                if res.iloc[useRow,8] > 1:
                    res.iloc[useRow,8] = 1
            
            elif test=="trinomial":
                testRes = ts_trinomial_ps(selDf[cat1], selDf[cat2], levels=levels)
                res.at[useRow,2] = testRes.iloc[0,0]
                res.at[useRow,3] = testRes.iloc[0,1]
                res.at[useRow,4] = testRes.iloc[0,2]
                res.at[useRow,5] = testRes.iloc[0,3]
                res.at[useRow,6] = testRes.iloc[0,3]*ncomp
                if res.iloc[useRow,6] > 1:
                    res.iloc[useRow,6] = 1
                
            useRow=useRow+1
    
    if test=="sign":
        res.columns = ["var 1", "var 2", "n pos", "n neg", "statistic", "p-value", "adj. p-value"]
    elif test=="wilcoxon":
        res.columns = ["var 1", "var 2", "nr", "mu", "W", "statistic", "df", "p-value", "adj. p-value"]
    elif test=="trinomial":
        res.columns = ["var 1", "var 2", "n pos", "n neg", "n 0", "p-value", "adj. p-value"]
        
    return res