code: def power_corr(
      r=None, n=None, power=None, alpha=0.05, alternative="two-sided"
  ):
      """
      Evaluate power, sample size, correlation coefficient or significance level of a correlation
      test.
  
      Parameters
      ----------
      r : float
          Correlation coefficient.
      n : int
          Number of observations (sample size).
      power : float
          Test power (= 1 - type II error).
      alpha : float
          Significance level (type I error probability). The default is 0.05.
      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.
  
      Notes
      -----
      Exactly ONE of the parameters ``r``, ``n``, ``power`` and ``alpha`` must be passed as None,
      and that parameter is determined from the others.
  
      ``alpha`` has a default value of 0.05 so None must be explicitly passed if you want to
      compute it.
  
      :py:func:`scipy.optimize.brenth` is used to solve power equations for other variables (i.e.
      sample size, effect size, or significance level). If the solving fails, a nan value is
      returned.
  
      This function is a Python adaptation of the `pwr.r.test` function implemented in the
      `pwr <https://cran.r-project.org/web/packages/pwr/pwr.pdf>`_ R package.
  
      Examples
      --------
      1. Compute achieved power given ``r``, ``n`` and ``alpha``
  
      >>> from pingouin import power_corr
      >>> print('power: %.4f' % power_corr(r=0.5, n=20))
      power: 0.6379
  
      2. Same but one-sided test
  
      >>> print('power: %.4f' % power_corr(r=0.5, n=20, alternative="greater"))
      power: 0.7510
  
      >>> print('power: %.4f' % power_corr(r=0.5, n=20, alternative="less"))
      power: 0.0000
  
      3. Compute required sample size given ``r``, ``power`` and ``alpha``
  
      >>> print('n: %.4f' % power_corr(r=0.5, power=0.80))
      n: 28.2484
  
      4. Compute achieved ``r`` given ``n``, ``power`` and ``alpha`` level
  
      >>> print('r: %.4f' % power_corr(n=20, power=0.80, alpha=0.05))
      r: 0.5822
  
      5. Compute achieved alpha level given ``r``, ``n`` and ``power``
  
      >>> print('alpha: %.4f' % power_corr(r=0.5, n=20, power=0.80, alpha=None))
      alpha: 0.1377
      """
      # Check the number of arguments that are None
      n_none = sum([v is None for v in [r, n, power, alpha]])
      if n_none != 1:
          raise ValueError(
              "Exactly one of n, r, power, and alpha must be None"
          )
  
      # Safety checks
      assert alternative in [
          "two-sided",
          "greater",
          "less",
      ], "Alternative must be one of 'two-sided' (default), 'greater' or 'less'."
  
      if r is not None:
          assert -1 <= r <= 1
          if alternative == "two-sided":
              r = abs(r)
      if alpha is not None:
          assert 0 < alpha <= 1
      if power is not None:
          assert 0 < power <= 1
      if n is not None:
          if n <= 4:
              warnings.warn(
                  "Sample size is too small to estimate power (n <= 4). Returning NaN."
              )
              return np.nan
  
      # Define main function
      if alternative == "two-sided":
  
          def func(r, n, power, alpha):
              dof = n - 2
              ttt = stats.t.ppf(1 - alpha / 2, dof)
              rc = np.sqrt(ttt**2 / (ttt**2 + dof))
              zr = np.arctanh(r) + r / (2 * (n - 1))
              zrc = np.arctanh(rc)
              power = stats.norm.cdf(
                  (zr - zrc) * np.sqrt(n - 3)
              ) + stats.norm.cdf((-zr - zrc) * np.sqrt(n - 3))
              return power
  
      elif alternative == "greater":
  
          def func(r, n, power, alpha):
              dof = n - 2
              ttt = stats.t.ppf(1 - alpha, dof)
              rc = np.sqrt(ttt**2 / (ttt**2 + dof))
              zr = np.arctanh(r) + r / (2 * (n - 1))
              zrc = np.arctanh(rc)
              power = stats.norm.cdf((zr - zrc) * np.sqrt(n - 3))
              return power
  
      else:  # alternative == "less":
  
          def func(r, n, power, alpha):
              r = -r
              dof = n - 2
              ttt = stats.t.ppf(1 - alpha, dof)
              rc = np.sqrt(ttt**2 / (ttt**2 + dof))
              zr = np.arctanh(r) + r / (2 * (n - 1))
              zrc = np.arctanh(rc)
              power = stats.norm.cdf((zr - zrc) * np.sqrt(n - 3))
              return power
  
      # Evaluate missing variable
      if power is None and n is not None and r is not None:
          # Compute achieved power given r, n and alpha
          return func(r, n, power=None, alpha=alpha)
  
      elif n is None and power is not None and r is not None:
          # Compute required sample size given r, power and alpha
  
          def _eval_n(n, r, power, alpha):
              return func(r, n, power, alpha) - power
  
          try:
              return brenth(
                  _eval_n, 4 + 1e-10, 1e09, args=(r, power, alpha)
              )
          except ValueError:  # pragma: no cover
              return np.nan
  
      elif r is None and power is not None and n is not None:
          # Compute achieved r given sample size, power and alpha level
  
          def _eval_r(r, n, power, alpha):
              return func(r, n, power, alpha) - power
  
          try:
              if alternative == "two-sided":
                  return brenth(
                      _eval_r, 1e-10, 1 - 1e-10, args=(n, power, alpha)
                  )
              else:
                  return brenth(
                      _eval_r,
                      -1 + 1e-10,
                      1 - 1e-10,
                      args=(n, power, alpha),
                  )
          except ValueError:  # pragma: no cover
              return np.nan
  
      else:
          # Compute achieved alpha (significance) level given r, n and power
  
          def _eval_alpha(alpha, r, n, power):
              return func(r, n, power, alpha) - power
  
          try:
              return brenth(
                  _eval_alpha, 1e-10, 1 - 1e-10, args=(r, n, power)
              )
          except ValueError:  # pragma: no cover
              return np.nan
  
file_path: pingouin/pingouin/power.py
imports: import warnings
  import numpy
  from scipy import stats
  from scipy.optimize import brenth
label_desc: Use image node_id 5 for calling a global function with example usage: power_corr(r, n, power, alpha, alternative) and returns: func, np, power, power, power, unknown, brenth, np, unknown, unknown, brenth, brenth, brenth, np, np