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

R中对按GaugeID分组的数据循环执行nls函数拟合提取参数w

批量分组nls拟合解决方案

报错原因

你遇到的报错是因为循环遍历GaugeID时未对每个GaugeID单独筛选子集就传入nls函数,导致长度为1的循环变量和全量数据集的变量长度不匹配。

方案1:tidyverse + broom 分组拟合(推荐)

该方案代码简洁,自带错误捕获不会因单个分组拟合失败中断全局流程:

# 加载依赖包
library(tidyverse)
library(broom)

# 分组拟合提取参数
w_result <- yearly %>%
  group_by(GaugeID) %>%
  nest() %>%
  mutate(
    # 对每个分组子集执行nls拟合,错误捕获避免中断
    nls_fit = map(data, ~ tryCatch(
      nls(ETvP ~ 1 + PETvP - (1 + PETvP^(w))^(1/w),
          data = .x,
          start = list(w = 2),
          # 可选:增加迭代次数解决收敛警告
          control = nls.control(maxiter = 1000)),
      error = function(e) NA
    )),
    # 提取w参数,拟合失败返回NA
    w_value = map_dbl(nls_fit, ~ ifelse(inherits(.x, "nls"), coef(.x)[["w"]], NA))
  ) %>%
  select(GaugeID, w_value) %>%
  ungroup()

方案2:base R 修正版for循环

适合不想引入tidyverse依赖的场景:

# 提取所有唯一GaugeID
gauge_list <- unique(yearly$GaugeID)
# 初始化结果存储
result_df <- data.frame(
  GaugeID = gauge_list,
  w_value = NA_real_
)

# 遍历拟合
for (i in seq_along(gauge_list)) {
  # 筛选当前分组的子集(核心修正点)
  sub_df <- yearly[yearly$GaugeID == gauge_list[i], ]
  # 执行拟合加错误捕获
  fit <- tryCatch(
    nls(ETvP ~ 1 + PETvP - (1 + PETvP^(w))^(1/w),
        data = sub_df,
        start = list(w = 2),
        control = nls.control(maxiter = 1000)),
    error = function(e) NA
  )
  # 写入结果
  if (inherits(fit, "nls")) {
    result_df$w_value[i] <- coef(fit)[["w"]]
  }
}

注意事项

  • 每个分组的有效样本量需要至少大于参数个数(本场景仅1个参数w,最少需要2个无缺失的有效样本,否则会拟合失败)
  • 最终结果中w_value为NA的分组,可单独提取子集排查数据质量或调整参数起始值重新拟合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:24:07