R生成图表报错调整:CDE代码绘图失败、nls收敛异常如何解决?
错误原因
当Code取值为CDE时,对应数据的Numbers列所有值均为2,没有任何波动。此时要拟合的模型Numbers ~ b1*Days^2+b2存在参数不可识别问题:只要b2=2,无论b1取任意值都可以完全拟合数据,导致nls函数计算时出现奇异矩阵,触发收敛错误。
解决方案
在函数内增加数据波动判断逻辑:如果Numbers的方差接近0,直接绘制水平线即可,无需调用nls拟合。
修正后的完整可执行代码如下:
library(dplyr) library(tidyverse) library(lubridate) dmda<-"2021-07-07" datas <- structure( list(Code = c("ABC","ABC","ABC","CDE","CDE","CDE"), Days = c(1,2,3,1,2,3), Numbers = c(11,17,3,2,2,2)), class = "data.frame", row.names = c(NA, -6L)) f1 <- function(dat, code_nm) { dat <- subset(dat, Code == code_nm) plot(Numbers ~ Days, xlim= c(0,7), ylim= c(0,30), xaxs='i',data = dat,main = paste0(dmda, "-", code_nm)) # 数值无波动时直接画水平线 if(var(dat$Numbers) < 1e-9){ b2_val <- unique(dat$Numbers) abline(h = b2_val, lwd=2) points(0, b2_val, col="red",pch=19,cex = 2,xpd=TRUE) text(.99,b2_val + 1,round(b2_val,1), cex=1.1,pos=4,offset =1,col="black") return(invisible()) } model <- nls(Numbers ~ b1*Days^2+b2,start = list(b1 = 0,b2 = 0),data = dat, algorithm = "port") new.data <- data.frame(Days = with(dat, seq(min(Days),max(Days),len = 45))) new.data <- rbind(0, new.data) lines(new.data$Days,predict(model,newdata = new.data),lwd=2) coef<-coef(model)[2] points(0, coef, col="red",pch=19,cex = 2,xpd=TRUE) text(.99,coef + 1,round(coef,1), cex=1.1,pos=4,offset =1,col="black") } f1(datas, "ABC") f1(datas, "CDE")
运行上述代码可以同时正常生成ABC和CDE两组对应的可视化图表。
内容的提问来源于stack exchange,提问作者user16774617
相关产品推荐
相关产品推荐

