% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/add_lagged_columns.R
\name{add_lagged_columns}
\alias{add_lagged_columns}
\title{Add Lagged Columns via Join}
\usage{
add_lagged_columns(
  data,
  cols,
  lag,
  max_lag = lag,
  by = NULL,
  drop_na = FALSE,
  ff_adjustment = FALSE,
  data_options = NULL
)
}
\arguments{
\item{data}{A data frame containing the variables to lag.}

\item{cols}{A character vector specifying the names of the columns to be
lagged. Each column produces a new column suffixed with \verb{_lag}.}

\item{lag}{An integer or a \code{lubridate::periods()} object, e.g.,
\code{months(1)}, specifying the minimum lag (inclusive) to apply.}

\item{max_lag}{An integer or a \code{lubridate::periods()} object specifying
the maximum lag (inclusive) to apply. Defaults to \code{lag} (exact lag).}

\item{by}{An optional character vector specifying grouping columns
(e.g., a stock identifier). Lagged values are matched within groups.
Defaults to \code{NULL}.}

\item{drop_na}{A logical value. If \code{TRUE}, \code{NA} values in the source
columns are excluded before matching, so the lookup skips over missing
observations. Applied independently per column. Defaults to \code{FALSE}.}

\item{ff_adjustment}{A logical value. If \code{TRUE}, only the last observation
per year (within each group defined by \code{by}) is retained as a source for
lagged values, following Fama-French conventions for annual accounting
data. Defaults to \code{FALSE}.}

\item{data_options}{A list of class \code{tidyfinance_data_options} (created via
\code{\link[=data_options]{data_options()}}) specifying column name mappings. The \code{date} element is
used to specify the date column. Uses \code{\link[=data_options]{data_options()}} default if \code{NULL}:
\code{"date" = "date"}.}
}
\value{
A data frame with the same rows as \code{data} and new columns appended,
each suffixed with \verb{_lag}. Unmatched rows receive \code{NA} in the lagged
columns.
}
\description{
Appends lagged versions of specified columns to a data frame using a
join-based approach.
}
\details{
When \code{lag == max_lag} (the default), an equi-join is used: source dates
are shifted forward by \code{lag} and matched exactly. When \code{lag < max_lag},
an inequality join is used: for each row, the most recent source value
within the window \verb{[date - max_lag, date - lag]} is selected.

The combination of \code{by} and date columns must be unique in \code{data}. If \code{by}
is \code{NULL}, dates alone must be unique.
}
\examples{
set.seed(42)
data <- tibble::tibble(
  permno = rep(1:2, each = 10),
  date = rep(
    seq.Date(as.Date("2023-01-01"), by = "month", length.out = 10),
    2
  ),
  size = runif(20, 100, 200),
  bm = runif(20, 0.5, 1.5)
)

# Exact lag: each row gets the value from exactly 2 months earlier
add_lagged_columns(
  data,
  cols = c("size", "bm"),
  lag = months(2),
  by = "permno"
)

# Window lag: each row gets the most recent value from 2 to 4 months earlier
add_lagged_columns(
  data,
  cols = "size",
  lag = months(2),
  max_lag = months(4),
  by = "permno"
)

}
\seealso{
Other rolling and lagging functions: 
\code{\link{compute_rolling_value}()},
\code{\link{join_lagged_values}()}
}
\concept{rolling and lagging functions}
