You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中绘制分箱散点图并叠加两条binsreg拟合线?

R语言实现带双拟合线的分箱散点图(对应Stata binscatter)

步骤1:安装并加载所需包

install.packages(c("binsreg", "ggplot2", "dplyr"))
library(binsreg)
library(ggplot2)
library(dplyr)

步骤2:实现Stata式分箱散点+双binsreg拟合线

方法一:基于binsreg绘图对象叠加

先绘制第一组分箱散点与拟合线并保存为ggplot对象,再叠加第二组拟合线:

# 生成第一组(b~a)的分箱散点+三次拟合线,对应Stata的20分位数设置
p <- binsreg(
  y = df1$b, 
  x = df1$a, 
  line = c(3,3),  # 指定三次多项式拟合
  nbins = 20,     # 20个分位数箱
  plot = TRUE
)

# 获取第二组(c~a)的拟合线数据
fit_c <- binsreg(
  y = df1$c, 
  x = df1$a, 
  line = c(3,3),
  plot = FALSE  # 仅返回拟合数据不直接绘图
)

# 叠加第二组拟合线到已有图中
p <- p + 
  geom_line(
    data = fit_c$plot$line, 
    aes(x = x, y = fit), 
    color = "red",  # 自定义颜色区分两组拟合线
    linetype = "solid"
  )

# 调整样式匹配Stata参数
p <- p +
  labs(y = "", x = "title") +
  theme(
    panel.grid.major.y = element_blank(),
    panel.grid.minor.y = element_blank(),
    point.color = "black"
  )

# 展示最终图
print(p)

方法二:手动构建分箱数据+叠加拟合线(更灵活)

如果需要完全自定义分箱细节,可手动计算分箱均值后再叠加拟合线:

# 计算a的20分位数箱均值
df_binned <- df1 %>%
  mutate(a_bin = ntile(a, 20)) %>%
  group_by(a_bin) %>%
  summarise(
    a_mean = mean(a),
    b_mean = mean(b)
  )

# 获取两组拟合线的坐标数据
fit_b <- binsreg(y=df1$b, x=df1$a, line=c(3,3), plot=FALSE)$plot$line
fit_c <- binsreg(y=df1$c, x=df1$a, line=c(3,3), plot=FALSE)$plot$line

# 绘图
ggplot() +
  # 分箱散点(对应Stata binscatter)
  geom_point(data=df_binned, aes(x=a_mean, y=b_mean), color="black") +
  # 第一组拟合线
  geom_line(data=fit_b, aes(x=x, y=fit), color="black") +
  # 第二组拟合线
  geom_line(data=fit_c, aes(x=x, y=fit), color="red") +
  # 样式调整
  labs(y = "", x = "title") +
  theme(panel.grid.y = element_blank())

关键参数对应说明

  • nbins=20 / ntile(a,20):对应Stata的nquantiles(20),将x变量分成20个等样本量分箱
  • line=c(3,3):指定三次多项式拟合线,匹配Stata binscatter的拟合逻辑
  • theme(panel.grid.y = element_blank()):对应Stata的ylabel(, nogrid),去掉y轴网格

内容的提问来源于stack exchange,提问作者Tanja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:09:32