code: def add_shifted_events(
      daily_event_df_dict: Dict[str, pd.DataFrame],
      shifted_effect_lags: Optional[List[str]] = None,
      event_df_date_col: str = EVENT_DF_DATE_COL,
      event_df_label_col: str = EVENT_DF_LABEL_COL,
  ) -> Dict[str, Any]:
      """This function does two things:
  
          - (1) adds shifted events to ``daily_event_df_dict`` and returns the new event dictionary.
          - (2) returns a list of new column names to be added in the model.
            This is useful when we need to remove these main effects from the model.
  
      Parameters
      ----------
      daily_event_df_dict : `Dict` [`str`, `pandas.DataFrame`]
          The input event configuration.
          A dictionary with keys being the event names and values being a pandas DataFrame of dates.
          See `~greykite.algo.forecast.silverkite.forecast_silverkite` for details.
      shifted_effect_lags : `List` [`str`] or None, default None
          Additional neighbor events based on given events.
          For example, passing ["-1D", "7D"] will add extra daily events which are 1 day before
          and 7 days after the given events.
          Offset format is {d}{freq} with any integer plus a frequency string. Must be parsable by pandas ``to_offset``.
          The new events' names will be the current events' names with suffix "{offset}_before" or "{offset}_after".
          For example, if we have an event named "US_Christmas Day",
          a "7D" shift will have name "US_Christmas Day_7D_after".
          This is useful when you expect an offset of the current holidays also has impact on the
          time series, or you want to interact the lagged terms with autoregression.
      event_df_date_col : `str`, default ``EVENT_DF_DATE_COL``
          Date column of the dataframes in ``daily_event_df_dict``.
      event_df_label_col : `str`, default ``EVENT_DF_LABEL_COL``
          Label column of the dataframes in ``daily_event_df_dict``.
  
      Returns
      -------
      shifted_events_dict : `Dict` [`str`, `Any`]
          A dictionary of results:
  
              - "new_daily_event_df_dict": the new event dictionary that expands the input
                  ``daily_event_df_dict`` by adding new shifted events.
                  Note that this is intended to be used to manually add the events.
                  One can also specify the ``events["daily_event_shifted_effect"]`` field to directly add them.
              - "shifted_events_cols": the column names of the newly added shifted event in the model.
                  This is useful when we need to remove these main effects from the model.
                  One can specify this in ``drop_pred_cols`` to achieve this.
      """
      if shifted_effect_lags is None:
          shifted_effect_lags = []
  
      new_daily_event_df_dict = {}
      shifted_events_cols = []
      drop_pred_cols = []
      for order in shifted_effect_lags:
          num, freq = split_offset_str(order)
          if num == 0:
              break
          num = int(num)
          lag_offset = to_offset(order)
          for name, event_df in daily_event_df_dict.items():
              new_event_df = event_df.copy()
              new_event_df[event_df_date_col] = pd.to_datetime(
                  new_event_df[event_df_date_col]
              )
              new_event_df[event_df_date_col] += lag_offset
              # Sets suffix of the new event.
              suffix = (
                  EVENT_SHIFTED_SUFFIX_BEFORE
                  if num < 0
                  else EVENT_SHIFTED_SUFFIX_AFTER
              )
              # Creates a new dataframe to add to `new_daily_event_df_dict`.
              new_name = f"{name}_{abs(num)}{freq}{suffix}"
              new_event_df[event_df_label_col] = new_name
              new_daily_event_df_dict[new_name] = new_event_df
              # Records the new column name in the model.
              new_col = f"{EVENT_PREFIX}_{new_name}"
              shifted_events_cols.append(new_col)
  
      if len(new_daily_event_df_dict) > 0:
          drop_pred_cols = get_event_pred_cols(new_daily_event_df_dict)
  
      new_daily_event_df_dict.update(daily_event_df_dict)
  
      return {
          "new_daily_event_df_dict": new_daily_event_df_dict,
          "shifted_events_cols": shifted_events_cols,
          "drop_pred_cols": drop_pred_cols,
      }
  
file_path: greykite/greykite/algo/common/holiday_utils.py
imports: import datetime
  from typing import Any
  from typing import Dict
  from typing import List
  from typing import Optional
  import pandas
  from pandas.tseries.frequencies import to_offset
  from greykite.algo.forecast.silverkite.forecast_simple_silverkite_helper import get_event_pred_cols
  from greykite.common.constants import EVENT_DF_DATE_COL
  from greykite.common.constants import EVENT_DF_LABEL_COL
  from greykite.common.constants import EVENT_PREFIX
  from greykite.common.constants import EVENT_SHIFTED_SUFFIX_AFTER
  from greykite.common.constants import EVENT_SHIFTED_SUFFIX_BEFORE
  from greykite.common.python_utils import split_offset_str
label_desc: Use image node_id 4 for calling a global function with example usage: add_shifted_events(daily_event_df_dict, shifted_effect_lags, event_df_date_col, event_df_label_col) and returns: dict