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

R语言optim()函数迭代时报'type 'closure' not subsettable'错误咨询

错误原因

核心问题来自两个低级错误:

  1. 目标函数参数顺序不符合optim要求:optim规定传入的损失函数第一个入参必须是待优化的参数向量,你定义的fit_nm2参数顺序是(data, par),第一个是固定数据集,第二个才是待优化参数。迭代时optim会把自动生成的候选参数传给损失函数的第一个入参,而你指定的data=rep被传给了第二个入参par,后续代码执行par[1]时,par实际是R内置的rep函数(closure类型),对函数取子集就会触发type 'closure' not subsettable报错。
  2. 变量命名冲突:你用R内置的重复函数名rep作为测试数据的变量名,进一步放大了参数传递错误的影响,即使调整参数顺序后,后续调用rep函数也可能出现变量覆盖问题。

迭代到中途才报错的原因是:前几轮迭代生成的参数刚好没触发par子集调用的校验,后续参数变化后才暴露了变量类型错误。

解决方法

按照以下步骤修正即可正常运行:

  1. 调整损失函数的参数顺序,将待优化的par放到第一个位置,同时增加参数合理性校验,避免无效参数(如标准差趋近于0、混合权重趋近于0/1)触发distr包内部报错:
library(distr)
library(e1071)

pmn2 <- function(p,mean1,mean2,sd1,sd2,w) {
  distr::p(
    distr::UnivarMixingDistribution(distr::Norm(mean1,sd1),
                                    distr::Norm(mean2,sd2),
                                    mixCoeff = c(w,1-w))
  )(p)
}

# 调整参数顺序,par放第一位
fit_nm2 <- function(par, data) {
  n <- nrow(data)
  bins <- data[,1]
  probs <- data[,2]
  wid <- (bins[n] - bins[1])/(n-1)
  # 先做参数校验,无效参数直接返回大损失值,让优化器跳过该区间
  w <- sigmoid(par[5])
  if (w < 1e-4 || w > 1 - 1e-4) return(1e10)
  sd1 <- exp(par[3])
  sd2 <- exp(par[4])
  if (sd1 < 1e-3 || sd2 < 1e-3) return(1e10)
  # 合并两次pmn2调用,减少重复计算
  mix_cdf <- p(UnivarMixingDistribution(Norm(par[1], sd1),
                                       Norm(par[2], sd2),
                                       mixCoeff = c(w, 1-w)))
  dif <- sum((mix_cdf(bins + wid) - mix_cdf(bins) - probs)^2)
  return(dif)
}
  1. 不要用rep作为数据变量名,换为无冲突的名称比如bin_data:
bin_data <- structure(c(4, 4.1, 4.2, 4.3, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9, 5, 
5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 6, 0.042145594, 
0.026819923, 0.003831418, 0.061302682, 0.011494253, 0.057471264, 
0.076628352, 0.042145594, 0.0651341, 0.042145594, 0.076628352, 
0.053639847, 0.026819923, 0.053639847, 0.08045977, 0.019157088, 
0.068965517, 0.072796935, 0.011494253, 0.049808429, 0.057471264
), .Dim = c(21L, 2L), .Dimnames = list(NULL, c("bins", "probs")))
  1. 重新调用optim即可正常运行:
fitnm2 <- optim(fn = fit_nm2, data = bin_data, par = c(5, 1, 5, 1, .5))

如果需要优化更稳定,可以指定method = "L-BFGS-B"给参数加上合理上下界,避免优化器探索到极端无效参数区间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 00:24:01