Panel and time series

Start with the expanded example for each command. Open the variants for options and alternative R approaches. Read the qualifications before adapting the code.

arima

ARIMA model

Stata

arima y, ar(1/2)

R Package:stats

arima(data$y, order = c(2, 0, 0))

Differs from Stata R and Stata ARIMA initialization and intercept parameterizations differ; match the likelihood method and transform intercepts before comparing coefficients.

carryforward

Carry the last observed value forward

Stata

carryforward x, replace

R Package:tidyr

tidyr::fill(data, x, .direction = "down")

Differs from Stata group_by(data, id) first to fill within each panel unit. fill() crosses panel boundaries unless grouped first; group_by(id) is needed for within-unit carryforward.

d.

First difference within each panel

Stata

generate d_x = D.x

R Package:tidystata

mutate(data, d_x = stata_diff(x, time = year), .by = id)

stata_diff(x, 2, time = year) is D2.x, the difference of differences.

f.

Lead within each panel

Stata

generate lead_x = F.x

R Package:tidystata

mutate(data, lead_x = stata_lead(x, time = year), .by = id)

Gaps in year give missing values, as in Stata.

l.

Lag within each panel

Stata

generate lag_x = L.x

R Package:tidystata

mutate(data, lag_x = stata_lag(x, time = year), .by = id)

Like Stata, gaps in year give missing values; dplyr::lag() shifts rows instead. Use stata_lag(x, 2, time = year) for L2.x and unit = “month” for monthly dates.

1 more examples and alternatives

Two-period lag within each panel

Stata

generate lag2_x = L2.x

R Package:dplyr

mutate(data, lag2_x = lag(x, 2, order_by = year), .by = id)

Differs from Stata lag(x, 2, order_by = year) shifts two observed rows; L2.x shifts two time units and returns missing across time gaps. Use stata_lag(x, 2, time = year) for that rule.

tsfill

Add rows for missing time points

Stata

tsfill

R Package:tsibble

tsibble::fill_gaps(ts_data)

Differs from Stata fill_gaps() fills each key’s observed range by default; choose .full explicitly for common panel bounds and ensure the tsibble interval matches the Stata delta.

tsline

Time-series line plot

Stata

tsline y

R Package:ggplot2

ggplot(data, aes(year, y)) + geom_line()

tsset

Declare time-series data

Stata

tsset year

R Package:tsibble

tsibble::as_tsibble(data, index = year)

xtdescribe

How many periods each panel unit has

Stata

xtdescribe

R Package:dplyr

count(count(data, id, name = "periods"), periods)

xtline

One line plot per panel unit

Stata

xtline y

R Package:ggplot2

ggplot(data, aes(year, y)) + geom_line() + facet_wrap(~id)

aes(group = id) without facets draws all units in one plot, like the overlay option.

xtset

Declare panel data

Stata

xtset id year

R Package:tsibble

tsibble::as_tsibble(data, key = id, index = year)

tidystata needs no declaration: stata_lag(x, time = year) with .by = id, and fixest takes panel.id = ~id + year.

xtsum

Overall and within standard deviations

Stata

xtsum x

R Package:dplyr

data |> mutate(m = mean(x, na.rm = TRUE), .by = id) |> summarise(overall = sd(x, na.rm = TRUE), within = sd(x - m, na.rm = TRUE))

The between part is the standard deviation of the id means: summarise(data, m = mean(x, na.rm = TRUE), .by = id) then sd(m).