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

使用ggpmisc的stat_poly_eq提取logit模型预测方程时遇报错

解决ggpmisc::stat_poly_eq添加方程时的报错及logit模型预测线绘制问题

问题描述

在基于真实数据绘制logit模型预测曲线并提取方程时,使用ggpmisc::stat_poly_eq函数,不添加use_label参数时能正常运行(仅显示R²=1),但添加use_label(labels=c("eq"))以显示方程时触发报错:

Error in `check_subclass()`:
! `x` must be either a string or a <Geom> object, not a <uneval> object.

报错来自ggplot2的check_subclass函数。

报错原因

  1. 语法错误:stat_poly_eq的use_label参数接受字符串或命名向量,而非函数调用。错误写法use_label(labels=c("eq"))会传入未求值的表达式(uneval对象),触发类型检查报错。
  2. 逻辑偏差:stat_poly_line和stat_poly_eq是用于拟合多项式回归的统计层,但代码中newdat已经是logit模型的非线性预测结果(S型曲线),用这两个函数会重新拟合多项式,既不符合logit模型的预测逻辑,也无法得到目标方程。

解决方案

步骤1:修正语法错误(仅解决报错,不匹配logit方程)

将错误的函数调用改为参数赋值:

stat_poly_eq(data=newdat, mapping=aes(x=newdat[[1]], y=newdat[[2]]),
             use_label = "eq")

注意:此方法仅解决报错,得到的是多项式拟合方程,不是logit模型的方程

步骤2:正确绘制logit预测曲线并显示logit方程

方法一:手动提取logit方程并添加

直接从模型中提取系数构建方程文本,用annotate添加到图中:

plot_logit_lab = function(log_mod){
  
  mod_frame = model.frame(log_mod)
  var_names = names(mod_frame)
  # 提取logit模型系数并保留三位小数
  coefs = round(coef(log_mod), 3)
  intercept = coefs[1]
  slope = coefs[2]
  # 构建概率形式的logit方程文本
  eq_text = paste0("P(y=1) = 1/(1+e^(-(", intercept, " + ", slope, "x)))")
  
  newdat = setNames(data.frame(seq(min(mod_frame[[2]]), max(mod_frame[[2]]), 
                                   len=100)),
                    var_names[2])

  newdat[var_names[1]] = predict(log_mod, newdata = newdat, type="response")
  
  the_plot <- ggplot() +
    geom_point(data=mod_frame, aes(x=.data[[var_names[2]]], y=.data[[var_names[1]]])) +   
    # 用geom_line绘制logit预测曲线,替代stat_poly_line
    geom_line(data=newdat, aes(x=.data[[var_names[2]]], y=.data[[var_names[1]]]), color="red") +
    # 在图中添加logit方程
    annotate("text", x=max(mod_frame[[2]])*0.8, y=max(mod_frame[[1]])*0.8, 
             label=eq_text, hjust=0, size=4)
  
  return(the_plot)
}

方法二:用ggpmisc::stat_fit_glm直接拟合并显示方程

无需手动计算预测值,直接用stat_fit_glm拟合logit模型并输出方程:

plot_logit_lab = function(log_mod){
  
  mod_frame = model.frame(log_mod)
  var_names = names(mod_frame)
  
  the_plot <- ggplot(mod_frame, aes(x=.data[[var_names[2]]], y=.data[[var_names[1]]])) +
    geom_point() +
    # 拟合logit模型并绘制曲线
    stat_fit_glm(method = "glm", method.args = list(family = binomial(link = "logit")),
                 geom = "line", aes(color="Logit Fit")) +
    # 解析并显示logit方程
    stat_fit_glm(method = "glm", method.args = list(family = binomial(link = "logit")),
                 geom = "text", aes(label = after_stat(eq.label)),
                 parse = TRUE, hjust=0, vjust=1) +
    scale_color_manual(values="red") +
    theme(legend.position="none")
  
  return(the_plot)
}

测试验证

运行原有测试代码,调用修正后的函数即可得到正确的logit预测曲线和方程:

car <- cars %>%
  mutate(d = case_when(dist < 50 ~ "less",
                        dist >= 50 ~ "more"),
         s = speed)

car$d <- factor(car$d, levels=c("less","more"))

car_sum <- car %>%
  count(s, d) %>%
  group_by(s) %>%
  mutate(s_n = sum(n),
         d_prob = n/sum(n))

car_logit <- glm(formula = d_prob ~ s,
                weight = s_n,
                family = binomial(link = "logit"),
                data = car_sum)

car_plot <- plot_logit_lab(car_logit)

car_plot

内容的提问来源于stack exchange,提问作者atlas-wants

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 10:28:11