code: def _final_frame_longer(
      df: pd.DataFrame,
      reps: int,
      index: Union[dict, None],
      outcome: dict,
      values: dict,
      names_to: Union[list, None],
      dropna: bool,
      names_transform: Union[str, Callable, dict, None],
      sort_by_appearance: bool,
      ignore_index: bool,
  ) -> pd.DataFrame:
      """
      Build final dataframe for pivot_longer.
      """
      len_index = len(df)
      indexer = np.tile(np.arange(len_index), reps)
  
      if (names_transform is not None) & (outcome is not None):
          if isinstance(names_transform, dict):
              outcome = {
                  key: arr.astype(names_transform[key], copy=False)
                  for key, arr in outcome.items()
                  if key in names_transform
              }
          else:
              outcome = {
                  key: arr.astype(names_transform, copy=False)
                  for key, arr in outcome.items()
              }
      if outcome is not None:
          outcome = {
              name: arr._values.repeat(len_index)
              for name, arr in outcome.items()
          }
      if dropna:
          if len(values) == 1:
              key = next(iter(values))
              any_nulls = pd.isna(values[key])
          else:
              any_nulls = [pd.isna(arr) for _, arr in values.items()]
              any_nulls = np.logical_and.reduce(any_nulls)
          if any_nulls.any():
              values = {
                  name: arr[~any_nulls] for name, arr in values.items()
              }
              indexer = indexer[~any_nulls]
              if outcome is not None:
                  outcome = {
                      name: arr[~any_nulls]
                      for name, arr in outcome.items()
                  }
  
      any_nulls = None
  
      df_index = df.index[indexer]
      if index:
          index = {name: arr[indexer] for name, arr in index.items()}
      else:
          index = {}
      if outcome is None:
          outcome = {}
  
      df = {**index, **outcome, **values}
  
      if names_to:
          # relevant if values_to is a sequence
          # helps with reordering the data
          # and is much faster than having to use `.loc`
          # after the DataFrame is created
          df = {name: df[name] for name in names_to}
  
      df = pd.DataFrame(df, copy=False, index=df_index)
      df_index = None
  
      if sort_by_appearance:
          indexer = indexer.argsort(kind="stable")
          df = df.take(indexer)
      indexer = None
  
      if ignore_index:
          df.index = range(len(df))
  
      if df.columns.names:
          df.columns.names = [None]
  
      return df
  
imports: import re
  import warnings
  from collections import defaultdict
  from itertools import chain, zip_longest
  from typing import Callable, Optional, Pattern, Union
  import numpy
  import pandas
  import pandas_flavor
  from pandas.api.types import is_categorical_dtype, is_extension_array_dtype, is_list_like
  from pandas.core.dtypes.concat import concat_compat
  from janitor.functions.utils import _computations_expand_grid, get_index_labels
  from janitor.utils import check, refactored_function
label_desc: Use image node_id 11 for calling a global function with example usage: _final_frame_longer(df, reps, index, outcome, values, names_to, dropna, names_transform, sort_by_appearance, ignore_index) and returns: df