code: def corr(x, y, alternative="two-sided", method="pearson", **kwargs):
      """(Robust) correlation between two variables.
  
      Parameters
      ----------
      x, y : array_like
          First and second set of observations. ``x`` and ``y`` must be
          independent.
      alternative : string
          Defines the alternative hypothesis, or tail of the correlation. Must be one of
          "two-sided" (default), "greater" or "less". Both "greater" and "less" return a one-sided
          p-value. "greater" tests against the alternative hypothesis that the correlation is
          positive (greater than zero), "less" tests against the hypothesis that the correlation is
          negative.
      method : string
          Correlation type:
  
          * ``'pearson'``: Pearson :math:`r` product-moment correlation
          * ``'spearman'``: Spearman :math:`\\rho` rank-order correlation
          * ``'kendall'``: Kendall's :math:`\\tau_B` correlation (for ordinal data)
          * ``'bicor'``: Biweight midcorrelation (robust)
          * ``'percbend'``: Percentage bend correlation (robust)
          * ``'shepherd'``: Shepherd's pi correlation (robust)
          * ``'skipped'``: Skipped correlation (robust)
      **kwargs : optional
          Optional argument(s) passed to the lower-level correlation functions.
  
      Returns
      -------
      stats : :py:class:`pandas.DataFrame`
  
          * ``'n'``: Sample size (after removal of missing values)
          * ``'outliers'``: number of outliers, only if a robust method was used
          * ``'r'``: Correlation coefficient
          * ``'CI95%'``: 95% parametric confidence intervals around :math:`r`
          * ``'p-val'``: p-value
          * ``'BF10'``: Bayes Factor of the alternative hypothesis (only for Pearson correlation)
          * ``'power'``: achieved power of the test with an alpha of 0.05.
  
      See also
      --------
      pairwise_corr : Pairwise correlation between columns of a pandas DataFrame
      partial_corr : Partial correlation
      rm_corr : Repeated measures correlation
  
      Notes
      -----
      The `Pearson correlation coefficient
      <https://en.wikipedia.org/wiki/Pearson_correlation_coefficient>`_
      measures the linear relationship between two datasets. Strictly speaking,
      Pearson's correlation requires that each dataset be normally distributed.
      Correlations of -1 or +1 imply a perfect negative and positive linear
      relationship, respectively, with 0 indicating the absence of association.
  
      .. math::
          r_{xy} = \\frac{\\sum_i(x_i - \\bar{x})(y_i - \\bar{y})}
          {\\sqrt{\\sum_i(x_i - \\bar{x})^2} \\sqrt{\\sum_i(y_i - \\bar{y})^2}}
          = \\frac{\\text{cov}(x, y)}{\\sigma_x \\sigma_y}
  
      where :math:`\\text{cov}` is the sample covariance and :math:`\\sigma`
      is the sample standard deviation.
  
      If ``method='pearson'``, The Bayes Factor is calculated using the
      :py:func:`pingouin.bayesfactor_pearson` function.
  
      The `Spearman correlation coefficient
      <https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient>`_
      is a non-parametric measure of the monotonicity of the relationship between
      two datasets. Unlike the Pearson correlation, the Spearman correlation does
      not assume that both datasets are normally distributed. Correlations of -1
      or +1 imply an exact negative and positive monotonic relationship,
      respectively. Mathematically, the Spearman correlation coefficient is
      defined as the Pearson correlation coefficient between the
      `rank variables <https://en.wikipedia.org/wiki/Ranking>`_.
  
      The `Kendall correlation coefficient
      <https://en.wikipedia.org/wiki/Kendall_rank_correlation_coefficient>`_
      is a measure of the correspondence between two rankings. Values also range
      from -1 (perfect disagreement) to 1 (perfect agreement), with 0 indicating
      the absence of association. Consistent with
      :py:func:`scipy.stats.kendalltau`, Pingouin returns the Tau-b coefficient,
      which adjusts for ties:
  
      .. math:: \\tau_B = \\frac{(P - Q)}{\\sqrt{(P + Q + T) (P + Q + U)}}
  
      where :math:`P` is the number of concordant pairs, :math:`Q` the number of
      discordand pairs, :math:`T` the number of ties in x, and :math:`U`
      the number of ties in y.
  
      The `biweight midcorrelation
      <https://en.wikipedia.org/wiki/Biweight_midcorrelation>`_ and
      percentage bend correlation [1]_ are both robust methods that
      protects against *univariate* outliers by down-weighting observations that
      deviate too much from the median.
  
      The Shepherd pi [2]_ correlation and skipped [3]_, [4]_ correlation are
      both robust methods that returns the Spearman correlation coefficient after
      removing *bivariate* outliers. Briefly, the Shepherd pi uses a
      bootstrapping of the Mahalanobis distance to identify outliers, while the
      skipped correlation is based on the minimum covariance determinant
      (which requires scikit-learn). Note that these two methods are
      significantly slower than the previous ones.
  
      The confidence intervals for the correlation coefficient are estimated
      using the Fisher transformation.
  
      .. important:: Rows with missing values (NaN) are automatically removed.
  
      References
      ----------
      .. [1] Wilcox, R.R., 1994. The percentage bend correlation coefficient.
         Psychometrika 59, 601–616. https://doi.org/10.1007/BF02294395
  
      .. [2] Schwarzkopf, D.S., De Haas, B., Rees, G., 2012. Better ways to
         improve standards in brain-behavior correlation analysis. Front.
         Hum. Neurosci. 6, 200. https://doi.org/10.3389/fnhum.2012.00200
  
      .. [3] Rousselet, G.A., Pernet, C.R., 2012. Improving standards in
         brain-behavior correlation analyses. Front. Hum. Neurosci. 6, 119.
         https://doi.org/10.3389/fnhum.2012.00119
  
      .. [4] Pernet, C.R., Wilcox, R., Rousselet, G.A., 2012. Robust correlation
         analyses: false positive and power validation using a new open
         source matlab toolbox. Front. Psychol. 3, 606.
         https://doi.org/10.3389/fpsyg.2012.00606
  
      Examples
      --------
      1. Pearson correlation
  
      >>> import numpy as np
      >>> import pingouin as pg
      >>> # Generate random correlated samples
      >>> np.random.seed(123)
      >>> mean, cov = [4, 6], [(1, .5), (.5, 1)]
      >>> x, y = np.random.multivariate_normal(mean, cov, 30).T
      >>> # Compute Pearson correlation
      >>> pg.corr(x, y).round(3)
                n      r         CI95%  p-val  BF10  power
      pearson  30  0.491  [0.16, 0.72]  0.006  8.55  0.809
  
      2. Pearson correlation with two outliers
  
      >>> x[3], y[5] = 12, -8
      >>> pg.corr(x, y).round(3)
                n      r          CI95%  p-val   BF10  power
      pearson  30  0.147  [-0.23, 0.48]  0.439  0.302  0.121
  
      3. Spearman correlation (robust to outliers)
  
      >>> pg.corr(x, y, method="spearman").round(3)
                 n      r         CI95%  p-val  power
      spearman  30  0.401  [0.05, 0.67]  0.028   0.61
  
      4. Biweight midcorrelation (robust)
  
      >>> pg.corr(x, y, method="bicor").round(3)
              n      r         CI95%  p-val  power
      bicor  30  0.393  [0.04, 0.66]  0.031  0.592
  
      5. Percentage bend correlation (robust)
  
      >>> pg.corr(x, y, method='percbend').round(3)
                 n      r         CI95%  p-val  power
      percbend  30  0.389  [0.03, 0.66]  0.034  0.581
  
      6. Shepherd's pi correlation (robust)
  
      >>> pg.corr(x, y, method='shepherd').round(3)
                 n  outliers      r        CI95%  p-val  power
      shepherd  30         2  0.437  [0.08, 0.7]   0.02  0.662
  
      7. Skipped spearman correlation (robust)
  
      >>> pg.corr(x, y, method='skipped').round(3)
                n  outliers      r        CI95%  p-val  power
      skipped  30         2  0.437  [0.08, 0.7]   0.02  0.662
  
      8. One-tailed Pearson correlation
  
      >>> pg.corr(x, y, alternative="greater", method='pearson').round(3)
              n      r           CI95%  p-val   BF10  power
      pearson  30  0.147  [-0.17, 1.0]   0.22  0.467  0.194
  
      >>> pg.corr(x, y, alternative="less", method='pearson').round(3)
              n        r         CI95%  p-val   BF10  power
      pearson  30  0.147  [-1.0, 0.43]   0.78  0.137  0.008
  
      9. Perfect correlation
  
      >>> pg.corr(x, -x).round(3)
                n    r         CI95%  p-val BF10  power
      pearson  30 -1.0  [-1.0, -1.0]    0.0  inf      1
  
      10. Using columns of a pandas dataframe
  
      >>> import pandas as pd
      >>> data = pd.DataFrame({'x': x, 'y': y})
      >>> pg.corr(data['x'], data['y']).round(3)
                n      r          CI95%  p-val   BF10  power
      pearson  30  0.147  [-0.23, 0.48]  0.439  0.302  0.121
      """
      # Safety check
      x = np.asarray(x)
      y = np.asarray(y)
      assert x.ndim == y.ndim == 1, "x and y must be 1D array."
      assert x.size == y.size, "x and y must have the same length."
      assert alternative in [
          "two-sided",
          "greater",
          "less",
      ], "Alternative must be one of 'two-sided' (default), 'greater' or 'less'."
      if "tail" in kwargs:
          raise ValueError(
              "Since Pingouin 0.4.0, the 'tail' argument has been renamed to 'alternative'."
          )
  
      # Remove rows with missing values
      x, y = remove_na(x, y, paired=True)
      n = x.size
  
      # Compute correlation coefficient and two-sided p-value
      if method == "pearson":
          r, pval = pearsonr(x, y)
      elif method == "spearman":
          r, pval = spearmanr(x, y, **kwargs)
      elif method == "kendall":
          r, pval = kendalltau(x, y, **kwargs)
      elif method == "bicor":
          r, pval = bicor(x, y, **kwargs)
      elif method == "percbend":
          r, pval = percbend(x, y, **kwargs)
      elif method == "shepherd":
          r, pval, outliers = shepherd(x, y, **kwargs)
      elif method == "skipped":
          r, pval, outliers = skipped(x, y, **kwargs)
      else:
          raise ValueError(f'Method "{method}" not recognized.')
  
      if np.isnan(r):
          # Correlation failed -- new in version v0.3.4, instead of raising an
          # error we just return a dataframe full of NaN (except sample size).
          # This avoid sudden stop in pingouin.pairwise_corr.
          return pd.DataFrame(
              {
                  "n": n,
                  "r": np.nan,
                  "CI95%": np.nan,
                  "p-val": np.nan,
                  "BF10": np.nan,
                  "power": np.nan,
              },
              index=[method],
          )
  
      # Sample size after outlier removal
      n_outliers = sum(outliers) if "outliers" in locals() else 0
      n_clean = n - n_outliers
  
      # Rounding errors caused an r value marginally beyond 1
      if abs(r) > 1 and np.isclose(abs(r), 1):
          r = np.clip(r, -1, 1)
  
      # Compute the parametric 95% confidence interval and power
      if abs(r) == 1:
          ci = [r, r]
          pr = 1
      else:
          ci = compute_esci(
              stat=r,
              nx=n_clean,
              ny=n_clean,
              eftype="r",
              decimals=6,
              alternative=alternative,
          )
          pr = power_corr(
              r=r,
              n=n_clean,
              power=None,
              alpha=0.05,
              alternative=alternative,
          )
  
      # Recompute p-value if tail is one-sided
      if alternative != "two-sided":
          pval = _correl_pvalue(
              r, n_clean, k=0, alternative=alternative
          )
  
      # Create dictionnary
      stats = {
          "n": n,
          "r": r,
          "CI95%": [ci],
          "p-val": pval,
          "power": pr,
      }
  
      if method in ["shepherd", "skipped"]:
          stats["outliers"] = n_outliers
  
      # Compute the BF10 for Pearson correlation only
      if method == "pearson":
          stats["BF10"] = bayesfactor_pearson(
              r, n_clean, alternative=alternative
          )
  
      # Convert to DataFrame
      stats = pd.DataFrame(stats, index=[method])
  
      # Define order
      col_keep = [
          "n",
          "outliers",
          "r",
          "CI95%",
          "p-val",
          "BF10",
          "power",
      ]
      col_order = [k for k in col_keep if k in stats.keys().tolist()]
      return _postprocess_dataframe(stats)[col_order]
  
imports: import warnings
  import numpy
  import pandas
  import pandas_flavor
  from scipy.spatial.distance import pdist, squareform
  from scipy.stats import pearsonr, spearmanr, kendalltau
  from pingouin.config import options
  from pingouin.power import power_corr
  from pingouin.multicomp import multicomp
  from pingouin.effsize import compute_esci
  from pingouin.utils import remove_na, _perm_pval, _postprocess_dataframe
  from pingouin.bayesian import bayesfactor_pearson
label_desc: Use image node_id 7 for calling a global function with example usage: corr(x, y, alternative, method) and returns: _postprocess_dataframe, pd