U
    Ãmœd§Y  ã                   @   s.  d dl Zd dlmZ d dlZd dlmZmZ d dlZd dl	m
Z
 d dlmZ d dlmZmZmZ d dlmZ dd	„ Zd
d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZG dd„ dƒZG dd„ dƒZedk�r*d dlZd dlmZ ej ddd d!d"d#gd$�Z!ed%e!d&� "¡ Z#ed'e!d&� "¡ Z$ee#d(d)�Z%dS )*é    N)Ústats)Ú	DataFrameÚIndex)ÚOLS)Úlrange)Ú_remove_intercept_patsyÚ_has_interceptÚ_intercept_idx)Úsummary2c                 C   sX   |d kr|   ¡ S |dkr| jS |dkr,| jS |dkr:| jS |dkrH| jS td| ƒ‚d S )NZhc0Zhc1Zhc2Zhc3z robust options %s not understood)Z
cov_paramsZcov_HC0Zcov_HC1Zcov_HC2Zcov_HC3Ú
ValueError)ÚmodelÚrobust© r   úP/home/sam/Atlas/atlas_env/lib/python3.8/site-packages/statsmodels/stats/anova.pyÚ_get_covariance   s    r   c                 K   s2  |  dd¡}|  dd¡}|  dd¡}|  dd¡}|r<| ¡ }| jj}| jj}|jd }| jj}	| jjj}
| jj	}t
|
jƒt|
ƒ d }d	| }d
dd||g}tt |df¡|d�}|dkrÔt| ||||
|||||ƒ
S |dkrît| |
||||ƒS |dk�r
t| |
||||ƒS |dk�rtdƒ‚ntdt|ƒ ƒ‚dS )a9  
    Anova table for one fitted linear model.

    Parameters
    ----------
    model : fitted linear model results instance
        A fitted linear model
    typ : int or str {1,2,3} or {"I","II","III"}
        Type of sum of squares to use.

    **kwargs**

    scale : float
        Estimate of variance, If None, will be estimated from the largest
    model. Default is None.
        test : str {"F", "Chisq", "Cp"} or None
        Test statistics to provide. Default is "F".

    Notes
    -----
    Use of this function is discouraged. Use anova_lm instead.
    ÚtestÚFÚscaleNÚtypé   r   r   zPR(>%s)ÚdfÚsum_sqÚmean_sqé   ©Úcolumns©r   ÚI)é   ZII)é   ZIII)é   ZIVzType IV not yet implementedzType %s not understood)ÚgetÚlowerr   ÚendogÚexogÚshapeZendog_namesÚdataÚdesign_infoÚ
exog_namesÚlenÚtermsr   r   ÚnpÚzerosÚanova1_lm_singleÚanova2_lm_singleÚanova3_lm_singleÚNotImplementedErrorr   Ústr)r   Úkwargsr   r   r   r   r#   r$   ÚnobsZresponse_namer'   r(   Ún_rowsÚpr_testÚnamesÚtabler   r   r   Úanova_single   sD    

   ÿÿ
ÿ

r8   c
                    sŠ  t | ddƒ}
|
dkr2tj |¡\}}t |j|¡}
t tˆ jƒtˆ j	ƒf¡}‡ fdd„ˆ j
D ƒ}t|ƒD ]\}}d|||f< qht ||
d ¡}tˆ ƒ}||  }t ˆ j
¡}||  }| ¡ }t|dg ƒ|_tj||   d¡|f |j|dd	gf< | j| jf|jdd	dgf< |d
k�rr|d	 |d  | j| j  ||< tj |d
 |d | j¡||< tjtjf|jd||gf< |d	 |d  |d< |S )aá  
    Anova table for one fitted linear model.

    Parameters
    ----------
    model : fitted linear model results instance
        A fitted linear model

    **kwargs**

    scale : float
        Estimate of variance, If None, will be estimated from the largest
    model. Default is None.
        test : str {"F", "Chisq", "Cp"} or None
        Test statistics to provide. Default is "F".

    Notes
    -----
    Use of this function is discouraged. Use anova_lm instead.
    ÚeffectsNc                    s   g | ]}ˆ   |¡‘qS r   )Úslice)Ú.0Úname©r'   r   r   Ú
<listcomp>x   s     z$anova1_lm_single.<locals>.<listcomp>r   r   ÚResidualr   r   r   r   )Úgetattrr+   ÚlinalgÚqrÚdotÚTr,   r)   r*   Zcolumn_namesÚ
term_namesÚ	enumerater	   ÚarrayÚtolistr   ÚindexZc_ÚsumÚlocÚssrÚdf_residr   ÚfÚsfÚnan)r   r#   r$   r3   r'   r7   r4   r   r5   r   r9   ÚqÚrZarrÚslicesÚiZslice_r   ÚidxrE   rI   r   r=   r   r-   [   s6    

(

ÿÿr-   c                 C   sŠ  |j dd… }t|ƒ}dd||g}tt |df¡|d�}t| dƒ}	t| |ƒ}
g }g }t|ƒD �]¨\}}| |¡}t|j	|j
ƒ}g }t|jƒ}|D ]R}t|jƒ}| |¡r�||ks�| |¡}| t|j	|j
ƒ¡ | t|j	|j
ƒ¡ q�t | jjjd ¡| }t | jjjd ¡| }|j�r‚t t ||
¡|j¡}ddlm} | |¡\}}|jd |jd  }t |dd…| d…f j|¡}n|}|jd }|d	k�rØ| j||
d
�}|j |j|j| |f< }|j|j|j| |f< ||j|j| df< | |j	¡ | | ¡ ¡ q\t |dg ƒ|_|j!t "|| jjjd d g ¡ }|| |d  | j# | j$ }||d< | j#| j$tj%tj%f|jddd||gf< |S )a‰  
    Anova type II table for one fitted linear model.

    Parameters
    ----------
    model : fitted linear model results instance
        A fitted linear model

    **kwargs**

    scale : float
        Estimate of variance, If None, will be estimated from the largest
    model. Default is None.
        test : str {"F", "Chisq", "Cp"} or None
        Test statistics to provide. Default is "F".

    Notes
    -----
    Use of this function is discouraged. Use anova_lm instead.

    Type II
    Sum of Squares compares marginal contribution of terms. Thus, it is
    not particularly useful for models with significant interaction terms.
    Nr   r   r    r   r   r   )rA   r   ©Zcov_pr?   )&r*   r   r   r+   r,   r   rF   r:   r   ÚstartÚstopÚsetÚfactorsÚissubsetÚextendÚeyer   r$   r%   ÚsizerC   rD   ÚscipyrA   rB   Úf_testÚfvaluerK   rI   ÚpvalueÚappendr<   r   ÚilocZargsortrL   rM   rP   )r   r'   r4   r   r5   r   Ú
terms_infor6   r7   ÚcovZ
robust_covÚ	col_orderrI   rT   ÚtermÚcolsÚL1ZL2Zterm_setÚtZ	other_setÚcolZLVLrA   Z
orth_complÚ_rR   ÚL12rN   Ú
test_valuerL   r   r   r   r.   ’   s\    





"

$ þr.   c                 C   sN  |t |ƒ7 }|j}dd||g}tt |df¡|d�}t| |ƒ}	g }
g }t|ƒD ] \}}| |¡}t | j	j
jd ¡| }|}|jd }|dkrÌ| j||	d�}|j |j|j| |f< }|j|j|j| |f< ||j|j| df< | | ¡ ¡ qNt|d	g ƒ|_|| |d  | j | j }||d< | j| jtjtjf|jd	dd||gf< |S )
Nr   r   r    r   r   r   r   rV   r?   )r   r*   r   r+   r,   r   rF   r:   r]   r   r$   r%   r`   ra   rK   rI   rb   rc   r<   r   rL   rM   rP   )r   r'   r4   r   r5   r   re   r6   r7   rf   rg   rI   rT   rh   ri   rj   rn   rR   rN   ro   rL   r   r   r   r/   ê   s6    


 þr/   c            
      O   sZ  |  dd¡}t| ƒdkr,| d }t|f|ŽS |dkrDtdt|ƒ ƒ‚|  dd¡}|  dd	¡}t| ƒ}d
| }dddd||g}tt |df¡|d�}	|s | d j}dd„ | D ƒ|	d< dd„ | D ƒ|	d< t 	|	d j
¡ |	j|	jdd	… df< |	d  	¡  |	d< |dk�rV|	d |	d  | |	d< tj |	d |	d |	d ¡|	|< tj|	j|	d  ¡ |f< |	S )aÁ	  
    Anova table for one or more fitted linear models.

    Parameters
    ----------
    args : fitted linear model results instance
        One or more fitted linear models
    scale : float
        Estimate of variance, If None, will be estimated from the largest
        model. Default is None.
    test : str {"F", "Chisq", "Cp"} or None
        Test statistics to provide. Default is "F".
    typ : str or int {"I","II","III"} or {1,2,3}
        The type of Anova test to perform. See notes.
    robust : {None, "hc0", "hc1", "hc2", "hc3"}
        Use heteroscedasticity-corrected coefficient covariance matrix.
        If robust covariance is desired, it is recommended to use `hc3`.

    Returns
    -------
    anova : DataFrame
        When args is a single model, return is DataFrame with columns:

        sum_sq : float64
            Sum of squares for model terms.
        df : float64
            Degrees of freedom for model terms.
        F : float64
            F statistic value for significance of adding model terms.
        PR(>F) : float64
            P-value for significance of adding model terms.

        When args is multiple models, return is DataFrame with columns:

        df_resid : float64
            Degrees of freedom of residuals in models.
        ssr : float64
            Sum of squares of residuals in models.
        df_diff : float64
            Degrees of freedom difference from previous model in args
        ss_dff : float64
            Difference in ssr from previous model in args
        F : float64
            F statistic comparing to previous model in args
        PR(>F): float64
            P-value for significance comparing to previous model in args

    Notes
    -----
    Model statistics are given in the order of args. Models must have been fit
    using the formula api.

    See Also
    --------
    model_results.compare_f_test, model_results.compare_lm_test

    Examples
    --------
    >>> import statsmodels.api as sm
    >>> from statsmodels.formula.api import ols
    >>> moore = sm.datasets.get_rdataset("Moore", "carData", cache=True) # load
    >>> data = moore.data
    >>> data = data.rename(columns={"partner.status" :
    ...                             "partner_status"}) # make name pythonic
    >>> moore_lm = ols('conformity ~ C(fcategory, Sum)*C(partner_status, Sum)',
    ...                 data=data).fit()
    >>> table = sm.stats.anova_lm(moore_lm, typ=2) # Type 2 Anova DataFrame
    >>> print(table)
    r   r   r   r   z6Multiple models only supported for type I. Got type %sr   r   r   NzPr(>%s)rM   rL   Zdf_diffZss_diffé   r   éÿÿÿÿc                 S   s   g | ]
}|j ‘qS r   )rL   ©r;   Zmdlr   r   r   r>   m  s     zanova_lm.<locals>.<listcomp>c                 S   s   g | ]
}|j ‘qS r   )rM   rr   r   r   r   r>   n  s     )r!   r)   r8   r   r1   r   r+   r,   r   ÚdiffÚvaluesrK   rI   r   rN   rO   rP   Zisnull)
Úargsr2   r   r   r   r   Zn_modelsr5   r6   r7   r   r   r   Úanova_lm  s6    Fÿ
&
ÿrv   c                 C   s.   t  dg| ¡}|D ]}| | }d||< q|S )NTF)r+   rG   )rS   Zslices_to_excludeÚnÚindrh   Úsr   r   r   Ú
_not_slice{  s
    
rz   c           	      C   s\   t |||jd ƒ}|| }t | |dd…|f  |¡¡}|j |¡}t| ƒt|ƒ }||fS )ah  
    Residual sum of squares of OLS model excluding factors in `keys`
    Assumes x matrix is orthogonal

    Parameters
    ----------
    y : array_like
        dependent variable
    x : array_like
        independent variables
    term_slices : a dict of slices
        term_slices[key] is a boolean array specifies the parameters
        associated with the factor `key`
    params : ndarray
        OLS solution of y = x * params
    keys : keys for term_slices
        factors to be excluded

    Returns
    -------
    rss : float
        residual sum of squares
    df : int
        degrees of freedom
    r   N)rz   r%   r+   ÚsubtractrC   rD   r)   )	ÚyÚxÚterm_slicesÚparamsÚkeysrx   Zparams1rL   rM   r   r   r   Ú_ssr_reduced_modelƒ  s    r�   c                   @   s2   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ ZdS )ÚAnovaRMaò  
    Repeated measures Anova using least squares regression

    The full model regression residual sum of squares is
    used to compare with the reduced model for calculating the
    within-subject effect sum of squares [1].

    Currently, only fully balanced within-subject designs are supported.
    Calculation of between-subject effects and corrections for violation of
    sphericity are not yet implemented.

    Parameters
    ----------
    data : DataFrame
    depvar : str
        The dependent variable in `data`
    subject : str
        Specify the subject id
    within : list[str]
        The within-subject factors
    between : list[str]
        The between-subject factors, this is not yet implemented
    aggregate_func : {None, 'mean', callable}
        If the data set contains more than a single observation per subject
        and cell of the specified model, this function will be used to
        aggregate the data before running the Anova. `None` (the default) will
        not perform any aggregation; 'mean' is s shortcut to `numpy.mean`.
        An exception will be raised if aggregation is required, but no
        aggregation function was specified.

    Returns
    -------
    results : AnovaResults instance

    Raises
    ------
    ValueError
        If the data need to be aggregated, but `aggregate_func` was not
        specified.

    Notes
    -----
    This implementation currently only supports fully balanced designs. If the
    data contain more than one observation per subject and cell of the design,
    these observations need to be aggregated into a single observation
    before the Anova is calculated, either manually or by passing an aggregation
    function via the `aggregate_func` keyword argument.
    Note that if the input data set was not balanced before performing the
    aggregation, the implied heteroscedasticity of the data is ignored.

    References
    ----------
    .. [*] Rutherford, Andrew. Anova and ANCOVA: a GLM approach. John Wiley & Sons, 2011.
    Nc                 C   sš   || _ || _|| _d|kr"tdƒ‚|| _|d k	r8tdƒ‚|| _|dkrPtj| _	n|| _	| 
|j|g| d�¡sŽ| j	d k	r‚|  ¡  nd}t|ƒ‚|  ¡  d S )NÚCzSFactor name cannot be 'C'! This is in conflict with patsy's contrast function name.z)Between subject effect not yet supported!Úmean)Zsubsetz‘The data set contains more than one observation per subject and cell. Either aggregate the data manually, or pass the `aggregate_func` parameter.)r&   ÚdepvarÚwithinr   Úbetweenr0   Úsubjectr+   r„   Úaggregate_funcÚequalsZdrop_duplicatesÚ
_aggregateÚ_check_data_balanced)Úselfr&   r…   rˆ   r†   r‡   r‰   Úmsgr   r   r   Ú__init__Ý  s$    


zAnovaRM.__init__c                 C   s.   | j j| jg| j dd�| j  | j¡| _ d S )NF)Zas_index)r&   Úgroupbyrˆ   r†   r…   Zaggr‰   ©r�   r   r   r   r‹   û  s    þþýzAnovaRM._aggregatec           	      C   sî   d}| j D ]}|t| j|  ¡ ƒ9 }q
i }t| jjd ƒD ]T}g }| j D ]}| | j| j| ¡ qHt|ƒ}||kr†|| d ||< q:d||< q:d}t|ƒ|kr¨t	|ƒ‚|| }|D ]}||| kr´t	|ƒ‚q´| jjd || krêt	dƒ‚dS )z¬raise if data is not balanced

        This raises a ValueError if the data is not balanced, and
        returns None if it is balance

        Return might change
        r   r   zData is unbalanced.z9There are more than 1 element in a cell! Missing factors?N)
r†   r)   r&   ÚuniqueÚranger%   rc   rd   Útupler   )	r�   Zfactor_levelsZwiZ
cell_countrI   Úkeyrl   Úerror_messageÚcountr   r   r   rŒ     s*    



zAnovaRM._check_data_balancedc                 C   sf  | j | j j}dd„ | jD ƒ}d| j }||g }tjd |¡| j d�}|jj	}|D ]4}t
 dg|jd  ¡}d||| < t
 |¡||< qTd	 |¡g}	t||	|jd ƒ}|d
d
…|f }t||ƒ}
|
 ¡ }|
j|jd k râtdƒ‚|	D ]}| |¡ qæ|D ]}|| | ||< qú|j}|j}|j}ddddg}tjt
 d¡|d�}|D �]}| j|k�rF|dk�rFt|||||gƒ\}}|| }|| | }|d	 |d
d… ¡k�s¶|d	 | |k�rÄ|| }|}n2t|||||d	 | gƒ\}}|| }|| | }|| }tj |||¡}| dd¡ dd¡}||j|df< ||j|df< ||j|df< ||j|df< �qFt|ƒS )zvestimate the model and compute the Anova table

        Returns
        -------
        AnovaResults instance
        c                 S   s   g | ]}d | ‘qS )ú
C(%s, Sum)r   )r;   rT   r   r   r   r>   ,  s     zAnovaRM.fit.<locals>.<listcomp>r˜   Ú*©r&   Fr   Tú:Nz$Independent variables are collinear.zF ValuezNum DFzDen DFzPr > F)r   r    r   Z	Interceptrq   zC(Ú z, Sum)) r&   r…   rt   r†   rˆ   ÚpatsyZdmatrixÚjoinr'   Zterm_name_slicesr+   rG   r%   rz   r   ÚfitZrankr   Úpopr   rM   rL   Úpdr   r,   r�   r   rN   rO   ÚreplacerK   ÚAnovaResults)r�   r|   r†   rˆ   rZ   r}   r~   r•   rx   Zterm_excluder   ÚresultsrT   r   rM   rL   r   Úanova_tableZssr1Z	df_resid1Zdf1ZmsmZmseZdf2r   Úprh   r   r   r   rŸ   "  sv    



    ÿÿ   þzAnovaRM.fit)NNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r�   r‹   rŒ   rŸ   r   r   r   r   r‚   ¥  s   7  ÿ
!r‚   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r£   zX
    Anova results class

    Attributes
    ----------
    anova_table : DataFrame
    c                 C   s
   || _ d S ©N)r¥   )r�   r¥   r   r   r   r�   m  s    zAnovaResults.__init__c                 C   s   |   ¡  ¡ S r«   )ÚsummaryÚ__str__r‘   r   r   r   r­   p  s    zAnovaResults.__str__c                 C   s"   t  ¡ }| d¡ | | j¡ |S )zlcreate summary results

        Returns
        -------
        summary : summary2.Summary instance
        ZAnova)r
   ÚSummaryZ	add_titleZadd_dfr¥   )r�   Zsummr   r   r   r¬   s  s    
zAnovaResults.summaryN)r§   r¨   r©   rª   r�   r­   r¬   r   r   r   r   r£   e  s   r£   Ú__main__)Úolsz	moore.csvr   Zpartner_statusZ
conformityZ	fcategoryZfscore)Zskiprowsr6   z5conformity ~ C(fcategory, Sum)*C(partner_status, Sum)rš   z#conformity ~ C(partner_status, Sum)r   )r   )&Únumpyr+   r_   r   Zpandasr¡   r   r   r�   Z#statsmodels.regression.linear_modelr   Zstatsmodels.compat.pythonr   Z statsmodels.formula.formulatoolsr   r   r	   Zstatsmodels.iolibr
   r   r8   r-   r.   r/   rv   rz   r�   r‚   r£   r§   Zstatsmodels.formula.apir°   Zread_csvZmoorerŸ   Zmoore_lmZmooreBr7   r   r   r   r   Ú<module>   sB   <7X'j" A
 ÿÿÿ
	