Skip to content

Instantly share code, notes, and snippets.

@kylebutts
Last active September 1, 2024 08:51
Show Gist options
  • Save kylebutts/eb4a493e217253a0ee92c6b9eec08bc2 to your computer and use it in GitHub Desktop.
Save kylebutts/eb4a493e217253a0ee92c6b9eec08bc2 to your computer and use it in GitHub Desktop.
Learning internals of `binsreg`
library(tidyverse)
library(fixest)
library(binsreg)
library(patchwork)

set.seed(20240829)
x <- runif(500)
w <- rnorm(n = 500, mean = x, sd = 1)
y <- sin(x) + w * 2 + rnorm(500, mean = 0, sd = 1)
df <- tibble(y = y, x = x, w = w) |>
  arrange(x) # For plotting, x in order makes line work
# Generate binned b-spline of x
bins <- function(x, p, s, n_bins) {
  knots <- binsreg:::genKnot.qs(x = x, J = n_bins)

  # Calls `splines::splineDesign` internally
  design <- binsreg:::binsreg.spdes(eval = x, p = p, s = s, knot = knots, deriv = 0)
  return(design)
}
t <- binsreg(df$y, df$x, w = as.matrix(df$w), line = c(2, 2))

# Using `fixest::feols`
Jopt <- t$opt$nbins.by
est <- feols(
  y ~ 0 + bins(x, p = 2, s = 2, n_bins = Jopt) + w,
  data = df
)
# Make predictions at mean of w
w_mean <- mean(df$w)
line_grid <- t$data.plot$"Group Full Sample"$data.line
line_grid$w <- w_mean
line_grid$fit_feols <- predict(est, newdata = line_grid)
p <- ggplot() +
  geom_line(
    aes(x = x, y = fit_feols),
    data = line_grid |> arrange(x)
  ) +
  theme_bw()
common_y_scale <- scale_y_continuous(
  limits = c(0.5, 3), expand = expansion(0.1, 0)
)
# Binsreg left and feols on right
(t$bins_plot + common_y_scale) + (p + common_y_scale)

Created on 2024-08-29 with reprex v2.1.0

# %%
library(tidyverse)
library(fixest)
library(binsreg)
library(patchwork)
set.seed(20240829)
x <- runif(500)
w <- rnorm(n = 500, mean = x, sd = 1)
y <- sin(x) + w * 2 + rnorm(500, mean = 0, sd = 1)
df <- tibble(y = y, x = x, w = w) |>
arrange(x) # For plotting, x in order makes line work
# %%
# Generate binned b-spline of x
bins <- function(x, p, s, n_bins) {
knots <- binsreg:::genKnot.qs(x = x, J = n_bins)
# Calls `splines::splineDesign` internally
design <- binsreg:::binsreg.spdes(eval = x, p = p, s = s, knot = knots, deriv = 0)
return(design)
}
# %%
#| fig.show: 'hide'
t <- binsreg(df$y, df$x, w = as.matrix(df$w), line = c(2, 2))
# Using `fixest::feols`
Jopt <- t$opt$nbins.by
est <- feols(
y ~ 0 + bins(x, p = 2, s = 2, n_bins = Jopt) + w,
data = df
)
# %%
# Make predictions at mean of w
w_mean <- mean(df$w)
line_grid <- t$data.plot$"Group Full Sample"$data.line
line_grid$w <- w_mean
line_grid$fit_feols <- predict(est, newdata = line_grid)
p <- ggplot() +
geom_line(
aes(x = x, y = fit_feols),
data = line_grid |> arrange(x)
) +
theme_bw()
# %%
#| fig.width: 12
#| fig.height: 8
common_y_scale <- scale_y_continuous(
limits = c(0.5, 3), expand = expansion(0.1, 0)
)
# Binsreg left and feols on right
(t$bins_plot + common_y_scale) + (p + common_y_scale)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment