code: def logrank_test(
      durations_A,
      durations_B,
      event_observed_A=None,
      event_observed_B=None,
      t_0=-1,
      weights_A=None,
      weights_B=None,
      weightings=None,
      **kwargs,
  ) -> StatisticalResult:
      r"""
      Measures and reports on whether two intensity processes are different. That is, given two
      event series, determines whether the data generating processes are statistically different.
      The test-statistic is chi-squared under the null hypothesis. Let :math:`h_i(t)` be the hazard ratio of
      group :math:`i` at time :math:`t`, then:
  
      .. math::
          \begin{align}
           & H_0: h_1(t) = h_2(t) \\
           & H_A: h_1(t) = c h_2(t), \;\; c \ne 1
          \end{align}
  
      This implicitly uses the log-rank weights.
  
      Note
      -----
      - *lifelines* logrank implementation only handles right-censored data.
  
      - The logrank test has maximum power when the assumption of proportional hazards is true. As a consequence, if the survival curves cross, the logrank test will give an inaccurate assessment of differences.
  
      - This implementation is a special case of the function ``multivariate_logrank_test``, which is used internally. See Survival and Event Analysis, page 108.
  
      - There are only disadvantages to using the log-rank test versus using the Cox regression. See more `here <https://discourse.datamethods.org/t/when-is-log-rank-preferred-over-univariable-cox-regression/2344>`_ for a discussion. To convert to using the Cox regression:
  
      .. code:: python
  
          from lifelines import CoxPHFitter
  
          dfA = pd.DataFrame({'E': event_observed_A, 'T': durations_A, 'groupA': 1})
          dfB = pd.DataFrame({'E': event_observed_B, 'T': durations_B, 'groupA': 0})
          df = pd.concat([dfA, dfB])
  
          cph = CoxPHFitter().fit(df, 'T', 'E')
          cph.print_summary()
  
  
  
      Parameters
      ----------
  
      durations_A: iterable
          a (n,) list-like of event durations (birth to death,...) for the first population.
  
      durations_B: iterable
          a (n,) list-like of event durations (birth to death,...) for the second population.
  
      event_observed_A: iterable, optional
          a (n,) list-like of censorship flags, (1 if observed, 0 if not), for the first population.
          Default assumes all observed.
  
      event_observed_B: iterable, optional
          a (n,) list-like of censorship flags, (1 if observed, 0 if not), for the second population.
          Default assumes all observed.
  
      weights_A: iterable, optional
          case weights
  
      weights_B: iterable, optional
          case weights
  
      t_0: float, optional (default=-1)
          The final time period under observation, and subjects who experience the event after this time are set to be censored.
          Specify -1 to use all time.
  
      weightings: str, optional
          apply a weighted logrank test: options are "wilcoxon" for Wilcoxon (also known as Breslow), "tarone-ware"
          for Tarone-Ware, "peto" for Peto test and "fleming-harrington" for Fleming-Harrington test.
          These are useful for testing for early or late differences in the survival curve. For the Fleming-Harrington
          test, keyword arguments p and q must also be provided with non-negative values.
  
          Weightings are applied at the ith ordered failure time, :math:`t_{i}`, according to:
              Wilcoxon: :math:`n_i`
              Tarone-Ware: :math:`\sqrt{n_i}`
              Peto: :math:`\bar{S}(t_i)`
              Fleming-Harrington: :math:`\hat{S}(t_i)^p \times (1 - \hat{S}(t_i))^q`
  
              where :math:`n_i` is the number at risk just prior to time :math:`t_{i}`, :math:`\bar{S}(t_i)` is
              Peto-Peto's modified survival estimate and :math:`\hat{S}(t_i)` is the left-continuous
              Kaplan-Meier survival estimate at time :math:`t_{i}`.
  
      Returns
      -------
  
      StatisticalResult
        a StatisticalResult object with properties ``p_value``, ``summary``, ``test_statistic``, ``print_summary``
  
      Examples
      --------
  
      .. code:: python
  
          T1 = [1, 4, 10, 12, 12, 3, 5.4]
          E1 = [1, 0, 1,  0,  1,  1, 1]
  
          T2 = [4, 5, 7, 11, 14, 20, 8, 8]
          E2 = [1, 1, 1, 1,  1,  1,  1, 1]
  
          from lifelines.statistics import logrank_test
          results = logrank_test(T1, T2, event_observed_A=E1, event_observed_B=E2)
  
          results.print_summary()
          print(results.p_value)        # 0.7676
          print(results.test_statistic) # 0.0872
  
  
      See Also
      --------
      multivariate_logrank_test
      pairwise_logrank_test
      survival_difference_at_fixed_point_in_time_test
      """
      event_times_A, event_times_B = (
          np.array(durations_A),
          np.array(durations_B),
      )
      if event_observed_A is None:
          event_observed_A = np.ones(event_times_A.shape[0])
      if event_observed_B is None:
          event_observed_B = np.ones(event_times_B.shape[0])
      if weights_A is None:
          weights_A = np.ones(event_times_A.shape[0])
      if weights_B is None:
          weights_B = np.ones(event_times_B.shape[0])
  
      event_times = np.r_[event_times_A, event_times_B]
      groups = np.r_[
          np.zeros(event_times_A.shape[0], dtype=int),
          np.ones(event_times_B.shape[0], dtype=int),
      ]
      event_observed = np.r_[event_observed_A, event_observed_B]
      weights = np.r_[weights_A, weights_B]
      return multivariate_logrank_test(
          event_times,
          groups,
          event_observed,
          t_0=t_0,
          weights=weights,
          test_name="logrank_test",
          weightings=weightings,
          **kwargs,
      )
  
imports: from itertools import combinations
  import warnings
  import numpy
  from scipy import stats
  import pandas
  from lifelines import utils
  from lifelines.utils import group_survival_table_from_events, string_rjustify, format_p_value, format_floats, interpolate_at_times_and_return_pandas, _expected_value_of_survival_up_to_t, _expected_value_of_survival_squared_up_to_t
  from lifelines import KaplanMeierFitter
label_desc: Use image node_id 4 for calling a global function with example usage: logrank_test(durations_A, durations_B, event_observed_A, event_observed_B, t_0, weights_A, weights_B, weightings) and returns: multivariate_logrank_test