R特定日期绘图报错:07/02、07/03运行失败但07/01可正常生成图形
报错原因
- 核心问题是你筛选后用于
nls拟合的数据点数量不足,同时部分日期的样本数值特征容易导致拟合不收敛:- 你使用
datas <- datas[dif:max(datas$Days, na.rm = TRUE),]对数据集切片:- 当
dmda = "2021-07-01"时,dif = as.Date("2021-07-01") - as.Date("2021-06-28") +1 = 4,切片后剩余4个样本点,足够支撑二次函数(2个参数)的非线性最小二乘拟合 - 当
dmda = "2021-07-02"时,dif = 5,切片后剩余3个样本点,且3个点的Numbers值均为13,完全水平的数值分布会导致nls计算梯度时出现奇异矩阵,无法收敛 - 当
dmda = "2021-07-03"时,dif = 6,切片后仅剩余2个样本点,完全无法满足nls拟合的自由度要求
- 当
- 你给
nls设置的起始值list(b1 = 0,b2 = 0)也会加剧收敛失败的概率,和实际数据的数值区间差异过大。
- 你使用
修复方案
你可以根据需求选择以下任意一种修复方式:
方案1:调整切片逻辑,保留全量样本做拟合
如果你没有必须截断前N天数据的需求,直接删除datas <- datas[dif:max(datas$Days, na.rm = TRUE),]这一行即可,所有日期的样本都保留7个数据点,可正常完成拟合。
方案2:增加样本量判断逻辑,避免拟合报错
如果必须保留截断逻辑,可在拟合前增加判断,仅当样本量≥3时执行拟合,同时调整起始值和迭代参数降低收敛失败概率:
# 原有代码不变,在切片后替换原拟合绘图部分即可 if(nrow(datas) >=3) { mod <- nls(Numbers ~ b1*Days^2+b2,start = list(b1 = -0.1,b2 = 12), data = datas, control = nls.control(maxiter = 1000)) new.data <- data.frame(Days = with(datas, seq(min(Days),max(Days),len = 45))) new.data <- rbind(0, new.data) lines(new.data$Days, predict(mod, newdata=new.data)) points(0, coef(mod)[2], col="red", pch=19, cex=1.2, xpd=TRUE) }
方案3:更换拟合模型
如果数据点少是预期情况,可以把nls二次拟合更换为线性模型lm,对样本量的要求更低,2个点即可完成拟合。
内容的提问来源于stack exchange,提问作者Antonio
相关产品推荐
相关产品推荐

